Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Compiler/src/Compiler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ else
using Core.Intrinsics, Core.IR

using Core: ABIOverride, Builtin, CodeInstance, IntrinsicFunction, MethodInstance, MethodMatch,
MethodTable, PartialOpaque, SimpleVector, TypeofVararg,
MethodTable, MethodCache, PartialOpaque, SimpleVector, TypeofVararg,
_apply_iterate, apply_type, compilerbarrier, donotdelete, memoryref_isassigned,
memoryrefget, memoryrefnew, memoryrefoffset, memoryrefset!, print, println, show, svec,
typename, unsafe_write, write
Expand Down
10 changes: 2 additions & 8 deletions Compiler/src/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -363,15 +363,13 @@ function find_union_split_method_matches(interp::AbstractInterpreter, argtypes::
arg_n = split_argtypes[i]::Vector{Any}
sig_n = argtypes_to_type(arg_n)
sig_n === Bottom && continue
mt = ccall(:jl_method_table_for, Any, (Any,), sig_n)
mt === nothing && return FailedMethodMatch("Could not identify method table for call")
mt = mt::MethodTable
thismatches = findall(sig_n, method_table(interp); limit = max_methods)
if thismatches === nothing
return FailedMethodMatch("For one of the union split cases, too many methods matched")
end
valid_worlds = intersect(valid_worlds, thismatches.valid_worlds)
thisfullmatch = any(match::MethodMatch->match.fully_covers, thismatches)
mt = Core.GlobalMethods
thisinfo = MethodMatchInfo(thismatches, mt, sig_n, thisfullmatch)
push!(infos, thisinfo)
for idx = 1:length(thismatches)
Expand All @@ -385,18 +383,14 @@ function find_union_split_method_matches(interp::AbstractInterpreter, argtypes::
end

function find_simple_method_matches(interp::AbstractInterpreter, @nospecialize(atype), max_methods::Int)
mt = ccall(:jl_method_table_for, Any, (Any,), atype)
if mt === nothing
return FailedMethodMatch("Could not identify method table for call")
end
mt = mt::MethodTable
matches = findall(atype, method_table(interp); limit = max_methods)
if matches === nothing
# this means too many methods matched
# (assume this will always be true, so we don't compute / update valid age in this case)
return FailedMethodMatch("Too many methods matched")
end
fullmatch = any(match::MethodMatch->match.fully_covers, matches)
mt = Core.GlobalMethods
info = MethodMatchInfo(matches, mt, atype, fullmatch)
applicable = MethodMatchTarget[MethodMatchTarget(matches[idx], info.edges, idx) for idx = 1:length(matches)]
return MethodMatches(applicable, info, matches.valid_worlds)
Expand Down
5 changes: 2 additions & 3 deletions Compiler/src/stmtinfo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,16 @@ end
add_edges_impl(edges::Vector{Any}, info::MethodMatchInfo) = _add_edges_impl(edges, info)
function _add_edges_impl(edges::Vector{Any}, info::MethodMatchInfo, mi_edge::Bool=false)
if !fully_covering(info)
# add legacy-style missing backedge info also
exists = false
for i in 2:length(edges)
if edges[i] === info.mt && edges[i-1] == info.atype
if edges[i] === Core.GlobalMethods && edges[i-1] == info.atype
exists = true
break
end
end
if !exists
push!(edges, info.atype)
push!(edges, info.mt)
push!(edges, Core.GlobalMethods)
end
end
nmatches = length(info.results)
Expand Down
5 changes: 1 addition & 4 deletions Compiler/src/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3199,15 +3199,12 @@ function _hasmethod_tfunc(interp::AbstractInterpreter, argtypes::Vector{Any}, sv
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
types = rewrap_unionall(Tuple{ft, unwrapped.parameters...}, types)::Type
end
mt = ccall(:jl_method_table_for, Any, (Any,), types)
if !isa(mt, MethodTable)
return CallMeta(Bool, Any, EFFECTS_THROWS, NoCallInfo())
end
match, valid_worlds = findsup(types, method_table(interp))
update_valid_age!(sv, valid_worlds)
if match === nothing
rt = Const(false)
vresults = MethodLookupResult(Any[], valid_worlds, true)
mt = Core.GlobalMethods
vinfo = MethodMatchInfo(vresults, mt, types, false) # XXX: this should actually be an info with invoke-type edge
else
rt = Const(true)
Expand Down
2 changes: 1 addition & 1 deletion Compiler/src/typeinfer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -767,7 +767,7 @@ function store_backedges(caller::CodeInstance, edges::SimpleVector)
if item isa Core.Binding
maybe_add_binding_backedge!(item, caller)
elseif item isa MethodTable
ccall(:jl_method_table_add_backedge, Cvoid, (Any, Any, Any), item, invokesig, caller)
ccall(:jl_method_table_add_backedge, Cvoid, (Any, Any), invokesig, caller)
else
item::MethodInstance
ccall(:jl_method_instance_add_backedge, Cvoid, (Any, Any, Any), item, invokesig, caller)
Expand Down
6 changes: 2 additions & 4 deletions Compiler/src/utilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,8 @@ end

function get_compileable_sig(method::Method, @nospecialize(atype), sparams::SimpleVector)
isa(atype, DataType) || return nothing
mt = ccall(:jl_method_get_table, Any, (Any,), method)
mt === nothing && return nothing
return ccall(:jl_normalize_to_compilable_sig, Any, (Any, Any, Any, Any, Cint),
mt, atype, sparams, method, #=int return_if_compileable=#1)
return ccall(:jl_normalize_to_compilable_sig, Any, (Any, Any, Any, Cint),
atype, sparams, method, #=int return_if_compileable=#1)
end


Expand Down
6 changes: 3 additions & 3 deletions base/Base_compiler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ function Core.kwcall(kwargs::NamedTuple, ::typeof(invoke), f, T, args...)
return invoke(Core.kwcall, T, kwargs, f, args...)
end
# invoke does not have its own call cache, but kwcall for invoke does
setfield!(typeof(invoke).name.mt, :max_args, 3, :monotonic) # invoke, f, T, args...
setfield!(typeof(invoke).name, :max_args, Int32(3), :monotonic) # invoke, f, T, args...

# define applicable(f, T, args...; kwargs...), without kwargs wrapping
# to forward to applicable
Expand Down Expand Up @@ -252,7 +252,7 @@ function Core.kwcall(kwargs::NamedTuple, ::typeof(invokelatest), f, args...)
@inline
return Core.invokelatest(Core.kwcall, kwargs, f, args...)
end
setfield!(typeof(invokelatest).name.mt, :max_args, 2, :monotonic) # invokelatest, f, args...
setfield!(typeof(invokelatest).name, :max_args, Int32(2), :monotonic) # invokelatest, f, args...

"""
invoke_in_world(world, f, args...; kwargs...)
Expand Down Expand Up @@ -286,7 +286,7 @@ function Core.kwcall(kwargs::NamedTuple, ::typeof(invoke_in_world), world::UInt,
@inline
return Core.invoke_in_world(world, Core.kwcall, kwargs, f, args...)
end
setfield!(typeof(invoke_in_world).name.mt, :max_args, 3, :monotonic) # invoke_in_world, world, f, args...
setfield!(typeof(invoke_in_world).name, :max_args, Int32(3), :monotonic) # invoke_in_world, world, f, args...

# core operations & types
include("promotion.jl")
Expand Down
4 changes: 2 additions & 2 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ macro deprecate(old, new, export_old=true)
maybe_export,
:($(esc(old)) = begin
$meta
depwarn($"`$oldcall` is deprecated, use `$newcall` instead.", Core.Typeof($(esc(fnexpr))).name.mt.name)
depwarn($"`$oldcall` is deprecated, use `$newcall` instead.", Core.Typeof($(esc(fnexpr))).name.singletonname)
$(esc(new))
end))
else
Expand All @@ -222,7 +222,7 @@ macro deprecate(old, new, export_old=true)
export_old ? Expr(:export, esc(old)) : nothing,
:(function $(esc(old))(args...; kwargs...)
$meta
depwarn($"`$old` is deprecated, use `$new` instead.", Core.Typeof($(esc(old))).name.mt.name)
depwarn($"`$old` is deprecated, use `$new` instead.", Core.Typeof($(esc(old))).name.singletonname)
$(esc(new))(args...; kwargs...)
end))
end
Expand Down
2 changes: 1 addition & 1 deletion base/docs/bindings.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,6 @@ end

aliasof(b::Binding) = defined(b) ? (a = aliasof(resolve(b), b); defined(a) ? a : b) : b
aliasof(d::DataType, b) = Binding(d.name.module, d.name.name)
aliasof(λ::Function, b) = (m = typeof(λ).name.mt; Binding(m.module, m.name))
aliasof(λ::Function, b) = (m = typeof(λ).name; Binding(m.module, m.singletonname))
aliasof(m::Module, b) = Binding(m, nameof(m))
aliasof(other, b) = b
2 changes: 1 addition & 1 deletion base/errorshow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ function showerror(io::IO, ex::MethodError)
print(io, "\nIn case you're trying to index into the array, use square brackets [] instead of parentheses ().")
end
# Check for local functions that shadow methods in Base
let name = ft.name.mt.name
let name = ft.name.singletonname
if f_is_function && isdefined(Base, name)
basef = getfield(Base, name)
if basef !== f && hasmethod(basef, arg_types)
Expand Down
30 changes: 0 additions & 30 deletions base/invalidation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,36 +15,6 @@ function iterate(gri::GlobalRefIterator, i = 1)
return ((b::Core.Binding).globalref, i+1)
end

const TYPE_TYPE_MT = Type.body.name.mt
const NONFUNCTION_MT = Core.MethodTable.name.mt
function foreach_module_mtable(visit, m::Module, world::UInt)
for gb in globalrefs(m)
binding = gb.binding
bpart = lookup_binding_partition(world, binding)
if is_defined_const_binding(binding_kind(bpart))
v = partition_restriction(bpart)
uw = unwrap_unionall(v)
name = gb.name
if isa(uw, DataType)
tn = uw.name
if tn.module === m && tn.name === name && tn.wrapper === v && isdefined(tn, :mt)
# this is the original/primary binding for the type (name/wrapper)
mt = tn.mt
if mt !== nothing && mt !== TYPE_TYPE_MT && mt !== NONFUNCTION_MT
@assert mt.module === m
visit(mt) || return false
end
end
elseif isa(v, Core.MethodTable) && v.module === m && v.name === name
# this is probably an external method table here, so let's
# assume so as there is no way to precisely distinguish them
visit(v) || return false
end
end
end
return true
end

function foreachgr(visit, src::CodeInfo)
stmts = src.code
for i = 1:length(stmts)
Expand Down
29 changes: 15 additions & 14 deletions base/methodshow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ function kwarg_decl(m::Method, kwtype = nothing)
if m.sig !== Tuple # OpaqueClosure or Builtin
kwtype = typeof(Core.kwcall)
sig = rewrap_unionall(Tuple{kwtype, NamedTuple, (unwrap_unionall(m.sig)::DataType).parameters...}, m.sig)
kwli = ccall(:jl_methtable_lookup, Any, (Any, Any, UInt), kwtype.name.mt, sig, get_world_counter())
kwli = ccall(:jl_methtable_lookup, Any, (Any, UInt), sig, get_world_counter())
if kwli !== nothing
kwli = kwli::Method
slotnames = ccall(:jl_uncompress_argnames, Vector{Symbol}, (Any,), kwli.slot_syms)
Expand Down Expand Up @@ -259,10 +259,10 @@ function show_method(io::IO, m::Method; modulecolor = :light_black, digit_align_
end

function show_method_list_header(io::IO, ms::MethodList, namefmt::Function)
mt = ms.mt
name = mt.name
hasname = isdefined(mt.module, name) &&
typeof(getfield(mt.module, name)) <: Function
tn = ms.tn
name = tn.singletonname
hasname = isdefined(tn.module, name) &&
typeof(getfield(tn.module, name)) <: Function
n = length(ms)
m = n==1 ? "method" : "methods"
print(io, "# $n $m")
Expand All @@ -271,18 +271,18 @@ function show_method_list_header(io::IO, ms::MethodList, namefmt::Function)
if hasname
what = (startswith(sname, '@') ?
"macro"
: mt.module === Core && mt.defs isa Core.TypeMapEntry && (mt.defs.func::Method).sig === Tuple ?
: tn.module === Core && tn.wrapper <: Core.Builtin ?
"builtin function"
: # else
"generic function")
print(io, " for ", what, " ", namedisplay, " from ")

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

printstyled(io, ms.mt.module, color=col)
printstyled(io, tn.module, color=col)
elseif '#' in sname
print(io, " for anonymous function ", namedisplay)
elseif mt === _TYPE_NAME.mt
elseif tn === _TYPE_NAME || iskindtype(tn.wrapper)
print(io, " for type constructor")
else
print(io, " for callable object")
Expand All @@ -293,6 +293,8 @@ end
# Determine the `modulecolor` value to pass to `show_method`
function _modulecolor(method::Method)
mmt = get_methodtable(method)
# TODO: this looks like a buggy bit of internal hacking, so disable for now
return nothing
if mmt === nothing || mmt.module === parentmodule(method)
return nothing
end
Expand All @@ -314,10 +316,10 @@ function _modulecolor(method::Method)
end

function show_method_table(io::IO, ms::MethodList, max::Int=-1, header::Bool=true)
mt = ms.mt
name = mt.name
hasname = isdefined(mt.module, name) &&
typeof(getfield(mt.module, name)) <: Function
tn = ms.tn
name = tn.singletonname
hasname = isdefined(tn.module, name) &&
typeof(getfield(tn.module, name)) <: Function
if header
show_method_list_header(io, ms, str -> "\""*str*"\"")
end
Expand Down Expand Up @@ -458,7 +460,6 @@ function show(io::IO, ::MIME"text/html", m::Method)
end

function show(io::IO, mime::MIME"text/html", ms::MethodList)
mt = ms.mt
show_method_list_header(io, ms, str -> "<b>"*str*"</b>")
print(io, "<ul>")
for meth in ms
Expand Down
2 changes: 1 addition & 1 deletion base/operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ function afoldl(op, a, bs...)
end
return y
end
setfield!(typeof(afoldl).name.mt, :max_args, 34, :monotonic)
setfield!(typeof(afoldl).name, :max_args, Int32(34), :monotonic)

for op in (:+, :*, :&, :|, :xor, :min, :max, :kron)
@eval begin
Expand Down
8 changes: 1 addition & 7 deletions base/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -933,13 +933,7 @@ this is a compiler-generated name. For explicitly-declared subtypes of
`Function`, it is the name of the function's type.
"""
function nameof(f::Function)
t = typeof(f)
mt = t.name.mt
if mt === Symbol.name.mt
# uses shared method table, so name is not unique to this function type
return nameof(t)
end
return mt.name
return typeof(f).name.singletonname
end

function nameof(f::Core.IntrinsicFunction)
Expand Down
20 changes: 9 additions & 11 deletions base/runtime_internals.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1356,14 +1356,14 @@ hasproperty(x, s::Symbol) = s in propertynames(x)
Make method `m` uncallable and force recompilation of any methods that use(d) it.
"""
function delete_method(m::Method)
ccall(:jl_method_table_disable, Cvoid, (Any, Any), get_methodtable(m), m)
ccall(:jl_method_table_disable, Cvoid, (Any,), m)
end


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

size(m::MethodList) = size(m.ms)
Expand All @@ -1374,10 +1374,10 @@ function MethodList(mt::Core.MethodTable)
visit(mt) do m
push!(ms, m)
end
return MethodList(ms, mt)
return MethodList(ms, Any.name)
end

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

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

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

function methods(@nospecialize(f),
Expand Down Expand Up @@ -1623,10 +1623,8 @@ end

function get_nospecializeinfer_sig(method::Method, @nospecialize(atype), sparams::SimpleVector)
isa(atype, DataType) || return method.sig
mt = ccall(:jl_method_get_table, Any, (Any,), method)
mt === nothing && return method.sig
return ccall(:jl_normalize_to_compilable_sig, Any, (Any, Any, Any, Any, Cint),
mt, atype, sparams, method, #=int return_if_compileable=#0)
return ccall(:jl_normalize_to_compilable_sig, Any, (Any, Any, Any, Cint),
atype, sparams, method, #=int return_if_compileable=#0)
end

is_nospecialized(method::Method) = method.nospecialize ≠ 0
Expand Down
Loading