Title: [246565] trunk
Revision
246565
Author
keith_mil...@apple.com
Date
2019-06-18 14:02:19 -0700 (Tue, 18 Jun 2019)

Log Message

Add support for WeakRef
https://bugs.webkit.org/show_bug.cgi?id=198710

Reviewed by Yusuke Suzuki.

Source/_javascript_Core:

Add support for WeakRefs which are now at stage 3
(https://tc39.es/proposal-weakrefs). This patch doesn't add
support for FinalizationGroups, which I'll add in another patch.

Some other things of interest. Per the spec, we cannot collect a
weak refs target unless it has not been dereffed (or created) in
the current microtask turn. i.e. WeakRefs are only allowed to be
collected at the end of a drain of the Microtask queue. My
understanding for this behavior is to reduce implementation
dependence on specific GC behavior in a given browser.

We track if a WeakRef is retaining its target by using a version
number on each WeakRef as well as on the VM. Whenever a WeakRef is
derefed we update its version number to match the VM's then
WriteBarrier ourselves. During marking if the VM and the WeakRef
have the same version number, the target is visited.

* _javascript_Core.xcodeproj/project.pbxproj:
* Sources.txt:
* heap/Heap.cpp:
(JSC::Heap::finalizeUnconditionalFinalizers):
* jsc.cpp:
(GlobalObject::finishCreation):
(functionReleaseWeakRefs):
* runtime/CommonIdentifiers.h:
* runtime/JSGlobalObject.cpp:
* runtime/JSGlobalObject.h:
* runtime/JSWeakObjectRef.cpp: Added.
(JSC::JSWeakObjectRef::finishCreation):
(JSC::JSWeakObjectRef::visitChildren):
(JSC::JSWeakObjectRef::finalizeUnconditionally):
(JSC::JSWeakObjectRef::toStringName):
* runtime/JSWeakObjectRef.h: Added.
* runtime/VM.cpp:
(JSC::VM::drainMicrotasks):
* runtime/VM.h:
(JSC::VM::setOnEachMicrotaskTick):
(JSC::VM::finalizeSynchronousJSExecution):
(JSC::VM::currentWeakRefVersion const):
* runtime/WeakObjectRefConstructor.cpp: Added.
(JSC::WeakObjectRefConstructor::finishCreation):
(JSC::WeakObjectRefConstructor::WeakObjectRefConstructor):
(JSC::callWeakRef):
(JSC::constructWeakRef):
* runtime/WeakObjectRefConstructor.h: Added.
(JSC::WeakObjectRefConstructor::create):
(JSC::WeakObjectRefConstructor::createStructure):
* runtime/WeakObjectRefPrototype.cpp: Added.
(JSC::WeakObjectRefPrototype::finishCreation):
(JSC::getWeakRef):
(JSC::protoFuncWeakRefDeref):
* runtime/WeakObjectRefPrototype.h: Added.

Source/WebCore:

We need to make sure the Web MicrotaskQueue notifies the JSC VM
that it has finished performing a microtask checkpoint. This lets
the JSC VM know it is safe to collect referenced WeakRefs. Since
there was no way to get the VM from the MicrotaskQueue I have
added a RefPtr to the queue's VM. For the main thread the VM lives
forever so is fine. For workers the queue and the VM share an
owner so this shouldn't matter either.

Tests: js/weakref-async-is-collected.html
       js/weakref-eventually-collects-values.html
       js/weakref-microtasks-dont-collect.html
       js/weakref-weakset-consistency.html

* dom/Microtasks.cpp:
(WebCore::MicrotaskQueue::MicrotaskQueue):
(WebCore::MicrotaskQueue::mainThreadQueue):
(WebCore::MicrotaskQueue::performMicrotaskCheckpoint):
* dom/Microtasks.h:
(WebCore::MicrotaskQueue::vm const):
* workers/WorkerGlobalScope.cpp:
(WebCore::WorkerGlobalScope::WorkerGlobalScope):

LayoutTests:

Add an asyncTestStart that mirrors the asyncTestStart behavior in
the JSC cli.

* http/tests/resources/js-test-pre.js:
(asyncTestStart):
* js/script-tests/weakref-async-is-collected.js: Added.
(makeWeakRef):
(turnEventLoop):
(async.foo):
(async.test):
* js/script-tests/weakref-eventually-collects-values.js: Added.
(makeWeakRef):
(turnEventLoop):
(let.weakRefs.async.test):
* js/script-tests/weakref-microtasks-dont-collect.js: Added.
(asyncTestStart.1.makeWeakRef):
(turnEventLoop):
(async.foo):
(async.test):
* js/script-tests/weakref-weakset-consistency.js: Added.
(makeWeakRef):
(turnEventLoop):
(async.foo):
(async.test):
* js/weakref-async-is-collected-expected.txt: Added.
* js/weakref-async-is-collected.html: Added.
* js/weakref-eventually-collects-values-expected.txt: Added.
* js/weakref-eventually-collects-values.html: Added.
* js/weakref-microtasks-dont-collect-expected.txt: Added.
* js/weakref-microtasks-dont-collect.html: Added.
* js/weakref-weakset-consistency-expected.txt: Added.
* js/weakref-weakset-consistency.html: Added.
* resources/js-test-pre.js:
(asyncTestStart):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (246564 => 246565)


--- trunk/LayoutTests/ChangeLog	2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/LayoutTests/ChangeLog	2019-06-18 21:02:19 UTC (rev 246565)
@@ -1,3 +1,45 @@
+2019-06-18  Keith Miller  <keith_mil...@apple.com>
+
+        Add support for WeakRef
+        https://bugs.webkit.org/show_bug.cgi?id=198710
+
+        Reviewed by Yusuke Suzuki.
+
+        Add an asyncTestStart that mirrors the asyncTestStart behavior in
+        the JSC cli.
+
+        * http/tests/resources/js-test-pre.js:
+        (asyncTestStart):
+        * js/script-tests/weakref-async-is-collected.js: Added.
+        (makeWeakRef):
+        (turnEventLoop):
+        (async.foo):
+        (async.test):
+        * js/script-tests/weakref-eventually-collects-values.js: Added.
+        (makeWeakRef):
+        (turnEventLoop):
+        (let.weakRefs.async.test):
+        * js/script-tests/weakref-microtasks-dont-collect.js: Added.
+        (asyncTestStart.1.makeWeakRef):
+        (turnEventLoop):
+        (async.foo):
+        (async.test):
+        * js/script-tests/weakref-weakset-consistency.js: Added.
+        (makeWeakRef):
+        (turnEventLoop):
+        (async.foo):
+        (async.test):
+        * js/weakref-async-is-collected-expected.txt: Added.
+        * js/weakref-async-is-collected.html: Added.
+        * js/weakref-eventually-collects-values-expected.txt: Added.
+        * js/weakref-eventually-collects-values.html: Added.
+        * js/weakref-microtasks-dont-collect-expected.txt: Added.
+        * js/weakref-microtasks-dont-collect.html: Added.
+        * js/weakref-weakset-consistency-expected.txt: Added.
+        * js/weakref-weakset-consistency.html: Added.
+        * resources/js-test-pre.js:
+        (asyncTestStart):
+
 2019-06-18  Daniel Bates  <daba...@apple.com>
 
         [iOS] Pressing key while holding Command should not insert character

Modified: trunk/LayoutTests/http/tests/resources/js-test-pre.js (246564 => 246565)


--- trunk/LayoutTests/http/tests/resources/js-test-pre.js	2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/LayoutTests/http/tests/resources/js-test-pre.js	2019-06-18 21:02:19 UTC (rev 246565)
@@ -757,6 +757,16 @@
     debug('<br /><span class="pass">TEST COMPLETE</span>');
 }
 
