Skip to content

Commit ee7e814

Browse files
authored
stacktraces: Add an extension point for printing custom-owner CIs (#58430)
On Julia master, it is possible to add custom CodeInstances with non `nothing` owner to the runtime system (e.g. by invoking them or with custom AbstractInterpreters). However, the backtrace printing for these custom code instances was not in any way distinguished from the backtrace printing for an ordinary code instance of the same method instance, making it sometimes hard to determine what code instance a particular backtrace was referring to (if the downstream compiler was making many different code instances for a particular MethodInstance). Remidy this by adding an explicit extension point that can be overwritten to modify the printing of these custom-owner CodeInstances.
1 parent eebda6c commit ee7e814

File tree

6 files changed

+25
-19
lines changed

6 files changed

+25
-19
lines changed

Compiler/src/Compiler.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ using Base: @_foldable_meta, @_gc_preserve_begin, @_gc_preserve_end, @nospeciali
6565
structdiff, tls_world_age, unconstrain_vararg_length, unionlen, uniontype_layout,
6666
uniontypes, unsafe_convert, unwrap_unionall, unwrapva, vect, widen_diagonal,
6767
_uncompressed_ir, maybe_add_binding_backedge!, datatype_min_ninitialized,
68-
partialstruct_init_undefs, fieldcount_noerror, _eval_import, _eval_using
68+
partialstruct_init_undefs, fieldcount_noerror, _eval_import, _eval_using,
69+
get_ci_mi
70+
6971
using Base.Order
7072

7173
import Base: ==, _topmod, append!, convert, copy, copy!, findall, first, get, get!,

Compiler/src/abstractinterpretation.jl

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2221,12 +2221,6 @@ function get_ci_abi(ci::CodeInstance)
22212221
(def::MethodInstance).specTypes
22222222
end
22232223

2224-
function get_ci_mi(ci::CodeInstance)
2225-
def = ci.def
2226-
isa(def, ABIOverride) && return def.def
2227-
return def::MethodInstance
2228-
end
2229-
22302224
function abstract_invoke(interp::AbstractInterpreter, arginfo::ArgInfo, si::StmtInfo, sv::AbsIntState)
22312225
argtypes = arginfo.argtypes
22322226
ft′ = argtype_by_index(argtypes, 2)

base/invalidation.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ invalidate_code_for_globalref!(gr::GlobalRef, invalidated_bpart::Core.BindingPar
188188
invalidate_code_for_globalref!(convert(Core.Binding, gr), invalidated_bpart, new_bpart, new_max_world)
189189

190190
function maybe_add_binding_backedge!(b::Core.Binding, edge::Union{Method, CodeInstance})
191-
meth = isa(edge, Method) ? edge : Compiler.get_ci_mi(edge).def
191+
meth = isa(edge, Method) ? edge : get_ci_mi(edge).def
192192
ccall(:jl_maybe_add_binding_backedge, Cint, (Any, Any, Any), b, edge, meth)
193193
return nothing
194194
end

base/runtime_internals.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1478,6 +1478,15 @@ end
14781478
_uncompressed_ir(codeinst::CodeInstance, s::String) =
14791479
ccall(:jl_uncompress_ir, Ref{CodeInfo}, (Any, Any, Any), codeinst.def.def::Method, codeinst, s)
14801480

1481+
function get_ci_mi(codeinst::CodeInstance)
1482+
def = codeinst.def
1483+
if def isa Core.ABIOverride
1484+
return def.def
1485+
else
1486+
return def::MethodInstance
1487+
end
1488+
end
1489+
14811490
"""
14821491
Base.generating_output([incremental::Bool])::Bool
14831492

base/stacktraces.jl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,12 @@ function show_spec_linfo(io::IO, frame::StackFrame)
273273
if linfo isa Union{MethodInstance, CodeInstance}
274274
def = frame_method_or_module(frame)
275275
if def isa Module
276-
Base.show_mi(io, linfo, #=from_stackframe=#true)
276+
Base.show_mi(io, linfo::MethodInstance, #=from_stackframe=#true)
277+
elseif linfo isa CodeInstance && linfo.owner !== nothing
278+
show_custom_spec_sig(io, linfo.owner, linfo, frame)
277279
else
280+
# Equivalent to the default implementation of `show_custom_spec_sig`
281+
# for `linfo isa CodeInstance`, but saves an extra dynamic dispatch.
278282
show_spec_sig(io, def, frame_mi(frame).specTypes)
279283
end
280284
else
@@ -284,6 +288,12 @@ function show_spec_linfo(io::IO, frame::StackFrame)
284288
end
285289
end
286290

291+
# Can be extended by compiler packages to customize backtrace display of custom code instance frames
292+
function show_custom_spec_sig(io::IO, @nospecialize(owner), linfo::CodeInstance, frame::StackFrame)
293+
mi = get_ci_mi(linfo)
294+
return show_spec_sig(io, mi.def, mi.specTypes)
295+
end
296+
287297
function show_spec_sig(io::IO, m::Method, @nospecialize(sig::Type))
288298
if get(io, :limit, :false)::Bool
289299
if !haskey(io, :displaysize)

base/staticdata.jl

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,13 @@
33
module StaticData
44

55
using .Core: CodeInstance, MethodInstance
6-
using .Base: JLOptions, Compiler, get_world_counter, _methods_by_ftype, get_methodtable
6+
using .Base: JLOptions, Compiler, get_world_counter, _methods_by_ftype, get_methodtable, get_ci_mi
77

88
const WORLD_AGE_REVALIDATION_SENTINEL::UInt = 1
99
const _jl_debug_method_invalidation = Ref{Union{Nothing,Vector{Any}}}(nothing)
1010
debug_method_invalidation(onoff::Bool) =
1111
_jl_debug_method_invalidation[] = onoff ? Any[] : nothing
1212

13-
function get_ci_mi(codeinst::CodeInstance)
14-
def = codeinst.def
15-
if def isa Core.ABIOverride
16-
return def.def
17-
else
18-
return def::MethodInstance
19-
end
20-
end
21-
2213
# Restore backedges to external targets
2314
# `edges` = [caller1, ...], the list of worklist-owned code instances internally
2415
# `ext_ci_list` = [caller1, ...], the list of worklist-owned code instances externally

0 commit comments

Comments
 (0)