Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

restore type cache pruning in sysimage saving #37650

Merged
merged 1 commit into from
Oct 30, 2020
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
12 changes: 0 additions & 12 deletions src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ static jl_value_t *jl_idtable_type = NULL;
static jl_typename_t *jl_idtable_typename = NULL;
static jl_value_t *jl_bigint_type = NULL;
static int gmp_limb_size = 0;
static arraylist_t builtin_typenames;

static void write_uint64(ios_t *s, uint64_t i) JL_NOTSAFEPOINT
{
Expand Down Expand Up @@ -2677,17 +2676,6 @@ void jl_init_serializer(void)
i += 1;
}
assert(i <= 256);

arraylist_new(&builtin_typenames, 0);
arraylist_push(&builtin_typenames, jl_array_typename);
arraylist_push(&builtin_typenames, ((jl_datatype_t*)jl_ref_type->body)->name);
arraylist_push(&builtin_typenames, jl_pointer_typename);
arraylist_push(&builtin_typenames, jl_type_typename);
arraylist_push(&builtin_typenames, ((jl_datatype_t*)jl_unwrap_unionall((jl_value_t*)jl_abstractarray_type))->name);
arraylist_push(&builtin_typenames, ((jl_datatype_t*)jl_unwrap_unionall((jl_value_t*)jl_densearray_type))->name);
arraylist_push(&builtin_typenames, jl_tuple_typename);
arraylist_push(&builtin_typenames, jl_vararg_typename);
arraylist_push(&builtin_typenames, jl_namedtuple_typename);
}