+function asyncTestStart() {
+    if (self.testRunner)
+        testRunner.waitUntilDone();
+}
+
+function asyncTestPassed() {
+    if (self.testRunner)
+        testRunner.notifyDone();
+}
+
 // It's possible for an async test to call finishJSTest() before js-test-post.js
 // has been parsed.
 function finishJSTest()

Added: trunk/LayoutTests/js/script-tests/weakref-async-is-collected.js (0 => 246565)


--- trunk/LayoutTests/js/script-tests/weakref-async-is-collected.js	                        (rev 0)
+++ trunk/LayoutTests/js/script-tests/weakref-async-is-collected.js	2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,45 @@
+asyncTestStart(1);
+function makeWeakRef() { return new WeakRef({foo: 1 }); }
+noInline(makeWeakRef);
+
+let loopCount = 10000;
+function turnEventLoop() {
+    return new Promise(function(resolve, reject) {
+        if (globalThis.window) {
+            // Turns out the test times out if we turn the event loop 10000 times...
+            loopCount = 1000;
+            window.setTimeout(() => {
+                resolve();
+            }, 0);
+        } else {
+            releaseWeakRefs();
+            resolve();
+        }
+    });
+}
+
+let weakRefs = [];
+
+async function* foo() {
+    let weak = makeWeakRef();
+    await 2;
+    if (weak.deref().foo !== 1)
+        throw new Error("Weak ref was collected too early");
+    await turnEventLoop();
+    weakRefs.push(weak);
+}
+
+async function test() {
+    for (let i = 0; i < loopCount; i++) {
+        for await (value of foo()) { }
+        if (i % 100 === 0)
+            gc();
+    }
+    gc();
+
+    if (weakRefs.find((weak) => weak.deref() === null) === undefined)
+        throw new Error("No weak ref value was collected");
+    asyncTestPassed();
+}
+
+test().catch(e => debug(e));

Added: trunk/LayoutTests/js/script-tests/weakref-eventually-collects-values.js (0 => 246565)


--- trunk/LayoutTests/js/script-tests/weakref-eventually-collects-values.js	                        (rev 0)
+++ trunk/LayoutTests/js/script-tests/weakref-eventually-collects-values.js	2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,40 @@
+asyncTestStart(1);
+
+function makeWeakRef() { return new WeakRef({foo: 1}); }
+noInline(makeWeakRef);
+
+let loopCount = 10000;
+function turnEventLoop() {
+    return new Promise(function(resolve, reject) {
+        if (globalThis.window) {
+            // Turns out the test times out if we turn the event loop 10000 times...
+            loopCount = 1000;
+            window.setTimeout(() => {
+                resolve();
+            }, 0);
+        } else {
+            releaseWeakRefs();
+            resolve();
+        }
+    });
+}
+
+let weakRefs = []
+
+async function test() {
+
+    for (let i = 0; i < loopCount; i++) {
+        let weak = makeWeakRef();
+        if (weak.deref().foo != 1)
+            throw new Error("weak ref was freed too early.");
+        weakRefs.push(weak);
+    }
+    await turnEventLoop();
+    gc();
+
+    if (!weakRefs.find((weak) => weak.deref() === null))
+        throw new Error("no weak ref was collected");
+    asyncTestPassed();
+}
+
+test().catch(e => debug(e));

Added: trunk/LayoutTests/js/script-tests/weakref-microtasks-dont-collect.js (0 => 246565)


--- trunk/LayoutTests/js/script-tests/weakref-microtasks-dont-collect.js	                        (rev 0)
+++ trunk/LayoutTests/js/script-tests/weakref-microtasks-dont-collect.js	2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,48 @@
+asyncTestStart(1);
+
+function makeWeakRef() { return new WeakRef({foo: 1 }); }
+noInline(makeWeakRef);
+
+let loopCount = 10000;
+
+function turnEventLoop() {
+    return new Promise(function(resolve, reject) {
+        if (globalThis.window) {
+            // Turns out the test times out if we turn the event loop 10000 times...
+            loopCount = 1000;
+            window.setTimeout(() => {
+                resolve();
+            }, 0);
+        } else {
+            releaseWeakRefs();
+            resolve();
+        }
+    });
+}
+
+let weakRefs = [];
+
+async function* foo() {
+    let weak = makeWeakRef();
+    let object = weak.deref();
+    yield await 1;
+    if (weak.deref() !== object)
+        throw new Error("Object appears to have been collected incorrectly");
+    object = null;
+    yield await turnEventLoop();
+    weakRefs.push(weak);
+}
+
+async function test() {
+    for (let i = 0; i < loopCount; i++) {
+        for await (value of foo()) { }
+    }
+    gc();
+
+    if (weakRefs.find((weak) => weak.deref() === null) === undefined)
+        throw new Error("No weak ref value was collected");
+    asyncTestPassed();
+}
+
+
+test().catch(e => debug(e));

Added: trunk/LayoutTests/js/script-tests/weakref-weakset-consistency.js (0 => 246565)


--- trunk/LayoutTests/js/script-tests/weakref-weakset-consistency.js	                        (rev 0)
+++ trunk/LayoutTests/js/script-tests/weakref-weakset-consistency.js	2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,42 @@
+asyncTestStart(1);
+function makeWeakRef() { return new WeakRef({foo: 1 }); }
+noInline(makeWeakRef);
+
+let loopCount = 10000;
+function turnEventLoop() {
+    return new Promise(function(resolve, reject) {
+        if (globalThis.window) {
+            // Turns out the test times out if we turn the event loop 10000 times...
+            loopCount = 1000;
+            window.setTimeout(() => {
+                resolve();
+            }, 0);
+        } else {
+            releaseWeakRefs();
+            resolve();
+        }
+    });
+}
+
+let weakSet = new WeakSet();
+let weakRefs = [];
+
+async function* foo() {
+    let weak = makeWeakRef();
+    weakSet.add(weak.deref());
+    await turnEventLoop();
+    weakRefs.push(weak);
+}
+
+async function test() {
+    for (let i = 0; i < loopCount; i++) {
+        for await (value of foo()) { }
+    }
+    gc();
+
+    if (weakRefs.find((weak) => weak.deref() && !weakSet.has(weak.deref())))
+        throw new Error("Weak ref has target but weak set lost reference." )
+    asyncTestPassed();
+}
+
+test().catch(e => debug(e));

