pike.git/
src/
interpret.c
Branch:
Tag:
Non-build tags
All tags
No tags
2017-11-18
2017-11-18 10:13:13 by Arne Goedeke <el@laramies.com>
ed7cdbf4c72739bda841e6e79073a65ce29d3854 (
260
lines) (+
168
/-
92
)
[
Show
|
Annotate
]
Branch:
arne/faster_calls_again
Interpreter: add tracing back into the new API
106:
PMOD_EXPORT int Pike_stack_size = EVALUATOR_STACK_SIZE; static void do_trace_call(struct byte_buffer *buf, INT32 args);
-
static void do_trace_func_return (
int got_retval,
struct object *o, int fun);
+
static void do_trace_func_return (struct object *o, int fun
, int got_retval
);
static void do_trace_return (struct byte_buffer *buf, int got_retval);
-
static void do_trace_efun_call(const struct svalue *s, INT32 args);
+
#ifdef PIKE_DEBUG
-
+
static void do_trace_efun_call(const struct svalue *s, INT32 args);
static void do_trace_efun_return(const struct svalue *s, int got_retval); #endif
1821:
#undef DO_IF_REAL_DEBUG #undef DO_IF_NOT_REAL_DEBUG
-
+
ATTRIBUTE((noinline)) static void do_trace_call(struct byte_buffer *b, INT32 args) {
1889:
buffer_free(b); }
+
#ifdef PIKE_DEBUG
ATTRIBUTE((noinline))
-
static void do_
dtrace
_
function
_call(
struct object *o,
const struct
identifier
*
function
, INT32 args) {
-
/*
DTrace
enter
probe
-
arg0: function name
-
arg1: object
-
*/
-
struct byte_buffer
obj_name
= BUFFER_INIT();
-
struct
svalue
obj_sval;
-
SET_SVAL
(
obj_sval, T_OBJECT, 0, object, o);
-
safe_describe_svalue(&obj_name, &obj_sval, 0, NULL);
-
PIKE_FN_START(function
->name->size_shift
== 0 ?
-
function->name->
str
:
"[widestring
fn
name]"
,
-
buffer_
get
_
string
(s)
)
;
-
buffer
_
free
(&
obj_name
);
+
static void do_
trace
_
efun
_call(const struct
svalue
*
s
, INT32 args) {
+
if
(Pike_interpreter.trace_level
>
1)
{
+
struct byte_buffer
buf
= BUFFER_INIT();
+
if
(
s
->
u.efun->
name->size_shift
)
+
buffer_add_
str
(&buf,
"[widestring
function
name]"
);
+
else
+
buffer_
add
_
str
(
&buf,
s
->u.efun->name->str
);
+
do
_
trace_call
(&
buf, args
);
}
-
-
ATTRIBUTE((noinline))
-
static
void
do_dtrace_func_return(struct object *o, int fun) {
-
/* DTrace leave probe
-
arg0: function name
-
*/
-
char *fn = "(unknown)";
-
if (
o && o->prog) {
-
struct identifier *id = ID_FROM_INT(o->prog, fun);
-
fn = id->name->size_shift == 0 ? id->name->str : "[widestring fn name]";
-
}
-
PIKE_FN_
DONE
(
fn
)
;
-
}
-
-
ATTRIBUTE((noinline
)
)
-
static
void do_dtrace_efun_call(const struct svalue *s, INT32 args)
{
+
if (PIKE_FN_
START_ENABLED
()) {
/* DTrace enter probe arg0: function name arg1: object
1928:
s->u.efun->name->str : "[widestring fn name]", ""); }
-
ATTRIBUTE((noinline))
-
static void do_dtrace_efun_return(const struct svalue *s, INT32 args) {
-
/* DTrace leave probe
-
arg0: function name
-
*/
-
PIKE_FN_DONE(s->u.efun->name->size_shift == 0 ?
-
s->u.efun->name->str : "[widestring fn name]");
+
} ATTRIBUTE((noinline))
-
static void do_trace_
function
_
call
(const struct
object
*
o
,
const
struct identifier *function, INT32 args
) {
-
struct byte_buffer buffer = BUFFER_INIT();
-
char buf[50];
-
-
sprintf(buf, "%lx->", (long) PTR_TO_INT (o));
-
buffer_add_str(&buffer, buf);
-
if (
function->name->size
_
shift)
-
buffer
_
add_str
(&buffer, "[widestring function name]");
-
else
-
buffer_add_str(&buffer, function-
>
name->str);
-
do_trace_call(&buffer, args
)
;
-
}
-
-
ATTRIBUTE((noinline))
-
static
void do_trace_efun_call(const struct svalue *s, INT32 args)
{
+
static void do_trace_
efun
_
return
(const struct
svalue
*
s
,
int
got_retval
) {
+
if (
Pike
_
interpreter.trace
_
level
>
1
) {
struct byte_buffer buf = BUFFER_INIT(); if (s->u.efun->name->size_shift) buffer_add_str (&buf, "[widestring function name]"); else buffer_add_str (&buf, s->u.efun->name->str);
-
do_trace_
call
(&buf,
args
);
+
buffer_add_str (&buf, "() ");
+
do_trace_
return
(&buf,
got_retval
);
}
-
-
ATTRIBUTE((noinline))
-
static
void
do
_
trace
_
svalue
_
call
(
const
struct
svalue
*
s,
INT32
args)
{
-
struct
byte_buffer
buf
=
BUFFER_INIT();
-
safe
_
describe
_
svalue
(
&buf,
s
,
0
,0);
-
do_trace_call(&buf,
args
);
+
if
(
PIKE_FN_DONE_ENABLED
())
{
+
/
*
DTrace
leave
probe
+
arg0: function name
+
*/
+
PIKE
_
FN
_
DONE
(
s->u.efun->name->size_shift
==
0
?
+
s->u.efun->name->str : "[widestring fn name]"
);
}
-
+
}
+
#endif
-
+
ATTRIBUTE((noinline))
-
static void do_trace_func_return (
int got_retval,
struct object *o, int fun)
+
static void do_trace_func_return (struct object *o, int fun
, int got_retval
)
{ struct byte_buffer b = BUFFER_INIT(); if (o) {
1991:
do_trace_return (&b, got_retval); }
-
#ifdef PIKE_DEBUG
+
ATTRIBUTE((noinline))
-
static void do_trace_efun_return(const struct svalue *s, int got_retval) {
-
struct byte_buffer buf = BUFFER_INIT();
-
if (s->u.efun->name->size_shift)
-
buffer_add_str (&buf, "[widestring function name]");
-
else
-
buffer_add_str (&buf, s->u.efun->name->str);
-
buffer_add_str (&buf, "() ");
-
do_trace_return (&buf, got_retval);
-
}
-
#endif
-
-
ATTRIBUTE((noinline))
+
static void do_trace_return (struct byte_buffer *b, int got_retval) { struct pike_string *filep = NULL;
2307:
#endif if(UNLIKELY(Pike_interpreter.trace_level>1))
-
do_trace_func_return (
1,
o, fun);
+
do_trace_func_return (
o
,
fun
,
1
);
#if defined (PIKE_USE_MACHINE_CODE) && defined (OPCODE_RETURN_JUMPADDR) free_object (o);
3317:
* */
+
static void callsite_trace_return(const struct pike_callsite *c);
+
static void callsite_trace_call_fun(const struct pike_callsite *c);
+
static void callsite_trace_call_svalue(const struct pike_callsite *c, const struct svalue *s);
+
ATTRIBUTE((noreturn, noinline)) static void callsite_svalue_error(struct pike_callsite *c, const struct svalue *s) { INT32 args = c->args;
3481:
#endif UNREACHABLE(break); }
-
+
/* * The cases which do _not_ return, have a frame created. These are: * CALLTYPE_CFUN, CALLTYPE_PIKEFUN and CALLTYPE_PARENT_CLONE.
3517:
check_stack(256); check_mark_stack(256);
+
+
if (PIKE_NEEDS_TRACE())
+
callsite_trace_call_fun(c);
} PMOD_EXPORT void callsite_resolve_lfun(struct pike_callsite *c, struct object *o, int lfun) {
3569:
callsite_resolve_lfun(c, s->u.object, LFUN_CALL); return; }
+
if (PIKE_NEEDS_TRACE())
+
callsite_trace_call_svalue(c, s);
} PMOD_EXPORT void callsite_reset_pikecall(struct pike_callsite *c) {
3739:
stack_pop_n_elems_keep_top (sp - retval - 1); low_destruct_objects_to_destruct(); }
+
+
if (PIKE_NEEDS_TRACE())
+
callsite_trace_return(c);
}
-
+
ATTRIBUTE((noinline))
+
static void callsite_trace_call_fun(const struct pike_callsite *c) {
+
struct object *o = Pike_fp->current_object;
+
struct identifier *function = ID_FROM_INT (o->prog, Pike_fp->fun);
+
+
if (Pike_interpreter.trace_level > 1) {
+
struct byte_buffer buf = BUFFER_INIT();
+
char tmp[50];
+
+
sprintf(tmp, "%lx->", (long) PTR_TO_INT (o));
+
buffer_add_str(&buf, tmp);
+
if (function->name->size_shift)
+
buffer_add_str (&buf, "[widestring function name]");
+
else
+
buffer_add_str(&buf, function->name->str);
+
do_trace_call(&buf, c->args);
+
}
+
if (PIKE_FN_START_ENABLED()) {
+
/* DTrace enter probe
+
arg0: function name
+
arg1: object
+
*/
+
struct byte_buffer buf = BUFFER_INIT();
+
struct svalue obj_sval;
+
SET_SVAL(obj_sval, T_OBJECT, 0, object, o);
+
safe_describe_svalue(&buf, &obj_sval, 0, NULL);
+
PIKE_FN_START(function->name->size_shift == 0 ?
+
function->name->str : "[widestring fn name]",
+
buffer_get_string(s));
+
buffer_free(&buf);
+
}
+
}
+
+
ATTRIBUTE((noinline))
+
static void callsite_trace_call_svalue(const struct pike_callsite *c, const struct svalue *s) {
+
if (Pike_interpreter.trace_level > 1) {
+
struct byte_buffer buf = BUFFER_INIT();
+
+
switch (c->type) {
+
case CALLTYPE_EFUN:
+
if (s->u.efun->name->size_shift)
+
buffer_add_str (&buf, "[widestring function name]");
+
else
+
buffer_add_str (&buf, s->u.efun->name->str);
+
break;
+
default:
+
/* this is CAST, CALL_ARRAY and the CLONE variants */
+
safe_describe_svalue(&buf, s, 0, 0);
+
break;
+
}
+
+
do_trace_call(&buf, c->args);
+
}
+
if (PIKE_FN_START_ENABLED()) {
+
struct byte_buffer buf = BUFFER_INIT();
+
const char *str;
+
+
switch (c->type) {
+
case CALLTYPE_EFUN:
+
if (s->u.efun->name->size_shift)
+
buffer_add_str (&buf, "[widestring function name]");
+
else
+
buffer_add_str (&buf, s->u.efun->name->str);
+
break;
+
default:
+
/* this is CAST, CALL_ARRAY and the CLONE variants */
+
safe_describe_svalue(&buf, s, 0, 0);
+
break;
+
}
+
+
PIKE_FN_START(buffer_get_string(&buf), "");
+
buffer_free(&buf);
+
}
+
}
+
+
ATTRIBUTE((noinline))
+
static void callsite_trace_return(const struct pike_callsite *c) {
+
if (Pike_interpreter.trace_level > 1) {
+
int got_retval = c->retval < Pike_sp;
+
+
if (c->type == CALLTYPE_CFUN || c->type == CALLTYPE_PIKEFUN) {
+
do_trace_func_return(c->frame->current_object, c->frame->fun, got_retval);
+
} else {
+
struct byte_buffer buf = BUFFER_INIT();
+
+
if (c->type == CALLTYPE_EFUN) {
+
buffer_add_str(&buf, "EFUN");
+
} else {
+
struct svalue sv;
+
+
switch (c->type) {
+
case CALLTYPE_PARENT_CLONE:
+
case CALLTYPE_CLONE:
+
SET_SVAL(sv, T_PROGRAM, 0, program, c->ptr);
+
break;
+
case CALLTYPE_CAST:
+
SET_SVAL(sv, T_TYPE, 0, type, c->ptr);
+
break;
+
default:
+
/* not really reachable */
+
SET_SVAL(sv, T_INT, 0, integer, 0);
+
break;
+
}
+
safe_describe_svalue(&buf, &sv, 0, 0);
+
}
+
+
do_trace_return(&buf, got_retval);
+
}
+
}
+
if (PIKE_FN_DONE_ENABLED()) {
+
/* TODO: fixme */
+
}
+
}
+
+
/* Without fancy accounting stuff. This one can't assume there is an * identifier corresponding to the frame (i.e. _fp_->ident might be * bogus). */