aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_trace.c
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2010-03-22 14:51:35 +0000
committerErlang/OTP <[email protected]>2010-03-22 15:56:43 +0100
commita4b4d36cdbbd692123443a1d3f19f1c452963201 (patch)
tree218002c4a2b38f69eb67d6388c8034820812fd47 /erts/emulator/beam/erl_trace.c
parent835dba95f810cc925ac856171014b9dbea8c90be (diff)
parent24095d93fb28bdd60abe771a426e39c6ff0f72c7 (diff)
downloadotp-a4b4d36cdbbd692123443a1d3f19f1c452963201.tar.gz
otp-a4b4d36cdbbd692123443a1d3f19f1c452963201.tar.bz2
otp-a4b4d36cdbbd692123443a1d3f19f1c452963201.zip
Merge branch 'pan/otp_8332_halfword' into dev
* pan/otp_8332_halfword: Teach testcase in driver_suite the new prototype for driver_async wx: Correct usage of driver callbacks from wx thread Adopt the new (R13B04) Nif functionality to the halfword codebase Support monitoring and demonitoring from driver threads Fix further test-suite problems Correct the VM to work for more test suites Teach {wordsize,internal|external} to system_info/1 Make tracing and distribution work Turn on instruction packing in the loader and virtual machine Add the BeamInstr data type for loaded BEAM code Fix the BEAM dissambler for the half-word emulator Store pointers to heap data in 32-bit words Add a custom mmap wrapper to force heaps into the lower address range Fit all heap data into the 32-bit address range
Diffstat (limited to 'erts/emulator/beam/erl_trace.c')
-rw-r--r--erts/emulator/beam/erl_trace.c247
1 files changed, 192 insertions, 55 deletions
diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c
index 2842c2361a..8addfcf5ad 100644
--- a/erts/emulator/beam/erl_trace.c
+++ b/erts/emulator/beam/erl_trace.c
@@ -397,11 +397,13 @@ WRITE_SYS_MSG_TO_PORT(Eterm unused_to,
*/
static void
do_send_schedfix_to_port(Port *trace_port, Eterm pid, Eterm timestamp) {
- Eterm local_heap[4+5+5];
+#define LOCAL_HEAP_SIZE (4+5+5)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
Eterm message;
Eterm *hp;
Eterm mfarity;
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
ASSERT(is_pid(pid));
ASSERT(is_tuple(timestamp));
ASSERT(*tuple_val(timestamp) == make_arityval(3));
@@ -426,6 +428,8 @@ do_send_schedfix_to_port(Port *trace_port, Eterm pid, Eterm timestamp) {
pid,
SYS_MSG_TYPE_UNDEFINED,
message);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
}
#endif
@@ -442,7 +446,9 @@ send_to_port(Process *c_p, Eterm message,
Eterm *tracer_pid, Uint *tracee_flags) {
Port* trace_port;
#ifndef ERTS_SMP
- Eterm ts, local_heap[4], *hp;
+#define LOCAL_HEAP_SIZE (4)
+ Eterm ts, *hp;
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
#endif
ASSERT(is_internal_port(*tracer_pid));
@@ -486,6 +492,8 @@ send_to_port(Process *c_p, Eterm message,
* (e.g. getting_linked) need not be the current process. That other
* process might not have timestamps enabled.
*/
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
if (*tracee_flags & F_TIMESTAMP) {
ASSERT(is_tuple(message));
hp = tuple_val(message);
@@ -522,6 +530,8 @@ send_to_port(Process *c_p, Eterm message,
*/
do_send_schedfix_to_port(trace_port, c_p->id, ts);
}
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
#endif
}
@@ -589,7 +599,10 @@ seq_trace_send_to_port(Process *c_p,
{
Port* trace_port;
#ifndef ERTS_SMP
- Eterm ts, local_heap[4], *hp;
+ Eterm ts, *hp;
+#define LOCAL_HEAP_SIZE (4)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
#endif
ASSERT(is_internal_port(seq_tracer));
@@ -607,6 +620,9 @@ seq_trace_send_to_port(Process *c_p,
if (INVALID_TRACER_PORT(trace_port, seq_tracer)) {
invalid_tracer_port:
system_seq_tracer = am_false;
+#ifndef ERTS_SMP
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#endif
return;
}
@@ -620,6 +636,7 @@ seq_trace_send_to_port(Process *c_p,
message);
#ifndef ERTS_SMP
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
return;
}
/* Make a fake schedule only if the current process is traced
@@ -660,6 +677,8 @@ seq_trace_send_to_port(Process *c_p,
*/
do_send_schedfix_to_port(trace_port, c_p->id, ts);
}
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
#endif
}
@@ -719,7 +738,8 @@ send_to_tracer(Process *tracee,
static void
trace_sched_aux(Process *p, Eterm what, int never_fake_sched)
{
- Eterm local_heap[5+4+1+TS_HEAP_WORDS];
+#define LOCAL_HEAP_SIZE (5+4+1+TS_HEAP_WORDS)
+ DeclareTmpHeap(local_heap,LOCAL_HEAP_SIZE,p);
Eterm tmp, mess, *hp;
ErlHeapFragment *bp = NULL;
ErlOffHeap *off_heap;
@@ -768,8 +788,10 @@ trace_sched_aux(Process *p, Eterm what, int never_fake_sched)
curr_func = p->current != NULL;
}
+ UseTmpHeap(LOCAL_HEAP_SIZE,p);
+
if (to_port)
- hp = &local_heap[0];
+ hp = local_heap;
else {
Uint size = 5;
if (curr_func)
@@ -802,6 +824,8 @@ trace_sched_aux(Process *p, Eterm what, int never_fake_sched)
}
send_to_tracer(p, tracer_ref, mess, &hp, bp, no_fake_sched);
+ UnUseTmpHeap(LOCAL_HEAP_SIZE,p);
+#undef LOCAL_HEAP_SIZE
}
/* Send {trace_ts, Pid, What, {Mod, Func, Arity}, Timestamp}
@@ -848,7 +872,10 @@ trace_send(Process *p, Eterm to, Eterm msg)
}
if (is_internal_port(p->tracer_proc)) {
- Eterm local_heap[11];
+#define LOCAL_HEAP_SIZE (11)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
mess = TUPLE5(hp, am_trace, p->id, operation, msg, to);
hp += 6;
@@ -857,6 +884,8 @@ trace_send(Process *p, Eterm to, Eterm msg)
hp = patch_ts(mess, hp);
}
send_to_port(p, mess, &p->tracer_proc, &p->trace_flags);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
erts_smp_mtx_unlock(&smq_mtx);
} else {
Uint need;
@@ -908,7 +937,10 @@ trace_receive(Process *rp, Eterm msg)
Eterm* hp;
if (is_internal_port(rp->tracer_proc)) {
- Eterm local_heap[10];
+#define LOCAL_HEAP_SIZE (10)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
mess = TUPLE4(hp, am_trace, rp->id, am_receive, msg);
hp += 5;
@@ -917,6 +949,8 @@ trace_receive(Process *rp, Eterm msg)
hp = patch_ts(mess, hp);
}
send_to_port(rp, mess, &rp->tracer_proc, &rp->trace_flags);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
erts_smp_mtx_unlock(&smq_mtx);
} else {
Uint hsz;
@@ -1018,7 +1052,10 @@ seq_trace_output_generic(Eterm token, Eterm msg, Uint type,
}
if (is_internal_port(seq_tracer)) {
- Eterm local_heap[64];
+#define LOCAL_HEAP_SIZE (64)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
label = SEQ_TRACE_T_LABEL(token);
lastcnt_serial = TUPLE2(hp, SEQ_TRACE_T_LASTCNT(token),
@@ -1043,6 +1080,8 @@ seq_trace_output_generic(Eterm token, Eterm msg, Uint type,
mess = TUPLE4(hp, am_seq_trace, label, mess, ts);
seq_trace_send_to_port(process, seq_tracer, mess, ts);
}
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
erts_smp_mtx_unlock(&smq_mtx);
} else {
#ifndef ERTS_SMP
@@ -1143,14 +1182,18 @@ seq_trace_output_generic(Eterm token, Eterm msg, Uint type,
* or {trace, Pid, return_to, {Mod, Func, Arity}}
*/
void
-erts_trace_return_to(Process *p, Uint *pc)
+erts_trace_return_to(Process *p, BeamInstr *pc)
{
+#define LOCAL_HEAP_SIZE (4+5+5)
Eterm* hp;
Eterm mfa;
Eterm mess;
- Eterm local_heap[4+5+5];
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
- Eterm *code_ptr = find_function_from_pc(pc);
+ BeamInstr *code_ptr = find_function_from_pc(pc);
+
+
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
hp = local_heap;
@@ -1196,6 +1239,8 @@ erts_trace_return_to(Process *p, Uint *pc)
mess = copy_struct(mess, size, &hp, off_heap);
ERTS_ENQ_TRACE_MSG(p->id, tracer_ref, mess, bp);
}
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
erts_smp_mtx_unlock(&smq_mtx);
}
@@ -1204,7 +1249,7 @@ erts_trace_return_to(Process *p, Uint *pc)
* or {trace, Pid, return_from, {Mod, Name, Arity}, Retval}
*/
void
-erts_trace_return(Process* p, Eterm* fi, Eterm retval, Eterm *tracer_pid)
+erts_trace_return(Process* p, BeamInstr* fi, Eterm retval, Eterm *tracer_pid)
{
Eterm* hp;
Eterm mfa;
@@ -1262,7 +1307,9 @@ erts_trace_return(Process* p, Eterm* fi, Eterm retval, Eterm *tracer_pid)
arity = fi[2];
if (is_internal_port(*tracer_pid)) {
- Eterm local_heap[4+6+5];
+#define LOCAL_HEAP_SIZE (4+6+5)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
hp = local_heap;
mfa = TUPLE3(hp, mod, name, make_small(arity));
hp += 4;
@@ -1273,6 +1320,8 @@ erts_trace_return(Process* p, Eterm* fi, Eterm retval, Eterm *tracer_pid)
hp = patch_ts(mess, hp);
}
send_to_port(p, mess, tracer_pid, tracee_flags);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
erts_smp_mtx_unlock(&smq_mtx);
} else {
ErlHeapFragment *bp;
@@ -1331,7 +1380,7 @@ erts_trace_return(Process* p, Eterm* fi, Eterm retval, Eterm *tracer_pid)
* Where Class is atomic but Value is any term.
*/
void
-erts_trace_exception(Process* p, Eterm mfa[3], Eterm class, Eterm value,
+erts_trace_exception(Process* p, BeamInstr mfa[3], Eterm class, Eterm value,
Eterm *tracer_pid)
{
Eterm* hp;
@@ -1385,21 +1434,26 @@ erts_trace_exception(Process* p, Eterm mfa[3], Eterm class, Eterm value,
}
if (is_internal_port(*tracer_pid)) {
- Eterm local_heap[4+3+6+5];
+#define LOCAL_HEAP_SIZE (4+3+6+5)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
- mfa_tuple = TUPLE3(hp, mfa[0], mfa[1], make_small(mfa[2]));
+ mfa_tuple = TUPLE3(hp, (Eterm) mfa[0], (Eterm) mfa[1], make_small((Eterm)mfa[2]));
hp += 4;
cv = TUPLE2(hp, class, value);
hp += 3;
mess = TUPLE5(hp, am_trace, p->id, am_exception_from, mfa_tuple, cv);
hp += 6;
- ASSERT((hp - local_heap)*sizeof(*hp) <= sizeof(local_heap));
+ ASSERT((hp - local_heap) <= LOCAL_HEAP_SIZE);
erts_smp_mtx_lock(&smq_mtx);
if (*tracee_flags & F_TIMESTAMP) {
hp = patch_ts(mess, hp); /* hp += 5 */
- ASSERT((hp - local_heap)*sizeof(*hp) == sizeof(local_heap));
+ ASSERT((hp - local_heap) == LOCAL_HEAP_SIZE);
}
send_to_port(p, mess, tracer_pid, tracee_flags);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
erts_smp_mtx_unlock(&smq_mtx);
} else {
ErlHeapFragment *bp;
@@ -1431,7 +1485,7 @@ erts_trace_exception(Process* p, Eterm mfa[3], Eterm class, Eterm value,
* Build the trace tuple and put it into receive queue of the tracer process.
*/
- mfa_tuple = TUPLE3(hp, mfa[0], mfa[1], make_small(mfa[2]));
+ mfa_tuple = TUPLE3(hp, (Eterm) mfa[0], (Eterm) mfa[1], make_small((Eterm) mfa[2]));
hp += 4;
value = copy_struct(value, value_size, &hp, off_heap);
cv = TUPLE2(hp, class, value);
@@ -1468,7 +1522,7 @@ erts_trace_exception(Process* p, Eterm mfa[3], Eterm class, Eterm value,
* if it is a pid or port we do a meta trace.
*/
Uint32
-erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
+erts_call_trace(Process* p, BeamInstr mfa[3], Binary *match_spec,
Eterm* args, int local, Eterm *tracer_pid)
{
Eterm* hp;
@@ -1483,7 +1537,8 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
Eterm tracee;
#endif
Eterm transformed_args[MAX_ARG];
- ErlSubBin sub_bin_heap;
+ DeclareTmpHeap(sub_bin_heap_et,ERL_SUB_BIN_SIZE,p);
+ ErlSubBin *sub_bin_heap = (ErlSubBin *) sub_bin_heap_et;
ASSERT(tracer_pid);
if (*tracer_pid == am_true) {
@@ -1534,19 +1589,20 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
* such as size_object() and copy_struct(), we must make sure that we
* temporarily convert any match contexts to sub binaries.
*/
- arity = mfa[2];
+ arity = (Eterm) mfa[2];
+ UseTmpHeap(ERL_SUB_BIN_SIZE,p);
#ifdef DEBUG
- sub_bin_heap.thing_word = 0;
+ sub_bin_heap->thing_word = 0;
#endif
for (i = 0; i < arity; i++) {
Eterm arg = args[i];
if (is_boxed(arg) && header_is_bin_matchstate(*boxed_val(arg))) {
ErlBinMatchState* ms = (ErlBinMatchState *) boxed_val(arg);
ErlBinMatchBuffer* mb = &ms->mb;
- ErlSubBin* sb = &sub_bin_heap;
+ ErlSubBin* sb = sub_bin_heap;
Uint bit_size;
- ASSERT(sub_bin_heap.thing_word == 0); /* At most one of match context */
+ ASSERT(sub_bin_heap->thing_word == 0); /* At most one of match context */
bit_size = mb->size - mb->offset;
sb->thing_word = HEADER_SUB_BIN;
@@ -1564,7 +1620,12 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
args = transformed_args;
if (is_internal_port(*tracer_pid)) {
+#if HEAP_ON_C_STACK
Eterm local_heap[64+MAX_ARG];
+#else
+ Eterm *local_heap = erts_alloc(ERTS_ALC_T_TEMP_TERM,
+ sizeof(Eterm)*(64+MAX_ARG));
+#endif
hp = local_heap;
if (!erts_is_valid_tracer_port(*tracer_pid)) {
@@ -1579,6 +1640,10 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
if (is_not_nil(tracee))
erts_smp_proc_unlock(p, ERTS_PROC_LOCKS_ALL_MINOR);
#endif
+#if !HEAP_ON_C_STACK
+ erts_free(ERTS_ALC_T_TEMP_TERM,local_heap);
+#endif
+ UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
return 0;
}
@@ -1605,6 +1670,10 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
&return_flags);
if (is_non_value(pam_result)) {
erts_match_set_release_result(p);
+#if !HEAP_ON_C_STACK
+ erts_free(ERTS_ALC_T_TEMP_TERM,local_heap);
+#endif
+ UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
return 0;
}
}
@@ -1612,16 +1681,28 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
/* Meta trace */
if (pam_result == am_false) {
erts_match_set_release_result(p);
+#if !HEAP_ON_C_STACK
+ erts_free(ERTS_ALC_T_TEMP_TERM,local_heap);
+#endif
+ UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
return return_flags;
}
} else {
/* Non-meta trace */
if (*tracee_flags & F_TRACE_SILENT) {
erts_match_set_release_result(p);
+#if !HEAP_ON_C_STACK
+ erts_free(ERTS_ALC_T_TEMP_TERM,local_heap);
+#endif
+ UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
return 0;
}
if (pam_result == am_false) {
erts_match_set_release_result(p);
+#if !HEAP_ON_C_STACK
+ erts_free(ERTS_ALC_T_TEMP_TERM,local_heap);
+#endif
+ UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
return return_flags;
}
if (local && (*tracee_flags & F_TRACE_RETURN_TO)) {
@@ -1644,7 +1725,7 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
hp += 2;
}
}
- mfa_tuple = TUPLE3(hp, mfa[0], mfa[1], mfa_tuple);
+ mfa_tuple = TUPLE3(hp, (Eterm) mfa[0], (Eterm) mfa[1], mfa_tuple);
hp += 4;
/*
@@ -1664,6 +1745,10 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
send_to_port(p, mess, tracer_pid, tracee_flags);
erts_smp_mtx_unlock(&smq_mtx);
erts_match_set_release_result(p);
+#if !HEAP_ON_C_STACK
+ erts_free(ERTS_ALC_T_TEMP_TERM,local_heap);
+#endif
+ UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
return *tracer_pid == NIL ? 0 : return_flags;
} else {
@@ -1706,6 +1791,7 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
if (is_not_nil(tracee))
erts_smp_proc_unlock(p, ERTS_PROC_LOCKS_ALL_MINOR);
#endif
+ UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
return 0;
}
@@ -1731,6 +1817,7 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
&return_flags);
if (is_non_value(pam_result)) {
erts_match_set_release_result(p);
+ UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
return 0;
}
}
@@ -1738,16 +1825,19 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
/* Meta trace */
if (pam_result == am_false) {
erts_match_set_release_result(p);
+ UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
return return_flags;
}
} else {
/* Non-meta trace */
if (*tracee_flags & F_TRACE_SILENT) {
erts_match_set_release_result(p);
+ UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
return 0;
}
if (pam_result == am_false) {
erts_match_set_release_result(p);
+ UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
return return_flags;
}
if (local && (*tracee_flags & F_TRACE_RETURN_TO)) {
@@ -1798,7 +1888,7 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
hp += 2;
}
}
- mfa_tuple = TUPLE3(hp, mfa[0], mfa[1], mfa_tuple);
+ mfa_tuple = TUPLE3(hp, (Eterm) mfa[0], (Eterm) mfa[1], mfa_tuple);
hp += 4;
/*
@@ -1831,6 +1921,7 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
ASSERT(hp == limit);
ERTS_ENQ_TRACE_MSG(tracee, tracer_ref, mess, bp);
erts_smp_mtx_unlock(&smq_mtx);
+ UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
return return_flags;
}
}
@@ -1851,7 +1942,10 @@ trace_proc(Process *c_p, Process *t_p, Eterm what, Eterm data)
int need;
if (is_internal_port(t_p->tracer_proc)) {
- Eterm local_heap[5+5];
+#define LOCAL_HEAP_SIZE (5+5)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
mess = TUPLE4(hp, am_trace, t_p->id, what, data);
hp += 5;
@@ -1868,6 +1962,8 @@ trace_proc(Process *c_p, Process *t_p, Eterm what, Eterm data)
c_p,
#endif
mess, &t_p->tracer_proc, &t_p->trace_flags);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
erts_smp_mtx_unlock(&smq_mtx);
} else {
Eterm tmp;
@@ -1919,7 +2015,10 @@ trace_proc_spawn(Process *p, Eterm pid,
Eterm* hp;
if (is_internal_port(p->tracer_proc)) {
- Eterm local_heap[4+6+5];
+#define LOCAL_HEAP_SIZE (4+6+5)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
mfa = TUPLE3(hp, mod, func, args);
hp += 4;
@@ -1930,6 +2029,8 @@ trace_proc_spawn(Process *p, Eterm pid,
hp = patch_ts(mess, hp);
}
send_to_port(p, mess, &p->tracer_proc, &p->trace_flags);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
erts_smp_mtx_unlock(&smq_mtx);
} else {
Eterm tmp;
@@ -1991,7 +2092,7 @@ void save_calls(Process *p, Export *e)
*/
Eterm
erts_bif_trace(int bif_index, Process* p,
- Eterm arg1, Eterm arg2, Eterm arg3, Uint *I)
+ Eterm arg1, Eterm arg2, Eterm arg3, BeamInstr *I)
{
Eterm result;
int meta = !!(erts_bif_trace_flags[bif_index] & BIF_TRACE_AS_META);
@@ -2005,10 +2106,10 @@ erts_bif_trace(int bif_index, Process* p,
* no tracing will occur. Doing the whole else branch will
* also do nothing, only slower.
*/
- Eterm (*func)(Process*, Eterm, Eterm, Eterm, Uint*) = bif_table[bif_index].f;
+ Eterm (*func)(Process*, Eterm, Eterm, Eterm, BeamInstr*) = bif_table[bif_index].f;
result = func(p, arg1, arg2, arg3, I);
} else {
- Eterm (*func)(Process*, Eterm, Eterm, Eterm, Uint*);
+ Eterm (*func)(Process*, Eterm, Eterm, Eterm, BeamInstr*);
Export* ep = bif_export[bif_index];
Uint32 flags = 0, flags_meta = 0;
int global = !!(erts_bif_trace_flags[bif_index] & BIF_TRACE_AS_GLOBAL);
@@ -2017,16 +2118,9 @@ erts_bif_trace(int bif_index, Process* p,
int applying = (I == &(ep->code[3])); /* Yup, the apply code for a bif
* is actually in the
* export entry */
- Eterm *cp = p->cp;
+ BeamInstr *cp = p->cp;
-#ifndef _OSE_
Eterm args[3] = {arg1, arg2, arg3};
-#else
- Eterm args[3];
- args[0] = arg1;
- args[1] = arg2;
- args[2] = arg3;
-#endif
/*
* Make continuation pointer OK, it is not during direct BIF calls,
@@ -2056,12 +2150,11 @@ erts_bif_trace(int bif_index, Process* p,
Eterm *cpp;
/* Maybe advance cp to skip trace stack frames */
for (cpp = p->stop; ; cp = cp_val(*cpp++)) {
- ASSERT(is_CP((Eterm) cp));
- if (*cp_val((Eterm) cp) == i_return_trace) {
+ if (*cp == i_return_trace) {
/* Skip stack frame variables */
while (is_not_CP(*cpp)) cpp++;
cpp += 2; /* Skip return_trace parameters */
- } else if (*cp_val((Eterm) cp) == i_return_to_trace) {
+ } else if (*cp == i_return_to_trace) {
/* A return_to trace message is going to be generated
* by normal means, so we do not have to.
*/
@@ -2078,7 +2171,8 @@ erts_bif_trace(int bif_index, Process* p,
if (reason != TRAP) {
Eterm class;
Eterm value = p->fvalue;
- Eterm nocatch[3];
+ DeclareTmpHeapNoproc(nocatch,3);
+ UseTmpHeapNoproc(3);
/* Expand error value like in handle_error() */
if (reason & EXF_ARGLIST) {
Eterm *tp;
@@ -2126,6 +2220,7 @@ erts_bif_trace(int bif_index, Process* p,
}
}
}
+ UnUseTmpHeapNoproc(3);
if ((flags_meta|flags) & MATCH_SET_EXCEPTION_TRACE) {
erts_smp_proc_lock(p, ERTS_PROC_LOCKS_ALL_MINOR);
p->trace_flags |= F_EXCEPTION_TRACE;
@@ -2213,15 +2308,19 @@ trace_gc(Process *p, Eterm what)
BIN_OLD_VHEAP(p),
BIN_OLD_VHEAP_SZ(p)
};
- Eterm local_heap[(sizeof(values)/sizeof(Uint))
- *(2/*cons*/ + 3/*2-tuple*/ + BIG_UINT_HEAP_SIZE)
- + 5/*4-tuple */ + TS_HEAP_WORDS];
+#define LOCAL_HEAP_SIZE \
+ (sizeof(values)/sizeof(Eterm)) * \
+ (2/*cons*/ + 3/*2-tuple*/ + BIG_UINT_HEAP_SIZE) + \
+ 5/*4-tuple */ + TS_HEAP_WORDS
+ DeclareTmpHeap(local_heap,LOCAL_HEAP_SIZE,p);
#ifdef DEBUG
Eterm* limit;
#endif
ASSERT(sizeof(values)/sizeof(Uint) == sizeof(tags)/sizeof(Eterm));
+ UseTmpHeap(LOCAL_HEAP_SIZE,p);
+
if (is_internal_port(p->tracer_proc)) {
hp = local_heap;
#ifdef DEBUG
@@ -2252,7 +2351,7 @@ trace_gc(Process *p, Eterm what)
#ifdef DEBUG
limit = hp + size;
- ASSERT(size <= sizeof(local_heap)/sizeof(Eterm));
+ ASSERT(size <= LOCAL_HEAP_SIZE);
#endif
msg = erts_bld_atom_uint_2tup_list(&hp,
@@ -2275,6 +2374,8 @@ trace_gc(Process *p, Eterm what)
else
ERTS_ENQ_TRACE_MSG(p->id, tracer_ref, msg, bp);
erts_smp_mtx_unlock(&smq_mtx);
+ UnUseTmpHeap(LOCAL_HEAP_SIZE,p);
+#undef LOCAL_HEAP_SIZE
}
@@ -2465,7 +2566,9 @@ profile_scheduler(Eterm scheduler_id, Eterm state) {
Uint Ms, s, us;
#ifndef ERTS_SMP
- Eterm local_heap[4 + 7];
+#define LOCAL_HEAP_SIZE (4 + 7)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
hp = local_heap;
#else
ErlHeapFragment *bp;
@@ -2498,6 +2601,8 @@ profile_scheduler(Eterm scheduler_id, Eterm state) {
#ifndef ERTS_SMP
profile_send(msg);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
#else
enqueue_sys_msg_unlocked(SYS_MSG_TYPE_SYSPROF, NIL, NIL, msg, bp);
#endif
@@ -2510,7 +2615,10 @@ profile_scheduler_q(Eterm scheduler_id, Eterm state, Eterm no_schedulers, Uint M
Eterm *hp, msg, timestamp;
#ifndef ERTS_SMP
- Eterm local_heap[4 + 7];
+#define LOCAL_HEAP_SIZE (4 + 7)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
#else
ErlHeapFragment *bp;
@@ -2528,6 +2636,8 @@ profile_scheduler_q(Eterm scheduler_id, Eterm state, Eterm no_schedulers, Uint M
msg = TUPLE6(hp, am_profile, am_scheduler, scheduler_id, state, no_schedulers, timestamp); hp += 7;
#ifndef ERTS_SMP
profile_send(msg);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
#else
enqueue_sys_msg_unlocked(SYS_MSG_TYPE_SYSPROF, NIL, NIL, msg, bp);
#endif
@@ -2558,7 +2668,10 @@ trace_port_open(Port *p, Eterm calling_pid, Eterm drv_name) {
Eterm* hp;
if (is_internal_port(p->tracer_proc)) {
- Eterm local_heap[5+6];
+#define LOCAL_HEAP_SIZE (5+6)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
mess = TUPLE5(hp, am_trace, calling_pid, am_open, p->id, drv_name);
@@ -2569,6 +2682,8 @@ trace_port_open(Port *p, Eterm calling_pid, Eterm drv_name) {
}
/* No fake schedule */
send_to_port(NULL, mess, &p->tracer_proc, &p->trace_flags);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
erts_smp_mtx_unlock(&smq_mtx);
} else {
ErlHeapFragment *bp;
@@ -2613,7 +2728,10 @@ trace_port(Port *t_p, Eterm what, Eterm data) {
Eterm* hp;
if (is_internal_port(t_p->tracer_proc)) {
- Eterm local_heap[5+5];
+#define LOCAL_HEAP_SIZE (5+5)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
mess = TUPLE4(hp, am_trace, t_p->id, what, data);
hp += 5;
@@ -2623,6 +2741,8 @@ trace_port(Port *t_p, Eterm what, Eterm data) {
}
/* No fake schedule */
send_to_port(NULL, mess, &t_p->tracer_proc, &t_p->trace_flags);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
erts_smp_mtx_unlock(&smq_mtx);
} else {
ErlHeapFragment *bp;
@@ -2674,7 +2794,10 @@ trace_sched_ports_where(Port *p, Eterm what, Eterm where) {
Eterm sched_id = am_undefined;
if (is_internal_port(p->tracer_proc)) {
- Eterm local_heap[5+6];
+#define LOCAL_HEAP_SIZE (5+6)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
if (IS_TRACED_FL(p, F_TRACE_SCHED_NO)) {
@@ -2700,6 +2823,8 @@ trace_sched_ports_where(Port *p, Eterm what, Eterm where) {
/* No fake scheduling */
send_to_port(NULL, mess, &p->tracer_proc, &p->trace_flags);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
erts_smp_mtx_unlock(&smq_mtx);
} else {
ErlHeapFragment *bp;
@@ -2750,7 +2875,11 @@ profile_runnable_port(Port *p, Eterm status) {
Eterm count = make_small(0);
#ifndef ERTS_SMP
- Eterm local_heap[4 + 6];
+#define LOCAL_HEAP_SIZE (4 + 6)
+
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
#else
@@ -2771,6 +2900,8 @@ profile_runnable_port(Port *p, Eterm status) {
#ifndef ERTS_SMP
profile_send(msg);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
#else
enqueue_sys_msg_unlocked(SYS_MSG_TYPE_SYSPROF, NIL, NIL, msg, bp);
#endif
@@ -2785,7 +2916,11 @@ profile_runnable_proc(Process *p, Eterm status){
Eterm where = am_undefined;
#ifndef ERTS_SMP
- Eterm local_heap[4 + 6 + 4];
+#define LOCAL_HEAP_SIZE (4 + 6 + 4)
+
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
#else
ErlHeapFragment *bp;
@@ -2818,6 +2953,8 @@ profile_runnable_proc(Process *p, Eterm status){
msg = TUPLE5(hp, am_profile, p->id, status, where, timestamp); hp += 6;
#ifndef ERTS_SMP
profile_send(msg);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
#else
enqueue_sys_msg_unlocked(SYS_MSG_TYPE_SYSPROF, NIL, NIL, msg, bp);
#endif