Added: trunk/LayoutTests/js/weakref-async-is-collected-expected.txt (0 => 246565)


--- trunk/LayoutTests/js/weakref-async-is-collected-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/weakref-async-is-collected-expected.txt	2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,4 @@
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/js/weakref-async-is-collected.html (0 => 246565)


--- trunk/LayoutTests/js/weakref-async-is-collected.html	                        (rev 0)
+++ trunk/LayoutTests/js/weakref-async-is-collected.html	2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/js/weakref-eventually-collects-values-expected.txt (0 => 246565)


--- trunk/LayoutTests/js/weakref-eventually-collects-values-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/weakref-eventually-collects-values-expected.txt	2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,4 @@
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/js/weakref-eventually-collects-values.html (0 => 246565)


--- trunk/LayoutTests/js/weakref-eventually-collects-values.html	                        (rev 0)
+++ trunk/LayoutTests/js/weakref-eventually-collects-values.html	2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/js/weakref-microtasks-dont-collect-expected.txt (0 => 246565)


--- trunk/LayoutTests/js/weakref-microtasks-dont-collect-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/weakref-microtasks-dont-collect-expected.txt	2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,4 @@
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/js/weakref-microtasks-dont-collect.html (0 => 246565)


--- trunk/LayoutTests/js/weakref-microtasks-dont-collect.html	                        (rev 0)
+++ trunk/LayoutTests/js/weakref-microtasks-dont-collect.html	2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/js/weakref-weakset-consistency-expected.txt (0 => 246565)


--- trunk/LayoutTests/js/weakref-weakset-consistency-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/weakref-weakset-consistency-expected.txt	2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,4 @@
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/js/weakref-weakset-consistency.html (0 => 246565)


--- trunk/LayoutTests/js/weakref-weakset-consistency.html	                        (rev 0)
+++ trunk/LayoutTests/js/weakref-weakset-consistency.html	2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>

Modified: trunk/LayoutTests/resources/js-test-pre.js (246564 => 246565)


--- trunk/LayoutTests/resources/js-test-pre.js	2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/LayoutTests/resources/js-test-pre.js	2019-06-18 21:02:19 UTC (rev 246565)
@@ -757,6 +757,16 @@
     debug('<br /><span class="pass">TEST COMPLETE</span>');
 }
 
+function asyncTestStart() {
+    if (self.testRunner)
+        testRunner.waitUntilDone();
+}
+
+function asyncTestPassed() {
+    if (self.testRunner)
+        testRunner.notifyDone();
+}
+
 // It's possible for an async test to call finishJSTest() before js-test-post.js
 // has been parsed.
 function finishJSTest()

Modified: trunk/Source/_javascript_Core/ChangeLog (246564 => 246565)


--- trunk/Source/_javascript_Core/ChangeLog	2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/_javascript_Core/ChangeLog	2019-06-18 21:02:19 UTC (rev 246565)
@@ -1,3 +1,63 @@
+2019-06-18  Keith Miller  <keith_mil...@apple.com>
+
+        Add support for WeakRef
+        https://bugs.webkit.org/show_bug.cgi?id=198710
+
+        Reviewed by Yusuke Suzuki.
+
+        Add support for WeakRefs which are now at stage 3
+        (https://tc39.es/proposal-weakrefs). This patch doesn't add
+        support for FinalizationGroups, which I'll add in another patch.
+
+        Some other things of interest. Per the spec, we cannot collect a
+        weak refs target unless it has not been dereffed (or created) in
+        the current microtask turn. i.e. WeakRefs are only allowed to be
+        collected at the end of a drain of the Microtask queue. My
+        understanding for this behavior is to reduce implementation
+        dependence on specific GC behavior in a given browser.
+
+        We track if a WeakRef is retaining its target by using a version
+        number on each WeakRef as well as on the VM. Whenever a WeakRef is
+        derefed we update its version number to match the VM's then
+        WriteBarrier ourselves. During marking if the VM and the WeakRef
+        have the same version number, the target is visited.
+
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * Sources.txt:
+        * heap/Heap.cpp:
+        (JSC::Heap::finalizeUnconditionalFinalizers):
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (functionReleaseWeakRefs):
+        * runtime/CommonIdentifiers.h:
+        * runtime/JSGlobalObject.cpp:
+        * runtime/JSGlobalObject.h:
+        * runtime/JSWeakObjectRef.cpp: Added.
+        (JSC::JSWeakObjectRef::finishCreation):
+        (JSC::JSWeakObjectRef::visitChildren):
+        (JSC::JSWeakObjectRef::finalizeUnconditionally):
+        (JSC::JSWeakObjectRef::toStringName):
+        * runtime/JSWeakObjectRef.h: Added.
+        * runtime/VM.cpp:
+        (JSC::VM::drainMicrotasks):
+        * runtime/VM.h:
+        (JSC::VM::setOnEachMicrotaskTick):
+        (JSC::VM::finalizeSynchronousJSExecution):
+        (JSC::VM::currentWeakRefVersion const):
+        * runtime/WeakObjectRefConstructor.cpp: Added.
+        (JSC::WeakObjectRefConstructor::finishCreation):
+        (JSC::WeakObjectRefConstructor::WeakObjectRefConstructor):
+        (JSC::callWeakRef):
+        (JSC::constructWeakRef):
+        * runtime/WeakObjectRefConstructor.h: Added.
+        (JSC::WeakObjectRefConstructor::create):
+        (JSC::WeakObjectRefConstructor::createStructure):
+        * runtime/WeakObjectRefPrototype.cpp: Added.
+        (JSC::WeakObjectRefPrototype::finishCreation):
+        (JSC::getWeakRef):
+        (JSC::protoFuncWeakRefDeref):
+        * runtime/WeakObjectRefPrototype.h: Added.
+
 2019-06-18  Tadeu Zagallo  <tzaga...@apple.com>
 
         Add missing mutator fence in compileNewFunction

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (246564 => 246565)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2019-06-18 21:02:19 UTC (rev 246565)
@@ -1076,6 +1076,9 @@
 		5370B4F61BF26205005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */; };
 		5381B9391E60E97D0090F794 /* WasmFaultSignalHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 5381B9381E60E97D0090F794 /* WasmFaultSignalHandler.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		53917E7B1B7906FA000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */; };
