Skip to content

Commit 798a81a

Browse files
committed
restore type cache pruning in sysimage saving
1 parent 109a1e1 commit 798a81a

File tree

4 files changed

+67
-23
lines changed

4 files changed

+67
-23
lines changed

src/dump.c

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ static jl_value_t *jl_idtable_type = NULL;
7878
static jl_typename_t *jl_idtable_typename = NULL;
7979
static jl_value_t *jl_bigint_type = NULL;
8080
static int gmp_limb_size = 0;
81-
static arraylist_t builtin_typenames;
8281

8382
static void write_uint64(ios_t *s, uint64_t i) JL_NOTSAFEPOINT
8483
{
@@ -2627,17 +2626,6 @@ void jl_init_serializer(void)
26272626
i += 1;
26282627
}
26292628
assert(i <= 256);
2630-
2631-
arraylist_new(&builtin_typenames, 0);
2632-
arraylist_push(&builtin_typenames, jl_array_typename);
2633-
arraylist_push(&builtin_typenames, ((jl_datatype_t*)jl_ref_type->body)->name);
2634-
arraylist_push(&builtin_typenames, jl_pointer_typename);
2635-
arraylist_push(&builtin_typenames, jl_type_typename);
2636-
arraylist_push(&builtin_typenames, ((jl_datatype_t*)jl_unwrap_unionall((jl_value_t*)jl_abstractarray_type))->name);
2637-
arraylist_push(&builtin_typenames, ((jl_datatype_t*)jl_unwrap_unionall((jl_value_t*)jl_densearray_type))->name);
2638-
arraylist_push(&builtin_typenames, jl_tuple_typename);
2639-
arraylist_push(&builtin_typenames, jl_vararg_typename);
2640-
arraylist_push(&builtin_typenames, jl_namedtuple_typename);
26412629
}
26422630

26432631
#ifdef __cplusplus

src/jltypes.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,13 @@ static jl_svec_t *cache_rehash_set(jl_svec_t *a, size_t newsz)
808808
}
809809
}
810810

