Skip to content

Commit

Permalink
Use uniquing target table to map gvars to uniqued values
Browse files Browse the repository at this point in the history
  • Loading branch information
vchuravy committed Oct 19, 2022
1 parent 743b061 commit dc8618c
Showing 1 changed file with 25 additions and 16 deletions.
41 changes: 25 additions & 16 deletions src/staticdata.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
`uniquing_list` also holds the serialized location of external DataTypes, MethodInstances, and singletons
in the serialized blob (i.e., new-at-the-time-of-serialization specializations).
`uniquing_target` is a hash table for which `uniquing_target[obj] -> chosen_target`.
Most of step 2 is handled by `jl_write_values`, followed by special handling of the dedicated parallel streams.
Expand Down Expand Up @@ -1864,7 +1865,7 @@ static uint32_t write_gvars(jl_serializer_state *s, arraylist_t *globals, arrayl
}

// Pointer relocation for native-code referenced global variables
static void jl_update_all_gvars(jl_serializer_state *s, uint32_t external_fns_begin)
static void jl_update_all_gvars(jl_serializer_state *s, uint32_t external_fns_begin, htable_t *uniquing_target)
{
if (sysimg_gvars_base == NULL)
return;
Expand All @@ -1880,7 +1881,11 @@ static void jl_update_all_gvars(jl_serializer_state *s, uint32_t external_fns_be
if (offset) {
if (gvname_index < (external_fns_begin-1)) { // external_fns_begin is 1-indexed, gvname_index is 0-indexed
uintptr_t v = get_item_for_reloc(s, base, size, offset, s->link_ids_gvars, &gvar_link_index);
// TODO(required): if (incremental) v = jl_as_global_root((jl_value_t*)v);
uintptr_t unique_value = (uintptr_t)ptrhash_get(uniquing_target, (void*)v);
if ((void*)unique_value != HT_NOTFOUND)
v = unique_value;
// if (s->incremental)
// v = (uintptr_t) jl_as_global_root((jl_value_t*)v);
*sysimg_gvars(sysimg_gvars_base, gvname_index) = (uintptr_t)v;
}
else {
Expand Down Expand Up @@ -2855,21 +2860,10 @@ static void jl_restore_system_image_from_stream_(ios_t *f, jl_array_t *depmods,
*pfld = (uintptr_t)newobj | GC_OLD;
else
*pfld = (uintptr_t)newobj;
ptrhash_put(&uniquing_target, (void*)obj, (void*)newobj);
assert(!(image_base < (char*)newobj && (char*)newobj <= image_base + sizeof_sysimg + sizeof(uintptr_t)));
assert(jl_typeis(obj, otyp));
}
// Write junk in place of the source data we used during uniquing, to catch inadvertent references to
// it from elsewhere.
for (size_t i = 0; i < s.uniquing_list.len; i++) {
void *item = s.uniquing_list.items[i];
jl_taggedvalue_t *o = jl_astaggedvalue(item);
if (o->type == (jl_value_t*)jl_method_instance_type)
memset(o, 0xba, sizeof(jl_value_t*) + sizeof(jl_method_instance_t));
else if (o->type == (jl_value_t*)jl_datatype_type)
memset(o, 0xba, sizeof(jl_value_t*) + sizeof(jl_datatype_t));
else
memset(o, 0xba, sizeof(jl_value_t*));
}
// Perform fixups: things like updating world ages, inserting methods & specializations, etc.
size_t world = jl_atomic_load_acquire(&jl_world_counter);
for (size_t i = 0; i < s.fixup_list.len; i++) {
Expand Down Expand Up @@ -2948,15 +2942,30 @@ static void jl_restore_system_image_from_stream_(ios_t *f, jl_array_t *depmods,
r->bnd_cache = b && b->value ? b : NULL;
}
}
arraylist_free(&s.uniquing_list);
arraylist_free(&s.fixup_list);

// s.link_ids_gvars will be processed in `jl_update_all_gvars`
// s.link_ids_external_fnvars will be processed in `jl_update_all_gvars`
ios_close(&relocs);
ios_close(&const_data);
jl_update_all_gvars(&s, external_fns_begin); // gvars relocs
jl_update_all_gvars(&s, external_fns_begin, &uniquing_target); // gvars relocs
ios_close(&gvar_record);

// Write junk in place of the source data we used during uniquing, to catch inadvertent references to
// it from elsewhere. This needs to be delayed after update_all_gvars so that we can rewire gvars as well.
for (size_t i = 0; i < s.uniquing_list.len; i++) {
void *item = s.uniquing_list.items[i];
jl_taggedvalue_t *o = jl_astaggedvalue(item);
if (o->type == (jl_value_t*)jl_method_instance_type)
memset(o, 0xba, sizeof(jl_value_t*) + sizeof(jl_method_instance_t));
else if (o->type == (jl_value_t*)jl_datatype_type)
memset(o, 0xba, sizeof(jl_value_t*) + sizeof(jl_datatype_t));
else
memset(o, 0xba, sizeof(jl_value_t*));
}
arraylist_free(&s.uniquing_list);
htable_free(&uniquing_target);

s.s = NULL;

if (0) {
Expand Down

0 comments on commit dc8618c

Please sign in to comment.