+		539930C822AD3B9A0051CDE2 /* WeakObjectRefConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 539930C722AD3B9A0051CDE2 /* WeakObjectRefConstructor.h */; };
+		539BFBAE22AD3C3A0023F4C0 /* WeakObjectRefPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = 539BFBAD22AD3C3A0023F4C0 /* WeakObjectRefPrototype.h */; };
+		539BFBB022AD3CDC0023F4C0 /* JSWeakObjectRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 539BFBAF22AD3CDC0023F4C0 /* JSWeakObjectRef.h */; };
 		539FB8BA1C99DA7C00940FA1 /* JSArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */; };
 		53B4BD121F68B32500D2BEA3 /* WasmOps.h in Headers */ = {isa = PBXBuildFile; fileRef = 533B15DE1DC7F463004D500A /* WasmOps.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		53B601EC2034B8C5006BE667 /* JSCast.h in Headers */ = {isa = PBXBuildFile; fileRef = 53B601EB2034B8C5006BE667 /* JSCast.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -3639,6 +3642,8 @@
 		536B319F1F7369BD0037FC33 /* glib */ = {isa = PBXFileReference; lastKnownFileType = folder; path = glib; sourceTree = "<group>"; };
 		5370B4F31BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AdaptiveInferredPropertyValueWatchpointBase.cpp; sourceTree = "<group>"; };
 		5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AdaptiveInferredPropertyValueWatchpointBase.h; sourceTree = "<group>"; };
+		5373B4D322AD8BF700803572 /* WeakObjectRefPrototype.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WeakObjectRefPrototype.cpp; sourceTree = "<group>"; };
+		5373B4D422ADB31400803572 /* WeakObjectRefConstructor.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WeakObjectRefConstructor.cpp; sourceTree = "<group>"; };
 		5381B9361E60E9660090F794 /* WasmFaultSignalHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmFaultSignalHandler.cpp; sourceTree = "<group>"; };
 		5381B9381E60E97D0090F794 /* WasmFaultSignalHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmFaultSignalHandler.h; sourceTree = "<group>"; };
 		5383AA2F1E65E8A100A532FC /* JSWebAssemblyCodeBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JSWebAssemblyCodeBlock.cpp; path = js/JSWebAssemblyCodeBlock.cpp; sourceTree = "<group>"; };
@@ -3645,6 +3650,10 @@
 		53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGenericTypedArrayViewPrototypeFunctions.h; sourceTree = "<group>"; };
 		53917E7C1B791106000EBD33 /* JSTypedArrayViewPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypedArrayViewPrototype.h; sourceTree = "<group>"; };
 		53917E831B791CB8000EBD33 /* TypedArrayPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; name = TypedArrayPrototype.js; path = builtins/TypedArrayPrototype.js; sourceTree = SOURCE_ROOT; };
+		539930C722AD3B9A0051CDE2 /* WeakObjectRefConstructor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WeakObjectRefConstructor.h; sourceTree = "<group>"; };
+		539BFBAD22AD3C3A0023F4C0 /* WeakObjectRefPrototype.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WeakObjectRefPrototype.h; sourceTree = "<group>"; };
+		539BFBAF22AD3CDC0023F4C0 /* JSWeakObjectRef.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSWeakObjectRef.h; sourceTree = "<group>"; };
+		539BFBB122AD3D8C0023F4C0 /* JSWeakObjectRef.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JSWeakObjectRef.cpp; sourceTree = "<group>"; };
 		539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSArrayInlines.h; sourceTree = "<group>"; };
 		53B0BE331E561AC900A8FC29 /* GetterSetterAccessCase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GetterSetterAccessCase.cpp; sourceTree = "<group>"; };
 		53B0BE351E561B0900A8FC29 /* ProxyableAccessCase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProxyableAccessCase.cpp; sourceTree = "<group>"; };
@@ -7128,6 +7137,8 @@
 				0F2B66D317B6B5AB00A7AE3F /* JSUint8ClampedArray.h */,
 				A7CA3AE117DA41AE006538AF /* JSWeakMap.cpp */,
 				A7CA3AE217DA41AE006538AF /* JSWeakMap.h */,
+				539BFBB122AD3D8C0023F4C0 /* JSWeakObjectRef.cpp */,
+				539BFBAF22AD3CDC0023F4C0 /* JSWeakObjectRef.h */,
 				709FB8611AE335C60039D069 /* JSWeakSet.cpp */,
 				709FB8621AE335C60039D069 /* JSWeakSet.h */,
 				1442565F15EDE98D0066A49B /* JSWithScope.cpp */,
@@ -7372,6 +7383,10 @@
 				E393ADD71FE702CC0022D681 /* WeakMapImplInlines.h */,
 				A7CA3ADF17DA41AE006538AF /* WeakMapPrototype.cpp */,
 				A7CA3AE017DA41AE006538AF /* WeakMapPrototype.h */,
+				5373B4D422ADB31400803572 /* WeakObjectRefConstructor.cpp */,
+				539930C722AD3B9A0051CDE2 /* WeakObjectRefConstructor.h */,
+				5373B4D322AD8BF700803572 /* WeakObjectRefPrototype.cpp */,
+				539BFBAD22AD3C3A0023F4C0 /* WeakObjectRefPrototype.h */,
 				709FB8631AE335C60039D069 /* WeakSetConstructor.cpp */,
 				709FB8641AE335C60039D069 /* WeakSetConstructor.h */,
 				709FB8651AE335C60039D069 /* WeakSetPrototype.cpp */,
@@ -9561,6 +9576,7 @@
 				A7CA3AE817DA41AE006538AF /* JSWeakMap.h in Headers */,
 				A7482E93116A7CAD003B0712 /* JSWeakObjectMapRefInternal.h in Headers */,
 				A7482B9311671147003B0712 /* JSWeakObjectMapRefPrivate.h in Headers */,
+				539BFBB022AD3CDC0023F4C0 /* JSWeakObjectRef.h in Headers */,
 				0F0B286B1EB8E6CF000EB5D2 /* JSWeakPrivate.h in Headers */,
 				709FB8681AE335C60039D069 /* JSWeakSet.h in Headers */,
 				7A9774A8206B82E4008D03D0 /* JSWeakValue.h in Headers */,
@@ -10010,6 +10026,8 @@
 				E3A32BC71FC83147007D7E76 /* WeakMapImpl.h in Headers */,
 				E393ADD81FE702D00022D681 /* WeakMapImplInlines.h in Headers */,
 				A7CA3AE617DA41AE006538AF /* WeakMapPrototype.h in Headers */,
