summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabrice Bellard <fabrice@bellard.org>2025-04-07 11:44:28 +0200
committerFabrice Bellard <fabrice@bellard.org>2025-04-07 11:44:28 +0200
commitc805d4f7846456bf6dade8b4f4258c85cbd178c3 (patch)
tree4d85242612a61dc26c84267519f085b6658ed1a8
parent19431019d55340f153642440a632a3d8967bc296 (diff)
downloadquickjs-c805d4f7846456bf6dade8b4f4258c85cbd178c3.tar.gz
quickjs-c805d4f7846456bf6dade8b4f4258c85cbd178c3.zip
fixed weakmap gc (#398)
-rw-r--r--quickjs.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/quickjs.c b/quickjs.c
index 1df5eda..6e18ec1 100644
--- a/quickjs.c
+++ b/quickjs.c
@@ -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);
}
}