Skip to content

Commit 0c002f9

Browse files
JeffBezansonjohanmon
authored andcommitted
make it possible to serialize SnoopCompile results (JuliaLang#39695)
- use `nothing` instead of NULL as a sentinel in specializations - remove some Serializer restrictions around saving Methods
1 parent c2f13a6 commit 0c002f9

File tree

5 files changed

+27
-24
lines changed

5 files changed

+27
-24
lines changed

src/dump.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -910,7 +910,7 @@ static int jl_collect_methcache_from_mod(jl_typemap_entry_t *ml, void *closure)
910910
size_t i, l = jl_svec_len(specializations);
911911
for (i = 0; i < l; i++) {
912912
jl_method_instance_t *callee = (jl_method_instance_t*)jl_svecref(specializations, i);
913-
if (callee != NULL)
913+
if ((jl_value_t*)callee != jl_nothing)
914914
collect_backedges(callee);
915915
}
916916
}

src/gf.c

+9-8
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ JL_DLLEXPORT jl_method_instance_t *jl_specializations_get_linfo(jl_method_t *m J
122122
JL_GC_PUSH1(&specializations); // clang-sa doesn't realize this loop uses specializations
123123
for (i = cl; i > 0; i--) {
124124
jl_method_instance_t *mi = jl_atomic_load_relaxed(&data[i - 1]);
125-
if (mi == NULL)
125+
if ((jl_value_t*)mi == jl_nothing)
126126
break;
127127
if (jl_types_equal(mi->specTypes, type)) {
128128
if (locked)
@@ -143,19 +143,20 @@ JL_DLLEXPORT jl_method_instance_t *jl_specializations_get_linfo(jl_method_t *m J
143143
jl_method_instance_t **data = (jl_method_instance_t**)jl_svec_data(specializations);
144144
for (i = 0; i < cl; i++) {
145145
jl_method_instance_t *mi = jl_atomic_load_relaxed(&data[i]);
146-
if (mi == NULL)
146+
if ((jl_value_t*)mi == jl_nothing)
147147
break;
148148
assert(!jl_types_equal(mi->specTypes, type));
149149
}
150150
}
151151
jl_method_instance_t *mi = jl_get_specialized(m, type, sparams);
152152
JL_GC_PUSH1(&mi);
153-
if (hv ? (i + 1 >= cl || jl_svecref(specializations, i + 1) != NULL) : (i <= 1 || jl_svecref(specializations, i - 2) != NULL)) {
153+
if (hv ? (i + 1 >= cl || jl_svecref(specializations, i + 1) != jl_nothing) : (i <= 1 || jl_svecref(specializations, i - 2) != jl_nothing)) {
154154
size_t ncl = cl < 8 ? 8 : (cl*3)>>1;
155155
jl_svec_t *nc = jl_alloc_svec_uninit(ncl);
156156
if (i > 0)
157157
memcpy((char*)jl_svec_data(nc), jl_svec_data(specializations), sizeof(void*) * i);
158-
memset((char*)jl_svec_data(nc) + sizeof(void*) * i, 0, sizeof(void*) * (ncl - cl));
158+
for (int j = 0; j < ncl - cl; j++)
159+
jl_svecset(nc, j+i, jl_nothing);
159160
if (i < cl)
160161
memcpy((char*)jl_svec_data(nc) + sizeof(void*) * (i + ncl - cl),
161162
(char*)jl_svec_data(specializations) + sizeof(void*) * i,
@@ -168,7 +169,7 @@ JL_DLLEXPORT jl_method_instance_t *jl_specializations_get_linfo(jl_method_t *m J
168169
}
169170
if (!hv)
170171
i -= 1;
171-
assert(jl_svecref(specializations, i) == NULL);
172+
assert(jl_svecref(specializations, i) == jl_nothing);
172173
jl_svecset(specializations, i, mi); // jl_atomic_store_release?
173174
if (hv) {
174175
// TODO: fuse lookup and insert steps?
@@ -413,7 +414,7 @@ static int get_method_unspec_list(jl_typemap_entry_t *def, void *closure)
413414
size_t i, l = jl_svec_len(specializations);
414415
for (i = 0; i < l; i++) {
415416
jl_method_instance_t *mi = (jl_method_instance_t*)jl_svecref(specializations, i);
416-
if (mi) {
417+
if ((jl_value_t*)mi != jl_nothing) {
417418
assert(jl_is_method_instance(mi));
418419
if (jl_rettype_inferred(mi, jl_world_counter, jl_world_counter) == jl_nothing)
419420
jl_array_ptr_1d_push((jl_array_t*)closure, (jl_value_t*)mi);
@@ -1561,7 +1562,7 @@ static void jl_method_table_invalidate(jl_methtable_t *mt, jl_typemap_entry_t *m
15611562
l = jl_svec_len(specializations);
15621563
for (i = 0; i < l; i++) {
15631564
jl_method_instance_t *mi = (jl_method_instance_t*)jl_svecref(specializations, i);
1564-
if (mi) {
1565+
if ((jl_value_t*)mi != jl_nothing) {
15651566
invalidated = 1;
15661567
invalidate_external(mi, methodentry->max_world);
15671568
invalidate_backedges(mi, methodentry->max_world, "jl_method_table_disable");
@@ -1728,7 +1729,7 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
17281729
enum morespec_options ambig = morespec_unknown;
17291730
for (i = 0; i < l; i++) {
17301731
jl_method_instance_t *mi = jl_atomic_load_relaxed(&data[i]);
1731-
if (mi == NULL)
1732+
if ((jl_value_t*)mi == jl_nothing)
17321733
continue;
17331734
isect3 = jl_type_intersection(m->sig, (jl_value_t*)mi->specTypes);
17341735
if (jl_type_intersection2(type, isect3, &isect, &isect2)) {

src/precompile.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -353,9 +353,9 @@ static int precompile_enq_all_specializations__(jl_typemap_entry_t *def, void *c
353353
jl_svec_t *specializations = def->func.method->specializations;
354354
size_t i, l = jl_svec_len(specializations);
355355
for (i = 0; i < l; i++) {
356-
jl_method_instance_t *mi = (jl_method_instance_t*)jl_svecref(specializations, i);
357-
if (mi != NULL)
358-
precompile_enq_specialization_(mi, closure);
356+
jl_value_t *mi = jl_svecref(specializations, i);
357+
if (mi != jl_nothing)
358+
precompile_enq_specialization_((jl_method_instance_t*)mi, closure);
359359
}
360360
}
361361
if (m->ccallable)

stdlib/Serialization/src/Serialization.jl

+12-10
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ function serialize(s::AbstractSerializer, meth::Method)
425425
serialize(s, nothing)
426426
end
427427
if isdefined(meth, :generator)
428-
serialize(s, Base._uncompressed_ast(meth, meth.generator.inferred)) # XXX: what was this supposed to do?
428+
serialize(s, meth.generator)
429429
else
430430
serialize(s, nothing)
431431
end
@@ -439,9 +439,12 @@ end
439439

440440
function serialize(s::AbstractSerializer, linfo::Core.MethodInstance)
441441
serialize_cycle(s, linfo) && return
442-
isa(linfo.def, Module) || error("can only serialize toplevel MethodInstance objects")
443442
writetag(s.io, METHODINSTANCE_TAG)
444-
serialize(s, linfo.uninferred)
443+
if isdefined(linfo, :uninferred)
444+
serialize(s, linfo.uninferred)
445+
else
446+
writetag(s.io, UNDEFREF_TAG)
447+
end
445448
serialize(s, nothing) # for backwards compat
446449
serialize(s, linfo.sparam_vals)
447450
serialize(s, Any) # for backwards compat
@@ -1036,11 +1039,7 @@ function deserialize(s::AbstractSerializer, ::Type{Method})
10361039
end
10371040
meth.slot_syms = slot_syms
10381041
if generator !== nothing
1039-
linfo = ccall(:jl_new_method_instance_uninit, Ref{Core.MethodInstance}, ())
1040-
linfo.specTypes = Tuple
1041-
linfo.inferred = generator
1042-
linfo.def = meth
1043-
meth.generator = linfo
1042+
meth.generator = generator
10441043
end
10451044
if recursion_relation !== nothing
10461045
meth.recursion_relation = recursion_relation
@@ -1059,7 +1058,10 @@ end
10591058
function deserialize(s::AbstractSerializer, ::Type{Core.MethodInstance})
10601059
linfo = ccall(:jl_new_method_instance_uninit, Ref{Core.MethodInstance}, (Ptr{Cvoid},), C_NULL)
10611060
deserialize_cycle(s, linfo)
1062-
linfo.uninferred = deserialize(s)::CodeInfo
1061+
tag = Int32(read(s.io, UInt8)::UInt8)
1062+
if tag != UNDEFREF_TAG
1063+
linfo.uninferred = handle_deserialize(s, tag)::CodeInfo
1064+
end
10631065
tag = Int32(read(s.io, UInt8)::UInt8)
10641066
if tag != UNDEFREF_TAG
10651067
# for reading files prior to v1.2
@@ -1068,7 +1070,7 @@ function deserialize(s::AbstractSerializer, ::Type{Core.MethodInstance})
10681070
linfo.sparam_vals = deserialize(s)::SimpleVector
10691071
_rettype = deserialize(s) # for backwards compat
10701072
linfo.specTypes = deserialize(s)
1071-
linfo.def = deserialize(s)::Module
1073+
linfo.def = deserialize(s)
10721074
return linfo
10731075
end
10741076

test/worlds.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,8 @@ function instance(f, types)
219219
if isa(specs, Nothing)
220220
elseif isa(specs, Core.SimpleVector)
221221
for i = 1:length(specs)
222-
if isassigned(specs, i)
223-
mi = specs[i]::Core.MethodInstance
222+
mi = specs[i]
223+
if mi isa Core.MethodInstance
224224
if mi.specTypes <: tt && tt <: mi.specTypes
225225
inst = mi
226226
break

0 commit comments

Comments
 (0)