+				539930C822AD3B9A0051CDE2 /* WeakObjectRefConstructor.h in Headers */,
+				539BFBAE22AD3C3A0023F4C0 /* WeakObjectRefPrototype.h in Headers */,
 				14E84FA114EE1ACC00D6D5D4 /* WeakSet.h in Headers */,
 				709FB86A1AE335C60039D069 /* WeakSetConstructor.h in Headers */,
 				14150133154BB13F005D8C98 /* WeakSetInlines.h in Headers */,

Modified: trunk/Source/_javascript_Core/Sources.txt (246564 => 246565)


--- trunk/Source/_javascript_Core/Sources.txt	2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/_javascript_Core/Sources.txt	2019-06-18 21:02:19 UTC (rev 246565)
@@ -873,6 +873,7 @@
 runtime/JSTypedArrayViewPrototype.cpp
 runtime/JSTypedArrays.cpp
 runtime/JSWeakMap.cpp
+runtime/JSWeakObjectRef.cpp
 runtime/JSWeakSet.cpp
 runtime/JSWithScope.cpp
 runtime/JSWrapperObject.cpp
@@ -969,6 +970,8 @@
 runtime/WeakMapConstructor.cpp
 runtime/WeakMapImpl.cpp
 runtime/WeakMapPrototype.cpp
+runtime/WeakObjectRefConstructor.cpp
+runtime/WeakObjectRefPrototype.cpp
 runtime/WeakSetConstructor.cpp
 runtime/WeakSetPrototype.cpp
 

Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (246564 => 246565)


--- trunk/Source/_javascript_Core/heap/Heap.cpp	2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp	2019-06-18 21:02:19 UTC (rev 246565)
@@ -53,6 +53,7 @@
 #include "JSLock.h"
 #include "JSVirtualMachineInternal.h"
 #include "JSWeakMap.h"
+#include "JSWeakObjectRef.h"
 #include "JSWeakSet.h"
 #include "JSWebAssemblyCodeBlock.h"
 #include "MachineStackMarker.h"
@@ -611,6 +612,8 @@
         finalizeMarkedUnconditionalFinalizers<JSWeakSet>(*vm()->m_weakSetSpace);
     if (vm()->m_weakMapSpace)
         finalizeMarkedUnconditionalFinalizers<JSWeakMap>(*vm()->m_weakMapSpace);
+    if (vm()->m_weakObjectRefSpace)
+        finalizeMarkedUnconditionalFinalizers<JSWeakObjectRef>(*vm()->m_weakObjectRefSpace);
     if (vm()->m_errorInstanceSpace)
         finalizeMarkedUnconditionalFinalizers<ErrorInstance>(*vm()->m_errorInstanceSpace);
 

Modified: trunk/Source/_javascript_Core/jsc.cpp (246564 => 246565)


