Skip to content

Commit 3c3d955

Browse files
committed
simplify, fix thread-safety
1 parent 0da5143 commit 3c3d955

File tree

7 files changed

+42
-18
lines changed

7 files changed

+42
-18
lines changed

Compiler/src/typeinfer.jl

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1559,9 +1559,6 @@ end
15591559

15601560
function typeinf_ext_toplevel(interp::AbstractInterpreter, mi::MethodInstance, source_mode::UInt8)
15611561
ci = typeinf_ext(interp, mi, source_mode)
1562-
if isa(ci, CodeInstance) && ccall(:jl_recording_inference_entrance_backtraces, Cint, ()) != 0
1563-
ccall(:jl_push_inference_entrance_backtraces, Cvoid, (Any,), ci => backtrace())
1564-
end
15651562
ci = add_codeinsts_to_jit!(interp, ci, source_mode)
15661563
return ci
15671564
end

doc/src/devdocs/diagnostics.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,13 @@ different purposes:
2525
`ccall`s records a backtrace on every entrance to type-inference, so that
2626
SnoopCompile can determine the caller of a dynamically-dispatched call. This
2727
is needed to attribute "cause" for new type inference.
28+
29+
The `jl_set_inference_entrance_backtraces` function accepts an array where
30+
inference entrance events will be recorded. Each inference event stores two
31+
consecutive array elements: first the `CodeInstance` object, then the
32+
backtrace representation. So for N inference events, the array will contain 2N
33+
elements arranged as: `[ci₁, bt₁, ci₂, bt₂, ..., ciₙ, btₙ]`.
34+
35+
Note that the backtrace elements `btᵢ` contain raw backtrace data that
36+
typically needs to be processed using `stacktrace(Base._reformat_bt(btᵢ...))`.
37+
to convert them into a usable stack trace format for analysis.

