Skip to content

Commit a96dab7

Browse files
vtjnashAmit Shirodkar
authored andcommitted
Revert "Add support for external method tables (JuliaLang#39697)" (JuliaLang#40862)
This reverts commit 39caf28.
1 parent 53ba4b7 commit a96dab7

File tree

16 files changed

+97
-319
lines changed

16 files changed

+97
-319
lines changed

base/compiler/methodtable.jl

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,6 @@ struct InternalMethodTable <: MethodTableView
2828
world::UInt
2929
end
3030

31-
"""
32-
struct OverlayMethodTable <: MethodTableView
33-
34-
Overlays the internal method table such that specific queries can be redirected to an
35-
external table, e.g., to override existing method.
36-
"""
37-
struct OverlayMethodTable <: MethodTableView
38-
world::UInt
39-
mt::Core.MethodTable
40-
end
41-
4231
"""
4332
struct CachedMethodTable <: MethodTableView
4433
@@ -65,26 +54,7 @@ function findall(@nospecialize(sig::Type{<:Tuple}), table::InternalMethodTable;
6554
_min_val = RefValue{UInt}(typemin(UInt))
6655
_max_val = RefValue{UInt}(typemax(UInt))
6756
_ambig = RefValue{Int32}(0)
68-
ms = _methods_by_ftype(sig, nothing, limit, table.world, false, _min_val, _max_val, _ambig)
69-
if ms === false
70-
return missing
71-
end
72-
return MethodLookupResult(ms::Vector{Any}, WorldRange(_min_val[], _max_val[]), _ambig[] != 0)
73-
end
74-
75-
function findall(@nospecialize(sig::Type{<:Tuple}), table::OverlayMethodTable; limit::Int=typemax(Int))
76-
_min_val = RefValue{UInt}(typemin(UInt))
77-
_max_val = RefValue{UInt}(typemax(UInt))
78-
_ambig = RefValue{Int32}(0)
79-
ms = _methods_by_ftype(sig, table.mt, limit, table.world, false, _min_val, _max_val, _ambig)
80-
if ms === false
81-
return missing
82-
elseif isempty(ms)
83-
# fall back to the internal method table
84-
_min_val[] = typemin(UInt)
85-
_max_val[] = typemax(UInt)
86-
ms = _methods_by_ftype(sig, nothing, limit, table.world, false, _min_val, _max_val, _ambig)
87-
end
57+
ms = _methods_by_ftype(sig, limit, table.world, false, _min_val, _max_val, _ambig)
8858
if ms === false
8959
return missing
9060
end

base/experimental.jl

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
module Experimental
1111

1212
using Base: Threads, sync_varname
13-
using Base.Meta
1413

1514
"""
1615
Const(A::Array)
@@ -257,36 +256,4 @@ end
257256
# OpaqueClosure
258257
include("opaque_closure.jl")
259258

260-
"""
261-
Experimental.@overlay mt [function def]
262-
263-
Define a method and add it to the method table `mt` instead of to the global method table.
264-
This can be used to implement a method override mechanism. Regular compilation will not
265-
consider these methods, and you should customize the compilation flow to look in these
266-
method tables (e.g., using [`Core.Compiler.OverlayMethodTable`](@ref)).
267-
268-
"""
269-
macro overlay(mt, def)
270-
def = macroexpand(__module__, def) # to expand @inline, @generated, etc
271-
if !isexpr(def, [:function, :(=)]) || !isexpr(def.args[1], :call)
272-
error("@overlay requires a function Expr")
273-
end
274-
def.args[1].args[1] = Expr(:overlay, mt, def.args[1].args[1])
275-
esc(def)
276-
end
277-
278-
"""
279-
Experimental.@MethodTable(name)
280-
281-
Create a new MethodTable in the current module, bound to `name`. This method table can be
282-
used with the [`Experimental.@overlay`](@ref) macro to define methods for a function without
283-
adding them to the global method table.
284-
"""
285-
macro MethodTable(name)
286-
isa(name, Symbol) || error("name must be a symbol")
287-
esc(quote
288-
const $name = ccall(:jl_new_method_table, Any, (Any, Any), $(quot(name)), $(__module__))
289-
end)
290-
end
291-
292259
end

base/reflection.jl

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -895,16 +895,13 @@ function _methods(@nospecialize(f), @nospecialize(t), lim::Int, world::UInt)
895895
end
896896

897897
function _methods_by_ftype(@nospecialize(t), lim::Int, world::UInt)
898-
return _methods_by_ftype(t, nothing, lim, world)
898+
return _methods_by_ftype(t, lim, world, false, RefValue{UInt}(typemin(UInt)), RefValue{UInt}(typemax(UInt)), Ptr{Int32}(C_NULL))
899899
end
900-
function _methods_by_ftype(@nospecialize(t), mt::Union{Core.MethodTable, Nothing}, lim::Int, world::UInt)
901-
return _methods_by_ftype(t, mt, lim, world, false, RefValue{UInt}(typemin(UInt)), RefValue{UInt}(typemax(UInt)), Ptr{Int32}(C_NULL))
900+
function _methods_by_ftype(@nospecialize(t), lim::Int, world::UInt, ambig::Bool, min::Array{UInt,1}, max::Array{UInt,1}, has_ambig::Array{Int32,1})
901+
return ccall(:jl_matching_methods, Any, (Any, Cint, Cint, UInt, Ptr{UInt}, Ptr{UInt}, Ptr{Int32}), t, lim, ambig, world, min, max, has_ambig)::Union{Array{Any,1}, Bool}
902902
end
903-
function _methods_by_ftype(@nospecialize(t), mt::Union{Core.MethodTable, Nothing}, lim::Int, world::UInt, ambig::Bool, min::Array{UInt,1}, max::Array{UInt,1}, has_ambig::Array{Int32,1})
904-
return ccall(:jl_matching_methods, Any, (Any, Any, Cint, Cint, UInt, Ptr{UInt}, Ptr{UInt}, Ptr{Int32}), t, mt, lim, ambig, world, min, max, has_ambig)::Union{Array{Any,1}, Bool}
905-
end
906-
function _methods_by_ftype(@nospecialize(t), mt::Union{Core.MethodTable, Nothing}, lim::Int, world::UInt, ambig::Bool, min::Ref{UInt}, max::Ref{UInt}, has_ambig::Ref{Int32})
907-
return ccall(:jl_matching_methods, Any, (Any, Any, Cint, Cint, UInt, Ptr{UInt}, Ptr{UInt}, Ptr{Int32}), t, mt, lim, ambig, world, min, max, has_ambig)::Union{Array{Any,1}, Bool}
903+
function _methods_by_ftype(@nospecialize(t), lim::Int, world::UInt, ambig::Bool, min::Ref{UInt}, max::Ref{UInt}, has_ambig::Ref{Int32})
904+
return ccall(:jl_matching_methods, Any, (Any, Cint, Cint, UInt, Ptr{UInt}, Ptr{UInt}, Ptr{Int32}), t, lim, ambig, world, min, max, has_ambig)::Union{Array{Any,1}, Bool}
908905
end
909906

910907
function _method_by_ftype(args...)
@@ -974,7 +971,7 @@ function methods_including_ambiguous(@nospecialize(f), @nospecialize(t))
974971
world = typemax(UInt)
975972
min = RefValue{UInt}(typemin(UInt))
976973
max = RefValue{UInt}(typemax(UInt))
977-
ms = _methods_by_ftype(tt, nothing, -1, world, true, min, max, Ptr{Int32}(C_NULL))
974+
ms = _methods_by_ftype(tt, -1, world, true, min, max, Ptr{Int32}(C_NULL))
978975
isa(ms, Bool) && return ms
979976
return MethodList(Method[(m::Core.MethodMatch).method for m in ms], typeof(f).name.mt)
980977
end
@@ -1536,7 +1533,7 @@ function isambiguous(m1::Method, m2::Method; ambiguous_bottom::Bool=false)
15361533
min = UInt[typemin(UInt)]
15371534
max = UInt[typemax(UInt)]
15381535
has_ambig = Int32[0]
1539-
ms = _methods_by_ftype(ti, nothing, -1, typemax(UInt), true, min, max, has_ambig)::Vector
1536+
ms = _methods_by_ftype(ti, -1, typemax(UInt), true, min, max, has_ambig)::Vector
15401537
has_ambig[] == 0 && return false
15411538
if !ambiguous_bottom
15421539
filter!(ms) do m::Core.MethodMatch

src/codegen.cpp

Lines changed: 47 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,7 @@ static const auto jlinvoke_func = new JuliaFunction{
566566
static const auto jlmethod_func = new JuliaFunction{
567567
"jl_method_def",
568568
[](LLVMContext &C) { return FunctionType::get(T_prjlvalue,
569-
{T_prjlvalue, T_prjlvalue, T_prjlvalue, T_pjlvalue}, false); },
569+
{T_prjlvalue, T_prjlvalue, T_pjlvalue}, false); },
570570
nullptr,
571571
};
572572
static const auto jlgenericfunction_func = new JuliaFunction{
@@ -4398,62 +4398,58 @@ static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr, ssize_t ssaval)
43984398
return emit_sparam(ctx, jl_unbox_long(args[0]) - 1);
43994399
}
44004400
else if (head == method_sym) {
4401-
if (jl_expr_nargs(ex) == 1) {
4402-
jl_value_t *mn = args[0];
4403-
assert(jl_expr_nargs(ex) != 1 || jl_is_symbol(mn) || jl_is_slot(mn));
4401+
jl_value_t *mn = args[0];
4402+
assert(jl_expr_nargs(ex) != 1 || jl_is_symbol(mn) || jl_is_slot(mn));
44044403

4405-
Value *bp = NULL, *name, *bp_owner = V_null;
4406-
jl_binding_t *bnd = NULL;
4407-
bool issym = jl_is_symbol(mn);
4408-
bool isglobalref = !issym && jl_is_globalref(mn);
4409-
jl_module_t *mod = ctx.module;
4410-
if (issym || isglobalref) {
4411-
if (isglobalref) {
4412-
mod = jl_globalref_mod(mn);
4413-
mn = (jl_value_t*)jl_globalref_name(mn);
4414-
}
4415-
JL_TRY {
4416-
if (jl_symbol_name((jl_sym_t*)mn)[0] == '@')
4417-
jl_errorf("macro definition not allowed inside a local scope");
4418-
name = literal_pointer_val(ctx, mn);
4419-
bnd = jl_get_binding_for_method_def(mod, (jl_sym_t*)mn);
4420-
}
4421-
JL_CATCH {
4422-
jl_value_t *e = jl_current_exception();
4423-
// errors. boo. root it somehow :(
4424-
bnd = jl_get_binding_wr(ctx.module, (jl_sym_t*)jl_gensym(), 1);
4425-
bnd->value = e;
4426-
bnd->constp = 1;
4427-
raise_exception(ctx, literal_pointer_val(ctx, e));
4428-
return ghostValue(jl_nothing_type);
4429-
}
4430-
bp = julia_binding_gv(ctx, bnd);
4431-
bp_owner = literal_pointer_val(ctx, (jl_value_t*)mod);
4432-
}
4433-
else if (jl_is_slot(mn) || jl_is_argument(mn)) {
4434-
int sl = jl_slot_number(mn)-1;
4435-
jl_varinfo_t &vi = ctx.slots[sl];
4436-
bp = vi.boxroot;
4437-
name = literal_pointer_val(ctx, (jl_value_t*)slot_symbol(ctx, sl));
4438-
}
4439-
if (bp) {
4440-
Value *mdargs[5] = { name, literal_pointer_val(ctx, (jl_value_t*)mod), bp,
4441-
bp_owner, literal_pointer_val(ctx, bnd) };
4442-
jl_cgval_t gf = mark_julia_type(
4443-
ctx,
4444-
ctx.builder.CreateCall(prepare_call(jlgenericfunction_func), makeArrayRef(mdargs)),
4445-
true,
4446-
jl_function_type);
4404+
Value *bp = NULL, *name, *bp_owner = V_null;
4405+
jl_binding_t *bnd = NULL;
4406+
bool issym = jl_is_symbol(mn);
4407+
bool isglobalref = !issym && jl_is_globalref(mn);
4408+
jl_module_t *mod = ctx.module;
4409+
if (issym || isglobalref) {
4410+
if (isglobalref) {
4411+
mod = jl_globalref_mod(mn);
4412+
mn = (jl_value_t*)jl_globalref_name(mn);
4413+
}
4414+
JL_TRY {
4415+
if (jl_symbol_name((jl_sym_t*)mn)[0] == '@')
4416+
jl_errorf("macro definition not allowed inside a local scope");
4417+
name = literal_pointer_val(ctx, mn);
4418+
bnd = jl_get_binding_for_method_def(mod, (jl_sym_t*)mn);
4419+
}
4420+
JL_CATCH {
4421+
jl_value_t *e = jl_current_exception();
4422+
// errors. boo. root it somehow :(
4423+
bnd = jl_get_binding_wr(ctx.module, (jl_sym_t*)jl_gensym(), 1);
4424+
bnd->value = e;
4425+
bnd->constp = 1;
4426+
raise_exception(ctx, literal_pointer_val(ctx, e));
4427+
return ghostValue(jl_nothing_type);
4428+
}
4429+
bp = julia_binding_gv(ctx, bnd);
4430+
bp_owner = literal_pointer_val(ctx, (jl_value_t*)mod);
4431+
}
4432+
else if (jl_is_slot(mn) || jl_is_argument(mn)) {
4433+
int sl = jl_slot_number(mn)-1;
4434+
jl_varinfo_t &vi = ctx.slots[sl];
4435+
bp = vi.boxroot;
4436+
name = literal_pointer_val(ctx, (jl_value_t*)slot_symbol(ctx, sl));
4437+
}
4438+
if (bp) {
4439+
Value *mdargs[5] = { name, literal_pointer_val(ctx, (jl_value_t*)mod), bp,
4440+
bp_owner, literal_pointer_val(ctx, bnd) };
4441+
jl_cgval_t gf = mark_julia_type(
4442+
ctx,
4443+
ctx.builder.CreateCall(prepare_call(jlgenericfunction_func), makeArrayRef(mdargs)),
4444+
true,
4445+
jl_function_type);
4446+
if (jl_expr_nargs(ex) == 1)
44474447
return gf;
4448-
}
4449-
emit_error(ctx, "method: invalid declaration");
4450-
return jl_cgval_t();
44514448
}
44524449
Value *a1 = boxed(ctx, emit_expr(ctx, args[1]));
44534450
Value *a2 = boxed(ctx, emit_expr(ctx, args[2]));
4454-
Value *mdargs[4] = {
4451+
Value *mdargs[3] = {
44554452
/*argdata*/a1,
4456-
ConstantPointerNull::get(cast<PointerType>(T_prjlvalue)),
44574453
/*code*/a2,
44584454
/*module*/literal_pointer_val(ctx, (jl_value_t*)ctx.module)
44594455
};

src/dump.c

Lines changed: 11 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -504,11 +504,6 @@ static void jl_serialize_code_instance(jl_serializer_state *s, jl_code_instance_
504504
jl_serialize_code_instance(s, codeinst->next, skip_partial_opaque);
505505
}
506506

507-
enum METHOD_SERIALIZATION_MODE {
508-
METHOD_INTERNAL = 1,
509-
METHOD_EXTERNAL_MT = 2,
510-
};
511-
512507
static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_literal) JL_GC_DISABLED
513508
{
514509
if (jl_serialize_generic(s, v)) {
@@ -632,34 +627,18 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_li
632627
else if (jl_is_method(v)) {
633628
write_uint8(s->s, TAG_METHOD);
634629
jl_method_t *m = (jl_method_t*)v;
635-
int serialization_mode = 0;
636-
if (m->is_for_opaque_closure || module_in_worklist(m->module))
637-
serialization_mode |= METHOD_INTERNAL;
638-
if (!(serialization_mode & METHOD_INTERNAL)) {
630+
int internal = 1;
631+
internal = m->is_for_opaque_closure || module_in_worklist(m->module);
632+
if (!internal) {
639633
// flag this in the backref table as special
640634
uintptr_t *bp = (uintptr_t*)ptrhash_bp(&backref_table, v);
641635
assert(*bp != (uintptr_t)HT_NOTFOUND);
642636
*bp |= 1;
643637
}
644638
jl_serialize_value(s, (jl_value_t*)m->sig);
645639
jl_serialize_value(s, (jl_value_t*)m->module);
646-
if (m->external_mt != NULL) {
647-
assert(jl_typeis(m->external_mt, jl_methtable_type));
648-
jl_methtable_t *mt = (jl_methtable_t*)m->external_mt;
649-
if (!module_in_worklist(mt->module)) {
650-
serialization_mode |= METHOD_EXTERNAL_MT;
651-
}
652-
}
653-
write_uint8(s->s, serialization_mode);
654-
if (serialization_mode & METHOD_EXTERNAL_MT) {
655-
// We reference this method table by module and binding
656-
jl_methtable_t *mt = (jl_methtable_t*)m->external_mt;
657-
jl_serialize_value(s, mt->module);
658-
jl_serialize_value(s, mt->name);
659-
} else {
660-
jl_serialize_value(s, (jl_value_t*)m->external_mt);
661-
}
662-
if (!(serialization_mode & METHOD_INTERNAL))
640+
write_uint8(s->s, internal);
641+
if (!internal)
663642
return;
664643
jl_serialize_value(s, m->specializations);
665644
jl_serialize_value(s, m->speckeyset);
@@ -973,10 +952,6 @@ static void jl_collect_lambdas_from_mod(jl_array_t *s, jl_module_t *m) JL_GC_DIS
973952
jl_collect_lambdas_from_mod(s, (jl_module_t*)b->value);
974953
}
975954
}
976-
else if (jl_is_mtable(bv)) {
977-
// a module containing an external method table
978-
jl_collect_methtable_from_mod(s, (jl_methtable_t*)bv);
979-
}
980955
}
981956
}
982957
}
@@ -1040,7 +1015,7 @@ static void jl_collect_backedges(jl_array_t *s, jl_array_t *t)
10401015
size_t min_valid = 0;
10411016
size_t max_valid = ~(size_t)0;
10421017
int ambig = 0;
1043-
jl_value_t *matches = jl_matching_methods((jl_tupletype_t*)sig, jl_nothing, -1, 0, jl_world_counter, &min_valid, &max_valid, &ambig);
1018+
jl_value_t *matches = jl_matching_methods((jl_tupletype_t*)sig, -1, 0, jl_world_counter, &min_valid, &max_valid, &ambig);
10441019
if (matches == jl_false) {
10451020
valid = 0;
10461021
break;
@@ -1483,18 +1458,8 @@ static jl_value_t *jl_deserialize_value_method(jl_serializer_state *s, jl_value_
14831458
jl_gc_wb(m, m->sig);
14841459
m->module = (jl_module_t*)jl_deserialize_value(s, (jl_value_t**)&m->module);
14851460
jl_gc_wb(m, m->module);
1486-
int serialization_mode = read_uint8(s->s);
1487-
if (serialization_mode & METHOD_EXTERNAL_MT) {
1488-
jl_module_t *mt_mod = (jl_module_t*)jl_deserialize_value(s, NULL);
1489-
jl_sym_t *mt_name = (jl_sym_t*)jl_deserialize_value(s, NULL);
1490-
m->external_mt = jl_get_global(mt_mod, mt_name);
1491-
jl_gc_wb(m, m->external_mt);
1492-
assert(jl_typeis(m->external_mt, jl_methtable_type));
1493-
} else {
1494-
m->external_mt = jl_deserialize_value(s, &m->external_mt);
1495-
jl_gc_wb(m, m->external_mt);
1496-
}
1497-
if (!(serialization_mode & METHOD_INTERNAL)) {
1461+
int internal = read_uint8(s->s);
1462+
if (!internal) {
14981463
assert(loc != NULL && loc != HT_NOTFOUND);
14991464
arraylist_push(&flagref_list, loc);
15001465
arraylist_push(&flagref_list, (void*)pos);
@@ -1932,7 +1897,7 @@ static void jl_insert_methods(jl_array_t *list)
19321897
assert(!meth->is_for_opaque_closure);
19331898
jl_tupletype_t *simpletype = (jl_tupletype_t*)jl_array_ptr_ref(list, i + 1);
19341899
assert(jl_is_method(meth));
1935-
jl_methtable_t *mt = jl_method_get_table(meth);
1900+
jl_methtable_t *mt = jl_method_table_for((jl_value_t*)meth->sig);
19361901
assert((jl_value_t*)mt != jl_nothing);
19371902
jl_method_table_insert(mt, meth, simpletype);
19381903
}
@@ -1962,7 +1927,7 @@ static void jl_verify_edges(jl_array_t *targets, jl_array_t **pvalids)
19621927
size_t max_valid = ~(size_t)0;
19631928
int ambig = 0;
19641929
// TODO: possibly need to included ambiguities too (for the optimizer correctness)?
1965-
jl_value_t *matches = jl_matching_methods((jl_tupletype_t*)sig, jl_nothing, -1, 0, jl_world_counter, &min_valid, &max_valid, &ambig);
1930+
jl_value_t *matches = jl_matching_methods((jl_tupletype_t*)sig, -1, 0, jl_world_counter, &min_valid, &max_valid, &ambig);
19661931
if (matches == jl_false || jl_array_len(matches) != jl_array_len(expected)) {
19671932
valid = 0;
19681933
}
@@ -2500,7 +2465,7 @@ static jl_method_t *jl_recache_method(jl_method_t *m)
25002465
{
25012466
assert(!m->is_for_opaque_closure);
25022467
jl_datatype_t *sig = (jl_datatype_t*)m->sig;
2503-
jl_methtable_t *mt = jl_method_get_table(m);
2468+
jl_methtable_t *mt = jl_method_table_for((jl_value_t*)m->sig);
25042469
assert((jl_value_t*)mt != jl_nothing);
25052470
jl_set_typeof(m, (void*)(intptr_t)0x30); // invalidate the old value to help catch errors
25062471
jl_method_t *_new = jl_lookup_method(mt, sig, m->module->primary_world);

0 commit comments

Comments
 (0)