--- trunk/Source/_javascript_Core/jsc.cpp	2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/_javascript_Core/jsc.cpp	2019-06-18 21:02:19 UTC (rev 246565)
@@ -329,6 +329,7 @@
 static EncodedJSValue JSC_HOST_CALL functionHasCustomProperties(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionDumpTypesForAllVariables(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionDrainMicrotasks(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionReleaseWeakRefs(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionIs32BitPlatform(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionCheckModuleSyntax(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionPlatformSupportsSamplingProfiler(ExecState*);
@@ -557,6 +558,7 @@
         addFunction(vm, "dumpTypesForAllVariables", functionDumpTypesForAllVariables , 0);
 
         addFunction(vm, "drainMicrotasks", functionDrainMicrotasks, 0);
+        addFunction(vm, "releaseWeakRefs", functionReleaseWeakRefs, 0);
 
         addFunction(vm, "getRandomSeed", functionGetRandomSeed, 0);
         addFunction(vm, "setRandomSeed", functionSetRandomSeed, 1);
@@ -2209,6 +2211,13 @@
     return JSValue::encode(jsUndefined());
 }
 
+EncodedJSValue JSC_HOST_CALL functionReleaseWeakRefs(ExecState* exec)
+{
+    VM& vm = exec->vm();
+    vm.finalizeSynchronousJSExecution();
+    return JSValue::encode(jsUndefined());
+}
+
 EncodedJSValue JSC_HOST_CALL functionIs32BitPlatform(ExecState*)
 {
 #if USE(JSVALUE64)

Modified: trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h (246564 => 246565)


--- trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h	2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h	2019-06-18 21:02:19 UTC (rev 246565)
@@ -88,6 +88,7 @@
     macro(counters) \
     macro(day) \
     macro(defineProperty) \
+    macro(deref) \
     macro(description) \
     macro(descriptions) \
     macro(detail) \

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (246564 => 246565)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2019-06-18 21:02:19 UTC (rev 246565)
@@ -122,6 +122,7 @@
 #include "JSTypedArrayViewPrototype.h"
 #include "JSTypedArrays.h"
 #include "JSWeakMap.h"
+#include "JSWeakObjectRef.h"
 #include "JSWeakSet.h"
 #include "JSWebAssembly.h"
 #include "JSWithScope.h"
@@ -172,6 +173,8 @@
 #include "WeakGCMapInlines.h"
 #include "WeakMapConstructor.h"
 #include "WeakMapPrototype.h"
+#include "WeakObjectRefConstructor.h"
+#include "WeakObjectRefPrototype.h"
 #include "WeakSetConstructor.h"
 #include "WeakSetPrototype.h"
 #include "WebAssemblyPrototype.h"
@@ -359,6 +362,7 @@
   Number                JSGlobalObject::m_numberObjectStructure      DontEnum|ClassStructure
   Symbol                JSGlobalObject::m_symbolObjectStructure      DontEnum|ClassStructure
   WeakMap               JSGlobalObject::m_weakMapStructure           DontEnum|ClassStructure
+  WeakRef               JSGlobalObject::m_weakObjectRefStructure     DontEnum|ClassStructure
   WeakSet               JSGlobalObject::m_weakSetStructure           DontEnum|ClassStructure
 @end
 */

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (246564 => 246565)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h	2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h	2019-06-18 21:02:19 UTC (rev 246565)
@@ -149,6 +149,7 @@
     macro(Error, error, error, ErrorInstance, Error, object) \
     macro(Number, number, numberObject, NumberObject, Number, object) \
     macro(Symbol, symbol, symbolObject, SymbolObject, Symbol, object) \
+    macro(WeakObjectRef, weakObjectRef, weakObjectRef, JSWeakObjectRef, WeakRef, object) \
     DEFINE_STANDARD_BUILTIN(macro, WeakMap, weakMap) \
     DEFINE_STANDARD_BUILTIN(macro, WeakSet, weakSet) \
 

Added: trunk/Source/_javascript_Core/runtime/JSWeakObjectRef.cpp (0 => 246565)


--- trunk/Source/_javascript_Core/runtime/JSWeakObjectRef.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/runtime/JSWeakObjectRef.cpp	2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2019 Apple, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSWeakObjectRef.h"
+
+#include "JSCInlines.h"
+
+namespace JSC {
+
+const ClassInfo JSWeakObjectRef::s_info = { "WeakRef", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWeakObjectRef) };
+
+void JSWeakObjectRef::finishCreation(VM& vm, JSObject* value)
+{
+    m_lastAccessVersion = vm.currentWeakRefVersion();
+    m_value.set(vm, this, value);
+    Base::finishCreation(vm);
+}
+
+void JSWeakObjectRef::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+    auto* thisObject = jsCast<JSWeakObjectRef*>(cell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    Base::visitChildren(thisObject, visitor);
+    // This doesn't need to be atomic because if we are out of date we will get write barriered and revisit ourselves.
+    if (visitor.vm().currentWeakRefVersion() == thisObject->m_lastAccessVersion) {
+        ASSERT(thisObject->m_value);
+        visitor.append(thisObject->m_value);
+    }
+}
+
+void JSWeakObjectRef::finalizeUnconditionally(VM& vm)
+{
+    if (m_value && !vm.heap.isMarked(m_value.get()))
+        m_value.clear();
+}
+
+String JSWeakObjectRef::toStringName(const JSC::JSObject*, ExecState*)
+{
+    return "Object"_s;
+}
+
+}
+

Added: trunk/Source/_javascript_Core/runtime/JSWeakObjectRef.h (0 => 246565)


--- trunk/Source/_javascript_Core/runtime/JSWeakObjectRef.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/runtime/JSWeakObjectRef.h	2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2019 Apple, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "JSObject.h"
+
+namespace JSC {
+
+class JSWeakObjectRef final : public JSNonFinalObject {
+public:
+    using Base = JSNonFinalObject;
+
+    DECLARE_EXPORT_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+    static JSWeakObjectRef* create(VM& vm, Structure* structure, JSObject* target)
+    {
+        JSWeakObjectRef* instance = new (NotNull, allocateCell<JSWeakObjectRef>(vm.heap)) JSWeakObjectRef(vm, structure);
+        instance->finishCreation(vm, target);
+        return instance;
+    }
+
+    JSObject* deref(VM& vm)
+    {
+        if (m_value && vm.currentWeakRefVersion() != m_lastAccessVersion) {
+            m_lastAccessVersion = vm.currentWeakRefVersion();
+            // Perform a GC barrier here so we rescan this object and keep the object alive if we wouldn't otherwise.
+            vm.heap.writeBarrier(this);
+        }
+
+        return m_value.get();
+    }
+
+    template<typename CellType, SubspaceAccess mode>
+    static IsoSubspace* subspaceFor(VM& vm)
+    {
+        return vm.weakObjectRefSpace<mode>();
+    }
+
+    void finalizeUnconditionally(VM&);
+    static void visitChildren(JSCell*, SlotVisitor&);
+
+private:
+    JSWeakObjectRef(VM& vm, Structure* structure)
+        : Base(vm, structure)
+    {
+    }
+
+    JS_EXPORT_PRIVATE void finishCreation(VM&, JSObject* value);
+
+    static String toStringName(const JSObject*, ExecState*);
+
+    uintptr_t m_lastAccessVersion;
+    WriteBarrier<JSObject> m_value;
+};
+
+} // namespace JSC
+

Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (246564 => 246565)


--- trunk/Source/_javascript_Core/runtime/VM.cpp	2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp	2019-06-18 21:02:19 UTC (rev 246565)
@@ -99,6 +99,7 @@
 #include "JSStringHeapCellType.h"
 #include "JSTemplateObjectDescriptor.h"
 #include "JSWeakMap.h"
+#include "JSWeakObjectRef.h"
 #include "JSWeakSet.h"
 #include "JSWebAssembly.h"
 #include "JSWebAssemblyCodeBlock.h"
@@ -1095,6 +1096,7 @@
         if (m_onEachMicrotaskTick)
             m_onEachMicrotaskTick(*this);
     }
+    finalizeSynchronousJSExecution();
 }
 
 void QueuedTask::run()
@@ -1249,6 +1251,7 @@
 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(proxyRevokeSpace, destructibleObjectHeapCellType.get(), ProxyRevoke)
 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(weakMapSpace, destructibleObjectHeapCellType.get(), JSWeakMap)
 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(weakSetSpace, destructibleObjectHeapCellType.get(), JSWeakSet)
+DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(weakObjectRefSpace, cellHeapCellType.get(), JSWeakObjectRef)
 #if JSC_OBJC_API_ENABLED
 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(objCCallbackFunctionSpace, destructibleObjectHeapCellType.get(), ObjCCallbackFunction)
 #endif

Modified: trunk/Source/_javascript_Core/runtime/VM.h (246564 => 246565)


--- trunk/Source/_javascript_Core/runtime/VM.h	2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/_javascript_Core/runtime/VM.h	2019-06-18 21:02:19 UTC (rev 246565)
@@ -403,6 +403,7 @@
     DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(errorInstanceSpace)
     DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(nativeStdFunctionSpace)
     DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(proxyRevokeSpace)
+    DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(weakObjectRefSpace)
     DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(weakSetSpace)
     DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(weakMapSpace)
 #if ENABLE(WEBASSEMBLY)
@@ -887,7 +888,10 @@
 
     void queueMicrotask(JSGlobalObject&, Ref<Microtask>&&);
     JS_EXPORT_PRIVATE void drainMicrotasks();
-    ALWAYS_INLINE void setOnEachMicrotaskTick(WTF::Function<void(VM&)>&& func) { m_onEachMicrotaskTick = WTFMove(func); }
+    void setOnEachMicrotaskTick(WTF::Function<void(VM&)>&& func) { m_onEachMicrotaskTick = WTFMove(func); }
+    void finalizeSynchronousJSExecution() { ASSERT(currentThreadIsHoldingAPILock()); m_currentWeakRefVersion++; }
+    uint64_t currentWeakRefVersion() const { return m_currentWeakRefVersion; }
+
     void setGlobalConstRedeclarationShouldThrow(bool globalConstRedeclarationThrow) { m_globalConstRedeclarationShouldThrow = globalConstRedeclarationThrow; }
     ALWAYS_INLINE bool globalConstRedeclarationShouldThrow() const { return m_globalConstRedeclarationShouldThrow; }
 
@@ -1057,6 +1061,7 @@
     std::unique_ptr<BytecodeIntrinsicRegistry> m_bytecodeIntrinsicRegistry;
 
     WTF::Function<void(VM&)> m_onEachMicrotaskTick;
+    uintptr_t m_currentWeakRefVersion { 0 };
 
 #if ENABLE(JIT)
 #if !ASSERT_DISABLED

Added: trunk/Source/_javascript_Core/runtime/WeakObjectRefConstructor.cpp (0 => 246565)


--- trunk/Source/_javascript_Core/runtime/WeakObjectRefConstructor.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/runtime/WeakObjectRefConstructor.cpp	2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2019 Apple, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WeakObjectRefConstructor.h"
+
+#include "Error.h"
+#include "IteratorOperations.h"
+#include "JSCInlines.h"
+#include "JSGlobalObject.h"
+#include "JSObjectInlines.h"
+#include "JSWeakObjectRef.h"
+#include "WeakObjectRefPrototype.h"
+
+namespace JSC {
+
+const ClassInfo WeakObjectRefConstructor::s_info = { "Function", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(WeakObjectRefConstructor) };
+
+void WeakObjectRefConstructor::finishCreation(VM& vm, WeakObjectRefPrototype* prototype)
+{
+    Base::finishCreation(vm, "WeakRef"_s, NameVisibility::Visible, NameAdditionMode::WithoutStructureTransition);
+    putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
+    putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
+}
+
+static EncodedJSValue JSC_HOST_CALL callWeakRef(ExecState*);
+static EncodedJSValue JSC_HOST_CALL constructWeakRef(ExecState*);
+
+WeakObjectRefConstructor::WeakObjectRefConstructor(VM& vm, Structure* structure)
+    : Base(vm, structure, callWeakRef, constructWeakRef)
+{
+}
+
+static EncodedJSValue JSC_HOST_CALL callWeakRef(ExecState* exec)
+{
+    VM& vm = exec->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+    return JSValue::encode(throwConstructorCannotBeCalledAsFunctionTypeError(exec, scope, "WeakRef"));
+}
+
+static EncodedJSValue JSC_HOST_CALL constructWeakRef(ExecState* exec)
+{
+    VM& vm = exec->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    if (!exec->argument(0).isObject())
+        return throwVMTypeError(exec, scope, "First argument to WeakRef should be an object"_s);
+
+    JSGlobalObject* globalObject = jsCast<InternalFunction*>(exec->jsCallee())->globalObject(vm);
+    Structure* WeakObjectRefStructure = InternalFunction::createSubclassStructure(exec, exec->newTarget(), globalObject->weakObjectRefStructure());
+    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+    RELEASE_AND_RETURN(scope, JSValue::encode(JSWeakObjectRef::create(vm, WeakObjectRefStructure, exec->uncheckedArgument(0).getObject())));
+}
+
+}
+

Added: trunk/Source/_javascript_Core/runtime/WeakObjectRefConstructor.h (0 => 246565)


--- trunk/Source/_javascript_Core/runtime/WeakObjectRefConstructor.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/runtime/WeakObjectRefConstructor.h	2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 Apple, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+namespace JSC {
+
+class WeakObjectRefConstructor final : public InternalFunction {
+public:
+    using Base = InternalFunction;
+
+    static WeakObjectRefConstructor* create(VM& vm, Structure* structure, WeakObjectRefPrototype* prototype, GetterSetter*)
+    {
+        WeakObjectRefConstructor* constructor = new (NotNull, allocateCell<WeakObjectRefConstructor>(vm.heap)) WeakObjectRefConstructor(vm, structure);
+        constructor->finishCreation(vm, prototype);
+        return constructor;
+    }
+
+    DECLARE_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(InternalFunctionType, StructureFlags), info());
+    }
+
+private:
+    WeakObjectRefConstructor(VM&, Structure*);
+    void finishCreation(VM&, WeakObjectRefPrototype*);
+};
+
+static_assert(sizeof(WeakObjectRefConstructor) == sizeof(InternalFunction));
+
+}

Added: trunk/Source/_javascript_Core/runtime/WeakObjectRefPrototype.cpp (0 => 246565)


--- trunk/Source/_javascript_Core/runtime/WeakObjectRefPrototype.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/runtime/WeakObjectRefPrototype.cpp	2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2019 Apple, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WeakObjectRefPrototype.h"
+
+#include "Error.h"
+#include "JSCInlines.h"
+#include "JSWeakObjectRef.h"
+
+namespace JSC {
+
+const ClassInfo WeakObjectRefPrototype::s_info = { "WeakRef", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(WeakObjectRefPrototype) };
+
+static EncodedJSValue JSC_HOST_CALL protoFuncWeakRefDeref(ExecState*);
+
+void WeakObjectRefPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
+{
+    Base::finishCreation(vm);
+    ASSERT(inherits(vm, info()));
+    didBecomePrototype();
+
+    // FIXME: It wouldn't be hard to make this an intrinsic.
+    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->deref, protoFuncWeakRefDeref, static_cast<unsigned>(PropertyAttribute::DontEnum), 0);
+
+    putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, "WeakRef"), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
+}
+
+ALWAYS_INLINE static JSWeakObjectRef* getWeakRef(CallFrame* callFrame, JSValue value)
+{
+    VM& vm = callFrame->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    if (UNLIKELY(!value.isObject())) {
+        throwTypeError(callFrame, scope, "Called WeakRef function on non-object"_s);
+        return nullptr;
+    }
+
+    auto* ref = jsDynamicCast<JSWeakObjectRef*>(vm, asObject(value));
+    if (LIKELY(ref))
+        return ref;
+
+    throwTypeError(callFrame, scope, "Called WeakRef function on a non-WeakRef object"_s);
+    return nullptr;
+}
+
+EncodedJSValue JSC_HOST_CALL protoFuncWeakRefDeref(CallFrame* callFrame)
+{
+    VM& vm = callFrame->vm();
+    auto* ref = getWeakRef(callFrame, callFrame->thisValue());
+    if (!ref)
+        return JSValue::encode(jsUndefined());
+
+    auto* value = ref->deref(vm);
+    return value ? JSValue::encode(value) : JSValue::encode(jsNull());
+}
+
+}

