Skip to content

Commit 1514949

Browse files
topolaritykpamnany
authored andcommitted
staticdata: Accept CodeInstances with addl. code from pkgimages
1 parent dbe2575 commit 1514949

File tree

5 files changed

+57
-20
lines changed

5 files changed

+57
-20
lines changed

base/compiler/typeinfer.jl

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# This file is a part of Julia. License is MIT: https://julialang.org/license
22

33
# Tracking of newly-inferred CodeInstances during precompilation
4-
const track_newly_inferred = RefValue{Bool}(false)
54
const newly_inferred = CodeInstance[]
65

76
# build (and start inferring) the inference frame for the top-level MethodInstance
@@ -404,11 +403,9 @@ function cache_result!(interp::AbstractInterpreter, result::InferenceResult)
404403
if !already_inferred
405404
inferred_result = transform_result_for_cache(interp, linfo, valid_worlds, result)
406405
code_cache(interp)[linfo] = ci = CodeInstance(interp, result, inferred_result, valid_worlds)
407-
if track_newly_inferred[]
408-
m = linfo.def
409-
if isa(m, Method) && m.module != Core
410-
ccall(:jl_push_newly_inferred, Cvoid, (Any,), ci)
411-
end
406+
m = linfo.def
407+
if isa(m, Method) && m.module != Core
408+
ccall(:jl_push_newly_inferred, Cvoid, (Any,), ci)
412409
end
413410
end
414411
unlock_mi_inference(interp, linfo)

