Skip to content

Commit 009bc4f

Browse files
timholyLilithHafner
authored andcommitted
Track method roots by precompile module (JuliaLang#43793)
For roots of a method added during incremental compilation, track the toplevel module build_id. This will ultimately allow such roots to be "relocatable" in compressed IR, pending future changes in compression.
1 parent efa47e3 commit 009bc4f

File tree

12 files changed

+215
-5
lines changed

12 files changed

+215
-5
lines changed

src/codegen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7549,7 +7549,7 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
75497549
break;
75507550
}
75517551
if (j == jlen) // not found - add to array
7552-
jl_array_ptr_1d_push(m->roots, ival);
7552+
jl_add_method_root(m, jl_precompile_toplevel_module, ival);
75537553
}
75547554
}
75557555
ctx.roots = NULL;

src/dump.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,7 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_li
704704
write_int8(s->s, m->constprop);
705705
jl_serialize_value(s, (jl_value_t*)m->slot_syms);
706706
jl_serialize_value(s, (jl_value_t*)m->roots);
707+
jl_serialize_value(s, (jl_value_t*)m->root_blocks);
707708
jl_serialize_value(s, (jl_value_t*)m->ccallable);
708709
jl_serialize_value(s, (jl_value_t*)m->source);
709710
jl_serialize_value(s, (jl_value_t*)m->unspecialized);
@@ -1573,6 +1574,9 @@ static jl_value_t *jl_deserialize_value_method(jl_serializer_state *s, jl_value_
15731574
m->roots = (jl_array_t*)jl_deserialize_value(s, (jl_value_t**)&m->roots);
15741575
if (m->roots)
15751576
jl_gc_wb(m, m->roots);
1577+
m->root_blocks = (jl_array_t*)jl_deserialize_value(s, (jl_value_t**)&m->root_blocks);
1578+
if (m->root_blocks)
1579+
jl_gc_wb(m, m->root_blocks);
15761580
m->ccallable = (jl_svec_t*)jl_deserialize_value(s, (jl_value_t**)&m->ccallable);
15771581
if (m->ccallable) {
15781582
jl_gc_wb(m, m->ccallable);
@@ -2312,6 +2316,8 @@ JL_DLLEXPORT int jl_save_incremental(const char *fname, jl_array_t *worklist)
23122316
}
23132317
JL_GC_PUSH2(&mod_array, &udeps);
23142318
mod_array = jl_get_loaded_modules(); // __toplevel__ modules loaded in this session (from Base.loaded_modules_array)
2319+
assert(jl_precompile_toplevel_module == NULL);
2320+
jl_precompile_toplevel_module = (jl_module_t*)jl_array_ptr_ref(worklist, jl_array_len(worklist)-1);
23152321

23162322
serializer_worklist = worklist;
23172323
write_header(&f);
@@ -2426,6 +2432,7 @@ JL_DLLEXPORT int jl_save_incremental(const char *fname, jl_array_t *worklist)
24262432
write_int32(&f, 0); // mark the end of the source text
24272433
ios_close(&f);
24282434
JL_GC_POP();
2435+
jl_precompile_toplevel_module = NULL;
24292436

24302437
return 0;
24312438
}

src/init.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,7 @@ JL_DLLEXPORT void julia_init(JL_IMAGE_SEARCH rel)
625625
libsupport_init();
626626
htable_new(&jl_current_modules, 0);
627627
JL_MUTEX_INIT(&jl_modules_mutex);
628+
jl_precompile_toplevel_module = NULL;
628629
ios_set_io_wait_func = jl_set_io_wait;
629630
jl_io_loop = uv_default_loop(); // this loop will internal events (spawning process etc.),
630631
// best to call this first, since it also initializes libuv

src/ircode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ static int literal_val_id(jl_ircode_state *s, jl_value_t *v) JL_GC_DISABLED
4848
return i;
4949
}
5050
}
51-
jl_array_ptr_1d_push(rs, v);
51+
jl_add_method_root(s->method, jl_precompile_toplevel_module, v);
5252
return jl_array_len(rs) - 1;
5353
}
5454

src/jl_exported_data.inc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
XX(jl_array_type) \
1919
XX(jl_array_typename) \
2020
XX(jl_array_uint8_type) \
21+
XX(jl_array_uint64_type) \
2122
XX(jl_atomicerror_type) \
2223
XX(jl_base_module) \
2324
XX(jl_bool_type) \
@@ -84,6 +85,7 @@
8485
XX(jl_pinode_type) \
8586
XX(jl_pointer_type) \
8687
XX(jl_pointer_typename) \
88+
XX(jl_precompile_toplevel_module) \
8789
XX(jl_quotenode_type) \
8890
XX(jl_readonlymemory_exception) \
8991
XX(jl_ref_type) \

