Skip to content

Commit 1a7ab8b

Browse files
authored
Add a native interpreter kwarg, forward method_table queries (#242)
* Forward the method table from the native interpreter. * Add keyword arguments to set the native interpreter. * Rename native_interpreter arguments.
1 parent e48b2ca commit 1a7ab8b

File tree

5 files changed

+42
-41
lines changed

5 files changed

+42
-41
lines changed

src/Cthulhu.jl

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ function _descend(term::AbstractTerminal, interp::CthulhuInterpreter, mi::Method
347347

348348
# forcibly enter and inspect the frame, although the native interpreter gave up
349349
if info isa UncachedCallInfo || info isa TaskCallInfo
350+
# XXX: this may use a different native interpreter
350351
next_interp = CthulhuInterpreter()
351352
next_mi = get_mi(info)::MethodInstance
352353
do_typeinf!(next_interp, next_mi)
@@ -470,26 +471,22 @@ function get_specialization(@nospecialize(F), @nospecialize(TT))
470471
return get_specialization(Base.signature_type(F, TT))
471472
end
472473

473-
function mkinterp(@nospecialize(args...))
474-
interp = CthulhuInterpreter()
474+
function mkinterp(interp::AbstractInterpreter, @nospecialize(args...))
475+
interp = CthulhuInterpreter(interp)
475476
mi = get_specialization(args...)
476-
do_typeinf!(interp, mi)
477-
(interp, mi)
477+
do_typeinf!(interp, mi)
478+
(interp, mi)
478479
end
479480

480-
# function mkinterp(mi::MethodInstance)
481-
# interp = CthulhuInterpreter()
482-
# do_typeinf!(interp, mi)
483-
# interp
484-
# end
485-
486-
function _descend(@nospecialize(args...); kwargs...)
487-
(interp, mi) = mkinterp(args...)
488-
_descend(interp, mi; kwargs...)
481+
function _descend(@nospecialize(args...);
482+
interp::AbstractInterpreter=NativeInterpreter(), kwargs...)
483+
(interp′, mi) = mkinterp(interp, args...)
484+
_descend(interp′, mi; kwargs...)
489485
end
490-
function _descend(term::AbstractTerminal, @nospecialize(args...); kwargs...)
491-
(interp, mi) = mkinterp(args...)
492-
_descend(term, interp, mi; kwargs...)
486+
function _descend(term::AbstractTerminal, @nospecialize(args...);
487+
interp=NativeInterpreter(), kwargs...)
488+
(interp′, mi) = mkinterp(interp, args...)
489+
_descend(term, interp′, mi; kwargs...)
493490
end
494491

495492
descend_code_typed(b::Bookmark; kw...) =
@@ -500,7 +497,7 @@ descend_code_warntype(b::Bookmark; kw...) =
500497

501498
FoldingTrees.writeoption(buf::IO, data::Data, charsused::Int) = FoldingTrees.writeoption(buf, data.callstr, charsused)
502499

503-
function ascend(term, mi; kwargs...)
500+
function ascend(term, mi; interp::AbstractInterpreter=NativeInterpreter(), kwargs...)
504501
root = treelist(mi)
505502
menu = TreeMenu(root)
506503
choice = menu.current
@@ -514,7 +511,7 @@ function ascend(term, mi; kwargs...)
514511
if !isroot(node)
515512
# Help user find the sites calling the parent
516513
miparent = instance(node.parent.data.nd)
517-
ulocs = find_caller_of(miparent, mi)
514+
ulocs = find_caller_of(interp, miparent, mi)
518515
if !isempty(ulocs)
519516
strlocs = [string(" "^k[3] * '"', k[2], "\", ", k[1], ": lines ", v) for (k, v) in ulocs]
520517
push!(strlocs, "Browse typed code")
@@ -535,9 +532,9 @@ function ascend(term, mi; kwargs...)
535532
end
536533
# The main application of `ascend` is finding cases of non-inferrability, so the
537534
# warn highlighting is useful.
538-
interp = CthulhuInterpreter()
539-
do_typeinf!(interp, mi)
540-
browsecodetyped && _descend(term, interp, mi; iswarn=true, optimize=false, interruptexc=false, kwargs...)
535+
interp = CthulhuInterpreter(interp)
536+
do_typeinf!(interp, mi)
537+
browsecodetyped && _descend(term, interp, mi; iswarn=true, optimize=false, interruptexc=false, kwargs...)
541538
end
542539
end
543540
end

src/interpreter.jl

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,32 @@ end
1616
const Remarks = Vector{Pair{Int, String}}
1717

1818
mutable struct CthulhuInterpreter <: AbstractInterpreter
19-
native::NativeInterpreter
19+
native::AbstractInterpreter
2020

2121
unopt::Dict{Union{MethodInstance, InferenceResult}, InferredSource}
2222
opt::Dict{MethodInstance, CodeInstance}
2323

2424
remarks::Dict{MethodInstance, Remarks}
2525
end
2626

27-
CthulhuInterpreter() = CthulhuInterpreter(
28-
NativeInterpreter(),
29-
Dict{MethodInstance, InferredSource}(),
30-
Dict{MethodInstance, CodeInstance}(),
31-
Dict{MethodInstance, Remarks}()
32-
)
27+
CthulhuInterpreter(interp::AbstractInterpreter=NativeInterpreter()) =
28+
CthulhuInterpreter(
29+
interp,
30+
Dict{MethodInstance, InferredSource}(),
31+
Dict{MethodInstance, CodeInstance}(),
32+
Dict{MethodInstance, Remarks}()
33+
)
3334

3435
import Core.Compiler: InferenceParams, OptimizationParams, get_world_counter,
35-
get_inference_cache, code_cache,
36+
get_inference_cache, code_cache, method_table,
3637
WorldView, lock_mi_inference, unlock_mi_inference, InferenceState
3738
using Base: @invoke
3839

3940
Compiler.InferenceParams(interp::CthulhuInterpreter) = InferenceParams(interp.native)
4041
Compiler.OptimizationParams(interp::CthulhuInterpreter) = OptimizationParams(interp.native)
4142
Compiler.get_world_counter(interp::CthulhuInterpreter) = get_world_counter(interp.native)
4243
Compiler.get_inference_cache(interp::CthulhuInterpreter) = get_inference_cache(interp.native)
44+
Compiler.method_table(interp::CthulhuInterpreter, sv::InferenceState) = method_table(interp.native, sv)
4345

4446
# No need to do any locking since we're not putting our results into the runtime cache
4547
Compiler.lock_mi_inference(interp::CthulhuInterpreter, mi::MethodInstance) = nothing

src/reflection.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -250,15 +250,15 @@ function callinfo(sig, rt, max_methods=-1; params=current_params())
250250
return MultiCallInfo(sig, rt, callinfos)
251251
end
252252

253-
function find_caller_of(callee::MethodInstance, caller::MethodInstance)
254-
interp = CthulhuInterpreter()
255-
do_typeinf!(interp, caller)
253+
function find_caller_of(interp::AbstractInterpreter, callee::MethodInstance, caller::MethodInstance)
254+
interp = CthulhuInterpreter(interp)
255+
do_typeinf!(interp, caller)
256256
params = current_params()
257257
locs = Tuple{Core.LineInfoNode,Int}[]
258258
for optimize in (true, false)
259-
(CI, rt, infos, slottypes) = lookup(interp, caller, optimize)
259+
(CI, rt, infos, slottypes) = lookup(interp, caller, optimize)
260260
CI = preprocess_ci!(CI, caller, optimize, CONFIG)
261-
callsites = find_callsites(interp, CI, infos, caller, slottypes, optimize; params=params)
261+
callsites = find_callsites(interp, CI, infos, caller, slottypes, optimize; params=params)
262262
callsites = filter(cs->is_callsite(cs, callee), callsites)
263263
foreach(cs -> add_sourceline!(locs, CI, cs.id), callsites)
264264
end

test/runtests.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ end
478478
end
479479
end
480480
function doprint(f)
481-
interp, mi = Cthulhu.mkinterp(f, ())
481+
interp, mi = Cthulhu.mkinterp(NativeInterpreter(), f, ())
482482
src, rt = Cthulhu.lookup(interp, mi, true)
483483
io = IOBuffer()
484484
Cthulhu.cthulhu_typed(io, :none, src, rt, mi; iswarn=false)
@@ -492,7 +492,7 @@ end
492492

493493
@testset "Issue #132" begin
494494
f132(w, dim) = [i == dim ? w[i]/2 : w[i]/1 for i in eachindex(w)]
495-
interp, mi = Cthulhu.mkinterp(f132, (Vector{Int}, Int))
495+
interp, mi = Cthulhu.mkinterp(NativeInterpreter(), f132, (Vector{Int}, Int))
496496
@test isa(mi, Core.MethodInstance) # just check that the above succeeded
497497
end
498498

@@ -562,9 +562,9 @@ end
562562
micaller = Cthulhu.get_specialization(caller, Tuple{Int})
563563
micallee_Int = Cthulhu.get_specialization(callee, Tuple{Int})
564564
micallee_Float4 = Cthulhu.get_specialization(callee, Tuple{Float64})
565-
info, lines = only(Cthulhu.find_caller_of(micallee_Int, micaller))
565+
info, lines = only(Cthulhu.find_caller_of(NativeInterpreter(), micallee_Int, micaller))
566566
@test info == (:caller, Symbol(@__FILE__), 0) && lines == [line1, line3]
567-
info, lines = only(Cthulhu.find_caller_of(micallee_Float4, micaller))
567+
info, lines = only(Cthulhu.find_caller_of(NativeInterpreter(), micallee_Float4, micaller))
568568
@test info == (:caller, Symbol(@__FILE__), 0) && lines == [line2]
569569

570570
# Detection in optimized (post-inlining) code
@@ -578,7 +578,7 @@ end
578578
_, line1, line2 = outercaller(7)
579579
micaller = Cthulhu.get_specialization(outercaller, Tuple{Int})
580580
micallee = Cthulhu.get_specialization(nicallee, Tuple{Int})
581-
callerinfo = Cthulhu.find_caller_of(micallee, micaller)
581+
callerinfo = Cthulhu.find_caller_of(NativeInterpreter(), micallee, micaller)
582582
@test length(callerinfo) == 2
583583
info, lines = callerinfo[1]
584584
@test info == (:outercaller, Symbol(@__FILE__), 0)
@@ -665,7 +665,7 @@ end
665665
include("codeview.jl")
666666

667667
@testset "Bookmarks" begin
668-
(interp, mi) = Cthulhu.mkinterp(sqrt, Tuple{Float64})
668+
(interp, mi) = Cthulhu.mkinterp(NativeInterpreter(), sqrt, Tuple{Float64})
669669
b = Cthulhu.Bookmark(mi, interp)
670670

671671
@testset "code_typed(bookmark)" begin

test/utils.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
using Core.Compiler: NativeInterpreter
2+
13
function process(@nospecialize(f), @nospecialize(TT=()); optimize=true)
2-
(interp, mi) = Cthulhu.mkinterp(f, TT)
4+
(interp, mi) = Cthulhu.mkinterp(NativeInterpreter(), f, TT)
35
(ci, rt, infos, slottypes) = Cthulhu.lookup(interp, mi, optimize; allow_no_codeinf=true)
46
if ci !== nothing
57
ci = Cthulhu.preprocess_ci!(ci, mi, optimize, Cthulhu.CthulhuConfig(dead_code_elimination=true))

0 commit comments

Comments
 (0)