@@ -1425,30 +1425,33 @@ static void jl_finalize_deserializer(jl_serializer_state *s) JL_GC_DISABLED
1425
1425
1426
1426
1427
1427
1428
- // --- helper functions ---
1429
-
1430
- // remove cached types not referenced in the stream
1431
- static int keep_type_cache_entry (jl_value_t * ti )
1428
+ static void jl_scan_type_cache_gv (jl_serializer_state * s , jl_svec_t * cache )
1432
1429
{
1433
- if (ptrhash_get (& backref_table , ti ) != HT_NOTFOUND || jl_get_llvm_gv (native_functions , ti ) != 0 )
1434
- return 1 ;
1435
- if (jl_is_datatype (ti )) {
1436
- jl_value_t * singleton = ((jl_datatype_t * )ti )-> instance ;
1437
- if (singleton && (ptrhash_get (& backref_table , singleton ) != HT_NOTFOUND ||
1438
- jl_get_llvm_gv (native_functions , singleton ) != 0 ))
1439
- return 1 ;
1440
- }
1441
- return 0 ;
1430
+ size_t l = jl_svec_len (cache ), i ;
1431
+ for (i = 0 ; i < l ; i ++ ) {
1432
+ jl_value_t * ti = jl_svecref (cache , i );
1433
+ if (ti == NULL || ti == jl_nothing )
1434
+ continue ;
1435
+ if (jl_get_llvm_gv (native_functions , ti )) {
1436
+ jl_serialize_value (s , ti );
1437
+ }
1438
+ else if (jl_is_datatype (ti )) {
1439
+ jl_value_t * singleton = ((jl_datatype_t * )ti )-> instance ;
1440
+ if (singleton && jl_get_llvm_gv (native_functions , singleton ))
1441
+ jl_serialize_value (s , ti );
1442
+ }
1443
+ }
1442
1444
}
1443
1445
1446
+ // remove cached types not referenced in the stream
1444
1447
static void jl_prune_type_cache_hash (jl_svec_t * cache )
1445
1448
{
1446
1449
size_t l = jl_svec_len (cache ), i ;
1447
1450
for (i = 0 ; i < l ; i ++ ) {
1448
1451
jl_value_t * ti = jl_svecref (cache , i );
1449
1452
if (ti == NULL || ti == jl_nothing )
1450
1453
continue ;
1451
- if (! keep_type_cache_entry ( ti ))
1454
+ if (ptrhash_get ( & backref_table , ti ) == HT_NOTFOUND )
1452
1455
jl_svecset (cache , i , jl_nothing );
1453
1456
}
1454
1457
}
@@ -1460,7 +1463,7 @@ static void jl_prune_type_cache_linear(jl_svec_t *cache)
1460
1463
jl_value_t * ti = jl_svecref (cache , i );
1461
1464
if (ti == NULL )
1462
1465
break ;
1463
- if (keep_type_cache_entry ( ti ))
1466
+ if (ptrhash_get ( & backref_table , ti ) != HT_NOTFOUND )
1464
1467
jl_svecset (cache , ins ++ , ti );
1465
1468
}
1466
1469
if (i > ins ) {
@@ -1526,14 +1529,28 @@ static void jl_save_system_image_to_stream(ios_t *f) JL_GC_DISABLED
1526
1529
jl_value_t * tag = * tags [i ];
1527
1530
jl_serialize_value (& s , tag );
1528
1531
}
1529
- // prune unused entries from built-in type caches
1532
+ // step 1.1: check for values only found in the generated code
1533
+ arraylist_t typenames ;
1534
+ arraylist_new (& typenames , 0 );
1530
1535
for (i = 0 ; i < backref_table .size ; i += 2 ) {
1531
1536
jl_typename_t * tn = (jl_typename_t * )backref_table .table [i ];
1532
1537
if (tn == HT_NOTFOUND || !jl_is_typename (tn ))
1533
1538
continue ;
1539
+ arraylist_push (& typenames , tn );
1540
+ }
1541
+ for (i = 0 ; i < typenames .len ; i ++ ) {
1542
+ jl_typename_t * tn = (jl_typename_t * )typenames .items [i ];
1543
+ jl_scan_type_cache_gv (& s , tn -> cache );
1544
+ jl_scan_type_cache_gv (& s , tn -> linearcache );
1545
+ }
1546
+ // step 1.2: prune (garbage collect) some special weak references from
1547
+ // built-in type caches
1548
+ for (i = 0 ; i < typenames .len ; i ++ ) {
1549
+ jl_typename_t * tn = (jl_typename_t * )typenames .items [i ];
1534
1550
jl_prune_type_cache_hash (tn -> cache );
1535
1551
jl_prune_type_cache_linear (tn -> linearcache );
1536
1552
}
1553
+ arraylist_free (& typenames );
1537
1554
}
1538
1555
1539
1556
{ // step 2: build all the sysimg sections
0 commit comments