src/jltypes.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2253,6 +2253,7 @@ void jl_init_types(void) JL_GC_DISABLED
22532253
jl_array_symbol_type = jl_apply_type2((jl_value_t*)jl_array_type, (jl_value_t*)jl_symbol_type, jl_box_long(1));
22542254
jl_array_uint8_type = jl_apply_type2((jl_value_t*)jl_array_type, (jl_value_t*)jl_uint8_type, jl_box_long(1));
22552255
jl_array_int32_type = jl_apply_type2((jl_value_t*)jl_array_type, (jl_value_t*)jl_int32_type, jl_box_long(1));
2256+
jl_array_uint64_type = jl_apply_type2((jl_value_t*)jl_array_type, (jl_value_t*)jl_uint64_type, jl_box_long(1));
22562257
jl_an_empty_vec_any = (jl_value_t*)jl_alloc_vec_any(0); // used internally
22572258
jl_atomic_store_relaxed(&jl_nonfunction_mt->leafcache, (jl_array_t*)jl_an_empty_vec_any);
22582259
jl_atomic_store_relaxed(&jl_type_type_mt->leafcache, (jl_array_t*)jl_an_empty_vec_any);
@@ -2392,7 +2393,7 @@ void jl_init_types(void) JL_GC_DISABLED
23922393
jl_method_type =
23932394
jl_new_datatype(jl_symbol("Method"), core,
23942395
jl_any_type, jl_emptysvec,
2395-
jl_perm_symsvec(26,
2396+
jl_perm_symsvec(27,
23962397
"name",
23972398
"module",
23982399
"file",
@@ -2408,6 +2409,7 @@ void jl_init_types(void) JL_GC_DISABLED
24082409
"unspecialized", // !const
24092410
"generator", // !const
24102411
"roots", // !const
2412+
"root_blocks", // !const
24112413
"ccallable", // !const
24122414
"invokes", // !const
24132415
"recursion_relation", // !const
@@ -2419,7 +2421,7 @@ void jl_init_types(void) JL_GC_DISABLED
24192421
"pure",
24202422
"is_for_opaque_closure",
24212423
"constprop"),
2422-
jl_svec(26,
2424+
jl_svec(27,
24232425
jl_symbol_type,
24242426
jl_module_type,
24252427
jl_symbol_type,
@@ -2435,6 +2437,7 @@ void jl_init_types(void) JL_GC_DISABLED
24352437
jl_any_type, // jl_method_instance_type
24362438
jl_any_type,
24372439
jl_array_any_type,
2440+
jl_array_uint64_type,
24382441
jl_simplevector_type,
24392442
jl_any_type,
24402443
jl_any_type,

src/julia.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,9 @@ typedef struct _jl_method_t {
291291
_Atomic(struct _jl_method_instance_t*) unspecialized; // unspecialized executable method instance, or null
292292
jl_value_t *generator; // executable code-generating function if available
293293
jl_array_t *roots; // pointers in generated code (shared to reduce memory), or null
294+
// Identify roots by module-of-origin. We only track the module for roots added during incremental compilation.
295+
// May be NULL if no external roots have been added, otherwise it's a Vector{UInt64}
296+
jl_array_t *root_blocks; // RLE (build_id, offset) pairs (even/odd indexing)
294297
jl_svec_t *ccallable; // svec(rettype, sig) if a ccallable entry point is requested for this
295298

296299
// cache of specializations of this method for invoke(), i.e.
@@ -708,6 +711,7 @@ extern JL_DLLIMPORT jl_value_t *jl_array_uint8_type JL_GLOBALLY_ROOTED;
708711
extern JL_DLLIMPORT jl_value_t *jl_array_any_type JL_GLOBALLY_ROOTED;
709712
extern JL_DLLIMPORT jl_value_t *jl_array_symbol_type JL_GLOBALLY_ROOTED;
710713
extern JL_DLLIMPORT jl_value_t *jl_array_int32_type JL_GLOBALLY_ROOTED;
714+
extern JL_DLLIMPORT jl_value_t *jl_array_uint64_type JL_GLOBALLY_ROOTED;
711715
extern JL_DLLIMPORT jl_datatype_t *jl_expr_type JL_GLOBALLY_ROOTED;
712716
extern JL_DLLIMPORT jl_datatype_t *jl_globalref_type JL_GLOBALLY_ROOTED;
713717
extern JL_DLLIMPORT jl_datatype_t *jl_linenumbernode_type JL_GLOBALLY_ROOTED;

src/julia_internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,8 @@ JL_DLLEXPORT jl_code_info_t *jl_new_code_info_uninit(void);
527527
void jl_resolve_globals_in_ir(jl_array_t *stmts, jl_module_t *m, jl_svec_t *sparam_vals,
528528
int binding_effects);
529529

530+
JL_DLLEXPORT void jl_add_method_root(jl_method_t *m, jl_module_t *mod, jl_value_t* root);
531+
530532
int jl_valid_type_param(jl_value_t *v);
531533

532534
JL_DLLEXPORT jl_value_t *jl_apply_2va(jl_value_t *f, jl_value_t **args, uint32_t nargs);
@@ -647,6 +649,7 @@ jl_binding_t *jl_get_module_binding(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t
647649
JL_DLLEXPORT void jl_binding_deprecation_warning(jl_module_t *m, jl_binding_t *b);
648650
extern jl_array_t *jl_module_init_order JL_GLOBALLY_ROOTED;
649651
extern htable_t jl_current_modules JL_GLOBALLY_ROOTED;
652+
extern JL_DLLEXPORT jl_module_t *jl_precompile_toplevel_module JL_GLOBALLY_ROOTED;
650653
int jl_compile_extern_c(void *llvmmod, void *params, void *sysimg, jl_value_t *declrt, jl_value_t *sigt);
651654

652655
jl_opaque_closure_t *jl_new_opaque_closure(jl_tupletype_t *argt, jl_value_t *isva, jl_value_t *rt_lb,

src/method.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,7 @@ JL_DLLEXPORT jl_method_t *jl_new_method_uninit(jl_module_t *module)
731731
m->sig = NULL;
732732
m->slot_syms = NULL;
733733
m->roots = NULL;
734+
m->root_blocks = NULL;
734735
m->ccallable = NULL;
735736
m->module = module;
736737
m->external_mt = NULL;
@@ -987,6 +988,53 @@ JL_DLLEXPORT jl_method_t* jl_method_def(jl_svec_t *argdata,
987988
return m;
988989
}
989990

991+
// root blocks
992+
993+
static uint64_t current_root_id(jl_array_t *root_blocks)
994+
{
995+
if (!root_blocks)
996+
return 0;
997+
assert(jl_is_array(root_blocks));
998+
size_t nx2 = jl_array_len(root_blocks);
999+
if (nx2 == 0)
1000+
return 0;
1001+
uint64_t *blocks = (uint64_t*)jl_array_data(root_blocks);
1002+
return blocks[nx2-2];
1003+
}
1004+
1005+
static void add_root_block(jl_array_t *root_blocks, uint64_t modid, size_t len)
1006+
{
1007+
assert(jl_is_array(root_blocks));
1008+
jl_array_grow_end(root_blocks, 2);
1009+
uint64_t *blocks = (uint64_t*)jl_array_data(root_blocks);
1010+
int nx2 = jl_array_len(root_blocks);
1011+
blocks[nx2-2] = modid;
1012+
blocks[nx2-1] = len;
1013+
}
1014+
1015+
JL_DLLEXPORT void jl_add_method_root(jl_method_t *m, jl_module_t *mod, jl_value_t* root)
1016+
{
1017+
JL_GC_PUSH2(&m, &root);
1018+
uint64_t modid = 0;
1019+
if (mod) {
1020+
assert(jl_is_module(mod));
1021+
modid = mod->build_id;
1022+
}
1023+
assert(jl_is_method(m));
1024+
if (!m->roots) {
1025+
m->roots = jl_alloc_vec_any(0);
1026+
jl_gc_wb(m, m->roots);
1027+
}
1028+
if (!m->root_blocks && modid != 0) {
1029+
m->root_blocks = jl_alloc_array_1d(jl_array_uint64_type, 0);
1030+
jl_gc_wb(m, m->root_blocks);
1031+
}
1032+
if (current_root_id(m->root_blocks) != modid)
1033+
add_root_block(m->root_blocks, modid, jl_array_len(m->roots));
1034+
jl_array_ptr_1d_push(m->roots, root);
1035+
JL_GC_POP();
1036+
}
1037+
9901038
#ifdef __cplusplus
9911039
}
9921040
#endif

src/staticdata.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ extern "C" {
2626
// TODO: put WeakRefs on the weak_refs list during deserialization
2727
// TODO: handle finalizers
2828

29-
#define NUM_TAGS 151
29+
#define NUM_TAGS 152
3030

3131
// An array of references that need to be restored from the sysimg
3232
// This is a manually constructed dual of the gvars array, which would be produced by codegen for Julia code, for C.
@@ -106,6 +106,7 @@ jl_value_t **const*const get_tags(void) {
106106
INSERT_TAG(jl_array_symbol_type);
107107
INSERT_TAG(jl_array_uint8_type);
108108
INSERT_TAG(jl_array_int32_type);
109+
INSERT_TAG(jl_array_uint64_type);
109110
INSERT_TAG(jl_int32_type);
110111
INSERT_TAG(jl_int64_type);
111112
INSERT_TAG(jl_bool_type);

0 commit comments

Comments
 (0)