Added: trunk/Source/_javascript_Core/runtime/WeakObjectRefPrototype.h (0 => 246565)


--- trunk/Source/_javascript_Core/runtime/WeakObjectRefPrototype.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/runtime/WeakObjectRefPrototype.h	2019-06-18 21:02:19 UTC (rev 246565)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2019 Apple, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "JSObject.h"
+
+namespace JSC {
+
+class WeakObjectRefPrototype final : public JSNonFinalObject {
+public:
+    using Base = JSNonFinalObject;
+
+    static WeakObjectRefPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
+    {
+        WeakObjectRefPrototype* prototype = new (NotNull, allocateCell<WeakObjectRefPrototype>(vm.heap)) WeakObjectRefPrototype(vm, structure);
+        prototype->finishCreation(vm, globalObject);
+        return prototype;
+    }
+
+    DECLARE_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+private:
+    WeakObjectRefPrototype(VM& vm, Structure* structure)
+        : Base(vm, structure)
+    {
+    }
+    void finishCreation(VM&, JSGlobalObject*);
+};
+
+}
+

Modified: trunk/Source/WebCore/ChangeLog (246564 => 246565)


--- trunk/Source/WebCore/ChangeLog	2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/WebCore/ChangeLog	2019-06-18 21:02:19 UTC (rev 246565)
@@ -1,3 +1,32 @@
+2019-06-18  Keith Miller  <keith_mil...@apple.com>
+
+        Add support for WeakRef
+        https://bugs.webkit.org/show_bug.cgi?id=198710
+
+        Reviewed by Yusuke Suzuki.
+
+        We need to make sure the Web MicrotaskQueue notifies the JSC VM
+        that it has finished performing a microtask checkpoint. This lets
+        the JSC VM know it is safe to collect referenced WeakRefs. Since
+        there was no way to get the VM from the MicrotaskQueue I have
+        added a RefPtr to the queue's VM. For the main thread the VM lives
+        forever so is fine. For workers the queue and the VM share an
+        owner so this shouldn't matter either.
+
+        Tests: js/weakref-async-is-collected.html
+               js/weakref-eventually-collects-values.html
+               js/weakref-microtasks-dont-collect.html
+               js/weakref-weakset-consistency.html
+
+        * dom/Microtasks.cpp:
+        (WebCore::MicrotaskQueue::MicrotaskQueue):
+        (WebCore::MicrotaskQueue::mainThreadQueue):
+        (WebCore::MicrotaskQueue::performMicrotaskCheckpoint):
+        * dom/Microtasks.h:
+        (WebCore::MicrotaskQueue::vm const):
+        * workers/WorkerGlobalScope.cpp:
+        (WebCore::WorkerGlobalScope::WorkerGlobalScope):
+
 2019-06-18  Kenneth Russell  <k...@chromium.org>
 
         Add preliminary ANGLE backend to WebCore

