On Mon Feb 16 21:53:33 2026 +0000, Jacek Caban wrote:
I do not see how we can know that J may be treated that way. Consider another case: A -> J -> B -> J, where A has an external reference, so it can't be collected. According to your description, J is not a root (or is it?). The GC would mark it as gray, and if J does not participate as alive in the CC, the CC might release B, which is obviously incorrect. J doesn't have to be a root, it has to be "reachable" from a root (i.e. it traverses from the root and marks them somehow, rest of JS objects are marked gray). But let's focus where J is not reachable from any root. Even if J is not reachable from any root and the GC consequently marks it as gray, B can't be collected because A isn't.
In other words, J is basically a "wrapped" XPCOM object that: 1) is treated as having no external refs to it *if* it is marked Gray. 2) is treated as having external refs otherwise. But now in your example it's not J that keeps it alive (because it has no external refs), it's A, because A has external refs to it, and reaches to B via J. Does that make sense? Let me know if I need to expand on it. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10045#note_129806