Skip to content

Commit a9d9880

Browse files
committed
erts: Make trace:info(S, MFA, Item) less wasteful
Don't spend time and heap memory on items not asked for.
1 parent 8eb8e1d commit a9d9880

File tree

1 file changed

+86
-48
lines changed

1 file changed

+86
-48
lines changed

erts/emulator/beam/erl_bif_trace.c

Lines changed: 86 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1798,6 +1798,7 @@ trace_info_pid(Process* p, ErtsTraceSession* session, Eterm pid_spec, Eterm key)
17981798
static int function_is_traced(Process *p,
17991799
ErtsTraceSession *session,
18001800
const ErtsCodeMFA *mfa,
1801+
int want,
18011802
Binary **ms, /* out */
18021803
Binary **ms_meta, /* out */
18031804
ErtsTracer *tracer_pid_meta, /* out */
@@ -1806,43 +1807,52 @@ static int function_is_traced(Process *p,
18061807
Eterm *call_memory) /* out */
18071808
{
18081809
const ErtsCodeInfo *ci;
1809-
const Export *ep;
1810-
Export e;
18111810

18121811
/* First look for an export entry */
1813-
e.info.mfa = *mfa;
1814-
if ((ep = export_get(&e)) != NULL) {
1815-
if (erts_is_export_trampoline_active(ep, erts_active_code_ix()) &&
1816-
! BeamIsOpCode(ep->trampoline.common.op, op_call_error_handler)) {
1812+
if (want & FUNC_TRACE_GLOBAL_TRACE) {
1813+
const Export *ep;
1814+
Export e;
18171815

1818-
ASSERT(BeamIsOpCode(ep->trampoline.common.op, op_i_generic_breakpoint));
1816+
e.info.mfa = *mfa;
1817+
if ((ep = export_get(&e)) != NULL) {
1818+
if (erts_is_export_trampoline_active(ep, erts_active_code_ix()) &&
1819+
! BeamIsOpCode(ep->trampoline.common.op, op_call_error_handler)) {
18191820

1820-
if (erts_is_trace_break(session, &ep->info, ms, 0)) {
1821-
return FUNC_TRACE_GLOBAL_TRACE;
1822-
}
1821+
ASSERT(BeamIsOpCode(ep->trampoline.common.op, op_i_generic_breakpoint));
18231822

1824-
ASSERT(!erts_is_trace_break(session, &ep->info, ms, 1));
1825-
ASSERT(!erts_is_mtrace_break(session, &ep->info, ms_meta, tracer_pid_meta));
1826-
ASSERT(!erts_is_call_break(p, session, 1, &ep->info, call_time));
1827-
ASSERT(!erts_is_call_break(p, session, 0, &ep->info, call_memory));
1828-
}
1823+
if (erts_is_trace_break(session, &ep->info, ms, 0)) {
1824+
return FUNC_TRACE_GLOBAL_TRACE;
1825+
}
1826+
1827+
ASSERT(!erts_is_trace_break(session, &ep->info, ms, 1));
1828+
ASSERT(!erts_is_mtrace_break(session, &ep->info, ms_meta, tracer_pid_meta));
1829+
ASSERT(!erts_is_call_break(p, session, 1, &ep->info, call_time));
1830+
ASSERT(!erts_is_call_break(p, session, 0, &ep->info, call_memory));
1831+
}
1832+
}
18291833
}
18301834

18311835
/* OK, now look for breakpoint tracing */
18321836
if ((ci = erts_find_local_func(mfa)) != NULL) {
1833-
int r = 0;
1834-
if (erts_is_trace_break(session, ci, ms, 1))
1835-
r |= FUNC_TRACE_LOCAL_TRACE;
1836-
if (erts_is_mtrace_break(session, ci, ms_meta, tracer_pid_meta))
1837-
r |= FUNC_TRACE_META_TRACE;
1838-
if (erts_is_count_break(session, ci, count))
1839-
r |= FUNC_TRACE_COUNT_TRACE;
1840-
if (erts_is_call_break(p, session, 1, ci, call_time))
1841-
r |= FUNC_TRACE_TIME_TRACE;
1842-
if (erts_is_call_break(p, session, 0, ci, call_memory))
1843-
r |= FUNC_TRACE_MEMORY_TRACE;
1837+
int got = 0;
1838+
1839+
if ((want & FUNC_TRACE_LOCAL_TRACE) && erts_is_trace_break(session, ci, ms, 1)) {
1840+
got |= FUNC_TRACE_LOCAL_TRACE;
1841+
}
1842+
if ((want & FUNC_TRACE_META_TRACE) && erts_is_mtrace_break(session, ci, ms_meta, tracer_pid_meta)) {
1843+
got |= FUNC_TRACE_META_TRACE;
1844+
}
1845+
if ((want & FUNC_TRACE_COUNT_TRACE) && erts_is_count_break(session, ci, count)) {
1846+
got |= FUNC_TRACE_COUNT_TRACE;
1847+
}
1848+
if ((want & FUNC_TRACE_TIME_TRACE) && erts_is_call_break(p, session, 1, ci, call_time)) {
1849+
got |= FUNC_TRACE_TIME_TRACE;
1850+
}
1851+
if ((want & FUNC_TRACE_MEMORY_TRACE) && erts_is_call_break(p, session, 0, ci, call_memory)) {
1852+
got |= FUNC_TRACE_MEMORY_TRACE;
1853+
}
18441854

1845-
return r ? r : FUNC_TRACE_UNTRACED;
1855+
return got ? got : FUNC_TRACE_UNTRACED;
18461856
}
18471857
return FUNC_TRACE_NOEXIST;
18481858
}
@@ -1912,37 +1922,65 @@ trace_info_func(Process* p, ErtsTraceSession* session,
19121922
Eterm* hp;
19131923
ErtsCodeMFA mfa;
19141924
Binary *ms = NULL, *ms_meta = NULL;
1915-
Uint count = 0;
1925+
Uint call_count = 0;
19161926
Eterm traced = am_false;
19171927
Eterm match_spec = am_false;
19181928
Eterm retval = am_false;
19191929
ErtsTracer meta = erts_tracer_nil;
19201930
Eterm call_time = NIL;
19211931
Eterm call_memory = NIL;
1922-
int r;
1932+
int want, got;
19231933

19241934
ASSERT(session);
19251935

19261936
if (!get_mfa_tuple(func_spec, &mfa)) {
19271937
goto error;
19281938
}
19291939

1930-
if (key == am_call_time || key == am_call_memory || key == am_all) {
1940+
switch (key) {
1941+
case am_traced:
1942+
case am_match_spec:
1943+
want = FUNC_TRACE_GLOBAL_TRACE | FUNC_TRACE_LOCAL_TRACE;
1944+
break;
1945+
case am_meta:
1946+
case am_meta_match_spec:
1947+
want = FUNC_TRACE_META_TRACE;
1948+
break;
1949+
case am_call_count:
1950+
want = FUNC_TRACE_COUNT_TRACE;
1951+
break;
1952+
case am_call_time:
1953+
want = FUNC_TRACE_TIME_TRACE;
1954+
break;
1955+
case am_call_memory:
1956+
want = FUNC_TRACE_MEMORY_TRACE;
1957+
break;
1958+
case am_all:
1959+
want = FUNC_TRACE_GLOBAL_TRACE | FUNC_TRACE_LOCAL_TRACE
1960+
| FUNC_TRACE_META_TRACE | FUNC_TRACE_COUNT_TRACE
1961+
| FUNC_TRACE_TIME_TRACE | FUNC_TRACE_MEMORY_TRACE;
1962+
break;
1963+
default:
1964+
goto error;
1965+
}
1966+
1967+
1968+
if (want & (FUNC_TRACE_TIME_TRACE | FUNC_TRACE_MEMORY_TRACE)) {
19311969
erts_proc_unlock(p, ERTS_PROC_LOCK_MAIN);
19321970
erts_thr_progress_block();
19331971
erts_proc_lock(p, ERTS_PROC_LOCK_MAIN);
19341972
}
19351973
erts_mtx_lock(&erts_dirty_bp_ix_mtx);
19361974

1937-
r = function_is_traced(p, session, &mfa, &ms, &ms_meta, &meta, &count,
1938-
&call_time, &call_memory);
1975+
got = function_is_traced(p, session, &mfa, want, &ms, &ms_meta, &meta,
1976+
&call_count, &call_time, &call_memory);
19391977

19401978
erts_mtx_unlock(&erts_dirty_bp_ix_mtx);
1941-
if ( (key == am_call_time) || (key == am_call_memory) || (key == am_all)) {
1942-
erts_thr_progress_unblock();
1979+
if (want & (FUNC_TRACE_TIME_TRACE | FUNC_TRACE_MEMORY_TRACE)) {
1980+
erts_thr_progress_unblock();
19431981
}
19441982

1945-
switch (r) {
1983+
switch (got) {
19461984
case FUNC_TRACE_NOEXIST:
19471985
hp = HAlloc(p, 3);
19481986
return TUPLE2(hp, key, am_undefined);
@@ -1954,7 +1992,7 @@ trace_info_func(Process* p, ErtsTraceSession* session,
19541992
match_spec = NIL; /* Fix up later if it's asked for*/
19551993
break;
19561994
default:
1957-
if (r & FUNC_TRACE_LOCAL_TRACE) {
1995+
if (got & FUNC_TRACE_LOCAL_TRACE) {
19581996
traced = am_local;
19591997
match_spec = NIL; /* Fix up later if it's asked for*/
19601998
}
@@ -1979,7 +2017,7 @@ trace_info_func(Process* p, ErtsTraceSession* session,
19792017
retval = NIL;
19802018
break;
19812019
case am_meta_match_spec:
1982-
if (r & FUNC_TRACE_META_TRACE) {
2020+
if (got & FUNC_TRACE_META_TRACE) {
19832021
if (ms_meta) {
19842022
retval = MatchSetGetSource(ms_meta);
19852023
retval = copy_object(retval, p);
@@ -1989,23 +2027,23 @@ trace_info_func(Process* p, ErtsTraceSession* session,
19892027
}
19902028
break;
19912029
case am_call_count:
1992-
if (r & FUNC_TRACE_COUNT_TRACE) {
1993-
retval = erts_make_integer(count, p);
2030+
if (got & FUNC_TRACE_COUNT_TRACE) {
2031+
retval = erts_make_integer(call_count, p);
19942032
}
19952033
break;
19962034
case am_call_time:
1997-
if (r & FUNC_TRACE_TIME_TRACE) {
2035+
if (got & FUNC_TRACE_TIME_TRACE) {
19982036
retval = call_time;
19992037
}
20002038
break;
20012039
case am_call_memory:
2002-
if (r & FUNC_TRACE_MEMORY_TRACE) {
2040+
if (got & FUNC_TRACE_MEMORY_TRACE) {
20032041
retval = call_memory;
20042042
}
20052043
break;
20062044
case am_all: {
20072045
Eterm match_spec_meta = am_false;
2008-
Eterm call_count = am_false;
2046+
Eterm call_count_term = am_false;
20092047
Eterm t, m;
20102048

20112049
/* ToDo: Rewrite this to loop and reuse the above cases */
@@ -2014,28 +2052,28 @@ trace_info_func(Process* p, ErtsTraceSession* session,
20142052
match_spec = MatchSetGetSource(ms);
20152053
match_spec = copy_object(match_spec, p);
20162054
}
2017-
if (r & FUNC_TRACE_META_TRACE) {
2055+
if (got & FUNC_TRACE_META_TRACE) {
20182056
if (ms_meta) {
20192057
match_spec_meta = MatchSetGetSource(ms_meta);
20202058
match_spec_meta = copy_object(match_spec_meta, p);
20212059
} else
20222060
match_spec_meta = NIL;
20232061
}
2024-
if (r & FUNC_TRACE_COUNT_TRACE) {
2025-
call_count = erts_make_integer(count, p);
2062+
if (got & FUNC_TRACE_COUNT_TRACE) {
2063+
call_count_term = erts_make_integer(call_count, p);
20262064
}
2027-
if (!(r & FUNC_TRACE_TIME_TRACE)) {
2065+
if (!(got & FUNC_TRACE_TIME_TRACE)) {
20282066
call_time = am_false;
20292067
}
2030-
if (!(r & FUNC_TRACE_MEMORY_TRACE)) {
2068+
if (!(got & FUNC_TRACE_MEMORY_TRACE)) {
20312069
call_memory = am_false;
20322070
}
20332071

20342072
m = erts_tracer_to_term(p, meta);
20352073

20362074
hp = HAlloc(p, (3+2)*7);
20372075
retval = NIL;
2038-
t = TUPLE2(hp, am_call_count, call_count); hp += 3;
2076+
t = TUPLE2(hp, am_call_count, call_count_term); hp += 3;
20392077
retval = CONS(hp, t, retval); hp += 2;
20402078
t = TUPLE2(hp, am_call_time, call_time); hp += 3;
20412079
retval = CONS(hp, t, retval); hp += 2;

0 commit comments

Comments
 (0)