Modified: trunk/Source/WebCore/dom/Microtasks.cpp (246564 => 246565)


--- trunk/Source/WebCore/dom/Microtasks.cpp	2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/WebCore/dom/Microtasks.cpp	2019-06-18 21:02:19 UTC (rev 246565)
@@ -22,6 +22,7 @@
 #include "config.h"
 #include "Microtasks.h"
 
+#include "CommonVM.h"
 #include "WorkerGlobalScope.h"
 #include <wtf/MainThread.h>
 #include <wtf/NeverDestroyed.h>
@@ -34,8 +35,9 @@
     queue.remove(*this);
 }
 
-MicrotaskQueue::MicrotaskQueue()
-    : m_timer(*this, &MicrotaskQueue::timerFired)
+MicrotaskQueue::MicrotaskQueue(JSC::VM& vm)
+    : m_vm(makeRef(vm))
+    , m_timer(*this, &MicrotaskQueue::timerFired)
 {
 }
 
@@ -44,7 +46,7 @@
 MicrotaskQueue& MicrotaskQueue::mainThreadQueue()
 {
     ASSERT(isMainThread());
-    static NeverDestroyed<MicrotaskQueue> queue;
+    static NeverDestroyed<MicrotaskQueue> queue(commonVM());
     return queue;
 }
 
@@ -87,6 +89,7 @@
         return;
 
     SetForScope<bool> change(m_performingMicrotaskCheckpoint, true);
+    JSC::JSLockHolder locker(vm());
 
     Vector<std::unique_ptr<Microtask>> toKeep;
     while (!m_microtaskQueue.isEmpty()) {
@@ -103,6 +106,7 @@
         }
     }
 
+    vm().finalizeSynchronousJSExecution();
     m_microtaskQueue = WTFMove(toKeep);
 }
 

Modified: trunk/Source/WebCore/dom/Microtasks.h (246564 => 246565)


--- trunk/Source/WebCore/dom/Microtasks.h	2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/WebCore/dom/Microtasks.h	2019-06-18 21:02:19 UTC (rev 246565)
@@ -72,19 +72,23 @@
     WEBCORE_EXPORT static MicrotaskQueue& mainThreadQueue();
     WEBCORE_EXPORT static MicrotaskQueue& contextQueue(ScriptExecutionContext&);
 
-    WEBCORE_EXPORT MicrotaskQueue();
+    WEBCORE_EXPORT MicrotaskQueue(JSC::VM&);
     WEBCORE_EXPORT ~MicrotaskQueue();
 
     WEBCORE_EXPORT void append(std::unique_ptr<Microtask>&&);
     WEBCORE_EXPORT void performMicrotaskCheckpoint();
 
+    JSC::VM& vm() const { return m_vm.get(); }
+
 private:
     WEBCORE_EXPORT void remove(const Microtask&);
 
     void timerFired();
 
-    bool m_performingMicrotaskCheckpoint = false;
+    bool m_performingMicrotaskCheckpoint { false };
     Vector<std::unique_ptr<Microtask>> m_microtaskQueue;
+    // For the main thread the VM lives forever. For workers it's lifetime is tied to our owning WorkerGlobalScope. Regardless, we retain the VM here to be safe.
+    Ref<JSC::VM> m_vm;
 
     // FIXME: Instead of a Timer, we should have a centralized Event Loop that calls performMicrotaskCheckpoint()
     // on every iteration, implementing https://html.spec.whatwg.org/multipage/webappapis.html#processing-model-9

Modified: trunk/Source/WebCore/workers/WorkerGlobalScope.cpp (246564 => 246565)


--- trunk/Source/WebCore/workers/WorkerGlobalScope.cpp	2019-06-18 20:59:35 UTC (rev 246564)
+++ trunk/Source/WebCore/workers/WorkerGlobalScope.cpp	2019-06-18 21:02:19 UTC (rev 246565)
@@ -64,7 +64,7 @@
     , m_thread(thread)
     , m_script(std::make_unique<WorkerScriptController>(this))
     , m_inspectorController(std::make_unique<WorkerInspectorController>(*this))
-    , m_microtaskQueue(std::make_unique<MicrotaskQueue>())
+    , m_microtaskQueue(std::make_unique<MicrotaskQueue>(m_script->vm()))
     , m_isOnline(isOnline)
     , m_shouldBypassMainWorldContentSecurityPolicy(shouldBypassMainWorldContentSecurityPolicy)
     , m_eventQueue(*this)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to