Skip to content

Commit

Permalink
remove special cases for Main in system image saving (#34828)
Browse files Browse the repository at this point in the history
`usings` and all bindings will now be preserved

make Core a top-level module (its parent is itself) instead of
setting its parent to Main.
  • Loading branch information
JeffBezanson authored and KristofferC committed Apr 11, 2020
1 parent 06714fe commit b690918
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 86 deletions.
3 changes: 3 additions & 0 deletions base/sysimg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,6 @@ end

empty!(LOAD_PATH)
empty!(DEPOT_PATH)

# Set up Main module
import Base.MainInclude: eval, include
34 changes: 13 additions & 21 deletions src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,30 +453,22 @@ static void jl_serialize_module(jl_serializer_state *s, jl_module_t *m)
for (i = 1; i < m->bindings.size; i += 2) {
if (table[i] != HT_NOTFOUND) {
jl_binding_t *b = (jl_binding_t*)table[i];
if (b->owner == m || m != jl_main_module) {
jl_serialize_value(s, b->name);
jl_value_t *e = b->value;
if (!b->constp && e && jl_is_cpointer(e) && jl_unbox_voidpointer(e) != (void*)-1 && jl_unbox_voidpointer(e) != NULL)
// reset Ptr fields to C_NULL (but keep MAP_FAILED / INVALID_HANDLE)
jl_serialize_cnull(s, jl_typeof(e));
else
jl_serialize_value(s, e);
jl_serialize_value(s, b->globalref);
jl_serialize_value(s, b->owner);
write_int8(s->s, (b->deprecated<<3) | (b->constp<<2) | (b->exportp<<1) | (b->imported));
}
jl_serialize_value(s, b->name);
jl_value_t *e = b->value;
if (!b->constp && e && jl_is_cpointer(e) && jl_unbox_voidpointer(e) != (void*)-1 && jl_unbox_voidpointer(e) != NULL)
// reset Ptr fields to C_NULL (but keep MAP_FAILED / INVALID_HANDLE)
jl_serialize_cnull(s, jl_typeof(e));
else
jl_serialize_value(s, e);
jl_serialize_value(s, b->globalref);
jl_serialize_value(s, b->owner);
write_int8(s->s, (b->deprecated<<3) | (b->constp<<2) | (b->exportp<<1) | (b->imported));
}
}
jl_serialize_value(s, NULL);
if (m == jl_main_module) {
write_int32(s->s, 1);
jl_serialize_value(s, (jl_value_t*)jl_core_module);
}
else {
write_int32(s->s, m->usings.len);
for(i=0; i < m->usings.len; i++) {
jl_serialize_value(s, (jl_value_t*)m->usings.items[i]);
}
write_int32(s->s, m->usings.len);
for(i=0; i < m->usings.len; i++) {
jl_serialize_value(s, (jl_value_t*)m->usings.items[i]);
}
write_uint8(s->s, m->istopmod);
write_uint64(s->s, m->uuid.hi);
Expand Down
10 changes: 1 addition & 9 deletions src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,7 @@ void _julia_init(JL_IMAGE_SEARCH rel)

if (!jl_options.image_file) {
jl_core_module = jl_new_module(jl_symbol("Core"));
jl_core_module->parent = jl_core_module;
jl_type_typename->mt->module = jl_core_module;
jl_top_module = jl_core_module;
jl_init_intrinsic_functions();
Expand All @@ -747,16 +748,7 @@ void _julia_init(JL_IMAGE_SEARCH rel)
post_boot_hooks();
}

// the Main module is the one which is always open, and set as the
// current module for bare (non-module-wrapped) toplevel expressions.
// it does "using Base" if Base is available.
if (jl_base_module != NULL) {
jl_add_standard_imports(jl_main_module);
jl_value_t *maininclude = jl_get_global(jl_base_module, jl_symbol("MainInclude"));
if (maininclude && jl_is_module(maininclude)) {
jl_module_import(jl_main_module, (jl_module_t*)maininclude, jl_symbol("include"));
jl_module_import(jl_main_module, (jl_module_t*)maininclude, jl_symbol("eval"));
}
// Do initialization needed before starting child threads
jl_value_t *f = jl_get_global(jl_base_module, jl_symbol("__preinit_threads__"));
if (f) {
Expand Down
94 changes: 40 additions & 54 deletions src/staticdata.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,19 +262,15 @@ static void jl_serialize_module(jl_serializer_state *s, jl_module_t *m)
for (i = 1; i < m->bindings.size; i += 2) {
if (table[i] != HT_NOTFOUND) {
jl_binding_t *b = (jl_binding_t*)table[i];
if (b->owner == m || m != jl_main_module) {
jl_serialize_value(s, b->name);
jl_serialize_value(s, b->value);
jl_serialize_value(s, b->globalref);
jl_serialize_value(s, b->owner);
}
jl_serialize_value(s, b->name);
jl_serialize_value(s, b->value);
jl_serialize_value(s, b->globalref);
jl_serialize_value(s, b->owner);
}
}

if (m != jl_main_module) {
for (i = 0; i < m->usings.len; i++) {
jl_serialize_value(s, (jl_value_t*)m->usings.items[i]);
}
for (i = 0; i < m->usings.len; i++) {
jl_serialize_value(s, (jl_value_t*)m->usings.items[i]);
}
}

Expand Down Expand Up @@ -495,65 +491,50 @@ static void jl_write_module(jl_serializer_state *s, uintptr_t item, jl_module_t
for (i = 1; i < m->bindings.size; i += 2) {
if (table[i] != HT_NOTFOUND) {
jl_binding_t *b = (jl_binding_t*)table[i];
if (b->owner == m || m != jl_main_module) {
write_gctaggedfield(s, (uintptr_t)BindingRef << RELOC_TAG_OFFSET);
tot += sizeof(void*);
size_t binding_reloc_offset = ios_pos(s->s);
record_gvar(s, jl_get_llvm_gv((jl_value_t*)b), ((uintptr_t)DataRef << RELOC_TAG_OFFSET) + binding_reloc_offset);
write_pointerfield(s, (jl_value_t*)b->name);
write_pointerfield(s, b->value);
write_pointerfield(s, b->globalref);
write_pointerfield(s, (jl_value_t*)b->owner);
size_t flag_offset = offsetof(jl_binding_t, owner) + sizeof(b->owner);
ios_write(s->s, (char*)b + flag_offset, sizeof(*b) - flag_offset);
tot += sizeof(jl_binding_t);
count += 1;
}
write_gctaggedfield(s, (uintptr_t)BindingRef << RELOC_TAG_OFFSET);
tot += sizeof(void*);
size_t binding_reloc_offset = ios_pos(s->s);
record_gvar(s, jl_get_llvm_gv((jl_value_t*)b), ((uintptr_t)DataRef << RELOC_TAG_OFFSET) + binding_reloc_offset);
write_pointerfield(s, (jl_value_t*)b->name);
write_pointerfield(s, b->value);
write_pointerfield(s, b->globalref);
write_pointerfield(s, (jl_value_t*)b->owner);
size_t flag_offset = offsetof(jl_binding_t, owner) + sizeof(b->owner);
ios_write(s->s, (char*)b + flag_offset, sizeof(*b) - flag_offset);
tot += sizeof(jl_binding_t);
count += 1;
}
}
assert(ios_pos(s->s) - reloc_offset == tot);
newm = (jl_module_t*)&s->s->buf[reloc_offset];
newm = (jl_module_t*)&s->s->buf[reloc_offset]; // buf might have been reallocated
newm->bindings.size = count; // stash the count in newm->size
newm->bindings.table = NULL;
memset(&newm->bindings._space, 0, sizeof(newm->bindings._space));

// write out the usings list
memset(&newm->usings._space, 0, sizeof(newm->usings._space));
if (m == jl_main_module) {
newm->usings.len = 1;
newm->usings.max = AL_N_INLINE;
if (m->usings.items == &m->usings._space[0]) {
newm->usings.items = (void**)offsetof(jl_module_t, usings._space);
arraylist_push(&s->relocs_list, (void*)(reloc_offset + offsetof(jl_module_t, usings.items)));
arraylist_push(&s->relocs_list, (void*)(((uintptr_t)DataRef << RELOC_TAG_OFFSET) + item));
arraylist_push(&s->relocs_list, (void*)(reloc_offset + offsetof(jl_module_t, usings._space[0])));
arraylist_push(&s->relocs_list, (void*)backref_id(s, jl_core_module));
size_t i;
for (i = 0; i < m->usings.len; i++) {
arraylist_push(&s->relocs_list, (void*)(reloc_offset + offsetof(jl_module_t, usings._space[i])));
arraylist_push(&s->relocs_list, (void*)backref_id(s, m->usings._space[i]));
}
}
else {
if (newm->usings.items == &newm->usings._space[0]) {
m->usings.max = AL_N_INLINE;
newm->usings.items = (void**)offsetof(jl_module_t, usings._space);
arraylist_push(&s->relocs_list, (void*)(reloc_offset + offsetof(jl_module_t, usings.items)));
arraylist_push(&s->relocs_list, (void*)(((uintptr_t)DataRef << RELOC_TAG_OFFSET) + item));
size_t i;
for (i = 0; i < m->usings.len; i++) {
arraylist_push(&s->relocs_list, (void*)(reloc_offset + offsetof(jl_module_t, usings._space[i])));
arraylist_push(&s->relocs_list, (void*)backref_id(s, m->usings._space[i]));
}
newm->usings.items = (void**)tot;
arraylist_push(&s->relocs_list, (void*)(reloc_offset + offsetof(jl_module_t, usings.items)));
arraylist_push(&s->relocs_list, (void*)(((uintptr_t)DataRef << RELOC_TAG_OFFSET) + item));
size_t i;
for (i = 0; i < m->usings.len; i++) {
write_pointerfield(s, (jl_value_t*)m->usings.items[i]);
tot += sizeof(void*);
}
else {
newm->usings.items = (void**)tot;
arraylist_push(&s->relocs_list, (void*)(reloc_offset + offsetof(jl_module_t, usings.items)));
arraylist_push(&s->relocs_list, (void*)(((uintptr_t)DataRef << RELOC_TAG_OFFSET) + item));
size_t i;
for (i = 0; i < m->usings.len; i++) {
write_pointerfield(s, (jl_value_t*)m->usings.items[i]);
tot += sizeof(void*);
}
for (; i < m->usings.max; i++) {
write_pointer(s->s);
tot += sizeof(void*);
}
// newm = (jl_module_t*)&s->s->buf[reloc_offset];
for (; i < m->usings.max; i++) {
write_pointer(s->s);
tot += sizeof(void*);
}
}
}
Expand Down Expand Up @@ -1265,6 +1246,11 @@ static void jl_reinit_item(jl_value_t *v, int how)
b += 1;
nbindings -= 1;
}
if (mod->usings.items != &mod->usings._space[0]) {
void **newitems = (void**)malloc_s(mod->usings.max * sizeof(void*));
memcpy(newitems, mod->usings.items, mod->usings.len * sizeof(void*));
mod->usings.items = newitems;
}
break;
}
default:
Expand Down
1 change: 0 additions & 1 deletion src/toplevel.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ void jl_init_main_module(void)

jl_main_module = jl_new_module(jl_symbol("Main"));
jl_main_module->parent = jl_main_module;
jl_core_module->parent = jl_main_module;
jl_set_const(jl_main_module, jl_symbol("Core"),
(jl_value_t*)jl_core_module);
jl_set_global(jl_core_module, jl_symbol("Main"),
Expand Down
2 changes: 1 addition & 1 deletion stdlib/Test/src/Test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1491,7 +1491,7 @@ function detect_unbound_args(mods...;
continue
end
f = Base.unwrap_unionall(getfield(mod, n))
if recursive && isa(f, Module) && parentmodule(f) === mod && nameof(f) === n
if recursive && isa(f, Module) && f !== mod && parentmodule(f) === mod && nameof(f) === n
subambs = detect_unbound_args(f, imported=imported, recursive=recursive)
union!(ambs, subambs)
elseif isa(f, DataType) && isdefined(f.name, :mt)
Expand Down

0 comments on commit b690918

Please sign in to comment.