@@ -25,12 +25,23 @@ function getroot(node::InstanceTree)
25
25
return node
26
26
end
27
27
28
+ function Base. show (io:: IO , node:: InstanceTree ; methods= false )
29
+ if get (io, :limit , false )
30
+ print (io, node. mi, " at depth " , node. depth, " with " , countchildren (node), " children" )
31
+ else
32
+ println (io, " " ^ Int (node. depth), methods ? node. mi. def : node. mi)
33
+ foreach (node. children) do child
34
+ show (io, child; methods= methods)
35
+ end
36
+ end
37
+ end
38
+
28
39
struct Invalidations
29
40
mt_backedges:: Vector{Pair{Any,InstanceTree}} # sig=>tree
30
- tables:: Vector{MethodInstance}
31
41
backedges:: Vector{Pair{MethodInstance,InstanceTree}}
42
+ mt_cache:: Vector{MethodInstance}
32
43
end
33
- Invalidations () = Invalidations (Pair{Any,InstanceTree}[], MethodInstance[], InstanceTree [])
44
+ Invalidations () = Invalidations (Pair{Any,InstanceTree}[], Pair{ MethodInstance,InstanceTree} [], MethodInstance [])
34
45
35
46
struct MethodInvalidations
36
47
method:: Method
@@ -61,20 +72,36 @@ countchildren(methinv::MethodInvalidations) = countchildren(methinv.invalidation
61
72
62
73
# We could use AbstractTrees here, but typically one is not interested in the full tree,
63
74
# just the top method and the number of children it has
64
- function Base. show (io:: IO , invalidations:: Invalidations )
75
+ function Base. show (io:: IO , invalidations:: Invalidations ; method = nothing )
65
76
iscompact = get (io, :compact , false )
66
77
function showlist (io, treelist, indent= 0 )
67
78
n = length (treelist)
68
79
for (i, tree) in enumerate (treelist)
80
+ sig = nothing
69
81
if isa (tree, Pair)
70
82
if isa (tree. first, Type)
71
83
print (io, " signature " , tree. first, " triggered " )
84
+ sig = tree. first
72
85
elseif isa (tree. first, MethodInstance)
73
86
print (io, tree. first, " triggered " )
87
+ sig = tree. first. specTypes
74
88
end
75
89
tree = tree. second
76
90
end
77
91
print (io, tree. mi, " (" , countchildren (tree), " children)" )
92
+ if isa (method, Method)
93
+ ms1, ms2 = method. sig <: sig , sig <: method.sig
94
+ diagnosis = if ms1 && ! ms2
95
+ " more specific"
96
+ elseif ms2 && ! ms1
97
+ " less specific"
98
+ elseif ms1 && ms2
99
+ " equal specificity"
100
+ else
101
+ " ambiguous"
102
+ end
103
+ printstyled (io, ' ' , diagnosis, color= :cyan )
104
+ end
78
105
if iscompact
79
106
i < n && print (io, " , " )
80
107
else
@@ -93,15 +120,15 @@ function Base.show(io::IO, invalidations::Invalidations)
93
120
end
94
121
iscompact && print (io, " ; " )
95
122
end
96
- if ! isempty (invalidations. tables )
97
- println (io, indent, length (invalidations. tables ), " mt_cache" )
123
+ if ! isempty (invalidations. mt_cache )
124
+ println (io, indent, length (invalidations. mt_cache ), " mt_cache" )
98
125
end
99
126
iscompact && print (io, ' ;' )
100
127
end
101
128
102
129
function Base. show (io:: IO , methinv:: MethodInvalidations )
103
130
println (io, methinv. reason, " " , methinv. method, " invalidated:" )
104
- show (io, methinv. invalidations)
131
+ show (io, methinv. invalidations; method = methinv . method )
105
132
end
106
133
107
134
# `list` is in RPN format, with the "reason" coming after the items
@@ -152,13 +179,15 @@ function invalidation_trees(list)
152
179
elseif isa (item, String)
153
180
loctag = item
154
181
if loctag == " invalidate_mt_cache"
155
- push! (invalidations. tables , mi)
182
+ push! (invalidations. mt_cache , mi)
156
183
tree = nothing
157
184
elseif loctag == " jl_method_table_insert"
158
185
push! (invalidations. backedges, mi=> getroot (tree))
159
186
tree = nothing
187
+ elseif loctag == " insert_backedges"
188
+ println (" insert_backedges for " , mi)
160
189
else
161
- error (" unexpected loctag " , loctag)
190
+ error (" unexpected loctag " , loctag, " at " , i )
162
191
end
163
192
else
164
193
error (" unexpected item " , item, " at " , i)
@@ -190,6 +219,13 @@ function invalidation_trees(list)
190
219
return sort (methodtrees; by= countchildren)
191
220
end
192
221
222
+ function Base. getindex (methodtree:: MethodInvalidations , fn:: Symbol )
223
+ invs = methodtree. invalidations
224
+ return getfield (invs, fn)
225
+ end
226
+
227
+ Base. getindex (methodtree:: MethodInvalidations , fn:: Symbol , idx:: Int ) = methodtree[fn][idx]
228
+
193
229
# function explain(methodtree::MethodInvalidations)
194
230
# meth, invalidations = methodtree
195
231
# if isa(meth, Method)
211
247
# end
212
248
# println(" ", countchildren(tree), " direct and indirect descendants")
213
249
# end
214
- # for tree in invalidations.tables
250
+ # for tree in invalidations.mt_cache
215
251
# println(" method table for ", tree.mi)
216
252
# println(" ", countchildren(tree), " direct and indirect descendants")
217
253
# end
228
264
# idx = findfirst(mi, inst.second)
229
265
# idx !== nothing && return Any[methodtree, :instances, i, idx...]
230
266
# end
231
- # for (i, inst) in enumerate(invalidations.tables )
267
+ # for (i, inst) in enumerate(invalidations.mt_cache )
232
268
# idx = findfirst(mi, inst)
233
- # idx !== nothing && return Any[methodtree, :tables , i, idx...]
269
+ # idx !== nothing && return Any[methodtree, :mt_cache , i, idx...]
234
270
# end
235
271
# end
236
272
# return nothing
0 commit comments