Skip to content

Commit d992554

Browse files
authored
optimize Type method table queries and insertions (#58216)
Ensure a total split of constructors and non-constructors, so they do not end up seaching the opposing table. Instead cache all kind lookups as keyed by typename(Type). Not really needed on its own, but it avoids a minor performance regression in #58131.
1 parent 7487b8f commit d992554

File tree

2 files changed

+22
-21
lines changed

2 files changed

+22
-21
lines changed

base/staticdata.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ function verify_method(codeinst::CodeInstance, stack::Vector{CodeInstance}, visi
174174
edge = get_ci_mi(edge)
175175
end
176176
if edge isa MethodInstance
177-
sig = typeintersect((edge.def::Method).sig, edge.specTypes) # TODO??
177+
sig = edge.specTypes
178178
min_valid2, max_valid2, matches = verify_call(sig, callees, j, 1, world)
179179
j += 1
180180
elseif edge isa Int
@@ -346,6 +346,7 @@ function verify_invokesig(@nospecialize(invokesig), expected::Method, world::UIn
346346
matched = nothing
347347
if invokesig === expected.sig
348348
# the invoke match is `expected` for `expected->sig`, unless `expected` is invalid
349+
# TODO: this is broken since PR #53415
349350
minworld = expected.primary_world
350351
maxworld = expected.deleted_world
351352
@assert minworld world

src/typemap.c

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,29 +23,29 @@ static int jl_is_any(jl_value_t *t1)
2323
return t1 == (jl_value_t*)jl_any_type;
2424
}
2525

26-
static jl_value_t *jl_type_extract_name(jl_value_t *t1 JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT
26+
static jl_value_t *jl_type_extract_name(jl_value_t *t1 JL_PROPAGATES_ROOT, int invariant) JL_NOTSAFEPOINT
2727
{
2828
if (jl_is_unionall(t1))
2929
t1 = jl_unwrap_unionall(t1);
3030
if (jl_is_vararg(t1)) {
31-
return jl_type_extract_name(jl_unwrap_vararg(t1));
31+
return jl_type_extract_name(jl_unwrap_vararg(t1), invariant);
3232
}
3333
else if (jl_is_typevar(t1)) {
34-
return jl_type_extract_name(((jl_tvar_t*)t1)->ub);
34+
return jl_type_extract_name(((jl_tvar_t*)t1)->ub, invariant);
3535
}
3636
else if (t1 == jl_bottom_type || t1 == (jl_value_t*)jl_typeofbottom_type || t1 == (jl_value_t*)jl_typeofbottom_type->super) {
3737
return (jl_value_t*)jl_typeofbottom_type->name; // put Union{} and typeof(Union{}) and Type{Union{}} together for convenience
3838
}
3939
else if (jl_is_datatype(t1)) {
4040
jl_datatype_t *dt = (jl_datatype_t*)t1;
41-
if (!jl_is_kind(t1))
42-
return (jl_value_t*)dt->name;
43-
return NULL;
41+
if (jl_is_kind(t1) && !invariant)
42+
return (jl_value_t*)jl_type_typename;
43+
return (jl_value_t*)dt->name;
4444
}
4545
else if (jl_is_uniontype(t1)) {
4646
jl_uniontype_t *u1 = (jl_uniontype_t*)t1;
47-
jl_value_t *tn1 = jl_type_extract_name(u1->a);
48-
jl_value_t *tn2 = jl_type_extract_name(u1->b);
47+
jl_value_t *tn1 = jl_type_extract_name(u1->a, invariant);
48+
jl_value_t *tn2 = jl_type_extract_name(u1->b, invariant);
4949
if (tn1 == tn2)
5050
return tn1;
5151
// TODO: if invariant is false, instead find the nearest common ancestor
@@ -71,7 +71,7 @@ static int jl_type_extract_name_precise(jl_value_t *t1, int invariant)
7171
}
7272
else if (jl_is_datatype(t1)) {
7373
jl_datatype_t *dt = (jl_datatype_t*)t1;
74-
if ((invariant || !dt->name->abstract) && !jl_is_kind(t1))
74+
if (invariant || !dt->name->abstract || dt->name == jl_type_typename)
7575
return 1;
7676
return 0;
7777
}
@@ -81,8 +81,8 @@ static int jl_type_extract_name_precise(jl_value_t *t1, int invariant)
8181
return 0;
8282
if (!jl_type_extract_name_precise(u1->b, invariant))
8383
return 0;
84-
jl_value_t *tn1 = jl_type_extract_name(u1->a);
85-
jl_value_t *tn2 = jl_type_extract_name(u1->b);
84+
jl_value_t *tn1 = jl_type_extract_name(u1->a, invariant);
85+
jl_value_t *tn2 = jl_type_extract_name(u1->b, invariant);
8686
if (tn1 == tn2)
8787
return 1;
8888
return 0;
@@ -469,7 +469,7 @@ static int jl_typemap_intersection_memory_visitor(jl_genericmemory_t *a, jl_valu
469469
tydt = (jl_datatype_t*)ttype;
470470
}
471471
else if (ttype) {
472-
ttype = jl_type_extract_name(ttype);
472+
ttype = jl_type_extract_name(ttype, tparam & 1);
473473
tydt = ttype ? (jl_datatype_t*)jl_unwrap_unionall(((jl_typename_t*)ttype)->wrapper) : NULL;
474474
}
475475
if (tydt == jl_any_type)
@@ -641,7 +641,7 @@ int jl_typemap_intersection_visitor(jl_typemap_t *map, int offs,
641641
if (maybe_type && !maybe_kind) {
642642
typetype = jl_unwrap_unionall(ty);
643643
typetype = jl_is_type_type(typetype) ? jl_tparam0(typetype) : NULL;
644-
name = typetype ? jl_type_extract_name(typetype) : NULL;
644+
name = typetype ? jl_type_extract_name(typetype, 1) : NULL;
645645
if (!typetype)
646646
exclude_typeofbottom = !jl_subtype((jl_value_t*)jl_typeofbottom_type, ty);
647647
else if (jl_is_typevar(typetype))
@@ -717,7 +717,7 @@ int jl_typemap_intersection_visitor(jl_typemap_t *map, int offs,
717717
}
718718
}
719719
else {
720-
jl_value_t *name = jl_type_extract_name(ty);
720+
jl_value_t *name = jl_type_extract_name(ty, 0);
721721
if (name && jl_type_extract_name_precise(ty, 0)) {
722722
// direct lookup of leaf types
723723
jl_value_t *ml = mtcache_hash_lookup(cachearg1, name);
@@ -782,7 +782,7 @@ int jl_typemap_intersection_visitor(jl_typemap_t *map, int offs,
782782
}
783783
jl_genericmemory_t *name1 = jl_atomic_load_relaxed(&cache->name1);
784784
if (name1 != (jl_genericmemory_t*)jl_an_empty_memory_any) {
785-
jl_value_t *name = jl_type_extract_name(ty);
785+
jl_value_t *name = jl_type_extract_name(ty, 0);
786786
if (name && jl_type_extract_name_precise(ty, 0)) {
787787
jl_datatype_t *super = (jl_datatype_t*)jl_unwrap_unionall(((jl_typename_t*)name)->wrapper);
788788
// direct lookup of concrete types
@@ -1003,7 +1003,7 @@ jl_typemap_entry_t *jl_typemap_assoc_by_type(
10031003
// now look at the optimized TypeName caches
10041004
jl_genericmemory_t *tname = jl_atomic_load_relaxed(&cache->tname);
10051005
if (tname != (jl_genericmemory_t*)jl_an_empty_memory_any) {
1006-
jl_value_t *a0 = ty && jl_is_type_type(ty) ? jl_type_extract_name(jl_tparam0(ty)) : NULL;
1006+
jl_value_t *a0 = ty && jl_is_type_type(ty) ? jl_type_extract_name(jl_tparam0(ty), 1) : NULL;
10071007
if (a0) { // TODO: if we start analyzing Union types in jl_type_extract_name, then a0 might be over-approximated here, leading us to miss possible subtypes
10081008
jl_datatype_t *super = (jl_datatype_t*)jl_unwrap_unionall(((jl_typename_t*)a0)->wrapper);
10091009
while (1) {
@@ -1042,7 +1042,7 @@ jl_typemap_entry_t *jl_typemap_assoc_by_type(
10421042
jl_genericmemory_t *name1 = jl_atomic_load_relaxed(&cache->name1);
10431043
if (name1 != (jl_genericmemory_t*)jl_an_empty_memory_any) {
10441044
if (ty) {
1045-
jl_value_t *a0 = jl_type_extract_name(ty);
1045+
jl_value_t *a0 = jl_type_extract_name(ty, 0);
10461046
if (a0) { // TODO: if we start analyzing Union types in jl_type_extract_name, then a0 might be over-approximated here, leading us to miss possible subtypes
10471047
jl_datatype_t *super = (jl_datatype_t*)jl_unwrap_unionall(((jl_typename_t*)a0)->wrapper);
10481048
while (1) {
@@ -1200,7 +1200,7 @@ jl_typemap_entry_t *jl_typemap_level_assoc_exact(jl_typemap_level_t *cache, jl_v
12001200
}
12011201
jl_genericmemory_t *tname = jl_atomic_load_relaxed(&cache->tname);
12021202
if (jl_is_kind(ty) && tname != (jl_genericmemory_t*)jl_an_empty_memory_any) {
1203-
jl_value_t *name = jl_type_extract_name(a1);
1203+
jl_value_t *name = jl_type_extract_name(a1, 1);
12041204
if (name) {
12051205
if (ty != (jl_value_t*)jl_datatype_type)
12061206
a1 = jl_unwrap_unionall(((jl_typename_t*)name)->wrapper);
@@ -1447,12 +1447,12 @@ static void jl_typemap_level_insert_(
14471447
jl_value_t *a0;
14481448
t1 = jl_unwrap_unionall(t1);
14491449
if (jl_is_type_type(t1)) {
1450-
a0 = jl_type_extract_name(jl_tparam0(t1));
1450+
a0 = jl_type_extract_name(jl_tparam0(t1), 1);
14511451
jl_datatype_t *super = a0 ? (jl_datatype_t*)jl_unwrap_unionall(((jl_typename_t*)a0)->wrapper) : jl_any_type;
14521452
jl_typemap_memory_insert_(map, &cache->tname, (jl_value_t*)super->name, newrec, (jl_value_t*)cache, 1, offs, NULL);
14531453
return;
14541454
}
1455-
a0 = jl_type_extract_name(t1);
1455+
a0 = jl_type_extract_name(t1, 0);
14561456
if (a0 && a0 != (jl_value_t*)jl_any_type->name) {
14571457
jl_typemap_memory_insert_(map, &cache->name1, a0, newrec, (jl_value_t*)cache, 0, offs, NULL);
14581458
return;

0 commit comments

Comments
 (0)