Skip to content

Commit 3157245

Browse files
vtjnashKristofferC
authored andcommitted
trim: fix corrupt dispatch tables (#59519)
Fix #59507 (cherry picked from commit cfd4cfd)
1 parent de2f3f2 commit 3157245

File tree

2 files changed

+56
-58
lines changed

2 files changed

+56
-58
lines changed

src/gf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ static int8_t jl_cachearg_offset(void)
124124
/// ----- Insertion logic for special entries ----- ///
125125

126126

127-
static uint_t speccache_hash(size_t idx, jl_value_t *data)
127+
uint_t speccache_hash(size_t idx, jl_value_t *data)
128128
{
129129
jl_method_instance_t *ml = (jl_method_instance_t*)jl_svecref(data, idx); // This must always happen inside the lock
130130
jl_value_t *sig = ml->specTypes;

src/staticdata.c

Lines changed: 55 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2624,49 +2624,64 @@ static void jl_prune_binding_backedges(jl_array_t *backedges)
26242624
jl_array_del_end(backedges, n - ins);
26252625
}
26262626

2627-
26282627
uint_t bindingkey_hash(size_t idx, jl_value_t *data);
2628+
uint_t speccache_hash(size_t idx, jl_value_t *data);
26292629

2630-
static void jl_prune_module_bindings(jl_module_t * m) JL_GC_DISABLED
2630+
static void jl_prune_idset(_Atomic(jl_svec_t*) *pkeys, _Atomic(jl_genericmemory_t*) *pkeyset, uint_t (*key_hash)(size_t, jl_value_t*), jl_value_t *parent) JL_GC_DISABLED
26312631
{
2632-
jl_svec_t *bindings = jl_atomic_load_relaxed(&m->bindings);
2633-
size_t l = jl_svec_len(bindings), i;
2634-
arraylist_t bindings_list;
2635-
arraylist_new(&bindings_list, 0);
2632+
jl_svec_t *keys = jl_atomic_load_relaxed(pkeys);
2633+
size_t l = jl_svec_len(keys), i;
26362634
if (l == 0)
26372635
return;
2636+
arraylist_t keys_list;
2637+
arraylist_new(&keys_list, 0);
26382638
for (i = 0; i < l; i++) {
2639-
jl_value_t *ti = jl_svecref(bindings, i);
2640-
if (ti == jl_nothing)
2639+
jl_value_t *k = jl_svecref(keys, i);
2640+
if (k == jl_nothing)
26412641
continue;
2642-
jl_binding_t *ref = ((jl_binding_t*)ti);
2643-
if (ptrhash_get(&serialization_order, ref) != HT_NOTFOUND)
2644-
arraylist_push(&bindings_list, ref);
2645-
}
2646-
jl_genericmemory_t *bindingkeyset = jl_atomic_load_relaxed(&m->bindingkeyset);
2647-
_Atomic(jl_genericmemory_t*)bindingkeyset2;
2648-
jl_atomic_store_relaxed(&bindingkeyset2, (jl_genericmemory_t*)jl_an_empty_memory_any);
2649-
jl_svec_t *bindings2 = jl_alloc_svec_uninit(bindings_list.len);
2650-
for (i = 0; i < bindings_list.len; i++) {
2651-
jl_binding_t *ref = (jl_binding_t*)bindings_list.items[i];
2652-
jl_svecset(bindings2, i, ref);
2653-
jl_smallintset_insert(&bindingkeyset2, (jl_value_t*)m, bindingkey_hash, i, (jl_value_t*)bindings2);
2654-
}
2655-
void *idx = ptrhash_get(&serialization_order, bindings);
2642+
if (ptrhash_get(&serialization_order, k) != HT_NOTFOUND)
2643+
arraylist_push(&keys_list, k);
2644+
}
2645+
jl_genericmemory_t *keyset = jl_atomic_load_relaxed(pkeyset);
2646+
_Atomic(jl_genericmemory_t*)keyset2;
2647+
jl_atomic_store_relaxed(&keyset2, (jl_genericmemory_t*)jl_an_empty_memory_any);
2648+
jl_svec_t *keys2 = jl_alloc_svec_uninit(keys_list.len);
2649+
for (i = 0; i < keys_list.len; i++) {
2650+
jl_binding_t *ref = (jl_binding_t*)keys_list.items[i];
2651+
jl_svecset(keys2, i, ref);
2652+
jl_smallintset_insert(&keyset2, parent, key_hash, i, (jl_value_t*)keys2);
2653+
}
2654+
void *idx = ptrhash_get(&serialization_order, keys);
26562655
assert(idx != HT_NOTFOUND && idx != (void*)(uintptr_t)-1);
2657-
assert(serialization_queue.items[(char*)idx - 1 - (char*)HT_NOTFOUND] == bindings);
2658-
ptrhash_put(&serialization_order, bindings2, idx);
2659-
serialization_queue.items[(char*)idx - 1 - (char*)HT_NOTFOUND] = bindings2;
2656+
assert(serialization_queue.items[(char*)idx - 1 - (char*)HT_NOTFOUND] == keys);
2657+
ptrhash_put(&serialization_order, keys2, idx);
2658+
serialization_queue.items[(char*)idx - 1 - (char*)HT_NOTFOUND] = keys2;
26602659

2661-
idx = ptrhash_get(&serialization_order, bindingkeyset);
2660+
idx = ptrhash_get(&serialization_order, keyset);
26622661
assert(idx != HT_NOTFOUND && idx != (void*)(uintptr_t)-1);
2663-
assert(serialization_queue.items[(char*)idx - 1 - (char*)HT_NOTFOUND] == bindingkeyset);
2664-
ptrhash_put(&serialization_order, jl_atomic_load_relaxed(&bindingkeyset2), idx);
2665-
serialization_queue.items[(char*)idx - 1 - (char*)HT_NOTFOUND] = jl_atomic_load_relaxed(&bindingkeyset2);
2666-
jl_atomic_store_relaxed(&m->bindings, bindings2);
2667-
jl_atomic_store_relaxed(&m->bindingkeyset, jl_atomic_load_relaxed(&bindingkeyset2));
2668-
jl_gc_wb(m, bindings2);
2669-
jl_gc_wb(m, jl_atomic_load_relaxed(&bindingkeyset2));
2662+
assert(serialization_queue.items[(char*)idx - 1 - (char*)HT_NOTFOUND] == keyset);
2663+
ptrhash_put(&serialization_order, jl_atomic_load_relaxed(&keyset2), idx);
2664+
serialization_queue.items[(char*)idx - 1 - (char*)HT_NOTFOUND] = jl_atomic_load_relaxed(&keyset2);
2665+
jl_atomic_store_relaxed(pkeys, keys2);
2666+
jl_gc_wb(parent, keys2);
2667+
jl_atomic_store_relaxed(pkeyset, jl_atomic_load_relaxed(&keyset2));
2668+
jl_gc_wb(parent, jl_atomic_load_relaxed(&keyset2));
2669+
}
2670+
2671+
static void jl_prune_method_specializations(jl_method_t *m) JL_GC_DISABLED
2672+
{
2673+
jl_value_t *specializations_ = jl_atomic_load_relaxed(&m->specializations);
2674+
if (!jl_is_svec(specializations_)) {
2675+
if (ptrhash_get(&serialization_order, specializations_) == HT_NOTFOUND)
2676+
record_field_change((jl_value_t **)&m->specializations, (jl_value_t*)jl_emptysvec);
2677+
return;
2678+
}
2679+
jl_prune_idset((_Atomic(jl_svec_t*)*)&m->specializations, &m->speckeyset, speccache_hash, (jl_value_t*)m);
2680+
}
2681+
2682+
static void jl_prune_module_bindings(jl_module_t *m) JL_GC_DISABLED
2683+
{
2684+
jl_prune_idset(&m->bindings, &m->bindingkeyset, bindingkey_hash, (jl_value_t*)m);
26702685
}
26712686

