Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
REGRESSION(265596@main) VM::performOpportunisticallyScheduledTasks() …
…should hold the JSLock when calling the sweeper. https://bugs.webkit.org/show_bug.cgi?id=259007 rdar://111505837 Reviewed by Justin Michaud. This makes it consistent with the incremental sweeper that currently fires off a timer, which also hold the JSLock while sweeping. Not holding the JSLock while sweeping has resulted in the RELEASE_ASSERT in the JSLock::DropAllLocks constructor failing. Here's how it happens: 1. For a normal timer triggered sweep, we go through JSRunLoopTimer::timerDidFire() which acquires the JSLock, and holds it while sweeping. 2. For an idle triggered VM::performOpportunisticallyScheduledTasks(), it does NOT hold the JSLock while sweeping. 3. While sweeping, we may call back into some ObjC code that wraps a JSValue. 4. Releasing that JSValue for the sweep, requires acquiring the JSLock. 5. On releasing that JSLock, if it’s the outermost lock (i.e. not a re-entrant lock), then the JSLock unlocking code will call Heap::releaseDelayedReleasedObjects(). 6. Heap::releaseDelayedReleasedObjects() uses DropAllLocks, which fails the RELEASE_ASSERT because we’re currently holding the JSLock and doing sweeping. 7. In contrast, for the normal timer triggered sweep, the outer most lock of the JSLock is JSRunLoopTimer::timerDidFire(). Hence, Heap::releaseDelayedReleasedObjects() won’t be called, and we won’t encounter this issue. The fix is simply to acquire and hold the JSLock while sweeping in VM::performOpportunisticallyScheduledTasks(). * Source/JavaScriptCore/runtime/JSLock.cpp: (JSC::JSLock::DropAllLocks::DropAllLocks): * Source/JavaScriptCore/runtime/VM.cpp: (JSC::VM::performOpportunisticallyScheduledTasks): Canonical link: https://commits.webkit.org/265871@main
- Loading branch information