Skip to content

Commit 7c7a082

Browse files
authored
Adjust to changes on nightly (#52)
1 parent b68ab4c commit 7c7a082

File tree

5 files changed

+70
-18
lines changed

5 files changed

+70
-18
lines changed

demos/abstract_analyze_versions.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ sigs, c1, c2 = split_comparable(sigstable, sigmaster)
6363
nz1, nz2 = tally0(c1, c2)
6464
println("$stablever has $nz1 with no backedges, master has $nz2")
6565
mx1, mx2 = maximum(c1), maximum(c2)
66-
isexported(sig) = (ft = Base.unwrap_unionall(sig).parameters[1]; isdefined(Main, ft.name.mt.name))
66+
get_fname(@nospecialize(fT::DataType)) = @static VERSION v"1.13.0-DEV.647" ? fT.name.singletonname : fT.name.mt.name
67+
isexported(sig) = (ft = Base.unwrap_unionall(sig).parameters[1]; isdefined(Main, get_fname(ft)))
6768
colors = [isexported(sig) ? "magenta" : "green" for sig in sigs]
6869

6970
function on_click(event)

src/MethodAnalysis.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module MethodAnalysis
33
using AbstractTrees
44

55
using Base: Callable, IdSet
6-
using Core: MethodInstance, CodeInfo, SimpleVector, MethodTable
6+
using Core: MethodInstance, CodeInstance, CodeInfo, SimpleVector, MethodTable
77
using Base.Meta: isexpr
88

99
export visit, visit_withmodule
@@ -66,11 +66,11 @@ end
6666
# A few fields are deliberately unchecked
6767
function equal(ci1::Core.CodeInfo, ci2::Core.CodeInfo)
6868
ret = ci1.code == ci2.code &&
69-
ci1.codelocs == ci2.codelocs &&
69+
(@static hasfield(Core.CodeInfo, :debuginfo) ? ci1.debuginfo == ci2.debuginfo :
70+
ci1.codelocs == ci2.codelocs && ci1.linetable == ci2.linetable) &&
7071
ci1.ssavaluetypes == ci2.ssavaluetypes &&
7172
ci1.ssaflags == ci2.ssaflags &&
7273
ci1.method_for_inference_limit_heuristics == ci2.method_for_inference_limit_heuristics &&
73-
ci1.linetable == ci2.linetable &&
7474
ci1.slotnames == ci2.slotnames &&
7575
ci1.slotflags == ci2.slotflags
7676
if VERSION >= v"1.2"

src/backedges.jl

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,19 @@ function direct_backedges(f::Union{Method,Callable}; skip::Bool=true)
6969
end
7070
end
7171
return false
72+
elseif isa(item, Core.TypeName)
73+
tn = item::Core.TypeName
74+
if isdefined(tn, :backedges)
75+
# `tn.backedges` is typed as `Core.MethodCache`, but is actually
76+
# a `Vector{Any}`; the pointer shenanigans mimic a reinterpret.
77+
sigmis = unsafe_pointer_to_objref(pointer_from_objref(tn.backedges))::Vector{Any}
78+
for i = 1:2:length(sigmis)
79+
sig, edge = sigmis[i], sigmis[i+1]::CodeInstance
80+
mi = Core.Compiler.get_ci_mi(edge)
81+
push!(bes, Pair{Any,MethodInstance}(sig, mi))
82+
push!(_skip, mi)
83+
end
84+
end
7285
elseif isa(item, MethodInstance)
7386
callee = item::MethodInstance
7487
if isdefined(callee, :backedges)
@@ -91,6 +104,7 @@ if isdefined(Core.Compiler, :BackedgeIterator)
91104
else
92105
function push_unskipped_backedges!(bes, callee, skip, _skip)
93106
for caller in callee.backedges
107+
isa(caller, CodeInstance) && (caller = Core.Compiler.get_ci_mi(caller))
94108
skip && caller _skip && continue
95109
push!(bes, callee=>caller)
96110
end
@@ -107,7 +121,10 @@ meaning it returns an empty list even when `mi.backedges` is not defined.
107121
function direct_backedges(mi::MethodInstance)
108122
out = MethodInstance[]
109123
if isdefined(mi, :backedges)
110-
append!(out, mi.backedges)
124+
for edge in mi.backedges
125+
isa(edge, CodeInstance) && (edge = Core.Compiler.get_ci_mi(edge))
126+
push!(out, edge)
127+
end
111128
end
112129
return out
113130
end

src/findcallers.jl

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,19 @@ export findcallers
33
function get_typed_instances!(srcs, @nospecialize(tt), method::Method, world, interp)
44
# This is essentially taken from code_typed_by_type
55
matches = Base._methods_by_ftype(tt, -1, world)
6-
if matches === false
7-
error("signature $(item.specTypes) does not correspond to a generic function")
6+
if matches === false || matches === nothing
7+
error("signature $tt does not correspond to a generic function")
88
end
99
for match in matches
1010
match.method == method || continue
11-
meth = Base.func_for_method_checked(match.method, tt, match.sparams)
12-
(src, ty) = isdefined(Core.Compiler, :NativeInterpreter) ?
11+
meth = match.method
12+
if isdefined(Base, :func_for_method_checked)
13+
meth = Base.func_for_method_checked(meth, tt, match.sparams)
14+
end
15+
ret = isdefined(Core.Compiler, :NativeInterpreter) ?
1316
Core.Compiler.typeinf_code(interp, meth, match.spec_types, match.sparams, false) :
1417
Core.Compiler.typeinf_code(meth, match.spec_types, match.sparams, false, interp)
18+
src = isa(ret, Tuple) ? ret[1] : ret::CodeInfo
1519
push!(srcs, (src, match.sparams))
1620
end
1721
return srcs
@@ -22,10 +26,10 @@ defaultinterp(world) = isdefined(Core.Compiler, :NativeInterpreter) ?
2226
Core.Compiler.NativeInterpreter(world) :
2327
Core.Compiler.Params(world)
2428

25-
function get_typed_instances(mi::MethodInstance; world=typemax(UInt), interp=defaultinterp(world))
29+
function get_typed_instances(mi::MethodInstance; world=default_world(), interp=defaultinterp(world))
2630
return get_typed_instances!(Tuple{CodeInfo,Core.SimpleVector}[], mi, world, interp)
2731
end
28-
function get_typed_instances(@nospecialize(tt), method::Method; world=typemax(UInt), interp=defaultinterp(world))
32+
function get_typed_instances(@nospecialize(tt), method::Method; world=default_world(), interp=defaultinterp(world))
2933
return get_typed_instances!(Tuple{CodeInfo,Core.SimpleVector}[], tt, method, world, interp)
3034
end
3135

@@ -95,8 +99,8 @@ callers3 = findcallers(f, argtyps->length(argtyps) == 1 && argtyps[1] === Vector
9599
`findcallers` is not guaranteed to find all calls. Calls can be "obfuscated" by many mechanisms,
96100
including calls from top level, calls where the function is a runtime variable, etc.
97101
"""
98-
function findcallers(f, argmatch::Union{Function,Nothing}, mis::AbstractVector{Core.MethodInstance};
99-
callhead::Symbol=:call, world=typemax(UInt), interp=defaultinterp(world))
102+
function findcallers(f, argmatch::Union{Function,Nothing}, mis::AbstractVector{MethodInstance};
103+
callhead::Symbol=:call, world=default_world(), interp=defaultinterp(world))
100104
callhead === :call || callhead === :invoke || callhead === :iterate || error(":call and :invoke are supported, got ", callhead)
101105
# Check that f is not a type with specified parameters
102106
if f isa DataType && !isempty(f.parameters)
@@ -105,7 +109,7 @@ function findcallers(f, argmatch::Union{Function,Nothing}, mis::AbstractVector{C
105109
# Construct a GlobalRef version of `f`
106110
ref = GlobalRef(parentmodule(f), nameof(f))
107111
callers = CallMatch[]
108-
srcs = Tuple{CodeInfo,Core.SimpleVector}[]
112+
srcs = Tuple{CodeInfo,SimpleVector}[]
109113
for item in mis
110114
empty!(srcs)
111115
try
@@ -140,6 +144,9 @@ function findcallers(f, argmatch::Union{Function,Nothing}, mis::AbstractVector{C
140144
throw(err)
141145
end
142146
end
147+
if isa(callee, Core.Const)
148+
callee = callee.val
149+
end
143150
matches = false
144151
if callee === f
145152
matches = true
@@ -188,6 +195,12 @@ function findcallers(f, argmatch::Union{Function,Nothing}, mis::AbstractVector{C
188195
return callers
189196
end
190197

198+
@static if isdefined(Base, :get_world_counter)
199+
default_world() = Base.get_world_counter()
200+
else
201+
default_world() = typemax(UInt)
202+
end
203+
191204
isglobalref(@nospecialize(g), mod::Module, name::Symbol) = isa(g, GlobalRef) && g.mod === mod && g.name === name
192205

193206
extract(a, sparams) = isa(a, Core.Const) ? Core.Typeof(a.val) :
@@ -203,7 +216,12 @@ function eval_ssa(src, sparams, id)
203216
if stmt.head === :call
204217
callee = stmt.args[1]
205218
if isglobalref(callee, Core, :apply_type)
206-
return stmt.args[2]
219+
ret = stmt.args[2]
220+
if isa(ret, Core.SSAValue)
221+
# try one level deeper
222+
ret = eval_ssa(src, sparams, ret.id)
223+
end
224+
return ret
207225
elseif isglobalref(callee, Base, :getproperty)
208226
modg, objq = stmt.args[2], stmt.args[3]
209227
if isa(modg, Core.SSAValue)

src/visit.jl

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,11 @@ function _visit(@nospecialize(operation), @nospecialize(f::Callable), visited::I
127127
print && println("Callable ", f)
128128
if operation(f)
129129
ml = methods(f)
130-
_visit(operation, ml.mt, visited, print)
130+
@static if hasfield(Base.MethodList, :mt)
131+
_visit(operation, ml.mt, visited, print)
132+
else
133+
_visit(operation, ml.tn, visited, print)
134+
end
131135
for m in ml.ms
132136
_visit(operation, m, visited, print)
133137
end
@@ -146,14 +150,17 @@ function _visit(@nospecialize(operation), ml::Base.MethodList, visited::IdSet{An
146150
ml visited && return nothing
147151
push!(visited, ml)
148152
print && println("MethodList ", ml)
149-
_visit(operation, ml.mt, visited, print)
153+
@static if hasfield(Base.MethodList, :mt)
154+
_visit(operation, ml.mt, visited, print)
155+
else
156+
_visit(operation, ml.tn, visited, print)
157+
end
150158
for m in ml.ms
151159
_visit(operation, m, visited, print)
152160
end
153161
return nothing
154162
end
155163

156-
157164
function _visit(@nospecialize(operation), mt::MethodTable, visited::IdSet{Any}, print::Bool)
158165
mt visited && return nothing
159166
push!(visited, mt)
@@ -162,6 +169,14 @@ function _visit(@nospecialize(operation), mt::MethodTable, visited::IdSet{Any},
162169
return nothing
163170
end
164171

172+
function _visit(@nospecialize(operation), tn::Core.TypeName, visited::IdSet{Any}, print::Bool)
173+
tn visited && return nothing
174+
push!(visited, tn)
175+
print && println("TypeName ", tn)
176+
operation(tn)
177+
return nothing
178+
end
179+
165180
function _visit(@nospecialize(operation), m::Method, visited::IdSet{Any}, print::Bool)
166181
m visited && return nothing
167182
push!(visited, m)
@@ -285,6 +300,7 @@ else
285300
push!(visited, mi)
286301
if operation(mi) && isdefined(mi, :backedges)
287302
for edge in mi.backedges
303+
isa(edge, CodeInstance) && (edge = Core.Compiler.get_ci_mi(edge))
288304
_visit_backedges(operation, edge, visited)
289305
end
290306
end

0 commit comments

Comments
 (0)