Skip to content

Commit 898e1c1

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 58daba4 commit 898e1c1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+980
-1007
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/stmtinfo.jl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,16 @@ end
4747
add_edges_impl(edges::Vector{Any}, info::MethodMatchInfo) = _add_edges_impl(edges, info)
4848
function _add_edges_impl(edges::Vector{Any}, info::MethodMatchInfo, mi_edge::Bool=false)
4949
if !fully_covering(info)
50-
# add legacy-style missing backedge info also
5150
exists = false
5251
for i in 2:length(edges)
53-
if edges[i] === info.mt && edges[i-1] == info.atype
52+
if edges[i] === Core._ && edges[i-1] == info.atype
5453
exists = true
5554
break
5655
end
5756
end
5857
if !exists
5958
push!(edges, info.atype)
60-
push!(edges, info.mt)
59+
push!(edges, Core._)
6160
end
6261
end
6362
nmatches = length(info.results)

Compiler/src/tfuncs.jl

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3199,15 +3199,12 @@ function _hasmethod_tfunc(interp::AbstractInterpreter, argtypes::Vector{Any}, sv
31993199
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
32003200
types = rewrap_unionall(Tuple{ft, unwrapped.parameters...}, types)::Type
32013201
end
3202-
mt = ccall(:jl_method_table_for, Any, (Any,), types)
3203-
if !isa(mt, MethodTable)
3204-
return CallMeta(Bool, Any, EFFECTS_THROWS, NoCallInfo())
3205-
end
32063202
match, valid_worlds = findsup(types, method_table(interp))
32073203
update_valid_age!(sv, valid_worlds)
32083204
if match === nothing
32093205
rt = Const(false)
32103206
vresults = MethodLookupResult(Any[], valid_worlds, true)
3207+
mt = getglobal(Core, :_)
32113208
vinfo = MethodMatchInfo(vresults, mt, types, false) # XXX: this should actually be an info with invoke-type edge
32123209
else
32133210
rt = Const(true)

Compiler/src/typeinfer.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -767,7 +767,7 @@ function store_backedges(caller::CodeInstance, edges::SimpleVector)
767767
if item isa Core.Binding
768768
maybe_add_binding_backedge!(item, caller)
769769
elseif item isa MethodTable
770-
ccall(:jl_method_table_add_backedge, Cvoid, (Any, Any, Any), item, invokesig, caller)
770+
ccall(:jl_method_table_add_backedge, Cvoid, (Any, Any), invokesig, caller)
771771
else
772772
item::MethodInstance
773773
ccall(:jl_method_instance_add_backedge, Cvoid, (Any, Any, Any), item, invokesig, caller)

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
@@ -218,7 +218,7 @@ function Core.kwcall(kwargs::NamedTuple, ::typeof(invoke), f, T, args...)
218218
return invoke(Core.kwcall, T, kwargs, f, args...)
219219
end
220220
# invoke does not have its own call cache, but kwcall for invoke does
221-
setfield!(typeof(invoke).name.mt, :max_args, 3, :monotonic) # invoke, f, T, args...
221+
setfield!(typeof(invoke).name, :max_args, Int32(3), :monotonic) # invoke, f, T, args...
222222

223223
# define applicable(f, T, args...; kwargs...), without kwargs wrapping
224224
# to forward to applicable
@@ -252,7 +252,7 @@ function Core.kwcall(kwargs::NamedTuple, ::typeof(invokelatest), f, args...)
252252
@inline
253253
return Core.invokelatest(Core.kwcall, kwargs, f, args...)
254254
end
255-
setfield!(typeof(invokelatest).name.mt, :max_args, 2, :monotonic) # invokelatest, f, args...
255+
setfield!(typeof(invokelatest).name, :max_args, Int32(2), :monotonic) # invokelatest, f, args...
256256

257257
"""
258258
invoke_in_world(world, f, args...; kwargs...)
@@ -286,7 +286,7 @@ function Core.kwcall(kwargs::NamedTuple, ::typeof(invoke_in_world), world::UInt,
286286
@inline
287287
return Core.invoke_in_world(world, Core.kwcall, kwargs, f, args...)
288288
end
289-
setfield!(typeof(invoke_in_world).name.mt, :max_args, 3, :monotonic) # invoke_in_world, world, f, args...
289+
setfield!(typeof(invoke_in_world).name, :max_args, Int32(3), :monotonic) # invoke_in_world, world, f, args...
290290

291291
# core operations & types
292292
include("promotion.jl")

base/deprecated.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ macro deprecate(old, new, export_old=true)
211211
maybe_export,
212212
:($(esc(old)) = begin
213213
$meta
214-
depwarn($"`$oldcall` is deprecated, use `$newcall` instead.", Core.Typeof($(esc(fnexpr))).name.mt.name)
214+
depwarn($"`$oldcall` is deprecated, use `$newcall` instead.", Core.Typeof($(esc(fnexpr))).name.singletonname)
215215
$(esc(new))
216216
end))
217217
else
@@ -222,7 +222,7 @@ macro deprecate(old, new, export_old=true)
222222
export_old ? Expr(:export, esc(old)) : nothing,
223223
:(function $(esc(old))(args...; kwargs...)
224224
$meta
225-
depwarn($"`$old` is deprecated, use `$new` instead.", Core.Typeof($(esc(old))).name.mt.name)
225+
depwarn($"`$old` is deprecated, use `$new` instead.", Core.Typeof($(esc(old))).name.singletonname)
226226
$(esc(new))(args...; kwargs...)
227227
end))
228228
end

base/docs/bindings.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,6 @@ end
4242

4343
aliasof(b::Binding) = defined(b) ? (a = aliasof(resolve(b), b); defined(a) ? a : b) : b
4444
aliasof(d::DataType, b) = Binding(d.name.module, d.name.name)
45-
aliasof::Function, b) = (m = typeof(λ).name.mt; Binding(m.module, m.name))
45+
aliasof::Function, b) = (m = typeof(λ).name; Binding(m.module, m.singletonname))
4646
aliasof(m::Module, b) = Binding(m, nameof(m))
4747
aliasof(other, b) = b

base/errorshow.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ function showerror(io::IO, ex::MethodError)
328328
print(io, "\nIn case you're trying to index into the array, use square brackets [] instead of parentheses ().")
329329
end
330330
# Check for local functions that shadow methods in Base
331-
let name = ft.name.mt.name
331+
let name = ft.name.singletonname
332332
if f_is_function && isdefined(Base, name)
333333
basef = getfield(Base, name)
334334
if basef !== f && hasmethod(basef, arg_types)

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: 15 additions & 14 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)
@@ -259,10 +259,10 @@ function show_method(io::IO, m::Method; modulecolor = :light_black, digit_align_
259259
end
260260

261261
function show_method_list_header(io::IO, ms::MethodList, namefmt::Function)
262-
mt = ms.mt
263-
name = mt.name
264-
hasname = isdefined(mt.module, name) &&
265-
typeof(getfield(mt.module, name)) <: Function
262+
tn = ms.tn
263+
name = tn.singletonname
264+
hasname = isdefined(tn.module, name) &&
265+
typeof(getfield(tn.module, name)) <: Function
266266
n = length(ms)
267267
m = n==1 ? "method" : "methods"
268268
print(io, "# $n $m")
@@ -271,18 +271,18 @@ 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+
: tn.module === Core && tn.wrapper <: Core.Builtin ?
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(tn.module))
281281

282-
printstyled(io, ms.mt.module, color=col)
282+
printstyled(io, tn.module, color=col)
283283
elseif '#' in sname
284284
print(io, " for anonymous function ", namedisplay)
285-
elseif mt === _TYPE_NAME.mt
285+
elseif tn === _TYPE_NAME || iskindtype(tn.wrapper)
286286
print(io, " for type constructor")
287287
else
288288
print(io, " for callable object")
@@ -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
@@ -314,10 +316,10 @@ function _modulecolor(method::Method)
314316
end
315317

316318
function show_method_table(io::IO, ms::MethodList, max::Int=-1, header::Bool=true)
317-
mt = ms.mt
318-
name = mt.name
319-
hasname = isdefined(mt.module, name) &&
320-
typeof(getfield(mt.module, name)) <: Function
319+
tn = ms.tn
320+
name = tn.singletonname
321+
hasname = isdefined(tn.module, name) &&
322+
typeof(getfield(tn.module, name)) <: Function
321323
if header
322324
show_method_list_header(io, ms, str -> "\""*str*"\"")
323325
end
@@ -458,7 +460,6 @@ function show(io::IO, ::MIME"text/html", m::Method)
458460
end
459461

460462
function show(io::IO, mime::MIME"text/html", ms::MethodList)
461-
mt = ms.mt
462463
show_method_list_header(io, ms, str -> "<b>"*str*"</b>")
463464
print(io, "<ul>")
464465
for meth in ms

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, :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.singletonname
943937
end
944938

945939
function nameof(f::Core.IntrinsicFunction)

base/runtime_internals.jl

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,14 +1356,14 @@ hasproperty(x, s::Symbol) = s in propertynames(x)
13561356
Make method `m` uncallable and force recompilation of any methods that use(d) it.
13571357
"""
13581358
function delete_method(m::Method)
1359-
ccall(:jl_method_table_disable, Cvoid, (Any, Any), get_methodtable(m), m)
1359+
ccall(:jl_method_table_disable, Cvoid, (Any,), m)
13601360
end
13611361

13621362

13631363
# type for reflecting and pretty-printing a subset of methods
13641364
mutable struct MethodList <: AbstractArray{Method,1}
13651365
ms::Array{Method,1}
1366-
mt::Core.MethodTable
1366+
tn::Core.TypeName # contains module.singletonname globalref for altering some aspects of printing
13671367
end
13681368

13691369
size(m::MethodList) = size(m.ms)
@@ -1374,10 +1374,10 @@ function MethodList(mt::Core.MethodTable)
13741374
visit(mt) do m
13751375
push!(ms, m)
13761376
end
1377-
return MethodList(ms, mt)
1377+
return MethodList(ms, Any.name)
13781378
end
13791379

1380-
function matches_to_methods(ms::Array{Any,1}, mt::Core.MethodTable, mod)
1380+
function matches_to_methods(ms::Array{Any,1}, tn::Core.TypeName, mod)
13811381
# Lack of specialization => a comprehension triggers too many invalidations via _collect, so collect the methods manually
13821382
ms = Method[(ms[i]::Core.MethodMatch).method for i in 1:length(ms)]
13831383
# Remove shadowed methods with identical type signatures
@@ -1392,7 +1392,7 @@ function matches_to_methods(ms::Array{Any,1}, mt::Core.MethodTable, mod)
13921392
mod === nothing || filter!(ms) do m
13931393
return parentmodule(m) mod
13941394
end
1395-
return MethodList(ms, mt)
1395+
return MethodList(ms, tn)
13961396
end
13971397

13981398
"""
@@ -1414,7 +1414,7 @@ function methods(@nospecialize(f), @nospecialize(t),
14141414
world = get_world_counter()
14151415
world == typemax(UInt) && error("code reflection cannot be used from generated functions")
14161416
ms = _methods(f, t, -1, world)::Vector{Any}
1417-
return matches_to_methods(ms, typeof(f).name.mt, mod)
1417+
return matches_to_methods(ms, typeof(f).name, mod)
14181418
end
14191419
methods(@nospecialize(f), @nospecialize(t), mod::Module) = methods(f, t, (mod,))
14201420

@@ -1425,7 +1425,7 @@ function methods_including_ambiguous(@nospecialize(f), @nospecialize(t))
14251425
min = RefValue{UInt}(typemin(UInt))
14261426
max = RefValue{UInt}(typemax(UInt))
14271427
ms = _methods_by_ftype(tt, nothing, -1, world, true, min, max, Ptr{Int32}(C_NULL))::Vector{Any}
1428-
return matches_to_methods(ms, typeof(f).name.mt, nothing)
1428+
return matches_to_methods(ms, typeof(f).name, nothing)
14291429
end
14301430

14311431
function methods(@nospecialize(f),
@@ -1614,10 +1614,8 @@ end
16141614

16151615
function get_nospecializeinfer_sig(method::Method, @nospecialize(atype), sparams::SimpleVector)
16161616
isa(atype, DataType) || return method.sig
1617-
mt = ccall(:jl_method_get_table, Any, (Any,), method)
1618-
mt === nothing && return method.sig
1619-
return ccall(:jl_normalize_to_compilable_sig, Any, (Any, Any, Any, Any, Cint),
1620-
mt, atype, sparams, method, #=int return_if_compileable=#0)
1617+
return ccall(:jl_normalize_to_compilable_sig, Any, (Any, Any, Any, Cint),
1618+
atype, sparams, method, #=int return_if_compileable=#0)
16211619
end
16221620

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

0 commit comments

Comments
 (0)