Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 1e4577ba8de434bc8942b01baf6b1d65ba967ab1
      
https://github.com/WebKit/WebKit/commit/1e4577ba8de434bc8942b01baf6b1d65ba967ab1
  Author: Yijia Huang <yijia_hu...@apple.com>
  Date:   2024-06-08 (Sat, 08 Jun 2024)

  Changed paths:
    M Source/JavaScriptCore/heap/WeakInlines.h
    M Source/JavaScriptCore/runtime/ArrayBuffer.cpp
    M Source/JavaScriptCore/runtime/DeferredWorkTimer.cpp
    M Source/JavaScriptCore/runtime/DeferredWorkTimer.h
    M Source/JavaScriptCore/runtime/JSGlobalObject.cpp
    M Source/JavaScriptCore/runtime/JSGlobalObject.h
    M Source/JavaScriptCore/runtime/VM.cpp
    M Source/JavaScriptCore/runtime/WaiterListManager.cpp
    M Source/JavaScriptCore/runtime/WaiterListManager.h
    M Source/JavaScriptCore/wasm/WasmStreamingCompiler.cpp
    M Source/JavaScriptCore/wasm/js/JSWebAssembly.cpp

  Log Message:
  -----------
  [JSC] Fix Atomics.waitAsync by using weak references in JSC::DeferredWorkTimer
https://bugs.webkit.org/show_bug.cgi?id=272896
rdar://126690921

Reviewed by Yusuke Suzuki.

Previously, we introduced JSC::DeferredWorkTimer by keeping the task related
dependencies and environment alive with strong references. This works fine
until Atomics.waitAsync is introduced. Consider a scenario that an 
Atomics.waitAsync
registered in the main thread with infinity timeout is never be resolved in the
runtime. At some point, the corresponding JSGlobalObject is no longer needed.
But the JSGlobalObject cannot be collected due to the previous registered
Atomics.waitAsync's JSPromise is strongly referenced and queued in the
DeferredWorkTimer.

To fix this issue, we can transfer the liveness responsibility from the
DeferredWorkTimer::TicketData to the target's JSGlobalObject. And this is
how it works. Given the graph as shown below:

            VM <----------------------------
            ^                              |
            |                              |
        JSGlobalObject_0      ----> JSGlobalObject_n -----
            ^                 |            ^             |
            |                 |            |             |
SharedArrayBufferContents -----            | S           | S
            ^                              |             |
            |                       W      |             |
            Waiter ----> TicketData -----> Target <------|
                            |                            |
                            |  W                         |
                            ------> Dependencies <--------

1. The JSGlobalObject_0 and JSGlobalObject_n may or may not be the same object,
   which is dependent on the VM.
2. The SharedArrayBufferContents is dependent on the multiple JSGlobalObjects.
3. The Waiter is dependent on the SharedArrayBufferContents.
4. The Waiter has a TicketData used to schedule a task to DeferredWorkTimer.
5. The TicketData replies on a Target and its corresponding Dependencies to 
complete the task.
6. The TicketData has weak references to the Target and Dependencies.
7. The Target's JSGlobalObject_n holds the strong references to the Target and 
Dependencies.

Then, we should do:
A. If JSGlobalObject_n is alive, then it should clear those strong references 
once the
   Waiter done the task.
B. If JSGlobalObject_n is dead, then it should clear the corresponding waiters 
first and
   then clear the other TicketDatas associating to it.

If no others are referencing JSGlobalObject_n and Target, GC would consider the 
strong reference
cycle in Target -> JSGlobalObject_n -> Target as dead status. Then, they are 
available
for recycling.

* Source/JavaScriptCore/heap/WeakInlines.h:
(JSC::operator==):
* Source/JavaScriptCore/runtime/DeferredWorkTimer.cpp:
(JSC::DeferredWorkTimer::TicketData::TicketData):
(JSC::DeferredWorkTimer::addPendingWork):
* Source/JavaScriptCore/runtime/DeferredWorkTimer.h:
* Source/JavaScriptCore/runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::visitChildrenImpl):
* Source/JavaScriptCore/runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::addObjectsForDeferredTaskTimer):
* Source/JavaScriptCore/wasm/WasmStreamingCompiler.cpp:
(JSC::Wasm::StreamingCompiler::StreamingCompiler):
* Source/JavaScriptCore/wasm/js/JSWebAssembly.cpp:
(JSC::JSWebAssembly::webAssemblyModuleValidateAsync):
(JSC::instantiate):
(JSC::compileAndInstantiate):

Canonical link: https://commits.webkit.org/279852@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to