diff options
author | Fabrice Bellard <fabrice@bellard.org> | 2025-04-07 11:44:28 +0200 |
---|---|---|
committer | Fabrice Bellard <fabrice@bellard.org> | 2025-04-07 11:44:28 +0200 |
commit | c805d4f7846456bf6dade8b4f4258c85cbd178c3 (patch) | |
tree | 4d85242612a61dc26c84267519f085b6658ed1a8 | |
parent | 19431019d55340f153642440a632a3d8967bc296 (diff) | |
download | quickjs-c805d4f7846456bf6dade8b4f4258c85cbd178c3.tar.gz quickjs-c805d4f7846456bf6dade8b4f4258c85cbd178c3.zip |
fixed weakmap gc (#398)
-rw-r--r-- | quickjs.c | 19 |
1 files changed, 19 insertions, 0 deletions
@@ -46992,10 +46992,29 @@ static void map_delete_weakrefs(JSRuntime *rt, JSWeakRefHeader *wh) { JSMapState *s = container_of(wh, JSMapState, weakref_header); struct list_head *el, *el1; + JSMapRecord *mr1, **pmr; + uint32_t h; list_for_each_safe(el, el1, &s->records) { JSMapRecord *mr = list_entry(el, JSMapRecord, link); if (!js_weakref_is_live(mr->key)) { + + /* even if key is not live it can be hashed as a pointer */ + h = map_hash_key(mr->key) & (s->hash_size - 1); + pmr = &s->hash_table[h]; + for(;;) { + mr1 = *pmr; + /* the entry may already be removed from the hash + table if the map was resized */ + if (mr1 == NULL) + goto done; + if (mr1 == mr) + break; + pmr = &mr1->hash_next; + } + /* remove from the hash table */ + *pmr = mr1->hash_next; + done: map_delete_record(rt, s, mr); } } |