Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7500,7 +7500,7 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
break;
}
if (j == jlen) // not found - add to array
jl_array_ptr_1d_push(m->roots, ival);
jl_add_method_root(m, jl_precompile_toplevel_module, ival);
}
}
ctx.roots = NULL;
Expand Down
7 changes: 7 additions & 0 deletions src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,7 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_li
write_int8(s->s, m->constprop);
jl_serialize_value(s, (jl_value_t*)m->slot_syms);
jl_serialize_value(s, (jl_value_t*)m->roots);
jl_serialize_value(s, (jl_value_t*)m->root_blocks);
jl_serialize_value(s, (jl_value_t*)m->ccallable);
jl_serialize_value(s, (jl_value_t*)m->source);
jl_serialize_value(s, (jl_value_t*)m->unspecialized);
Expand Down Expand Up @@ -1573,6 +1574,9 @@ static jl_value_t *jl_deserialize_value_method(jl_serializer_state *s, jl_value_
m->roots = (jl_array_t*)jl_deserialize_value(s, (jl_value_t**)&m->roots);
if (m->roots)
jl_gc_wb(m, m->roots);
m->root_blocks = (jl_array_t*)jl_deserialize_value(s, (jl_value_t**)&m->root_blocks);
if (m->root_blocks)
jl_gc_wb(m, m->root_blocks);
m->ccallable = (jl_svec_t*)jl_deserialize_value(s, (jl_value_t**)&m->ccallable);
if (m->ccallable) {
jl_gc_wb(m, m->ccallable);
Expand Down Expand Up @@ -2312,6 +2316,8 @@ JL_DLLEXPORT int jl_save_incremental(const char *fname, jl_array_t *worklist)
}
JL_GC_PUSH2(&mod_array, &udeps);
mod_array = jl_get_loaded_modules(); // __toplevel__ modules loaded in this session (from Base.loaded_modules_array)
assert(jl_precompile_toplevel_module == NULL);
jl_precompile_toplevel_module = (jl_module_t*)jl_array_ptr_ref(worklist, jl_array_len(worklist)-1);

serializer_worklist = worklist;
write_header(&f);
Expand Down Expand Up @@ -2426,6 +2432,7 @@ JL_DLLEXPORT int jl_save_incremental(const char *fname, jl_array_t *worklist)
write_int32(&f, 0); // mark the end of the source text
ios_close(&f);
JL_GC_POP();
jl_precompile_toplevel_module = NULL;

return 0;
}
Expand Down
1 change: 1 addition & 0 deletions src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,7 @@ JL_DLLEXPORT void julia_init(JL_IMAGE_SEARCH rel)
libsupport_init();
htable_new(&jl_current_modules, 0);
JL_MUTEX_INIT(&jl_modules_mutex);
jl_precompile_toplevel_module = NULL;
ios_set_io_wait_func = jl_set_io_wait;
jl_io_loop = uv_default_loop(); // this loop will internal events (spawning process etc.),
// best to call this first, since it also initializes libuv
Expand Down
2 changes: 1 addition & 1 deletion src/ircode.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ static int literal_val_id(jl_ircode_state *s, jl_value_t *v) JL_GC_DISABLED
return i;
}
}
jl_array_ptr_1d_push(rs, v);
jl_add_method_root(s->method, jl_precompile_toplevel_module, v);
return jl_array_len(rs) - 1;
}

