Skip to content

Commit 6467c56

Browse files
committed
make just one MethodTable
Most of the complexity here is because of the need to provide legacy support to the experimental external/overlay MethodTable, otherwise this would just be a simple renaming of Table->Cache, which would then have simply been unnecessary and made this PR very tiny. Oh well.
1 parent 772745b commit 6467c56

38 files changed

+763
-716
lines changed

Compiler/src/Compiler.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ else
3838
using Core.Intrinsics, Core.IR
3939

4040
using Core: ABIOverride, Builtin, CodeInstance, IntrinsicFunction, MethodInstance, MethodMatch,
41-
MethodTable, PartialOpaque, SimpleVector, TypeofVararg,
41+
MethodTable, MethodCache, PartialOpaque, SimpleVector, TypeofVararg,
4242
_apply_iterate, apply_type, compilerbarrier, donotdelete, memoryref_isassigned,
4343
memoryrefget, memoryrefnew, memoryrefoffset, memoryrefset!, print, println, show, svec,
4444
typename, unsafe_write, write

Compiler/src/abstractinterpretation.jl

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -363,15 +363,13 @@ function find_union_split_method_matches(interp::AbstractInterpreter, argtypes::
363363
arg_n = split_argtypes[i]::Vector{Any}
364364
sig_n = argtypes_to_type(arg_n)
365365
sig_n === Bottom && continue
366-
mt = ccall(:jl_method_table_for, Any, (Any,), sig_n)
367-
mt === nothing && return FailedMethodMatch("Could not identify method table for call")
368-
mt = mt::MethodTable
369366
thismatches = findall(sig_n, method_table(interp); limit = max_methods)
370367
if thismatches === nothing
371368
return FailedMethodMatch("For one of the union split cases, too many methods matched")
372369
end
373370
valid_worlds = intersect(valid_worlds, thismatches.valid_worlds)
374371
thisfullmatch = any(match::MethodMatch->match.fully_covers, thismatches)
372+
mt = getglobal(Core, :_)
375373
thisinfo = MethodMatchInfo(thismatches, mt, sig_n, thisfullmatch)
376374
push!(infos, thisinfo)
377375
for idx = 1:length(thismatches)
@@ -385,18 +383,14 @@ function find_union_split_method_matches(interp::AbstractInterpreter, argtypes::
385383
end
386384

387385
function find_simple_method_matches(interp::AbstractInterpreter, @nospecialize(atype), max_methods::Int)
388-
mt = ccall(:jl_method_table_for, Any, (Any,), atype)
389-
if mt === nothing
390-
return FailedMethodMatch("Could not identify method table for call")
391-
end
392-
mt = mt::MethodTable
393386
matches = findall(atype, method_table(interp); limit = max_methods)
394387
if matches === nothing
395388
# this means too many methods matched
396389
# (assume this will always be true, so we don't compute / update valid age in this case)
397390
return FailedMethodMatch("Too many methods matched")
398391
end
399392
fullmatch = any(match::MethodMatch->match.fully_covers, matches)
393+
mt = getglobal(Core, :_)
400394
info = MethodMatchInfo(matches, mt, atype, fullmatch)
401395
applicable = MethodMatchTarget[MethodMatchTarget(matches[idx], info.edges, idx) for idx = 1:length(matches)]
402396
return MethodMatches(applicable, info, matches.valid_worlds)

Compiler/src/tfuncs.jl

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3195,15 +3195,12 @@ function _hasmethod_tfunc(interp::AbstractInterpreter, argtypes::Vector{Any}, sv
31953195
isdispatchelem(ft) || return CallMeta(Bool, Any, Effects(), NoCallInfo()) # check that we might not have a subtype of `ft` at runtime, before doing supertype lookup below
31963196
types = rewrap_unionall(Tuple{ft, unwrapped.parameters...}, types)::Type
31973197
end
3198-
mt = ccall(:jl_method_table_for, Any, (Any,), types)
3199-
if !isa(mt, MethodTable)
3200-
return CallMeta(Bool, Any, EFFECTS_THROWS, NoCallInfo())
3201-
end
32023198
match, valid_worlds = findsup(types, method_table(interp))
32033199
update_valid_age!(sv, valid_worlds)
32043200
if match === nothing
32053201
rt = Const(false)
32063202
vresults = MethodLookupResult(Any[], valid_worlds, true)
3203+
mt = getglobal(Core, :_)
32073204
vinfo = MethodMatchInfo(vresults, mt, types, false) # XXX: this should actually be an info with invoke-type edge
32083205
else
32093206
rt = Const(true)

Compiler/src/utilities.jl

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,8 @@ end
158158

159159
function get_compileable_sig(method::Method, @nospecialize(atype), sparams::SimpleVector)
160160
isa(atype, DataType) || return nothing
161-
mt = ccall(:jl_method_get_table, Any, (Any,), method)
162-
mt === nothing && return nothing
163-
return ccall(:jl_normalize_to_compilable_sig, Any, (Any, Any, Any, Any, Cint),
164-
mt, atype, sparams, method, #=int return_if_compileable=#1)
161+
return ccall(:jl_normalize_to_compilable_sig, Any, (Any, Any, Any, Cint),
162+
atype, sparams, method, #=int return_if_compileable=#1)
165163
end
166164

167165

base/Base_compiler.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ function Core.kwcall(kwargs::NamedTuple, ::typeof(invoke), f, T, args...)
211211
return invoke(Core.kwcall, T, kwargs, f, args...)
212212
end
213213
# invoke does not have its own call cache, but kwcall for invoke does
214-
setfield!(typeof(invoke).name.mt, :max_args, 3, :monotonic) # invoke, f, T, args...
214+
setfield!(typeof(invoke).name.mt, :max_args, Int32(3), :monotonic) # invoke, f, T, args...
215215

216216
# define applicable(f, T, args...; kwargs...), without kwargs wrapping
217217
# to forward to applicable
@@ -245,7 +245,7 @@ function Core.kwcall(kwargs::NamedTuple, ::typeof(invokelatest), f, args...)
245245
@inline
246246
return Core.invokelatest(Core.kwcall, kwargs, f, args...)
247247
end
248-
setfield!(typeof(invokelatest).name.mt, :max_args, 2, :monotonic) # invokelatest, f, args...
248+
setfield!(typeof(invokelatest).name.mt, :max_args, Int32(2), :monotonic) # invokelatest, f, args...
249249

250250
"""
251251
invoke_in_world(world, f, args...; kwargs...)
@@ -279,7 +279,7 @@ function Core.kwcall(kwargs::NamedTuple, ::typeof(invoke_in_world), world::UInt,
279279
@inline
280280
return Core.invoke_in_world(world, Core.kwcall, kwargs, f, args...)
281281
end
282-
setfield!(typeof(invoke_in_world).name.mt, :max_args, 3, :monotonic) # invoke_in_world, world, f, args...
282+
setfield!(typeof(invoke_in_world).name.mt, :max_args, Int32(3), :monotonic) # invoke_in_world, world, f, args...
283283

284284
# core operations & types
285285
include("promotion.jl")

base/invalidation.jl

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -15,36 +15,6 @@ function iterate(gri::GlobalRefIterator, i = 1)
1515
return ((b::Core.Binding).globalref, i+1)
1616
end
1717

18-
const TYPE_TYPE_MT = Type.body.name.mt
19-
const NONFUNCTION_MT = Core.MethodTable.name.mt
20-
function foreach_module_mtable(visit, m::Module, world::UInt)
21-
for gb in globalrefs(m)
22-
binding = gb.binding
23-
bpart = lookup_binding_partition(world, binding)
24-
if is_defined_const_binding(binding_kind(bpart))
25-
v = partition_restriction(bpart)
26-
uw = unwrap_unionall(v)
27-
name = gb.name
28-
if isa(uw, DataType)
29-
tn = uw.name
30-
if tn.module === m && tn.name === name && tn.wrapper === v && isdefined(tn, :mt)
31-
# this is the original/primary binding for the type (name/wrapper)
32-
mt = tn.mt
33-
if mt !== nothing && mt !== TYPE_TYPE_MT && mt !== NONFUNCTION_MT
34-
@assert mt.module === m
35-
visit(mt) || return false
36-
end
37-
end
38-
elseif isa(v, Core.MethodTable) && v.module === m && v.name === name
39-
# this is probably an external method table here, so let's
40-
# assume so as there is no way to precisely distinguish them
41-
visit(v) || return false
42-
end
43-
end
44-
end
45-
return true
46-
end
47-
4818
function foreachgr(visit, src::CodeInfo)
4919
stmts = src.code
5020
for i = 1:length(stmts)

base/methodshow.jl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ function kwarg_decl(m::Method, kwtype = nothing)
8181
if m.sig !== Tuple # OpaqueClosure or Builtin
8282
kwtype = typeof(Core.kwcall)
8383
sig = rewrap_unionall(Tuple{kwtype, NamedTuple, (unwrap_unionall(m.sig)::DataType).parameters...}, m.sig)
84-
kwli = ccall(:jl_methtable_lookup, Any, (Any, Any, UInt), kwtype.name.mt, sig, get_world_counter())
84+
kwli = ccall(:jl_methtable_lookup, Any, (Any, UInt), sig, get_world_counter())
8585
if kwli !== nothing
8686
kwli = kwli::Method
8787
slotnames = ccall(:jl_uncompress_argnames, Vector{Symbol}, (Any,), kwli.slot_syms)
@@ -271,15 +271,15 @@ function show_method_list_header(io::IO, ms::MethodList, namefmt::Function)
271271
if hasname
272272
what = (startswith(sname, '@') ?
273273
"macro"
274-
: mt.module === Core && mt.defs isa Core.TypeMapEntry && (mt.defs.func::Method).sig === Tuple ?
274+
: mt.module === Core && mt.cache isa Core.TypeMapEntry && ((mt.cache.func::MethodInstance).def::Method).sig === Tuple ?
275275
"builtin function"
276276
: # else
277277
"generic function")
278278
print(io, " for ", what, " ", namedisplay, " from ")
279279

280-
col = get!(() -> popfirst!(STACKTRACE_MODULECOLORS), STACKTRACE_FIXEDCOLORS, parentmodule_before_main(ms.mt.module))
280+
col = get!(() -> popfirst!(STACKTRACE_MODULECOLORS), STACKTRACE_FIXEDCOLORS, parentmodule_before_main(mt.module))
281281

282-
printstyled(io, ms.mt.module, color=col)
282+
printstyled(io, mt.module, color=col)
283283
elseif '#' in sname
284284
print(io, " for anonymous function ", namedisplay)
285285
elseif mt === _TYPE_NAME.mt
@@ -293,6 +293,8 @@ end
293293
# Determine the `modulecolor` value to pass to `show_method`
294294
function _modulecolor(method::Method)
295295
mmt = get_methodtable(method)
296+
# TODO: this looks like a buggy bit of internal hacking, so disable for now
297+
return nothing
296298
if mmt === nothing || mmt.module === parentmodule(method)
297299
return nothing
298300
end

base/operators.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ function afoldl(op, a, bs...)
633633
end
634634
return y
635635
end
636-
setfield!(typeof(afoldl).name.mt, :max_args, 34, :monotonic)
636+
setfield!(typeof(afoldl).name.mt, :max_args, Int32(34), :monotonic)
637637

638638
for op in (:+, :*, :&, :|, :xor, :min, :max, :kron)
639639
@eval begin

base/reflection.jl

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -933,13 +933,7 @@ this is a compiler-generated name. For explicitly-declared subtypes of
933933
`Function`, it is the name of the function's type.
934934
"""
935935
function nameof(f::Function)
936-
t = typeof(f)
937-
mt = t.name.mt
938-
if mt === Symbol.name.mt
939-
# uses shared method table, so name is not unique to this function type
940-
return nameof(t)
941-
end
942-
return mt.name
936+
return typeof(f).name.mt.name
943937
end
944938

945939
function nameof(f::Core.IntrinsicFunction)

base/runtime_internals.jl

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,14 +1331,14 @@ hasproperty(x, s::Symbol) = s in propertynames(x)
13311331
Make method `m` uncallable and force recompilation of any methods that use(d) it.
13321332
"""
13331333
function delete_method(m::Method)
1334-
ccall(:jl_method_table_disable, Cvoid, (Any, Any), get_methodtable(m), m)
1334+
ccall(:jl_method_table_disable, Cvoid, (Any,), m)
13351335
end
13361336

13371337

13381338
# type for reflecting and pretty-printing a subset of methods
13391339
mutable struct MethodList <: AbstractArray{Method,1}
13401340
ms::Array{Method,1}
1341-
mt::Core.MethodTable
1341+
mt::Core.MethodCache # contains module.name globalref for pretty printing
13421342
end
13431343

13441344
size(m::MethodList) = size(m.ms)
@@ -1349,10 +1349,10 @@ function MethodList(mt::Core.MethodTable)
13491349
visit(mt) do m
13501350
push!(ms, m)
13511351
end
1352-
return MethodList(ms, mt)
1352+
return MethodList(ms, mt.cache)
13531353
end
13541354

1355-
function matches_to_methods(ms::Array{Any,1}, mt::Core.MethodTable, mod)
1355+
function matches_to_methods(ms::Array{Any,1}, mt::Core.MethodCache, mod)
13561356
# Lack of specialization => a comprehension triggers too many invalidations via _collect, so collect the methods manually
13571357
ms = Method[(ms[i]::Core.MethodMatch).method for i in 1:length(ms)]
13581358
# Remove shadowed methods with identical type signatures
@@ -1589,10 +1589,8 @@ end
15891589

15901590
function get_nospecializeinfer_sig(method::Method, @nospecialize(atype), sparams::SimpleVector)
15911591
isa(atype, DataType) || return method.sig
1592-
mt = ccall(:jl_method_get_table, Any, (Any,), method)
1593-
mt === nothing && return method.sig
1594-
return ccall(:jl_normalize_to_compilable_sig, Any, (Any, Any, Any, Any, Cint),
1595-
mt, atype, sparams, method, #=int return_if_compileable=#0)
1592+
return ccall(:jl_normalize_to_compilable_sig, Any, (Any, Any, Any, Cint),
1593+
atype, sparams, method, #=int return_if_compileable=#0)
15961594
end
15971595

15981596
is_nospecialized(method::Method) = method.nospecialize 0

0 commit comments

Comments
 (0)