Skip to content

Commit be77eb8

Browse files
committed
For dispatch, move from using a tree to a hash lookup of leaf types
This lets us put more objects in here without incurring additional search code (just the initial cost of computing the hash for the tuple type lookup computation).
1 parent f4a983d commit be77eb8

File tree

11 files changed

+232
-119
lines changed

11 files changed

+232
-119
lines changed

src/ast.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -962,7 +962,7 @@ static jl_value_t *jl_invoke_julia_macro(jl_array_t *args, jl_module_t *inmodule
962962
jl_value_t *result;
963963
JL_TRY {
964964
margs[0] = jl_toplevel_eval(*ctx, margs[0]);
965-
jl_method_instance_t *mfunc = jl_method_lookup(margs, nargs, 1, world);
965+
jl_method_instance_t *mfunc = jl_method_lookup(margs, nargs, world);
966966
JL_GC_PROMISE_ROOTED(mfunc);
967967
if (mfunc == NULL) {
968968
jl_method_error(margs[0], &margs[1], nargs, world);

src/builtins.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -990,8 +990,7 @@ JL_CALLABLE(jl_f_applicable)
990990
{
991991
JL_NARGSV(applicable, 1);
992992
size_t world = jl_get_ptls_states()->world_age;
993-
return jl_method_lookup(args, nargs, 1, world) != NULL ?
994-
jl_true : jl_false;
993+
return jl_method_lookup(args, nargs, world) != NULL ? jl_true : jl_false;
995994
}
996995

997996
JL_CALLABLE(jl_f_invoke)

src/datatype.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ JL_DLLEXPORT jl_methtable_t *jl_new_method_table(jl_sym_t *name, jl_module_t *mo
4949
mt->name = jl_demangle_typename(name);
5050
mt->module = module;
5151
mt->defs = jl_nothing;
52+
mt->leafcache = (jl_array_t*)jl_an_empty_vec_any;
5253
mt->cache = jl_nothing;
5354
mt->max_args = 0;
5455
mt->kwsorter = NULL;

src/dump.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2237,9 +2237,6 @@ STATIC_INLINE jl_value_t *verify_type(jl_value_t *v) JL_NOTSAFEPOINT
22372237
}
22382238
#endif
22392239

2240-
jl_datatype_t *jl_lookup_cache_type_(jl_datatype_t *type);
2241-
void jl_cache_type_(jl_datatype_t *type);
2242-
22432240
static jl_datatype_t *jl_recache_type(jl_datatype_t *dt) JL_GC_DISABLED
22442241
{
22452242
jl_datatype_t *t; // the type after unique'ing

src/gf.c

Lines changed: 168 additions & 45 deletions
Large diffs are not rendered by default.

src/init.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,6 @@ void _julia_init(JL_IMAGE_SEARCH rel)
721721
else {
722722
jl_init_types();
723723
jl_init_codegen();
724-
jl_an_empty_vec_any = (jl_value_t*)jl_alloc_vec_any(0); // used internally
725724
}
726725

727726
jl_init_tasks();

src/jltypes.c

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -822,17 +822,9 @@ static void cache_insert_type_linear(jl_datatype_t *type, ssize_t insert_at)
822822
#ifndef NDEBUG
823823
static int is_cacheable(jl_datatype_t *type)
824824
{
825-
// only cache types whose behavior will not depend on the identities
826-
// of contained TypeVars
827-
assert(jl_is_datatype(type));
828-
jl_svec_t *t = type->parameters;
829-
if (jl_svec_len(t) == 0 && jl_emptytuple_type != NULL) // Tuple{} is the only type eligible for this that doesn't have parameters
830-
return 0;
831-
// cache abstract types with no free type vars
832-
if (jl_is_abstracttype(type))
833-
return !jl_has_free_typevars((jl_value_t*)type);
834-
// ... or concrete types
835-
return jl_is_concrete_type((jl_value_t*)type);
825+
// ensure cache only contains types whose behavior will not depend on the
826+
// identities of contained TypeVars
827+
return !jl_has_free_typevars((jl_value_t*)type);
836828
}
837829
#endif
838830

@@ -1943,18 +1935,19 @@ void jl_init_types(void) JL_GC_DISABLED
19431935
jl_methtable_type->name->mt = jl_nonfunction_mt;
19441936
jl_methtable_type->super = jl_any_type;
19451937
jl_methtable_type->parameters = jl_emptysvec;
1946-
jl_methtable_type->name->names = jl_perm_symsvec(11, "name", "defs",
1947-
"cache", "max_args",
1938+
jl_methtable_type->name->names = jl_perm_symsvec(12, "name", "defs",
1939+
"leafcache", "cache", "max_args",
19481940
"kwsorter", "module",
19491941
"backedges", "", "", "offs", "");
1950-
jl_methtable_type->types = jl_svec(11, jl_symbol_type, jl_any_type, jl_any_type, jl_any_type/*jl_long*/,
1942+
jl_methtable_type->types = jl_svec(12, jl_symbol_type, jl_any_type, jl_any_type,
1943+
jl_any_type, jl_any_type/*jl_long*/,
19511944
jl_any_type, jl_any_type/*module*/,
19521945
jl_any_type/*any vector*/, jl_any_type/*long*/, jl_any_type/*int32*/,
19531946
jl_any_type/*uint8*/, jl_any_type/*uint8*/);
19541947
jl_methtable_type->instance = NULL;
19551948
jl_methtable_type->abstract = 0;
19561949
jl_methtable_type->mutabl = 1;
1957-
jl_methtable_type->ninitialized = 4;
1950+
jl_methtable_type->ninitialized = 5;
19581951
jl_precompute_memoized_dt(jl_methtable_type, 1);
19591952

19601953
jl_symbol_type->name = jl_new_typename_in(jl_symbol("Symbol"), core);
@@ -2152,6 +2145,9 @@ void jl_init_types(void) JL_GC_DISABLED
21522145
jl_array_symbol_type = jl_apply_type2((jl_value_t*)jl_array_type, (jl_value_t*)jl_symbol_type, jl_box_long(1));
21532146
jl_array_uint8_type = jl_apply_type2((jl_value_t*)jl_array_type, (jl_value_t*)jl_uint8_type, jl_box_long(1));
21542147
jl_array_int32_type = jl_apply_type2((jl_value_t*)jl_array_type, (jl_value_t*)jl_int32_type, jl_box_long(1));
2148+
jl_an_empty_vec_any = (jl_value_t*)jl_alloc_vec_any(0); // used internally
2149+
jl_nonfunction_mt->leafcache = (jl_array_t*)jl_an_empty_vec_any;
2150+
jl_type_type_mt->leafcache = (jl_array_t*)jl_an_empty_vec_any;
21552151

21562152
jl_expr_type =
21572153
jl_new_datatype(jl_symbol("Expr"), core,
@@ -2466,18 +2462,18 @@ void jl_init_types(void) JL_GC_DISABLED
24662462
jl_svecset(jl_typename_type->types, 1, jl_module_type);
24672463
jl_svecset(jl_typename_type->types, 6, jl_long_type);
24682464
jl_svecset(jl_typename_type->types, 3, jl_type_type);
2469-
jl_svecset(jl_methtable_type->types, 3, jl_long_type);
2470-
jl_svecset(jl_methtable_type->types, 5, jl_module_type);
2471-
jl_svecset(jl_methtable_type->types, 6, jl_array_any_type);
2465+
jl_svecset(jl_methtable_type->types, 4, jl_long_type);
2466+
jl_svecset(jl_methtable_type->types, 6, jl_module_type);
2467+
jl_svecset(jl_methtable_type->types, 7, jl_array_any_type);
24722468
#ifdef __LP64__
2473-
jl_svecset(jl_methtable_type->types, 7, jl_int64_type); // unsigned long
2474-
jl_svecset(jl_methtable_type->types, 8, jl_int64_type); // uint32_t plus alignment
2469+
jl_svecset(jl_methtable_type->types, 8, jl_int64_type); // unsigned long
2470+
jl_svecset(jl_methtable_type->types, 9, jl_int64_type); // uint32_t plus alignment
24752471
#else
2476-
jl_svecset(jl_methtable_type->types, 7, jl_int32_type); // DWORD
2477-
jl_svecset(jl_methtable_type->types, 8, jl_int32_type); // uint32_t
2472+
jl_svecset(jl_methtable_type->types, 8, jl_int32_type); // DWORD
2473+
jl_svecset(jl_methtable_type->types, 9, jl_int32_type); // uint32_t
24782474
#endif
2479-
jl_svecset(jl_methtable_type->types, 9, jl_uint8_type);
24802475
jl_svecset(jl_methtable_type->types, 10, jl_uint8_type);
2476+
jl_svecset(jl_methtable_type->types, 11, jl_uint8_type);
24812477
jl_svecset(jl_method_type->types, 13, jl_method_instance_type);
24822478
jl_svecset(jl_method_instance_type->types, 5, jl_code_instance_type);
24832479
jl_svecset(jl_code_instance_type->types, 8, jl_voidpointer_type);

src/julia.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,7 @@ typedef struct _jl_methtable_t {
537537
JL_DATA_TYPE
538538
jl_sym_t *name; // sometimes a hack used by serialization to handle kwsorter
539539
jl_typemap_t *defs;
540+
jl_array_t *leafcache;
540541
jl_typemap_t *cache;
541542
intptr_t max_args; // max # of non-vararg arguments in a signature
542543
jl_value_t *kwsorter; // keyword argument sorter function

src/julia_internal.h

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,8 @@ jl_datatype_t *jl_new_uninitialized_datatype(void);
462462
void jl_precompute_memoized_dt(jl_datatype_t *dt, int cacheable);
463463
jl_datatype_t *jl_wrap_Type(jl_value_t *t); // x -> Type{x}
464464
jl_value_t *jl_wrap_vararg(jl_value_t *t, jl_value_t *n);
465+
jl_datatype_t *jl_lookup_cache_type_(jl_datatype_t *type);
466+
void jl_cache_type_(jl_datatype_t *type);
465467
void jl_assign_bits(void *dest, jl_value_t *bits) JL_NOTSAFEPOINT;
466468
void set_nth_field(jl_datatype_t *st, void *v, size_t i, jl_value_t *rhs) JL_NOTSAFEPOINT;
467469
jl_expr_t *jl_exprn(jl_sym_t *head, size_t n);
@@ -482,7 +484,7 @@ int jl_is_toplevel_only_expr(jl_value_t *e) JL_NOTSAFEPOINT;
482484
jl_value_t *jl_call_scm_on_ast(const char *funcname, jl_value_t *expr, jl_module_t *inmodule);
483485
void jl_linenumber_to_lineinfo(jl_code_info_t *ci, jl_value_t *name);
484486

485-
jl_method_instance_t *jl_method_lookup(jl_value_t **args, size_t nargs, int cache, size_t world);
487+
jl_method_instance_t *jl_method_lookup(jl_value_t **args, size_t nargs, size_t world);
486488
jl_value_t *jl_gf_invoke(jl_value_t *types, jl_value_t *f, jl_value_t **args, size_t nargs);
487489
jl_method_instance_t *jl_lookup_generic(jl_value_t **args, uint32_t nargs, uint32_t callsite, size_t world) JL_ALWAYS_LEAFTYPE;
488490
JL_DLLEXPORT jl_value_t *jl_matching_methods(jl_tupletype_t *types, int lim, int include_ambiguous,
@@ -1048,13 +1050,12 @@ struct jl_typemap_info {
10481050
jl_datatype_t **jl_contains; // the type that is being put in this
10491051
};
10501052

1051-
jl_typemap_entry_t *jl_typemap_insert(jl_typemap_t **cache,
1052-
jl_value_t *parent JL_PROPAGATES_ROOT,
1053-
jl_tupletype_t *type,
1054-
jl_tupletype_t *simpletype, jl_svec_t *guardsigs,
1055-
jl_value_t *newvalue, int8_t offs,
1056-
const struct jl_typemap_info *tparams,
1057-
size_t min_world, size_t max_world);
1053+
void jl_typemap_insert(jl_typemap_t **cache, jl_value_t *parent,
1054+
jl_typemap_entry_t *newrec, int8_t offs,
1055+
const struct jl_typemap_info *tparams);
1056+
jl_typemap_entry_t *jl_typemap_alloc(
1057+
jl_tupletype_t *type, jl_tupletype_t *simpletype, jl_svec_t *guardsigs,
1058+
jl_value_t *newvalue, size_t min_world, size_t max_world);
10581059

10591060
struct jl_typemap_assoc {
10601061
// inputs

src/precompile.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -314,12 +314,6 @@ static void jl_compile_all_defs(void)
314314
JL_GC_POP();
315315
}
316316

317-
static int precompile_enq_all_cache__(jl_typemap_entry_t *l, void *closure)
318-
{
319-
jl_array_ptr_1d_push((jl_array_t*)closure, (jl_value_t*)l->func.linfo);
320-
return 1;
321-
}
322-
323317
static int precompile_enq_specialization_(jl_method_instance_t *mi, void *closure)
324318
{
325319
assert(jl_is_method_instance(mi));
@@ -370,7 +364,6 @@ static int precompile_enq_all_specializations__(jl_typemap_entry_t *def, void *c
370364
static void precompile_enq_all_specializations_(jl_methtable_t *mt, void *env)
371365
{
372366
jl_typemap_visitor(mt->defs, precompile_enq_all_specializations__, env);
373-
jl_typemap_visitor(mt->cache, precompile_enq_all_cache__, env);
374367
}
375368

376369
void jl_compile_now(jl_method_instance_t *mi);

0 commit comments

Comments
 (0)