Expand Down
2 changes: 2 additions & 0 deletions src/jl_exported_data.inc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
XX(jl_array_type) \
XX(jl_array_typename) \
XX(jl_array_uint8_type) \
XX(jl_array_uint64_type) \
XX(jl_atomicerror_type) \
XX(jl_base_module) \
XX(jl_bool_type) \
Expand Down Expand Up @@ -84,6 +85,7 @@
XX(jl_pinode_type) \
XX(jl_pointer_type) \
XX(jl_pointer_typename) \
XX(jl_precompile_toplevel_module) \
XX(jl_quotenode_type) \
XX(jl_readonlymemory_exception) \
XX(jl_ref_type) \
Expand Down
7 changes: 5 additions & 2 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -2253,6 +2253,7 @@ void jl_init_types(void) JL_GC_DISABLED
jl_array_symbol_type = jl_apply_type2((jl_value_t*)jl_array_type, (jl_value_t*)jl_symbol_type, jl_box_long(1));
jl_array_uint8_type = jl_apply_type2((jl_value_t*)jl_array_type, (jl_value_t*)jl_uint8_type, jl_box_long(1));
jl_array_int32_type = jl_apply_type2((jl_value_t*)jl_array_type, (jl_value_t*)jl_int32_type, jl_box_long(1));
jl_array_uint64_type = jl_apply_type2((jl_value_t*)jl_array_type, (jl_value_t*)jl_uint64_type, jl_box_long(1));
jl_an_empty_vec_any = (jl_value_t*)jl_alloc_vec_any(0); // used internally
jl_atomic_store_relaxed(&jl_nonfunction_mt->leafcache, (jl_array_t*)jl_an_empty_vec_any);
jl_atomic_store_relaxed(&jl_type_type_mt->leafcache, (jl_array_t*)jl_an_empty_vec_any);
Expand Down Expand Up @@ -2392,7 +2393,7 @@ void jl_init_types(void) JL_GC_DISABLED
jl_method_type =
jl_new_datatype(jl_symbol("Method"), core,
jl_any_type, jl_emptysvec,
jl_perm_symsvec(26,
jl_perm_symsvec(27,
"name",
"module",
"file",
Expand All @@ -2408,6 +2409,7 @@ void jl_init_types(void) JL_GC_DISABLED
"unspecialized", // !const
"generator", // !const
"roots", // !const
"root_blocks", // !const
"ccallable", // !const
"invokes", // !const
"recursion_relation", // !const
Expand All @@ -2419,7 +2421,7 @@ void jl_init_types(void) JL_GC_DISABLED
"pure",
"is_for_opaque_closure",
"constprop"),
jl_svec(26,
jl_svec(27,
jl_symbol_type,
jl_module_type,
jl_symbol_type,
Expand All @@ -2435,6 +2437,7 @@ void jl_init_types(void) JL_GC_DISABLED
jl_any_type, // jl_method_instance_type
jl_any_type,
jl_array_any_type,
jl_array_uint64_type,
jl_simplevector_type,
jl_any_type,
jl_any_type,
Expand Down
4 changes: 4 additions & 0 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,9 @@ typedef struct _jl_method_t {
_Atomic(struct _jl_method_instance_t*) unspecialized; // unspecialized executable method instance, or null
jl_value_t *generator; // executable code-generating function if available
jl_array_t *roots; // pointers in generated code (shared to reduce memory), or null
// Identify roots by module-of-origin. We only track the module for roots added during incremental compilation.
// May be NULL if no external roots have been added, otherwise it's a Vector{UInt64}
jl_array_t *root_blocks; // RLE (build_id, offset) pairs (even/odd indexing)
jl_svec_t *ccallable; // svec(rettype, sig) if a ccallable entry point is requested for this

// cache of specializations of this method for invoke(), i.e.
Expand Down Expand Up @@ -708,6 +711,7 @@ extern JL_DLLIMPORT jl_value_t *jl_array_uint8_type JL_GLOBALLY_ROOTED;
extern JL_DLLIMPORT jl_value_t *jl_array_any_type JL_GLOBALLY_ROOTED;
extern JL_DLLIMPORT jl_value_t *jl_array_symbol_type JL_GLOBALLY_ROOTED;
extern JL_DLLIMPORT jl_value_t *jl_array_int32_type JL_GLOBALLY_ROOTED;
extern JL_DLLIMPORT jl_value_t *jl_array_uint64_type JL_GLOBALLY_ROOTED;
extern JL_DLLIMPORT jl_datatype_t *jl_expr_type JL_GLOBALLY_ROOTED;
extern JL_DLLIMPORT jl_datatype_t *jl_globalref_type JL_GLOBALLY_ROOTED;
extern JL_DLLIMPORT jl_datatype_t *jl_linenumbernode_type JL_GLOBALLY_ROOTED;
Expand Down
3 changes: 3 additions & 0 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,8 @@ JL_DLLEXPORT jl_code_info_t *jl_new_code_info_uninit(void);
void jl_resolve_globals_in_ir(jl_array_t *stmts, jl_module_t *m, jl_svec_t *sparam_vals,
int binding_effects);

JL_DLLEXPORT void jl_add_method_root(jl_method_t *m, jl_module_t *mod, jl_value_t* root);

int jl_valid_type_param(jl_value_t *v);

JL_DLLEXPORT jl_value_t *jl_apply_2va(jl_value_t *f, jl_value_t **args, uint32_t nargs);
Expand Down Expand Up @@ -645,6 +647,7 @@ jl_binding_t *jl_get_module_binding(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t
JL_DLLEXPORT void jl_binding_deprecation_warning(jl_module_t *m, jl_binding_t *b);
extern jl_array_t *jl_module_init_order JL_GLOBALLY_ROOTED;
extern htable_t jl_current_modules JL_GLOBALLY_ROOTED;
extern JL_DLLEXPORT jl_module_t *jl_precompile_toplevel_module JL_GLOBALLY_ROOTED;
int jl_compile_extern_c(void *llvmmod, void *params, void *sysimg, jl_value_t *declrt, jl_value_t *sigt);

jl_opaque_closure_t *jl_new_opaque_closure(jl_tupletype_t *argt, jl_value_t *isva, jl_value_t *rt_lb,
Expand Down
48 changes: 48 additions & 0 deletions src/method.c
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,7 @@ JL_DLLEXPORT jl_method_t *jl_new_method_uninit(jl_module_t *module)
m->sig = NULL;
m->slot_syms = NULL;
m->roots = NULL;
m->root_blocks = NULL;
m->ccallable = NULL;
m->module = module;
m->external_mt = NULL;
Expand Down Expand Up @@ -987,6 +988,53 @@ JL_DLLEXPORT jl_method_t* jl_method_def(jl_svec_t *argdata,
return m;
}

// root blocks

static uint64_t current_root_id(jl_array_t *root_blocks)
{
if (!root_blocks)
return 0;
assert(jl_is_array(root_blocks));
size_t nx2 = jl_array_len(root_blocks);
if (nx2 == 0)
return 0;
uint64_t *blocks = (uint64_t*)jl_array_data(root_blocks);
return blocks[nx2-2];
}

static void add_root_block(jl_array_t *root_blocks, uint64_t modid, size_t len)
{
assert(jl_is_array(root_blocks));
jl_array_grow_end(root_blocks, 2);
uint64_t *blocks = (uint64_t*)jl_array_data(root_blocks);
int nx2 = jl_array_len(root_blocks);
blocks[nx2-2] = modid;
blocks[nx2-1] = len;
}

JL_DLLEXPORT void jl_add_method_root(jl_method_t *m, jl_module_t *mod, jl_value_t* root)
{
JL_GC_PUSH2(&m, &root);
uint64_t modid = 0;
if (mod) {
assert(jl_is_module(mod));
modid = mod->build_id;
}
assert(jl_is_method(m));
if (!m->roots) {
m->roots = jl_alloc_vec_any(0);
jl_gc_wb(m, m->roots);
}
if (!m->root_blocks && modid != 0) {
m->root_blocks = jl_alloc_array_1d(jl_array_uint64_type, 0);
jl_gc_wb(m, m->root_blocks);
}
if (current_root_id(m->root_blocks) != modid)
add_root_block(m->root_blocks, modid, jl_array_len(m->roots));
jl_array_ptr_1d_push(m->roots, root);
JL_GC_POP();
}

#ifdef __cplusplus
}
#endif
3 changes: 2 additions & 1 deletion src/staticdata.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ extern "C" {
// TODO: put WeakRefs on the weak_refs list during deserialization
// TODO: handle finalizers

#define NUM_TAGS 151
#define NUM_TAGS 152

// An array of references that need to be restored from the sysimg
// This is a manually constructed dual of the gvars array, which would be produced by codegen for Julia code, for C.
Expand Down Expand Up @@ -106,6 +106,7 @@ jl_value_t **const*const get_tags(void) {
INSERT_TAG(jl_array_symbol_type);
INSERT_TAG(jl_array_uint8_type);
INSERT_TAG(jl_array_int32_type);
INSERT_TAG(jl_array_uint64_type);
INSERT_TAG(jl_int32_type);
INSERT_TAG(jl_int64_type);
INSERT_TAG(jl_bool_type);
Expand Down
10 changes: 10 additions & 0 deletions src/toplevel.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ JL_DLLEXPORT const char *jl_filename = "none"; // need to update jl_critical_err
htable_t jl_current_modules;
jl_mutex_t jl_modules_mutex;

// During incremental compilation, the following gets set
JL_DLLEXPORT jl_module_t *jl_precompile_toplevel_module; // the toplevel module currently being defined

JL_DLLEXPORT void jl_add_standard_imports(jl_module_t *m)
{
jl_module_t *base_module = jl_base_relative_to(m);
Expand Down Expand Up @@ -138,11 +141,16 @@ static jl_value_t *jl_eval_module_expr(jl_module_t *parent_module, jl_expr_t *ex
ptrhash_put(&jl_current_modules, (void*)newm, (void*)((uintptr_t)HT_NOTFOUND + 1));
JL_UNLOCK(&jl_modules_mutex);

jl_module_t *old_toplevel_module = jl_precompile_toplevel_module;

// copy parent environment info into submodule
newm->uuid = parent_module->uuid;
if (jl_is__toplevel__mod(parent_module)) {
newm->parent = newm;
jl_register_root_module(newm);
if (jl_options.incremental) {
jl_precompile_toplevel_module = newm;
}
}
else {
newm->parent = parent_module;
Expand Down Expand Up @@ -261,6 +269,8 @@ static jl_value_t *jl_eval_module_expr(jl_module_t *parent_module, jl_expr_t *ex
}
}

jl_precompile_toplevel_module = old_toplevel_module;

JL_GC_POP();
return (jl_value_t*)newm;
}
Expand Down
Loading