Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 5fa36a13d44e90e3d2f491e398e4465614fdf10a
https://github.com/WebKit/WebKit/commit/5fa36a13d44e90e3d2f491e398e4465614fdf10a
Author: Dan Hecht <[email protected]>
Date: 2026-10-07 (Wed, 07 Oct 2026)
Changed paths:
M Source/JavaScriptCore/heap/Heap.cpp
M Source/JavaScriptCore/heap/HeapInlines.h
Log Message:
-----------
[JSC] Assert that Heap methods are only passed cells from that Heap
https://bugs.webkit.org/show_bug.cgi?id=326529
rdar://189320586
Reviewed by Yijia Huang.
Once VMs can share objects, a VM's code can hold a cell that its own heap did
not allocate, and may pass it to its own heap's methods. Several Heap methods
answer questions about the cell they are given using their own heap's state,
which is wrong for a shared cell from another heap:
- isMarked() reads the cell's mark bits against this heap's marking version.
A collection of several heaps could give them all one version, but a later
collection of just one of them advances only that heap's, after which
isMarked() reads another heap's live cell as dead.
- addToRememberedSet(), which every write barrier's slow path reaches, puts
the cell in this heap's remembered set. That is where a shared cell should
go, so that no other heap's set needs synchronizing, but the code there
assumes the cell is marked only by this heap's collections and that no
other thread writes to it. A FIXME there says so.
- reportExtraMemoryAllocatedSlowCase() charges the extra memory to this heap
rather than to the heap whose cell owns it. It then decides whether marking
will count the memory, from this heap's barrier threshold, fence flag and
isMarked(), and if not adds it to this heap's retained extra memory. Those
describe this heap's collection, not the cell's: while the cell's heap is
marking and this heap is not, the check skips the fence it needs, may read a
stale cell state, and counts the memory as retained by the wrong heap.
- addReference() records the cell as an ArrayBuffer's owner in this heap's
set, which is pruned with this heap's isMarked().
- addFinalizer() puts the handle in the cell's heap but names this heap's
finalizer owner, which the cell's heap calls when it sweeps the cell,
possibly after this heap is gone.
- protect() and unprotect() root the cell in this heap's protected set, which
a collection of the cell's own heap alone would not see.
Nothing passes another heap's cell today. Assert that each of these is given
one of its own heap's cells, to help ensure these invariants are not silently
violated.
* Source/JavaScriptCore/heap/Heap.cpp:
(JSC::Heap::reportExtraMemoryAllocatedSlowCase):
(JSC::Heap::protect):
(JSC::Heap::unprotect):
(JSC::Heap::addReference):
(JSC::Heap::addToRememberedSet):
(JSC::Heap::clearConcurrentRetainedDataIfPossible):
* Source/JavaScriptCore/heap/HeapInlines.h:
(JSC::Heap::isMarked):
Canonical link: https://commits.webkit.org/322980@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications