Skip to content

Commit

Permalink
make the TypeMap capable of splitting on any concrete type
Browse files Browse the repository at this point in the history
previously, the TypeMap could only split on leaf types now it also has
the ability to split on concrete types

this allows it to ensure that each type gets its own linear list to scan
to find its constructors, instead of needing to search through all
constructors
  • Loading branch information
vtjnash committed Jul 2, 2020
1 parent 2538f93 commit 03823dd
Show file tree
Hide file tree
Showing 8 changed files with 413 additions and 69 deletions.
15 changes: 15 additions & 0 deletions base/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,7 @@ function visit(f, mt::Core.MethodTable)
nothing
end
function visit(f, mc::Core.TypeMapLevel)
mc.bottom !== nothing && visit(f, mc.bottom)
if mc.targ !== nothing
e = mc.targ::Vector{Any}
for i in 2:2:length(e)
Expand All @@ -922,6 +923,20 @@ function visit(f, mc::Core.TypeMapLevel)
isassigned(e, i) && visit(f, e[i])
end
end
if mc.tname !== nothing
for e in mc.tname::SimpleVector
e = e::Vector{Any}
for i in 2:2:length(e)
isassigned(e, i) && visit(f, e[i])
end
end
end
if mc.name1 !== nothing
e = mc.name1::Vector{Any}
for i in 2:2:length(e)
isassigned(e, i) && visit(f, e[i])
end
end
mc.list !== nothing && visit(f, mc.list)
mc.any !== nothing && visit(f, mc.any)
nothing
Expand Down
6 changes: 3 additions & 3 deletions src/datatype.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,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 = 1;
mt->offs = 0;
mt->frozen = 0;
return mt;
}
Expand Down Expand Up @@ -569,8 +569,8 @@ JL_DLLEXPORT jl_datatype_t *jl_new_datatype(
// as an optimization
tn->mt = jl_new_method_table(name, module);
jl_gc_wb(tn, tn->mt);
if (jl_svec_len(parameters) > 0)
tn->mt->offs = 0;
if (jl_svec_len(parameters) == 0 && !abstract)
tn->mt->offs = 1;
}
else {
// Everything else, gets to use the unified table
Expand Down
16 changes: 0 additions & 16 deletions src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -783,22 +783,6 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_li
}
return;
}
if (t == jl_typemap_level_type) {
// perform some compression on the typemap levels
// (which will need to be rehashed during deserialization anyhow)
jl_typemap_level_t *node = (jl_typemap_level_t*)v;
assert( // make sure this type has the expected ordering and layout
offsetof(jl_typemap_level_t, arg1) == 0 * sizeof(jl_value_t*) &&
offsetof(jl_typemap_level_t, targ) == 1 * sizeof(jl_value_t*) &&
offsetof(jl_typemap_level_t, linear) == 2 * sizeof(jl_value_t*) &&
offsetof(jl_typemap_level_t, any) == 3 * sizeof(jl_value_t*) &&
sizeof(jl_typemap_level_t) == 4 * sizeof(jl_value_t*));
jl_serialize_value(s, node->arg1);
jl_serialize_value(s, node->targ);
jl_serialize_value(s, node->linear);
jl_serialize_value(s, node->any);
return;
}

char *data = (char*)jl_data_ptr(v);
size_t i, j, np = t->layout->npointers;
Expand Down
13 changes: 9 additions & 4 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1871,7 +1871,6 @@ void jl_init_types(void) JL_GC_DISABLED
jl_any_type->super = jl_any_type;
jl_nonfunction_mt = jl_any_type->name->mt;
jl_any_type->name->mt = NULL;
jl_nonfunction_mt->offs = 0;

jl_type_type = (jl_unionall_t*)jl_new_abstracttype((jl_value_t*)jl_symbol("Type"), core, jl_any_type, jl_emptysvec);
jl_type_typename = ((jl_datatype_t*)jl_type_type)->name;
Expand Down Expand Up @@ -2089,17 +2088,23 @@ void jl_init_types(void) JL_GC_DISABLED

jl_typemap_level_type =
jl_new_datatype(jl_symbol("TypeMapLevel"), core, jl_any_type, jl_emptysvec,
jl_perm_symsvec(4,
jl_perm_symsvec(7,
"bottom",
"arg1",
"targ",
"name1",
"tname",
"list",
"any"),
jl_svec(4,
jl_svec(7,
jl_any_type,
jl_any_type,
jl_any_type,
jl_any_type,
jl_any_type,
jl_any_type,
jl_any_type),
0, 1, 4);
0, 1, 7);

jl_typemap_entry_type =
jl_new_datatype(jl_symbol("TypeMapEntry"), core, jl_any_type, jl_emptysvec,
Expand Down
22 changes: 16 additions & 6 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -523,14 +523,24 @@ typedef struct _jl_typemap_entry_t {
int8_t va; // isVararg(sig)
} jl_typemap_entry_t;

// one level in a TypeMap tree
// indexed by key if it is a sublevel in an array
// one level in a TypeMap tree (each level splits on a type at a given offset)
typedef struct _jl_typemap_level_t {
JL_DATA_TYPE
jl_array_t *arg1;
jl_array_t *targ;
jl_typemap_entry_t *linear; // jl_typemap_t * (but no more levels)
jl_typemap_t *any; // type at offs is Any
// these vectors contains vectors of more levels in their intended visit order
// with an index that gives the functionality of a sorted dict.
// The first entry may be bottom (for entries which have no type at offs)
// next split may be on Type{T} as LeafTypes then TypeNames parents up to Any
// next split may be on LeafType
// next split may be on TypeName
jl_typemap_entry_t *bottom; // jl_typemap_t * (but no more levels) for entries which have no type at offs
jl_array_t *arg1; // contains LeafType
jl_array_t *targ; // contains Type{LeafType}
jl_array_t *name1; // contains non-abstract TypeName
jl_svec_t *tname; // contains a list of Type{TypeName} dicts, for parents up to Any
// next a linear list of unsortable things (no more levels)
jl_typemap_entry_t *linear;
// finally, start a new level if the type at offs is Any
jl_typemap_t *any;
} jl_typemap_level_t;

// contains the TypeMap for one Type
Expand Down
2 changes: 1 addition & 1 deletion src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -1038,7 +1038,7 @@ void jl_mach_gc_end(void);

typedef uint_t (*smallintset_hash)(size_t val, jl_svec_t *data);
typedef int (*smallintset_eq)(size_t val, const void *key, jl_svec_t *data, uint_t hv);
ssize_t jl_smallintset_lookup(jl_array_t *cache JL_PROPAGATES_ROOT, smallintset_eq eq, const void *key, jl_svec_t *data, uint_t hv);
ssize_t jl_smallintset_lookup(jl_array_t *cache, smallintset_eq eq, const void *key, jl_svec_t *data, uint_t hv);
void jl_smallintset_insert(jl_array_t **pcache, jl_value_t *parent, smallintset_hash hash, size_t val, jl_svec_t *data);

// -- typemap.c -- //
Expand Down
4 changes: 4 additions & 0 deletions src/rtutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,10 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
n += jl_static_show_x(out, li->uninferred, depth);
}
}
else if (vt == jl_typename_type) {
n += jl_static_show_x(out, jl_unwrap_unionall(((jl_typename_t*)v)->wrapper), depth);
n += jl_printf(out, ".name");
}
else if (vt == jl_simplevector_type) {
n += jl_show_svec(out, (jl_svec_t*)v, "svec", "(", ")");
}
Expand Down
Loading

0 comments on commit 03823dd

Please sign in to comment.