26722687
static void strip_slotnames(jl_array_t *slotnames, int n)
@@ -3231,32 +3246,15 @@ static void jl_save_system_image_to_stream(ios_t *f, jl_array_t *mod_array,
32313246
// step 1.5: prune (garbage collect) some special weak references known caches
32323247
for (i = 0; i < serialization_queue.len; i++) {
32333248
jl_value_t *v = (jl_value_t*)serialization_queue.items[i];
3234-
if (jl_options.trim) {
3235-
if (jl_is_method(v)) {
3236-
jl_method_t *m = (jl_method_t*)v;
3237-
jl_value_t *specializations_ = jl_atomic_load_relaxed(&m->specializations);
3238-
if (!jl_is_svec(specializations_)) {
3239-
if (ptrhash_get(&serialization_order, specializations_) == HT_NOTFOUND)
3240-
record_field_change((jl_value_t **)&m->specializations, (jl_value_t*)jl_emptysvec);
3241-
continue;
3242-
}
3243-
3244-
jl_svec_t *specializations = (jl_svec_t *)specializations_;
3245-
size_t l = jl_svec_len(specializations), i;
3246-
for (i = 0; i < l; i++) {
3247-
jl_value_t *mi = jl_svecref(specializations, i);
3248-
if (mi == jl_nothing)
3249-
continue;
3250-
if (ptrhash_get(&serialization_order, mi) == HT_NOTFOUND)
3251-
jl_svecset(specializations, i, jl_nothing);
3252-
}
3253-
}
3254-
else if (jl_is_module(v)) {
3249+
if (jl_is_method(v)) {
3250+
if (jl_options.trim)
3251+
jl_prune_method_specializations((jl_method_t*)v);
3252+
}
3253+
else if (jl_is_module(v)) {
3254+
if (jl_options.trim)
32553255
jl_prune_module_bindings((jl_module_t*)v);
3256-
}
32573256
}
3258-
// Not else
3259-
if (jl_is_typename(v)) {
3257+
else if (jl_is_typename(v)) {
32603258
jl_typename_t *tn = (jl_typename_t*)v;
32613259
jl_atomic_store_relaxed(&tn->cache,
32623260
jl_prune_type_cache_hash(jl_atomic_load_relaxed(&tn->cache)));

0 commit comments

Comments
 (0)