base/loading.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2225,15 +2225,15 @@ function include_package_for_output(pkg::PkgId, input::String, depot_path::Vecto
22252225
end
22262226

22272227
ccall(:jl_set_newly_inferred, Cvoid, (Any,), Core.Compiler.newly_inferred)
2228-
Core.Compiler.track_newly_inferred.x = true
2228+
ccall(:jl_track_newly_inferred, Cvoid, (Cint,), 1)
22292229
try
22302230
Base.include(Base.__toplevel__, input)
22312231
catch ex
22322232
precompilableerror(ex) || rethrow()
22332233
@debug "Aborting `create_expr_cache'" exception=(ErrorException("Declaration of __precompile__(false) not allowed"), catch_backtrace())
22342234
exit(125) # we define status = 125 means PrecompileableError
22352235
finally
2236-
Core.Compiler.track_newly_inferred.x = false
2236+
ccall(:jl_track_newly_inferred, Cvoid, (Cint,), 0)
22372237
end
22382238
end
22392239

src/gf.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2874,6 +2874,8 @@ static void _generate_from_hint(jl_method_instance_t *mi, size_t world)
28742874
if (codeinst == jl_nothing) {
28752875
(void)jl_type_infer(mi, world, 1);
28762876
codeinst = jl_rettype_inferred(mi, world, world);
2877+
} else {
2878+
jl_push_newly_inferred(codeinst);
28772879
}
28782880
if (codeinst != jl_nothing) {
28792881
if (jl_atomic_load_relaxed(&((jl_code_instance_t*)codeinst)->invoke) == jl_fptr_const_return)

src/staticdata.c

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -594,8 +594,25 @@ static void jl_load_sysimg_so(void)
594594
static int jl_needs_serialization(jl_serializer_state *s, jl_value_t *v) JL_NOTSAFEPOINT
595595
{
596596
// ignore items that are given a special relocation representation
597-
if (s->incremental && jl_object_in_image(v))
597+
if (s->incremental && jl_object_in_image(v)) {
598+
if (native_functions && jl_is_code_instance(v)) {
599+
// serialize a copy of a CodeInstance, if we have code to add for it
600+
jl_code_instance_t *ci = (jl_code_instance_t *)v;
601+
if (jl_atomic_load_relaxed(&ci->invoke) == NULL) {
602+
int32_t invokeptr_id = 0;
603+
int32_t specfptr_id = 0;
604+
// see if we generated code for it
605+
jl_get_function_id(
606+
native_functions,
607+
(jl_code_instance_t *)v,
608+
&invokeptr_id,
609+
&specfptr_id
610+
);
611+
return (invokeptr_id != 0) || (specfptr_id != 0);
612+
}
613+
}
598614
return 0;
615+
}
599616

600617
if (v == NULL || jl_is_symbol(v) || v == jl_nothing) {
601618
return 0;
@@ -1041,15 +1058,16 @@ static uintptr_t _backref_id(jl_serializer_state *s, jl_value_t *v, jl_array_t *
10411058
uint8_t u8 = *(uint8_t*)v;
10421059
return ((uintptr_t)TagRef << RELOC_TAG_OFFSET) + u8 + 2 + NBOX_C + NBOX_C;
10431060
}
1044-
if (s->incremental && jl_object_in_image(v)) {
1045-
assert(link_ids);
1046-
uintptr_t item = add_external_linkage(s, v, link_ids);
1047-
assert(item && "no external linkage identified");
1048-
return item;
1049-
}
10501061
if (idx == HT_NOTFOUND) {
10511062
idx = ptrhash_get(&serialization_order, v);
10521063
if (idx == HT_NOTFOUND) {
1064+
if (s->incremental && jl_object_in_image(v)) {
1065+
assert(link_ids);
1066+
uintptr_t item = add_external_linkage(s, v, link_ids);
1067+
assert(item && "no external linkage identified");
1068+
return item;
1069+
}
1070+
// something went wrong
10531071
jl_(jl_typeof(v));
10541072
jl_(v);
10551073
}

src/staticdata_utils.c

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,15 @@ static uint64_t jl_worklist_key(jl_array_t *worklist) JL_NOTSAFEPOINT
8383
}
8484

8585
static jl_array_t *newly_inferred JL_GLOBALLY_ROOTED /*FIXME*/;
86+
static _Atomic(int) track_newly_inferred = 0;
8687
// Mutex for newly_inferred
8788
jl_mutex_t newly_inferred_mutex;
8889

90+
JL_DLLEXPORT void jl_track_newly_inferred(int enable)
91+
{
92+
jl_atomic_store_release(&track_newly_inferred, enable);
93+
}
94+
8995
// Register array of newly-inferred MethodInstances
9096
// This gets called as the first step of Base.include_package_for_output
9197
JL_DLLEXPORT void jl_set_newly_inferred(jl_value_t* _newly_inferred)
@@ -97,9 +103,11 @@ JL_DLLEXPORT void jl_set_newly_inferred(jl_value_t* _newly_inferred)
97103
JL_DLLEXPORT void jl_push_newly_inferred(jl_value_t* ci)
98104
{
99105
JL_LOCK(&newly_inferred_mutex);
100-
size_t end = jl_array_len(newly_inferred);
101-
jl_array_grow_end(newly_inferred, 1);
102-
jl_arrayset(newly_inferred, ci, end);
106+
if (jl_atomic_load_acquire(&track_newly_inferred)) {
107+
size_t end = jl_array_len(newly_inferred);
108+
jl_array_grow_end(newly_inferred, 1);
109+
jl_arrayset(newly_inferred, ci, end);
110+
}
103111
JL_UNLOCK(&newly_inferred_mutex);
104112
}
105113

@@ -230,8 +238,11 @@ static jl_array_t *queue_external_cis(jl_array_t *list)
230238
for (i = n0; i-- > 0; ) {
231239
jl_code_instance_t *ci = (jl_code_instance_t*)jl_array_ptr_ref(list, i);
232240
assert(jl_is_code_instance(ci));
233-
if (!ci->relocatability)
241+
if (!ci->relocatability && !jl_object_in_image((jl_value_t *)ci)) {
242+
// we don't care about re-locatability for duplicated CI's
243+
// since the original copy will provide sufficient roots anyway
234244
continue;
245+
}
235246
jl_method_instance_t *mi = ci->def;
236247
jl_method_t *m = mi->def.method;
237248
if (ci->inferred && jl_is_method(m) && jl_object_in_image((jl_value_t*)m->module)) {
@@ -1121,6 +1132,10 @@ static void jl_insert_backedges(jl_array_t *edges, jl_array_t *ext_targets, jl_a
11211132
jl_method_instance_t *caller = ci->def;
11221133
if (ci->inferred && jl_rettype_inferred(caller, minworld, ~(size_t)0) == jl_nothing) {
11231134
jl_mi_cache_insert(caller, ci);
1135+
} else if (jl_atomic_load_relaxed(&ci->invoke) != NULL &&
1136+
jl_method_compiled(caller, ci->min_world) == NULL) {
1137+
// new CI has fresh code for us
1138+
jl_mi_cache_insert(caller, ci);
11241139
}
11251140
//jl_static_show((jl_stream*)ios_stderr, (jl_value_t*)caller);
11261141
//ios_puts("free\n", ios_stderr);
@@ -1158,14 +1173,19 @@ static void jl_insert_backedges(jl_array_t *edges, jl_array_t *ext_targets, jl_a
11581173
// then enable any methods associated with it
11591174
void *ci = ptrhash_get(&visited, (void*)caller);
11601175
//assert(ci != HT_NOTFOUND);
1161-
if (ci != HT_NOTFOUND) {
1176+
if (ci != HT_NOTFOUND && maxvalid != 0) {
11621177
// have some new external code to use
11631178
assert(jl_is_code_instance(ci));
11641179
jl_code_instance_t *codeinst = (jl_code_instance_t*)ci;
11651180
assert(codeinst->min_world == minworld && codeinst->inferred);
1181+
assert(maxvalid >= minworld);
11661182
codeinst->max_world = maxvalid;
11671183
if (jl_rettype_inferred(caller, minworld, maxvalid) == jl_nothing) {
11681184
jl_mi_cache_insert(caller, codeinst);
1185+
} else if (jl_atomic_load_relaxed(&codeinst->invoke) != NULL &&
1186+
jl_method_compiled(caller, codeinst->min_world) == NULL) {
1187+
// new CI has fresh code for us
1188+
jl_mi_cache_insert(caller, codeinst);
11691189
}
11701190
}
11711191
}

0 commit comments

Comments
 (0)