Skip to content

Commit b57f8d1

Browse files
authored
Export method instance lookup functions (#52176)
1 parent 7fe08e0 commit b57f8d1

File tree

5 files changed

+57
-36
lines changed

5 files changed

+57
-36
lines changed

src/gf.c

+43-34
Original file line numberDiff line numberDiff line change
@@ -1444,34 +1444,45 @@ static jl_method_instance_t *cache_method(
14441444

14451445
static jl_method_match_t *_gf_invoke_lookup(jl_value_t *types JL_PROPAGATES_ROOT, jl_value_t *mt, size_t world, size_t *min_valid, size_t *max_valid);
14461446

1447-
static jl_method_instance_t *jl_mt_assoc_by_type(jl_methtable_t *mt JL_PROPAGATES_ROOT, jl_datatype_t *tt, size_t world)
1447+
static jl_method_instance_t *jl_mt_assoc_by_type(jl_methtable_t *mt JL_PROPAGATES_ROOT, jl_datatype_t *tt JL_MAYBE_UNROOTED, size_t world)
14481448
{
1449-
// caller must hold the mt->writelock
1449+
jl_genericmemory_t *leafcache = jl_atomic_load_relaxed(&mt->leafcache);
1450+
jl_typemap_entry_t *entry = lookup_leafcache(leafcache, (jl_value_t*)tt, world);
1451+
if (entry)
1452+
return entry->func.linfo;
1453+
JL_TIMING(METHOD_LOOKUP_SLOW, METHOD_LOOKUP_SLOW);
1454+
jl_method_match_t *matc = NULL;
1455+
JL_GC_PUSH2(&tt, &matc);
1456+
JL_LOCK(&mt->writelock);
14501457
assert(tt->isdispatchtuple || tt->hasfreetypevars);
1458+
jl_method_instance_t *mi = NULL;
14511459
if (tt->isdispatchtuple) {
14521460
jl_genericmemory_t *leafcache = jl_atomic_load_relaxed(&mt->leafcache);
14531461
jl_typemap_entry_t *entry = lookup_leafcache(leafcache, (jl_value_t*)tt, world);
14541462
if (entry)
1455-
return entry->func.linfo;
1463+
mi = entry->func.linfo;
14561464
}
14571465

1458-
struct jl_typemap_assoc search = {(jl_value_t*)tt, world, NULL, 0, ~(size_t)0};
1459-
jl_typemap_entry_t *entry = jl_typemap_assoc_by_type(jl_atomic_load_relaxed(&mt->cache), &search, jl_cachearg_offset(mt), /*subtype*/1);
1460-
if (entry)
1461-
return entry->func.linfo;
1466+
if (!mi) {
1467+
struct jl_typemap_assoc search = {(jl_value_t*)tt, world, NULL, 0, ~(size_t)0};
1468+
jl_typemap_entry_t *entry = jl_typemap_assoc_by_type(jl_atomic_load_relaxed(&mt->cache), &search, jl_cachearg_offset(mt), /*subtype*/1);
1469+
if (entry)
1470+
mi = entry->func.linfo;
1471+
}
14621472

1463-
size_t min_valid = 0;
1464-
size_t max_valid = ~(size_t)0;
1465-
jl_method_match_t *matc = _gf_invoke_lookup((jl_value_t*)tt, jl_nothing, world, &min_valid, &max_valid);
1466-
jl_method_instance_t *nf = NULL;
1467-
if (matc) {
1468-
JL_GC_PUSH1(&matc);
1469-
jl_method_t *m = matc->method;
1470-
jl_svec_t *env = matc->sparams;
1471-
nf = cache_method(mt, &mt->cache, (jl_value_t*)mt, tt, m, world, min_valid, max_valid, env);
1472-
JL_GC_POP();
1473+
if (!mi) {
1474+
size_t min_valid = 0;
1475+
size_t max_valid = ~(size_t)0;
1476+
matc = _gf_invoke_lookup((jl_value_t*)tt, jl_nothing, world, &min_valid, &max_valid);
1477+
if (matc) {
1478+
jl_method_t *m = matc->method;
1479+
jl_svec_t *env = matc->sparams;
1480+
mi = cache_method(mt, &mt->cache, (jl_value_t*)mt, tt, m, world, min_valid, max_valid, env);
1481+
}
14731482
}
1474-
return nf;
1483+
JL_UNLOCK(&mt->writelock);
1484+
JL_GC_POP();
1485+
return mi;
14751486
}
14761487

14771488

@@ -2233,7 +2244,19 @@ static jl_tupletype_t *lookup_arg_type_tuple(jl_value_t *arg1 JL_PROPAGATES_ROOT
22332244
return jl_lookup_arg_tuple_type(arg1, args, nargs, 1);
22342245
}
22352246

2236-
jl_method_instance_t *jl_method_lookup(jl_value_t **args, size_t nargs, size_t world)
2247+
JL_DLLEXPORT jl_method_instance_t *jl_method_lookup_by_tt(jl_tupletype_t *tt, size_t world, jl_value_t *_mt)
2248+
{
2249+
jl_methtable_t *mt = NULL;
2250+
if (_mt == jl_nothing)
2251+
mt = jl_gf_ft_mtable(jl_tparam0(tt));
2252+
else {
2253+
assert(jl_isa(_mt, (jl_value_t*)jl_methtable_type));
2254+
mt = (jl_methtable_t*) _mt;
2255+
}
2256+
return jl_mt_assoc_by_type(mt, tt, world);
2257+
}
2258+
2259+
JL_DLLEXPORT jl_method_instance_t *jl_method_lookup(jl_value_t **args, size_t nargs, size_t world)
22372260
{
22382261
assert(nargs > 0 && "expected caller to handle this case");
22392262
jl_methtable_t *mt = jl_gf_mtable(args[0]);
@@ -2242,16 +2265,7 @@ jl_method_instance_t *jl_method_lookup(jl_value_t **args, size_t nargs, size_t w
22422265
if (entry)
22432266
return entry->func.linfo;
22442267
jl_tupletype_t *tt = arg_type_tuple(args[0], &args[1], nargs);
2245-
jl_genericmemory_t *leafcache = jl_atomic_load_relaxed(&mt->leafcache);
2246-
entry = lookup_leafcache(leafcache, (jl_value_t*)tt, world);
2247-
if (entry)
2248-
return entry->func.linfo;
2249-
JL_GC_PUSH1(&tt);
2250-
JL_LOCK(&mt->writelock);
2251-
jl_method_instance_t *sf = jl_mt_assoc_by_type(mt, tt, world);
2252-
JL_UNLOCK(&mt->writelock);
2253-
JL_GC_POP();
2254-
return sf;
2268+
return jl_mt_assoc_by_type(mt, tt, world);
22552269
}
22562270

22572271
// return a Vector{Any} of svecs, each describing a method match:
@@ -3051,14 +3065,9 @@ STATIC_INLINE jl_method_instance_t *jl_lookup_generic_(jl_value_t *F, jl_value_t
30513065
mfunc = entry->func.linfo;
30523066
}
30533067
else {
3054-
JL_GC_PUSH1(&tt);
30553068
assert(tt);
3056-
JL_LOCK(&mt->writelock);
30573069
// cache miss case
3058-
JL_TIMING(METHOD_LOOKUP_SLOW, METHOD_LOOKUP_SLOW);
30593070
mfunc = jl_mt_assoc_by_type(mt, tt, world);
3060-
JL_UNLOCK(&mt->writelock);
3061-
JL_GC_POP();
30623071
if (jl_options.malloc_log)
30633072
jl_gc_sync_total_bytes(last_alloc); // discard allocation count from compilation
30643073
if (mfunc == NULL) {

src/jl_exported_funcs.inc

+2
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@
238238
XX(jl_get_world_counter) \
239239
XX(jl_get_zero_subnormals) \
240240
XX(jl_gf_invoke_lookup) \
241+
XX(jl_method_lookup_by_tt) \
242+
XX(jl_method_lookup) \
241243
XX(jl_gf_invoke_lookup_worlds) \
242244
XX(jl_git_branch) \
243245
XX(jl_git_commit) \

src/julia.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -1294,7 +1294,8 @@ STATIC_INLINE void jl_array_uint32_set(void *a, size_t i, uint32_t x) JL_NOTSAFE
12941294
#define jl_string_data(s) ((char*)s + sizeof(void*))
12951295
#define jl_string_len(s) (*(size_t*)s)
12961296

1297-
#define jl_gf_mtable(f) (((jl_datatype_t*)jl_typeof(f))->name->mt)
1297+
#define jl_gf_ft_mtable(ft) (((jl_datatype_t*)ft)->name->mt)
1298+
#define jl_gf_mtable(f) (jl_gf_ft_mtable(jl_typeof(f)))
12981299
#define jl_gf_name(f) (jl_gf_mtable(f)->name)
12991300

13001301
// struct type info

src/julia_internal.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -777,7 +777,8 @@ JL_DLLEXPORT int jl_is_toplevel_only_expr(jl_value_t *e) JL_NOTSAFEPOINT;
777777
jl_value_t *jl_call_scm_on_ast_and_loc(const char *funcname, jl_value_t *expr,
778778
jl_module_t *inmodule, const char *file, int line);
779779

780-
jl_method_instance_t *jl_method_lookup(jl_value_t **args, size_t nargs, size_t world);
780+
JL_DLLEXPORT jl_method_instance_t *jl_method_lookup_by_tt(jl_tupletype_t *tt, size_t world, jl_value_t *_mt);
781+
JL_DLLEXPORT jl_method_instance_t *jl_method_lookup(jl_value_t **args, size_t nargs, size_t world);
781782

782783
jl_value_t *jl_gf_invoke_by_method(jl_method_t *method, jl_value_t *gf, jl_value_t **args, size_t nargs);
783784
jl_value_t *jl_gf_invoke(jl_value_t *types, jl_value_t *f, jl_value_t **args, size_t nargs);

test/reflection.jl

+8
Original file line numberDiff line numberDiff line change
@@ -1004,6 +1004,14 @@ end
10041004
@test Base.default_tt(m.f4) == Tuple
10051005
end
10061006

1007+
@testset "lookup mi" begin
1008+
@test 1+1 == 2
1009+
mi1 = @ccall jl_method_lookup_by_tt(Tuple{typeof(+), Int, Int}::Any, Base.get_world_counter()::Csize_t, nothing::Any)::Ref{Core.MethodInstance}
1010+
@test mi1.def.name == :+
1011+
mi2 = @ccall jl_method_lookup(Any[+, 1, 1]::Ptr{Any}, 3::Csize_t, Base.get_world_counter()::Csize_t)::Ref{Core.MethodInstance}
1012+
@test mi1 == mi2
1013+
end
1014+
10071015
Base.@assume_effects :terminates_locally function issue41694(x::Int)
10081016
res = 1
10091017
0 x < 20 || error("bad fact")

0 commit comments

Comments
 (0)