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

Reply via email to