#ifdef __cplusplus
Expand Down
9 changes: 5 additions & 4 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ static jl_datatype_t *lookup_type_set(jl_svec_t *cache, jl_value_t **key, size_t
jl_datatype_t *val = jl_atomic_load_relaxed(&tab[index]);
if (val == NULL)
return NULL;
if (val->hash == hv && typekey_eq(val, key, n))
if ((jl_value_t*)val != jl_nothing && val->hash == hv && typekey_eq(val, key, n))
return val;
index = (index + 1) & (sz - 1);
iter++;
Expand All @@ -656,7 +656,7 @@ static jl_datatype_t *lookup_type_setvalue(jl_svec_t *cache, jl_value_t *key1, j
jl_datatype_t *val = jl_atomic_load_relaxed(&tab[index]);
if (val == NULL)
return NULL;
if (val->hash == hv && typekeyvalue_eq(val, key1, key, n, leaf))
if ((jl_value_t*)val != jl_nothing && val->hash == hv && typekeyvalue_eq(val, key1, key, n, leaf))
return val;
index = (index + 1) & (sz - 1);
iter++;
Expand Down Expand Up @@ -744,7 +744,8 @@ static int cache_insert_type_set_(jl_svec_t *a, jl_datatype_t *val, uint_t hv)
orig = index;
size_t maxprobe = max_probe(sz);
do {
if (tab[index] == NULL) {
jl_value_t *tab_i = (jl_value_t*)tab[index];
if (tab_i == NULL || tab_i == jl_nothing) {
jl_atomic_store_release(&tab[index], val);
jl_gc_wb(a, val);
return 1;
Expand Down Expand Up @@ -794,7 +795,7 @@ static jl_svec_t *cache_rehash_set(jl_svec_t *a, size_t newsz)
JL_GC_PUSH1(&newa);
for (i = 0; i < sz; i += 1) {
jl_datatype_t *val = ol[i];
if (val != NULL) {
if (val != NULL && (jl_value_t*)val != jl_nothing) {
uint_t hv = val->hash;
if (!cache_insert_type_set_(newa, val, hv)) {
break;
Expand Down
81 changes: 54 additions & 27 deletions src/staticdata.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ static arraylist_t deser_sym;
static htable_t backref_table;
static int backref_table_numel;
static arraylist_t layout_table;
static arraylist_t builtin_typenames;

// list of (size_t pos, (void *f)(jl_value_t*)) entries
// for the serializer to mark values in need of rework by function f
Expand Down Expand Up @@ -259,8 +258,8 @@ static uintptr_t jl_fptr_id(void *fptr)
return *(uintptr_t*)pbp;
}

#define jl_serialize_value(s, v) jl_serialize_value_(s,(jl_value_t*)(v))
static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v);
#define jl_serialize_value(s, v) jl_serialize_value_(s,(jl_value_t*)(v),1)
static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int recursive);


static void jl_serialize_module(jl_serializer_state *s, jl_module_t *m)
Expand All @@ -287,7 +286,7 @@ static void jl_serialize_module(jl_serializer_state *s, jl_module_t *m)

#define NBOX_C 1024

static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v)
static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int recursive)
{
// ignore items that are given a special representation
if (v == NULL || jl_is_symbol(v)) {
Expand Down Expand Up @@ -331,6 +330,8 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v)
// skip it
}
else if (jl_is_svec(v)) {
if (!recursive)
return;
size_t i, l = jl_svec_len(v);
jl_value_t **data = jl_svec_data(v);
for (i = 0; i < l; i++) {
Expand Down Expand Up @@ -366,6 +367,17 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v)
else if (jl_typeis(v, jl_module_type)) {
jl_serialize_module(s, (jl_module_t*)v);
}
else if (jl_is_typename(v)) {
jl_typename_t *tn = (jl_typename_t*)v;
jl_serialize_value(s, tn->name);
jl_serialize_value(s, tn->module);
jl_serialize_value(s, tn->names);
jl_serialize_value(s, tn->wrapper);
jl_serialize_value_(s, (jl_value_t*)tn->cache, 0);
jl_serialize_value_(s, (jl_value_t*)tn->linearcache, 0);
jl_serialize_value(s, tn->mt);
jl_serialize_value(s, tn->partial);
}
else if (t->layout->nfields > 0) {
char *data = (char*)jl_data_ptr(v);
size_t i, np = t->layout->npointers;
Expand Down Expand Up @@ -1235,7 +1247,7 @@ static void jl_finalize_serializer(jl_serializer_state *s, arraylist_t *list)
}


static void jl_reinit_item(jl_value_t *v, int how)
static void jl_reinit_item(jl_value_t *v, int how) JL_GC_DISABLED
{
switch (how) {
case 1: { // rehash IdDict
Expand Down Expand Up @@ -1280,7 +1292,7 @@ static void jl_reinit_item(jl_value_t *v, int how)
}


static void jl_finalize_deserializer(jl_serializer_state *s)
static void jl_finalize_deserializer(jl_serializer_state *s) JL_GC_DISABLED
{
// run reinitialization functions
uintptr_t base = (uintptr_t)&s->s->buf[0];
Expand All @@ -1298,21 +1310,40 @@ static void jl_finalize_deserializer(jl_serializer_state *s)
// --- helper functions ---

// remove cached types not referenced in the stream
static void jl_prune_type_cache(jl_svec_t *cache)
static int keep_type_cache_entry(jl_value_t *ti)
{
if (ptrhash_get(&backref_table, ti) != HT_NOTFOUND || jl_get_llvm_gv(native_functions, ti) != 0)
return 1;
if (jl_is_datatype(ti)) {
jl_value_t *singleton = ((jl_datatype_t*)ti)->instance;
if (singleton && (ptrhash_get(&backref_table, singleton) != HT_NOTFOUND ||
jl_get_llvm_gv(native_functions, singleton) != 0))
return 1;
}
return 0;
}

static void jl_prune_type_cache_hash(jl_svec_t *cache)
{
size_t l = jl_svec_len(cache), i;
for (i = 0; i < l; i++) {
jl_value_t *ti = jl_svecref(cache, i);
if (ti == NULL || ti == jl_nothing)
continue;
if (!keep_type_cache_entry(ti))
jl_svecset(cache, i, jl_nothing);
}
}

static void jl_prune_type_cache_linear(jl_svec_t *cache)
{
size_t l = jl_svec_len(cache), ins = 0, i;
for (i = 0; i < l; i++) {
jl_value_t *ti = jl_svecref(cache, i);
if (ti == NULL)
break;
if (ptrhash_get(&backref_table, ti) != HT_NOTFOUND || jl_get_llvm_gv(native_functions, ti) != 0)
if (keep_type_cache_entry(ti))
jl_svecset(cache, ins++, ti);
else if (jl_is_datatype(ti)) {
jl_value_t *singleton = ((jl_datatype_t*)ti)->instance;
if (singleton && (ptrhash_get(&backref_table, singleton) != HT_NOTFOUND ||
jl_get_llvm_gv(native_functions, singleton) != 0))
jl_svecset(cache, ins++, ti);
}
}
if (i > ins) {
memset(&jl_svec_data(cache)[ins], 0, (i - ins) * sizeof(jl_value_t*));
Expand All @@ -1325,7 +1356,7 @@ static void jl_prune_type_cache(jl_svec_t *cache)
static void jl_init_serializer2(int);
static void jl_cleanup_serializer2(void);

static void jl_save_system_image_to_stream(ios_t *f)
static void jl_save_system_image_to_stream(ios_t *f) JL_GC_DISABLED
{
jl_gc_collect(JL_GC_FULL);
jl_gc_collect(JL_GC_INCREMENTAL); // sweep finalizers
Expand Down Expand Up @@ -1376,15 +1407,13 @@ static void jl_save_system_image_to_stream(ios_t *f)
jl_value_t *tag = *tags[i];
jl_serialize_value(&s, tag);
}
for (i = 0; i < builtin_typenames.len; i++) {
jl_typename_t *tn = (jl_typename_t*)builtin_typenames.items[i];
jl_prune_type_cache(tn->cache);
jl_prune_type_cache(tn->linearcache);
}
for (i = 0; i < builtin_typenames.len; i++) {
jl_typename_t *tn = (jl_typename_t*)builtin_typenames.items[i];
jl_serialize_value(&s, tn->cache);
jl_serialize_value(&s, tn->linearcache);
// prune unused entries from built-in type caches
for (i = 0; i < backref_table.size; i += 2) {
jl_typename_t *tn = (jl_typename_t*)backref_table.table[i];
if (tn == HT_NOTFOUND || !jl_is_typename(tn))
continue;
jl_prune_type_cache_hash(tn->cache);
jl_prune_type_cache_linear(tn->linearcache);
}
}

Expand Down Expand Up @@ -1509,7 +1538,7 @@ JL_DLLEXPORT void jl_set_sysimg_so(void *handle)
sysimg_fptrs = jl_init_processor_sysimg(handle);
}

static void jl_restore_system_image_from_stream(ios_t *f)
static void jl_restore_system_image_from_stream(ios_t *f) JL_GC_DISABLED
{
JL_TIMING(SYSIMG_LOAD);
int en = jl_gc_enable(0);
Expand Down Expand Up @@ -1686,7 +1715,6 @@ static void jl_init_serializer2(int for_serialize)
htable_new(&symbol_table, 0);
htable_new(&fptr_to_id, sizeof(id_to_fptrs) / sizeof(*id_to_fptrs));
htable_new(&backref_table, 0);
arraylist_new(&builtin_typenames, 0);
uintptr_t i;
for (i = 0; id_to_fptrs[i] != NULL; i++) {
ptrhash_put(&fptr_to_id, (void*)(uintptr_t)id_to_fptrs[i], (void*)(i + 2));
Expand All @@ -1704,7 +1732,6 @@ static void jl_cleanup_serializer2(void)
htable_reset(&fptr_to_id, 0);
htable_reset(&backref_table, 0);
arraylist_free(&deser_sym);
arraylist_free(&builtin_typenames);
}

#ifdef __cplusplus
Expand Down