src/gf.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,14 @@ jl_code_instance_t *jl_type_infer(jl_method_instance_t *mi, size_t world, uint8_
492492
if (ci && !jl_is_code_instance(ci)) {
493493
ci = NULL;
494494
}
495+
496+
// Record inference entrance backtrace if enabled
497+
if (ci) {
498+
JL_GC_PUSH1(&ci);
499+
jl_push_inference_entrance_backtraces((jl_value_t*)ci);
500+
JL_GC_POP();
501+
}
502+
495503
JL_GC_POP();
496504
#endif
497505

src/julia.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2276,8 +2276,7 @@ JL_DLLEXPORT jl_value_t *jl_object_top_module(jl_value_t* v) JL_NOTSAFEPOINT;
22762276
JL_DLLEXPORT void jl_set_newly_inferred(jl_value_t *newly_inferred);
22772277
JL_DLLEXPORT void jl_push_newly_inferred(jl_value_t *ci);
22782278
JL_DLLEXPORT void jl_set_inference_entrance_backtraces(jl_value_t *inference_entrance_backtraces);
2279-
JL_DLLEXPORT int jl_recording_inference_entrance_backtraces(void);
2280-
JL_DLLEXPORT void jl_push_inference_entrance_backtraces(jl_value_t *ci_bt_pair);
2279+
JL_DLLEXPORT void jl_push_inference_entrance_backtraces(jl_value_t *ci);
22812280
JL_DLLEXPORT void jl_write_compiler_output(void);
22822281

22832282
// parsing

src/julia_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,6 +1506,7 @@ size_t rec_backtrace_ctx(jl_bt_element_t *bt_data, size_t maxsize, bt_context_t
15061506
size_t rec_backtrace_ctx_dwarf(jl_bt_element_t *bt_data, size_t maxsize, bt_context_t *ctx, jl_gcframe_t *pgcstack) JL_NOTSAFEPOINT;
15071507
#endif
15081508
JL_DLLEXPORT jl_value_t *jl_get_backtrace(void);
1509+
JL_DLLEXPORT jl_value_t *jl_backtrace_from_here(int returnsp, int skip);
15091510
void jl_critical_error(int sig, int si_code, bt_context_t *context, jl_task_t *ct);
15101511
JL_DLLEXPORT void jl_raise_debugger(void) JL_NOTSAFEPOINT;
15111512
JL_DLLEXPORT void jl_gdblookup(void* ip) JL_NOTSAFEPOINT;

src/staticdata_utils.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -142,21 +142,24 @@ JL_DLLEXPORT void jl_set_inference_entrance_backtraces(jl_value_t* _inference_en
142142
assert(_inference_entrance_backtraces == NULL || _inference_entrance_backtraces == jl_nothing || jl_is_array(_inference_entrance_backtraces));
143143
if (_inference_entrance_backtraces == jl_nothing)
144144
_inference_entrance_backtraces = NULL;
145+
JL_LOCK(&inference_entrance_backtraces_mutex);
145146
inference_entrance_backtraces = (jl_array_t*) _inference_entrance_backtraces;
147+
JL_UNLOCK(&inference_entrance_backtraces_mutex);
146148
}
147149

148-
JL_DLLEXPORT int jl_recording_inference_entrance_backtraces(void)
149-
{
150-
return inference_entrance_backtraces != NULL;
151-
}
152150

153-
JL_DLLEXPORT void jl_push_inference_entrance_backtraces(jl_value_t* ci_bt_pair)
151+
JL_DLLEXPORT void jl_push_inference_entrance_backtraces(jl_value_t* ci)
154152
{
155-
assert(inference_entrance_backtraces);
156153
JL_LOCK(&inference_entrance_backtraces_mutex);
154+
if (inference_entrance_backtraces == NULL) {
155+
JL_UNLOCK(&inference_entrance_backtraces_mutex);
156+
return;
157+
}
158+
jl_value_t* backtrace = jl_backtrace_from_here(0, 1);
157159
size_t end = jl_array_nrows(inference_entrance_backtraces);
158-
jl_array_grow_end(inference_entrance_backtraces, 1);
159-
jl_array_ptr_set(inference_entrance_backtraces, end, ci_bt_pair);
160+
jl_array_grow_end(inference_entrance_backtraces, 2);
161+
jl_array_ptr_set(inference_entrance_backtraces, end, ci);
162+
jl_array_ptr_set(inference_entrance_backtraces, end + 1, backtrace);
160163
JL_UNLOCK(&inference_entrance_backtraces_mutex);
161164
}
162165

test/stacktraces.jl

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -279,15 +279,21 @@ end
279279
ccall(:jl_set_inference_entrance_backtraces, Cvoid, (Any,), nothing)
280280
ln = @__LINE__() - 2
281281
fl = Symbol(@__FILE__())
282-
@test length(dispatch_backtraces) == 2
282+
@test length(dispatch_backtraces) == 4 # 2 ci-backtrace pairs, stored as 4 separate elements
283283
mcallee, mcaller = only(methods(callee)), only(methods(caller))
284-
@test any(dispatch_backtraces) do (ci, trace)
285-
ci.def.def === mcallee && any(stacktrace(trace)) do sf
284+
# Extract pairs from the flattened array format: ci at odd indices, backtrace at even indices
285+
pairs = [(dispatch_backtraces[i], dispatch_backtraces[i+1]) for i in 1:2:length(dispatch_backtraces)]
286+
@test any(pairs) do (ci, trace)
287+
# trace is a SimpleVector from jl_backtrace_from_here, need to reformat before stacktrace
288+
bt = Base._reformat_bt(trace[1], trace[2])
289+
ci.def.def === mcallee && any(stacktrace(bt)) do sf
286290
sf.file == fl && sf.line == ln
287291
end
288292
end
289-
@test any(dispatch_backtraces) do (ci, trace)
290-
ci.def.def === mcaller && any(stacktrace(trace)) do sf
293+
@test any(pairs) do (ci, trace)
294+
# trace is a SimpleVector from jl_backtrace_from_here, need to reformat before stacktrace
295+
bt = Base._reformat_bt(trace[1], trace[2])
296+
ci.def.def === mcaller && any(stacktrace(bt)) do sf
291297
sf.file == fl && sf.line == ln
292298
end
293299
end

0 commit comments

Comments
 (0)