811+
void jl_rehash_type_cache(jl_typename_t *name)
812+
{
813+
jl_svec_t *newa = cache_rehash_set(name->cache, jl_svec_len(name->cache));
814+
jl_atomic_store_release(&name->cache, newa);
815+
jl_gc_wb(name, newa);
816+
}
817+
811818
static void cache_insert_type_linear(jl_datatype_t *type, ssize_t insert_at)
812819
{
813820
jl_svec_t *cache = type->name->linearcache;

src/julia_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,7 @@ jl_value_t *jl_wrap_vararg(jl_value_t *t, jl_value_t *n);
471471
void jl_reinstantiate_inner_types(jl_datatype_t *t);
472472
jl_datatype_t *jl_lookup_cache_type_(jl_datatype_t *type);
473473
void jl_cache_type_(jl_datatype_t *type);
474+
void jl_rehash_type_cache(jl_typename_t *name);
474475
void jl_assign_bits(void *dest, jl_value_t *bits) JL_NOTSAFEPOINT;
475476
void set_nth_field(jl_datatype_t *st, void *v, size_t i, jl_value_t *rhs) JL_NOTSAFEPOINT;
476477
jl_expr_t *jl_exprn(jl_sym_t *head, size_t n);

src/staticdata.c

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ static int backref_table_numel;
101101
static arraylist_t layout_table;
102102
static arraylist_t builtin_typenames;
103103

104+
// # of typenames whose caches are treated as weak references
105+
#define NUM_BUILTIN_TYPENAMES 9
106+
104107
// list of (size_t pos, (void *f)(jl_value_t*)) entries
105108
// for the serializer to mark values in need of rework by function f
106109
// during deserialization later
@@ -1304,7 +1307,7 @@ static void jl_prune_type_cache(jl_svec_t *cache)
13041307
for (i = 0; i < l; i++) {
13051308
jl_value_t *ti = jl_svecref(cache, i);
13061309
if (ti == NULL)
1307-
break;
1310+
continue;
13081311
if (ptrhash_get(&backref_table, ti) != HT_NOTFOUND || jl_get_llvm_gv(native_functions, ti) != 0)
13091312
jl_svecset(cache, ins++, ti);
13101313
else if (jl_is_datatype(ti)) {
@@ -1316,6 +1319,9 @@ static void jl_prune_type_cache(jl_svec_t *cache)
13161319
}
13171320
if (i > ins) {
13181321
memset(&jl_svec_data(cache)[ins], 0, (i - ins) * sizeof(jl_value_t*));
1322+
while (l > 0 && l/2 >= ins)
1323+
l = l/2;
1324+
jl_svec_len(cache) = l == 0 ? 1 : l;
13191325
}
13201326
}
13211327

@@ -1324,6 +1330,7 @@ static void jl_prune_type_cache(jl_svec_t *cache)
13241330

13251331
static void jl_init_serializer2(int);
13261332
static void jl_cleanup_serializer2(void);
1333+
static void init_builtin_typenames(void);
13271334

13281335
static void jl_save_system_image_to_stream(ios_t *f)
13291336
{
@@ -1353,6 +1360,8 @@ static void jl_save_system_image_to_stream(ios_t *f)
13531360
s.ptls = jl_get_ptls_states();
13541361
arraylist_new(&s.relocs_list, 0);
13551362
arraylist_new(&s.gctags_list, 0);
1363+
arraylist_t typecaches;
1364+
arraylist_new(&typecaches, 0);
13561365

13571366
// empty!(Core.ARGS)
13581367
if (jl_core_module != NULL) {
@@ -1372,19 +1381,22 @@ static void jl_save_system_image_to_stream(ios_t *f)
13721381

13731382
{ // step 1: record values (recursively) that need to go in the image
13741383
size_t i;
1384+
// temporarily un-reference builtin type caches to make them effectively weak references
1385+
for (i = 0; i < builtin_typenames.len; i++) {
1386+
jl_typename_t *tn = (jl_typename_t*)builtin_typenames.items[i];
1387+
arraylist_push(&typecaches, tn->cache);
1388+
tn->cache = NULL;
1389+
arraylist_push(&typecaches, tn->linearcache);
1390+
tn->linearcache = NULL;
1391+
}
13751392
for (i = 0; tags[i] != NULL; i++) {
13761393
jl_value_t *tag = *tags[i];
13771394
jl_serialize_value(&s, tag);
13781395
}
1379-
for (i = 0; i < builtin_typenames.len; i++) {
1380-
jl_typename_t *tn = (jl_typename_t*)builtin_typenames.items[i];
1381-
jl_prune_type_cache(tn->cache);
1382-
jl_prune_type_cache(tn->linearcache);
1383-
}
1384-
for (i = 0; i < builtin_typenames.len; i++) {
1385-
jl_typename_t *tn = (jl_typename_t*)builtin_typenames.items[i];
1386-
jl_serialize_value(&s, tn->cache);
1387-
jl_serialize_value(&s, tn->linearcache);
1396+
for (i = 0; i < typecaches.len; i++) {
1397+
jl_svec_t *sv = (jl_svec_t*)typecaches.items[i];
1398+
jl_prune_type_cache(sv);
1399+
jl_serialize_value(&s, sv);
13881400
}
13891401
}
13901402

@@ -1437,6 +1449,13 @@ static void jl_save_system_image_to_stream(ios_t *f)
14371449
jl_write_value(&s, tag);
14381450
}
14391451
jl_write_value(&s, s.ptls->root_task->tls);
1452+
for (i = 0; i < typecaches.len;) {
1453+
jl_typename_t *tn = (jl_typename_t*)builtin_typenames.items[i/2];
1454+
tn->cache = (jl_svec_t*)typecaches.items[i++];
1455+
jl_write_value(&s, tn->cache);
1456+
tn->linearcache = (jl_svec_t*)typecaches.items[i++];
1457+
jl_write_value(&s, tn->linearcache);
1458+
}
14401459
write_uint32(f, jl_get_gs_ctr());
14411460
write_uint32(f, jl_world_counter);
14421461
write_uint32(f, jl_typeinf_world);
@@ -1449,6 +1468,7 @@ static void jl_save_system_image_to_stream(ios_t *f)
14491468
arraylist_free(&ccallable_list);
14501469
arraylist_free(&s.relocs_list);
14511470
arraylist_free(&s.gctags_list);
1471+
arraylist_free(&typecaches);
14521472
jl_cleanup_serializer2();
14531473

14541474
jl_gc_enable(en);
@@ -1561,6 +1581,11 @@ static void jl_restore_system_image_from_stream(ios_t *f)
15611581
s.ptls->root_task = (jl_task_t*)jl_gc_alloc(s.ptls, sizeof(jl_task_t), jl_task_type);
15621582
memset(s.ptls->root_task, 0, sizeof(jl_task_t));
15631583
s.ptls->root_task->tls = jl_read_value(&s);
1584+
arraylist_t typecaches;
1585+
arraylist_new(&typecaches, 0);
1586+
for (i = 0; i < NUM_BUILTIN_TYPENAMES*2; i++) {
1587+
arraylist_push(&typecaches, jl_read_value(&s));
1588+
}
15641589
jl_init_int32_int64_cache();
15651590
jl_init_box_caches();
15661591

@@ -1591,6 +1616,13 @@ static void jl_restore_system_image_from_stream(ios_t *f)
15911616
s.s = NULL;
15921617

15931618
s.s = f;
1619+
init_builtin_typenames();
1620+
for (i = 0; i < builtin_typenames.len; i++) {
1621+
jl_typename_t *tn = (jl_typename_t*)builtin_typenames.items[i];
1622+
tn->cache = (jl_svec_t*)typecaches.items[i*2];
1623+
tn->linearcache = (jl_svec_t*)typecaches.items[i*2 + 1];
1624+
jl_rehash_type_cache(tn);
1625+
}
15941626
// reinit items except ccallables
15951627
jl_finalize_deserializer(&s);
15961628
s.s = NULL;
@@ -1623,6 +1655,7 @@ static void jl_restore_system_image_from_stream(ios_t *f)
16231655
ios_close(&fptr_record);
16241656
ios_close(&sysimg);
16251657
s.s = NULL;
1658+
arraylist_free(&typecaches);
16261659

16271660
jl_gc_reset_alloc_count();
16281661
jl_gc_enable(en);
@@ -1674,13 +1707,28 @@ JL_DLLEXPORT void jl_restore_system_image_data(const char *buf, size_t len)
16741707

16751708
// --- init ---
16761709

1710+
static void init_builtin_typenames(void)
1711+
{
1712+
arraylist_new(&builtin_typenames, NUM_BUILTIN_TYPENAMES);
1713+
arraylist_push(&builtin_typenames, jl_array_typename);
1714+
arraylist_push(&builtin_typenames, ((jl_datatype_t*)jl_ref_type->body)->name);
1715+
arraylist_push(&builtin_typenames, jl_pointer_typename);
1716+
arraylist_push(&builtin_typenames, jl_type_typename);
1717+
arraylist_push(&builtin_typenames, ((jl_datatype_t*)jl_unwrap_unionall((jl_value_t*)jl_abstractarray_type))->name);
1718+
arraylist_push(&builtin_typenames, ((jl_datatype_t*)jl_unwrap_unionall((jl_value_t*)jl_densearray_type))->name);
1719+
arraylist_push(&builtin_typenames, jl_tuple_typename);
1720+
arraylist_push(&builtin_typenames, jl_vararg_typename);
1721+
arraylist_push(&builtin_typenames, jl_namedtuple_typename);
1722+
assert(builtin_typenames.len == NUM_BUILTIN_TYPENAMES);
1723+
}
1724+
16771725
static void jl_init_serializer2(int for_serialize)
16781726
{
16791727
if (for_serialize) {
16801728
htable_new(&symbol_table, 0);
16811729
htable_new(&fptr_to_id, sizeof(id_to_fptrs) / sizeof(*id_to_fptrs));
16821730
htable_new(&backref_table, 0);
1683-
arraylist_new(&builtin_typenames, 0);
1731+
init_builtin_typenames();
16841732
uintptr_t i;
16851733
for (i = 0; id_to_fptrs[i] != NULL; i++) {
16861734
ptrhash_put(&fptr_to_id, (void*)(uintptr_t)id_to_fptrs[i], (void*)(i + 2));

0 commit comments

Comments
 (0)