On Fri Jul 14 12:00:19 2023 +0000, Gabriel Ivăncescu wrote:
I think the easiest way to fix this in all cases (complicated cyclic refs) is to treat WeakMaps entries as *extensions* to the key object, rather than as part of the WeakMap itself. So when traversing in the GC, traverse the entry values as part of the key object's traversal (like we traverse its props, prototype, etc), as if they were linked from the key object. Do **not** traverse them during the WeakMap traversal itself, because the WeakMap shouldn't hold a ref to the entry values, it's the key object who should, basically (we still add a ref when setting the entry, but the ref is held by the key object!). After all, WeakMap entries cannot be accessed without the key, so it makes sense to "move" the ref to the key itself. When unlinking the key, as an optimization, nothing special needs to be done, because we can remove the entry when fixing the weak refs later if the keys are gc_marked (the mark means the key was unlinked already, and so should its "extensions" from the WeakMaps, since we haven't). What do you think?
Treating them as an object extension only would not handle things like: ``` var m = new WeakMap(); m.set(key, m); m = null; ```
We could instead traverse map entry value in step 2 of GC only when it's marked twice: once from the map and once from object itself. Unless I'm missing something, this should get all cases right.