Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dispatch speedups #21760

Closed
wants to merge 2 commits into from
Closed
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
3 changes: 3 additions & 0 deletions base/serialize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,9 @@ function deserialize_typename(s::AbstractSerializer, number)
maxa = deserialize(s)::Int
if makenew
tn.mt = ccall(:jl_new_method_table, Any, (Any, Any), name, tn.module)
if isempty(parameters)
tn.mt.offs = 1
end
tn.mt.name = mtname
tn.mt.max_args = maxa
for def in defs
Expand Down
2 changes: 1 addition & 1 deletion src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4652,7 +4652,7 @@ static Function *gen_cfun_wrapper(jl_function_t *ff, jl_value_t *jlrettype, jl_t
}

const struct jl_typemap_info cfunction_cache = {
1, &jl_voidpointer_type
1, 0, &jl_voidpointer_type
};

// Get the LLVM Function* for the C-callable entry point for a certain function
Expand Down
3 changes: 3 additions & 0 deletions src/datatype.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ JL_DLLEXPORT jl_methtable_t *jl_new_method_table(jl_sym_t *name, jl_module_t *mo
mt->kwsorter = NULL;
mt->backedges = NULL;
JL_MUTEX_INIT(&mt->writelock);
mt->offs = 0;
return mt;
}

Expand Down Expand Up @@ -395,6 +396,8 @@ JL_DLLEXPORT jl_datatype_t *jl_new_datatype(
if (!abstract) {
tn->mt = jl_new_method_table(name, module);
jl_gc_wb(tn, tn->mt);
if (jl_svec_len(parameters) == 0)
tn->mt->offs = 1;
}
}
t->name = tn;
Expand Down
7 changes: 2 additions & 5 deletions src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -2001,8 +2001,7 @@ static void jl_reinit_item(jl_value_t *v, int how, arraylist_t *tracee_list)
case 3: { // rehash MethodTable
jl_methtable_t *mt = (jl_methtable_t*)v;
jl_typemap_rehash(mt->defs, 0);
// TODO: consider reverting this when we can split on Type{...} better
jl_typemap_rehash(mt->cache, 1); //(mt == jl_type_typename->mt) ? 0 : 1);
jl_typemap_rehash(mt->cache, mt->offs);
if (tracee_list)
arraylist_push(tracee_list, mt);
break;
Expand Down Expand Up @@ -2672,7 +2671,7 @@ void jl_init_serializer(void)

jl_emptysvec, jl_emptytuple, jl_false, jl_true, jl_nothing, jl_any_type,
call_sym, invoke_sym, goto_ifnot_sym, return_sym, body_sym, line_sym,
lambda_sym, jl_symbol("tuple"), assign_sym, isdefined_sym,
lambda_sym, jl_symbol("tuple"), assign_sym, isdefined_sym, jl_box_uint8(0), jl_box_uint8(1),

// empirical list of very common symbols
#include "common_symbols1.inc"
Expand All @@ -2690,7 +2689,6 @@ void jl_init_serializer(void)
jl_box_int32(30), jl_box_int32(31), jl_box_int32(32),
#ifndef _P64
jl_box_int32(33), jl_box_int32(34), jl_box_int32(35),
jl_box_int32(36), jl_box_int32(37),
#endif
jl_box_int64(0), jl_box_int64(1), jl_box_int64(2),
jl_box_int64(3), jl_box_int64(4), jl_box_int64(5),
Expand All @@ -2705,7 +2703,6 @@ void jl_init_serializer(void)
jl_box_int64(30), jl_box_int64(31), jl_box_int64(32),
#ifdef _P64
jl_box_int64(33), jl_box_int64(34), jl_box_int64(35),
jl_box_int64(36), jl_box_int64(37),
#endif
jl_labelnode_type, jl_linenumbernode_type, jl_gotonode_type,
jl_quotenode_type, jl_type_type, jl_bottom_type, jl_ref_type,
Expand Down
9 changes: 4 additions & 5 deletions src/gf.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,19 +123,18 @@ void jl_call_tracer(tracer_cb callback, jl_value_t *tracee)
/// ----- Definitions for various internal TypeMaps ----- ///

const struct jl_typemap_info method_defs = {
0, &jl_method_type
0, 0, &jl_method_type
};
const struct jl_typemap_info lambda_cache = {
0, &jl_method_instance_type
0, 1, &jl_method_instance_type
};
const struct jl_typemap_info tfunc_cache = {
1, &jl_any_type
1, 0, &jl_any_type
};

static int8_t jl_cachearg_offset(jl_methtable_t *mt)
{
// TODO: consider reverting this when we can split on Type{...} better
return 1; //(mt == jl_type_type_mt) ? 0 : 1;
return mt->offs;
}

/// ----- Insertion logic for special entries ----- ///
Expand Down
17 changes: 12 additions & 5 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1609,6 +1609,7 @@ void jl_init_types(void)
jl_typename_type->name = jl_new_typename_in(jl_symbol("TypeName"), core);
jl_typename_type->name->wrapper = (jl_value_t*)jl_typename_type;
jl_typename_type->name->mt = jl_new_method_table(jl_typename_type->name->name, core);
jl_typename_type->name->mt->offs = 1;
jl_typename_type->super = jl_any_type;
jl_typename_type->parameters = jl_emptysvec;
jl_typename_type->name->names = jl_perm_symsvec(8, "name", "module",
Expand All @@ -1629,15 +1630,17 @@ void jl_init_types(void)
jl_methtable_type->name = jl_new_typename_in(jl_symbol("MethodTable"), core);
jl_methtable_type->name->wrapper = (jl_value_t*)jl_methtable_type;
jl_methtable_type->name->mt = jl_new_method_table(jl_methtable_type->name->name, core);
jl_methtable_type->name->mt->offs = 1;
jl_methtable_type->super = jl_any_type;
jl_methtable_type->parameters = jl_emptysvec;
jl_methtable_type->name->names = jl_perm_symsvec(9, "name", "defs",
jl_methtable_type->name->names = jl_perm_symsvec(10, "name", "defs",
"cache", "max_args",
"kwsorter", "module",
"backedges", "", "");
jl_methtable_type->types = jl_svec(9, jl_sym_type, jl_any_type, jl_any_type, jl_any_type/*jl_long*/,
"backedges", "", "", "offs");
jl_methtable_type->types = jl_svec(10, jl_sym_type, jl_any_type, jl_any_type, jl_any_type/*jl_long*/,
jl_any_type, jl_any_type/*module*/,
jl_any_type/*any vector*/, jl_any_type/*long*/, jl_any_type/*int32*/);
jl_any_type/*any vector*/, jl_any_type/*long*/, jl_any_type/*int32*/,
jl_any_type/*uint8*/);
jl_methtable_type->uid = jl_assign_type_uid();
jl_methtable_type->instance = NULL;
jl_methtable_type->struct_decl = NULL;
Expand All @@ -1649,6 +1652,7 @@ void jl_init_types(void)
jl_sym_type->name = jl_new_typename_in(jl_symbol("Symbol"), core);
jl_sym_type->name->wrapper = (jl_value_t*)jl_sym_type;
jl_sym_type->name->mt = jl_new_method_table(jl_sym_type->name->name, core);
jl_sym_type->name->mt->offs = 1;
jl_sym_type->super = jl_any_type;
jl_sym_type->parameters = jl_emptysvec;
jl_sym_type->name->names = jl_emptysvec;
Expand All @@ -1665,6 +1669,7 @@ void jl_init_types(void)
jl_simplevector_type->name = jl_new_typename_in(jl_symbol("SimpleVector"), core);
jl_simplevector_type->name->wrapper = (jl_value_t*)jl_simplevector_type;
jl_simplevector_type->name->mt = jl_new_method_table(jl_simplevector_type->name->name, core);
jl_simplevector_type->name->mt->offs = 1;
jl_simplevector_type->super = jl_any_type;
jl_simplevector_type->parameters = jl_emptysvec;
jl_simplevector_type->name->names = jl_emptysvec;
Expand Down Expand Up @@ -2056,10 +2061,12 @@ void jl_init_types(void)
jl_svecset(jl_methtable_type->types, 6, jl_array_any_type);
#ifdef __LP64__
jl_svecset(jl_methtable_type->types, 7, jl_int64_type); // unsigned long
jl_svecset(jl_methtable_type->types, 8, jl_int64_type); // uint32_t plus alignment
#else
jl_svecset(jl_methtable_type->types, 7, jl_int32_type); // DWORD
#endif
jl_svecset(jl_methtable_type->types, 8, jl_int32_type); // uint32_t
#endif
jl_svecset(jl_methtable_type->types, 9, jl_uint8_type);
jl_svecset(jl_method_type->types, 10, jl_method_instance_type);
jl_svecset(jl_method_type->types, 11, jl_method_instance_type);
jl_svecset(jl_method_instance_type->types, 12, jl_voidpointer_type);
Expand Down
3 changes: 2 additions & 1 deletion src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ typedef struct _jl_typemap_level_t {
struct jl_ordereddict_t arg1;
struct jl_ordereddict_t targ;
jl_typemap_entry_t *linear; // union jl_typemap_t (but no more levels)
union jl_typemap_t any; // type at offs is Any
union jl_typemap_t any; // type at offs is skipped; will be split later
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you're changing the meaning of this field, can you reorder this list to show the sort order and rename it something else.

I think I would still like to keep the any field also, as a possible means of splitting Method tables for incremental deserialization. Scanning these tables is currently almost all of the cost there. There's fairly few instances of this type (probably a couple thousand tops), and they're already usually expected to be gigantic (several hundred to several thousand bytes).

jl_value_t *key; // [nullable]
} jl_typemap_level_t;

Expand All @@ -463,6 +463,7 @@ typedef struct _jl_methtable_t {
jl_module_t *module; // used for incremental serialization to locate original binding
jl_array_t *backedges;
jl_mutex_t writelock;
uint8_t offs; // 0, or 1 to skip splitting typemap on first (function) argument
} jl_methtable_t;

typedef struct {
Expand Down
1 change: 1 addition & 0 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,7 @@ STATIC_INLINE void jl_free_aligned(void *p)
// passed around as self-documentation of the parameters of the type
struct jl_typemap_info {
int8_t unsorted; // whether this should be unsorted
int8_t simplekeys; // whether keys are restricted to simple kinds of types used in method caches
jl_datatype_t **jl_contains; // the type that is being put in this
};

Expand Down
Loading