Skip to content

Commit 03823dd

Browse files
committed
make the TypeMap capable of splitting on any concrete type
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
1 parent 2538f93 commit 03823dd

File tree

8 files changed

+413
-69
lines changed

8 files changed

+413
-69
lines changed

base/reflection.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -910,6 +910,7 @@ function visit(f, mt::Core.MethodTable)
910910
nothing
911911
end
912912
function visit(f, mc::Core.TypeMapLevel)
913+
mc.bottom !== nothing && visit(f, mc.bottom)
913914
if mc.targ !== nothing
914915
e = mc.targ::Vector{Any}
915916
for i in 2:2:length(e)
@@ -922,6 +923,20 @@ function visit(f, mc::Core.TypeMapLevel)
922923
isassigned(e, i) && visit(f, e[i])
923924
end
924925
end
926+
if mc.tname !== nothing
927+
for e in mc.tname::SimpleVector
928+
e = e::Vector{Any}
929+
for i in 2:2:length(e)
930+
isassigned(e, i) && visit(f, e[i])
931+
end
932+
end
933+
end
934+
if mc.name1 !== nothing
935+
e = mc.name1::Vector{Any}
936+
for i in 2:2:length(e)
937+
isassigned(e, i) && visit(f, e[i])
938+
end
939+
end
925940
mc.list !== nothing && visit(f, mc.list)
926941
mc.any !== nothing && visit(f, mc.any)
927942
nothing

src/datatype.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ JL_DLLEXPORT jl_methtable_t *jl_new_method_table(jl_sym_t *name, jl_module_t *mo
5555
mt->kwsorter = NULL;
5656
mt->backedges = NULL;
5757
JL_MUTEX_INIT(&mt->writelock);
58-
mt->offs = 1;
58+
mt->offs = 0;
5959
mt->frozen = 0;
6060
return mt;
6161
}
@@ -569,8 +569,8 @@ JL_DLLEXPORT jl_datatype_t *jl_new_datatype(
569569
// as an optimization
570570
tn->mt = jl_new_method_table(name, module);
571571
jl_gc_wb(tn, tn->mt);
572-
if (jl_svec_len(parameters) > 0)
573-
tn->mt->offs = 0;
572+
if (jl_svec_len(parameters) == 0 && !abstract)
573+
tn->mt->offs = 1;
574574
}
575575
else {
576576
// Everything else, gets to use the unified table

src/dump.c

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -783,22 +783,6 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_li
783783
}
784784
return;
785785
}
786-
if (t == jl_typemap_level_type) {
787-
// perform some compression on the typemap levels
788-
// (which will need to be rehashed during deserialization anyhow)
789-
jl_typemap_level_t *node = (jl_typemap_level_t*)v;
790-
assert( // make sure this type has the expected ordering and layout
791-
offsetof(jl_typemap_level_t, arg1) == 0 * sizeof(jl_value_t*) &&
792-
offsetof(jl_typemap_level_t, targ) == 1 * sizeof(jl_value_t*) &&
793-
offsetof(jl_typemap_level_t, linear) == 2 * sizeof(jl_value_t*) &&
794-
offsetof(jl_typemap_level_t, any) == 3 * sizeof(jl_value_t*) &&
795-
sizeof(jl_typemap_level_t) == 4 * sizeof(jl_value_t*));
796-
jl_serialize_value(s, node->arg1);
797-
jl_serialize_value(s, node->targ);
798-
jl_serialize_value(s, node->linear);
799-
jl_serialize_value(s, node->any);
800-
return;
801-
}
802786

803787
char *data = (char*)jl_data_ptr(v);
804788
size_t i, j, np = t->layout->npointers;

src/jltypes.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1871,7 +1871,6 @@ void jl_init_types(void) JL_GC_DISABLED
18711871
jl_any_type->super = jl_any_type;
18721872
jl_nonfunction_mt = jl_any_type->name->mt;
18731873
jl_any_type->name->mt = NULL;
1874-
jl_nonfunction_mt->offs = 0;
18751874

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

20902089
jl_typemap_level_type =
20912090
jl_new_datatype(jl_symbol("TypeMapLevel"), core, jl_any_type, jl_emptysvec,
2092-
jl_perm_symsvec(4,
2091+
jl_perm_symsvec(7,
2092+
"bottom",
20932093
"arg1",
20942094
"targ",
2095+
"name1",
2096+
"tname",
20952097
"list",
20962098
"any"),
2097-
jl_svec(4,
2099+
jl_svec(7,
2100+
jl_any_type,
2101+
jl_any_type,
2102+
jl_any_type,
20982103
jl_any_type,
20992104
jl_any_type,
21002105
jl_any_type,
21012106
jl_any_type),
2102-
0, 1, 4);
2107+
0, 1, 7);
21032108

21042109
jl_typemap_entry_type =
21052110
jl_new_datatype(jl_symbol("TypeMapEntry"), core, jl_any_type, jl_emptysvec,

src/julia.h

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -523,14 +523,24 @@ typedef struct _jl_typemap_entry_t {
523523
int8_t va; // isVararg(sig)
524524
} jl_typemap_entry_t;
525525

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

536546
// contains the TypeMap for one Type

src/julia_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1038,7 +1038,7 @@ void jl_mach_gc_end(void);
10381038

10391039
typedef uint_t (*smallintset_hash)(size_t val, jl_svec_t *data);
10401040
typedef int (*smallintset_eq)(size_t val, const void *key, jl_svec_t *data, uint_t hv);
1041-
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);
1041+
ssize_t jl_smallintset_lookup(jl_array_t *cache, smallintset_eq eq, const void *key, jl_svec_t *data, uint_t hv);
10421042
void jl_smallintset_insert(jl_array_t **pcache, jl_value_t *parent, smallintset_hash hash, size_t val, jl_svec_t *data);
10431043

10441044
// -- typemap.c -- //

src/rtutils.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,10 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
664664
n += jl_static_show_x(out, li->uninferred, depth);
665665
}
666666
}
667+
else if (vt == jl_typename_type) {
668+
n += jl_static_show_x(out, jl_unwrap_unionall(((jl_typename_t*)v)->wrapper), depth);
669+
n += jl_printf(out, ".name");
670+
}
667671
else if (vt == jl_simplevector_type) {
668672
n += jl_show_svec(out, (jl_svec_t*)v, "svec", "(", ")");
669673
}

0 commit comments

Comments
 (0)