Title: [211385] trunk
Revision
211385
Author
mattba...@apple.com
Date
2017-01-30 14:01:07 -0800 (Mon, 30 Jan 2017)

Log Message

Web Inspector: Need some limit on Async Call Stacks for async loops (rAF loops)
https://bugs.webkit.org/show_bug.cgi?id=165633
<rdar://problem/29738502>

Reviewed by Joseph Pecoraro.

Source/_javascript_Core:

This patch limits the memory used by the Inspector backend to store async
stack trace data.

Asynchronous stack traces are stored as a disjoint set of parent pointer
trees. Tree nodes represent asynchronous operations, and hold a copy of
the stack trace at the time the operation was scheduled. Each tree can
be regarded as a set of stack traces, stored as singly linked lists that
share part of their structure (specifically their tails). Traces belonging
to the same tree will at least share a common root. A stack trace begins
at a leaf node and follows the chain of parent pointers to the root of
of the tree. Leaf nodes always contain pending asynchronous calls.

When an asynchronous operation is scheduled with requestAnimationFrame,
setInterval, etc, a node is created containing the current call stack and
some bookkeeping data for the operation. An unique identifier comprised
of an operation type and callback identifier is mapped to the node. If
scheduling the callback was itself the result of an asynchronous call,
the node becomes a child of the node associated with that call, otherwise
it becomes the root of a new tree.

A node is either `pending`, `active`, `dispatched`, or `canceled`. Nodes
start out as pending. After a callback for a pending node is dispatched
the node is marked as such, unless it is a repeating callback such as
setInterval, in which case it remains pending. Once a node is no longer
pending it is removed, as long as it has no children. Since nodes are
reference counted, it is a property of the stack trace tree that nodes
that are no longer pending and have no children pointing to them will be
automatically pruned from the tree.

If an async operation is canceled (e.g. cancelTimeout), the associated
node is marked as such. If the callback is not being dispatched at the
time, and has no children, it is removed.

Because async operations can be chained indefinitely, stack traces are
limited to a maximum depth. The depth of a stack trace is equal to the
sum of the depths of its nodes, with a node's depth equal to the number
of frames in its associated call stack. For any stack trace,

    S = { sšŸ¶, sšŸ·, …, sš‘˜ }, with endpoints sšŸ¶, sš‘˜
    depth(S) = depth(sšŸ¶) + depth(sšŸ·) + … + depth(sš‘˜)

A stack trace is truncated when it exceeds the maximum depth. Truncation
occurs on node boundaries, not call frames, consequently the maximum depth
is more of a target than a guarantee:

    d = maximum stack trace depth
    for all S, depth(S) ≤ d + depth(sš‘˜)

Because nodes can belong to multiple stack traces, it may be necessary
to clone the tail of a stack trace being truncated to prevent other traces
from being effected.

* CMakeLists.txt:
* _javascript_Core.xcodeproj/project.pbxproj:
* inspector/AsyncStackTrace.cpp: Added.
(Inspector::AsyncStackTrace::create):
(Inspector::AsyncStackTrace::AsyncStackTrace):
(Inspector::AsyncStackTrace::~AsyncStackTrace):
(Inspector::AsyncStackTrace::isPending):
(Inspector::AsyncStackTrace::isLocked):
(Inspector::AsyncStackTrace::willDispatchAsyncCall):
(Inspector::AsyncStackTrace::didDispatchAsyncCall):
(Inspector::AsyncStackTrace::didCancelAsyncCall):
(Inspector::AsyncStackTrace::buildInspectorObject):
(Inspector::AsyncStackTrace::truncate):
(Inspector::AsyncStackTrace::remove):
* inspector/AsyncStackTrace.h:
* inspector/agents/InspectorDebuggerAgent.cpp:
(Inspector::InspectorDebuggerAgent::didScheduleAsyncCall):
(Inspector::InspectorDebuggerAgent::didCancelAsyncCall):
(Inspector::InspectorDebuggerAgent::willDispatchAsyncCall):
(Inspector::InspectorDebuggerAgent::didDispatchAsyncCall):
(Inspector::InspectorDebuggerAgent::didPause):
(Inspector::InspectorDebuggerAgent::clearAsyncStackTraceData):
(Inspector::InspectorDebuggerAgent::buildAsyncStackTrace): Deleted.
(Inspector::InspectorDebuggerAgent::refAsyncCallData): Deleted.
(Inspector::InspectorDebuggerAgent::derefAsyncCallData): Deleted.
* inspector/agents/InspectorDebuggerAgent.h:
* inspector/protocol/Console.json:

Source/WebInspectorUI:

* Localizations/en.lproj/localizedStrings.js:
Text for "Truncated" marker tree element.

* UserInterface/Models/StackTrace.js:
(WebInspector.StackTrace):
(WebInspector.StackTrace.fromPayload):
(WebInspector.StackTrace.prototype.get truncated):
Plumbing for new Console.StackTrace property `truncated`.

* UserInterface/Views/ThreadTreeElement.css:
(.tree-outline > .item.thread + ol > .item.truncated-call-frames):
(.tree-outline > .item.thread + ol > .item.truncated-call-frames .icon):
Styles for "Truncated" marker tree element.

* UserInterface/Views/ThreadTreeElement.js:
(WebInspector.ThreadTreeElement.prototype.refresh):
Append "Truncated" marker tree element if necessary.

* Versions/Inspector-iOS-10.3.json:

LayoutTests:

Add truncation test cases and cleanup call frame logging.

* inspector/debugger/async-stack-trace-expected.txt:
* inspector/debugger/async-stack-trace.html:
* inspector/debugger/resources/log-active-stack-trace.js: Added.
(TestPage.registerInitializer.window.getActiveStackTrace):
(TestPage.registerInitializer.logStackTrace.logCallFrame):
(TestPage.registerInitializer.):
(TestPage.registerInitializer.window.logActiveStackTrace):
(TestPage.registerInitializer):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (211384 => 211385)


--- trunk/LayoutTests/ChangeLog	2017-01-30 21:02:16 UTC (rev 211384)
+++ trunk/LayoutTests/ChangeLog	2017-01-30 22:01:07 UTC (rev 211385)
@@ -1,3 +1,22 @@
+2017-01-30  Matt Baker  <mattba...@apple.com>
+
+        Web Inspector: Need some limit on Async Call Stacks for async loops (rAF loops)
+        https://bugs.webkit.org/show_bug.cgi?id=165633
+        <rdar://problem/29738502>
+
+        Reviewed by Joseph Pecoraro.
+
+        Add truncation test cases and cleanup call frame logging.
+
+        * inspector/debugger/async-stack-trace-expected.txt:
+        * inspector/debugger/async-stack-trace.html:
+        * inspector/debugger/resources/log-active-stack-trace.js: Added.
+        (TestPage.registerInitializer.window.getActiveStackTrace):
+        (TestPage.registerInitializer.logStackTrace.logCallFrame):
+        (TestPage.registerInitializer.):
+        (TestPage.registerInitializer.window.logActiveStackTrace):
+        (TestPage.registerInitializer):
+
 2017-01-30  Ryan Haddad  <ryanhad...@apple.com>
 
         Unreviewed, rolling out r211345.

Modified: trunk/LayoutTests/inspector/debugger/async-stack-trace-expected.txt (211384 => 211385)


--- trunk/LayoutTests/inspector/debugger/async-stack-trace-expected.txt	2017-01-30 21:02:16 UTC (rev 211384)
+++ trunk/LayoutTests/inspector/debugger/async-stack-trace-expected.txt	2017-01-30 22:01:07 UTC (rev 211385)
@@ -6,57 +6,64 @@
 PAUSE #1
 CALL STACK:
 0: [F] pauseThenFinishTest
--- [N] requestAnimationFrame ----
-1: [F] testRequestAnimationFrame
-2: [P] Global Code
+ASYNC CALL STACK:
+1: --- requestAnimationFrame ---
+2: [F] testRequestAnimationFrame
+3: [P] Global Code
 
 -- Running test case: CheckAsyncStackTrace.SetTimeout
 PAUSE #1
 CALL STACK:
 0: [F] pauseThenFinishTest
--- [N] setTimeout ----
-1: [F] testSetTimeout
-2: [P] Global Code
+ASYNC CALL STACK:
+1: --- setTimeout ---
+2: [F] testSetTimeout
+3: [P] Global Code
 
 -- Running test case: CheckAsyncStackTrace.SetInterval
 PAUSE #1
 CALL STACK:
 0: [F] intervalFired
--- [N] setInterval ----
-1: [F] testSetInterval
-2: [P] Global Code
+ASYNC CALL STACK:
+1: --- setInterval ---
+2: [F] testSetInterval
+3: [P] Global Code
 PAUSE #2
 CALL STACK:
 0: [F] intervalFired
--- [N] setInterval ----
-1: [F] testSetInterval
-2: [P] Global Code
+ASYNC CALL STACK:
+1: --- setInterval ---
+2: [F] testSetInterval
+3: [P] Global Code
 PAUSE #3
 CALL STACK:
 0: [F] intervalFired
--- [N] setInterval ----
-1: [F] testSetInterval
-2: [P] Global Code
+ASYNC CALL STACK:
+1: --- setInterval ---
+2: [F] testSetInterval
+3: [P] Global Code
 
 -- Running test case: CheckAsyncStackTrace.ChainedRequestAnimationFrame
 PAUSE #1
 CALL STACK:
 0: [F] pauseThenFinishTest
--- [N] requestAnimationFrame ----
-1: [F] testRequestAnimationFrame
--- [N] requestAnimationFrame ----
-2: [F] testChainedRequestAnimationFrame
-3: [P] Global Code
+ASYNC CALL STACK:
+1: --- requestAnimationFrame ---
+2: [F] testRequestAnimationFrame
+3: --- requestAnimationFrame ---
+4: [F] testChainedRequestAnimationFrame
+5: [P] Global Code
 
 -- Running test case: CheckAsyncStackTrace.ReferenceCounting
 PAUSE #1
 CALL STACK:
 0: [F] pauseThenFinishTest
--- [N] setTimeout ----
-1: [F] intervalFired
--- [N] setInterval ----
-2: [F] testReferenceCounting
-3: [P] Global Code
+ASYNC CALL STACK:
+1: --- setTimeout ---
+2: [F] intervalFired
+3: --- setInterval ---
+4: [F] testReferenceCounting
+5: [P] Global Code
 -- Running test setup.
 Save DebuggerManager.asyncStackTraceDepth
 
@@ -67,8 +74,44 @@
 -- Running test setup.
 Save DebuggerManager.asyncStackTraceDepth
 
--- Running test case: AsyncStackTrace.SetStackTraceDepth
-PASS: Number of call frames should be equal to the depth setting.
+-- Running test case: AsyncStackTrace.ForceTruncationOnCallStackBoundary
+Set Debugger.asyncStackTraceDepth equal to 4
+PASS: Non-root StackTrace should not be truncated.
+PASS: Non-root StackTrace should not be truncated.
+PASS: StackTrace root should be truncated.
+PASS: StackTrace should be truncated to the nearest call stack.
+CALL STACK:
+0: [F] pauseThenFinishTest
+1: [F] repeat
+ASYNC CALL STACK:
+2: --- requestAnimationFrame ---
+3: [F] repeat
+4: --- requestAnimationFrame ---
+5: [F] repeat
+(remaining call frames truncated)
 -- Running test teardown.
 Restore DebuggerManager.asyncStackTraceDepth
+-- Running test setup.
+Save DebuggerManager.asyncStackTraceDepth
 
+-- Running test case: AsyncStackTrace.ForceTruncationWithinCallStack
+Set Debugger.asyncStackTraceDepth equal to 5
+PASS: Non-root StackTrace should not be truncated.
+PASS: Non-root StackTrace should not be truncated.
+PASS: Non-root StackTrace should not be truncated.
+PASS: StackTrace root should be truncated.
+PASS: StackTrace should be truncated to the nearest call stack.
+CALL STACK:
+0: [F] pauseThenFinishTest
+1: [F] repeat
+ASYNC CALL STACK:
+2: --- requestAnimationFrame ---
+3: [F] repeat
+4: --- requestAnimationFrame ---
+5: [F] repeat
+6: --- requestAnimationFrame ---
+7: [F] repeat
+(remaining call frames truncated)
+-- Running test teardown.
+Restore DebuggerManager.asyncStackTraceDepth
+

Modified: trunk/LayoutTests/inspector/debugger/async-stack-trace.html (211384 => 211385)


--- trunk/LayoutTests/inspector/debugger/async-stack-trace.html	2017-01-30 21:02:16 UTC (rev 211384)
+++ trunk/LayoutTests/inspector/debugger/async-stack-trace.html	2017-01-30 22:01:07 UTC (rev 211385)
@@ -2,6 +2,7 @@
 <html>
 <head>
 <script src=""
+<script src=""
 <script>
 const timerDelay = 20;
 
@@ -48,55 +49,22 @@
     testFunction();
 }
 
+function repeatingRequestAnimationFrame(repeatCount) {
+    let count = 0;
+    function repeat() {
+        if (count++ === repeatCount) {
+            pauseThenFinishTest();
+            return;
+        }
+        requestAnimationFrame(repeat);
+    }
+    requestAnimationFrame(repeat);
+}
+
 function test()
 {
     let suite = InspectorTest.createAsyncSuite("AsyncStackTrace");
 
-    function activeTargetData() {
-        InspectorTest.assert(WebInspector.debuggerManager.activeCallFrame, "Active call frame should exist.");
-        if (!WebInspector.debuggerManager.activeCallFrame)
-            return null;
-
-        let targetData = WebInspector.debuggerManager.dataForTarget(WebInspector.debuggerManager.activeCallFrame.target);
-        InspectorTest.assert(targetData, "Data for active call frame target should exist.");
-        return targetData;
-    }
-
-    function logCallStack() {
-        function callFrameString(callFrame) {
-            let code = callFrame.nativeCode ? "N" : (callFrame.programCode ? "P" : "F");
-            return `[${code}] ${callFrame.functionName}`;
-        }
-
-        function logCallFrames(callFrames) {
-            for (let callFrame of callFrames) {
-                InspectorTest.log(`${callFrameIndex++}: ${callFrameString(callFrame)}`);
-                // Skip remaining call frames after the test harness entry point.
-                if (callFrame.programCode)
-                    break;
-            }
-        }
-
-        let {callFrames, asyncStackTrace} = activeTargetData();
-        InspectorTest.assert(callFrames);
-        InspectorTest.assert(asyncStackTrace);
-
-        let callFrameIndex = 0;
-        logCallFrames(callFrames);
-
-        while (asyncStackTrace) {
-            let callFrames = asyncStackTrace.callFrames;
-            let topCallFrameIsBoundary = asyncStackTrace.topCallFrameIsBoundary;
-            asyncStackTrace = asyncStackTrace.parentStackTrace;
-            if (!callFrames || !callFrames.length)
-                continue;
-
-            let boundaryLabel = topCallFrameIsBoundary ? callFrameString(callFrames.shift()) : "(async)";
-            InspectorTest.log(`-- ${boundaryLabel} ----`);
-            logCallFrames(callFrames);
-        }
-    }
-
     function addSimpleTestCase(name, _expression_) {
         suite.addTestCase({
             name: `CheckAsyncStackTrace.${name}`,
@@ -104,8 +72,7 @@
                 let pauseCount = 0;
                 function handlePaused() {
                     InspectorTest.log(`PAUSE #${++pauseCount}`);
-                    InspectorTest.log("CALL STACK:");
-                    logCallStack();
+                    logActiveStackTrace();
                     WebInspector.debuggerManager.resume();
                 }
 
@@ -146,8 +113,9 @@
         test(resolve, reject) {
             WebInspector.debuggerManager.awaitEvent(WebInspector.DebuggerManager.Event.Paused)
             .then((event) => {
-                let stackTrace = activeTargetData().asyncStackTrace;
-                InspectorTest.expectNull(stackTrace, "Async stack trace should be null.");
+                let stackTrace = getActiveStackTrace();
+                let asyncStackTrace = stackTrace.parentStackTrace;
+                InspectorTest.expectNull(asyncStackTrace, "Async stack trace should be null.");
                 WebInspector.debuggerManager.resume().then(resolve, reject);
             });
 
@@ -156,29 +124,56 @@
         }
     });
 
-    suite.addTestCase({
-        name: "AsyncStackTrace.SetStackTraceDepth",
-        setup,
-        teardown,
-        test(resolve, reject) {
-            WebInspector.debuggerManager.awaitEvent(WebInspector.DebuggerManager.Event.Paused)
-            .then((event) => {
-                let stackTrace = activeTargetData().asyncStackTrace;
-                InspectorTest.assert(stackTrace && stackTrace.callFrames);
-                if (!stackTrace || !stackTrace.callFrames)
-                    reject();
+    function addTruncateTestCase(name, asyncStackTraceDepth) {
+        suite.addTestCase({
+            name: `AsyncStackTrace.${name}`,
+            setup,
+            teardown,
+            test(resolve, reject) {
+                // When repeatingRequestAnimationFrame calls rAF, the backend will store a call stack with length 2:
+                // one frame for the caller and one for the asynchronous boundary. As a result, the parity of
+                // Debugger.asyncStackTraceDepth determines whether the trace is truncated on a call stack boundary
+                // (even) or call frame boundary (odd). Since truncation doesn't remove individual call frames,
+                // the depth of the resulting stack trace may exceed the depth setting:
+                //     S = { sšŸ¶, sšŸ·, …, sš‘˜ }
+                //     T = truncate(S)
+                //     depth(T) ≤ d + depth(tš‘˜)
+                const framesPerCallStack = 2;
+                const expectedStackTraceDepth = asyncStackTraceDepth + (asyncStackTraceDepth % framesPerCallStack);
 
-                InspectorTest.expectEqual(stackTrace.callFrames.length, maxStackDepth, "Number of call frames should be equal to the depth setting.");
-                WebInspector.debuggerManager.resume().then(resolve, reject);
-            });
+                WebInspector.debuggerManager.awaitEvent(WebInspector.DebuggerManager.Event.Paused)
+                .then((event) => {
+                    let stackTrace = getActiveStackTrace();
+                    InspectorTest.assert(stackTrace && stackTrace.callFrames);
+                    if (!stackTrace || !stackTrace.callFrames)
+                        reject();
 
-            const maxStackDepth = 2;
-            const functionCallCount = maxStackDepth * 2;
-            WebInspector.debuggerManager.asyncStackTraceDepth = maxStackDepth;
-            InspectorTest.evaluateInPage(`recursiveCallThenTest(testRequestAnimationFrame, ${functionCallCount})`);
-        }
-    });
+                    let stackTraceDepth = 0;
+                    while (stackTrace.parentStackTrace) {
+                        InspectorTest.expectFalse(stackTrace.truncated, "Non-root StackTrace should not be truncated.");
+                        stackTrace = stackTrace.parentStackTrace;
+                        stackTraceDepth += stackTrace.callFrames.length;
+                    }
 
+                    InspectorTest.expectThat(stackTrace.truncated, "StackTrace root should be truncated.");
+                    InspectorTest.expectEqual(stackTraceDepth, expectedStackTraceDepth, "StackTrace should be truncated to the nearest call stack.");
+
+                    logActiveStackTrace();
+                    WebInspector.debuggerManager.resume().then(resolve, reject);
+                });
+
+                InspectorTest.log(`Set Debugger.asyncStackTraceDepth equal to ${asyncStackTraceDepth}`);
+                WebInspector.debuggerManager.asyncStackTraceDepth = asyncStackTraceDepth;
+
+                let repeatCount = Math.floor(asyncStackTraceDepth / framesPerCallStack) + 1;
+                InspectorTest.evaluateInPage(`repeatingRequestAnimationFrame(${repeatCount})`);
+            }
+        });
+    }
+
+    addTruncateTestCase("ForceTruncationOnCallStackBoundary", 4);
+    addTruncateTestCase("ForceTruncationWithinCallStack", 5);
+
     suite.runTestCasesAndFinish();
 }
 </script>

Added: trunk/LayoutTests/inspector/debugger/resources/log-active-stack-trace.js (0 => 211385)


--- trunk/LayoutTests/inspector/debugger/resources/log-active-stack-trace.js	                        (rev 0)
+++ trunk/LayoutTests/inspector/debugger/resources/log-active-stack-trace.js	2017-01-30 22:01:07 UTC (rev 211385)
@@ -0,0 +1,67 @@
+TestPage.registerInitializer(() => {
+    window.getActiveStackTrace = function() {
+        InspectorTest.assert(WebInspector.debuggerManager.activeCallFrame, "Active call frame should exist.");
+        if (!WebInspector.debuggerManager.activeCallFrame)
+            return null;
+
+        let targetData = WebInspector.debuggerManager.dataForTarget(WebInspector.debuggerManager.activeCallFrame.target);
+        InspectorTest.assert(targetData, "Data for active call frame target should exist.");
+        if (!targetData)
+            return null;
+
+        const topCallFrameIsBoundary = false;
+        const truncated = false;
+        return new WebInspector.StackTrace(targetData.callFrames, topCallFrameIsBoundary, truncated, targetData.asyncStackTrace);
+    }
+
+    window.logActiveStackTrace = function() {
+        function logStackTrace(stackTrace) {
+            let foundAsyncBoundary = false;
+            let callFrameIndex = 0;
+
+            function logCallFrame(callFrame, isAsyncBoundary) {
+                let label = callFrame.functionName;
+                if (isAsyncBoundary)
+                    InspectorTest.log(`${callFrameIndex}: --- ${label} ---`);
+                else {
+                    let code = callFrame.nativeCode ? "N" : (callFrame.programCode ? "P" : "F");
+                    InspectorTest.log(`${callFrameIndex}: [${code}] ${label}`);
+                }
+                callFrameIndex++;
+            }
+
+            InspectorTest.log("CALL STACK:");
+
+            while (stackTrace) {
+                let callFrames = stackTrace.callFrames;
+                let topCallFrameIsBoundary = stackTrace.topCallFrameIsBoundary;
+                let truncated = stackTrace.truncated;
+                stackTrace = stackTrace.parentStackTrace;
+                if (!callFrames || !callFrames.length)
+                    continue;
+
+                if (topCallFrameIsBoundary) {
+                    if (!foundAsyncBoundary) {
+                        InspectorTest.log("ASYNC CALL STACK:");
+                        foundAsyncBoundary = true;
+                    }
+                    logCallFrame(callFrames[0], true);
+                }
+
+                for (let i = topCallFrameIsBoundary ? 1 : 0; i < callFrames.length; ++i) {
+                    let callFrame = callFrames[i];
+                    logCallFrame(callFrame);
+
+                    // Skip call frames after the test harness entry point.
+                    if (callFrame.programCode)
+                        break;
+                }
+
+                if (truncated)
+                    InspectorTest.log("(remaining call frames truncated)");
+            }
+        }
+
+        logStackTrace(getActiveStackTrace());
+    }
+});

Modified: trunk/Source/_javascript_Core/CMakeLists.txt (211384 => 211385)


--- trunk/Source/_javascript_Core/CMakeLists.txt	2017-01-30 21:02:16 UTC (rev 211384)
+++ trunk/Source/_javascript_Core/CMakeLists.txt	2017-01-30 22:01:07 UTC (rev 211385)
@@ -514,6 +514,7 @@
     heap/WeakSet.cpp
     heap/WriteBarrierSupport.cpp
 
+    inspector/AsyncStackTrace.cpp
     inspector/ConsoleMessage.cpp
     inspector/ContentSearchUtilities.cpp
     inspector/EventLoop.cpp

Modified: trunk/Source/_javascript_Core/ChangeLog (211384 => 211385)


--- trunk/Source/_javascript_Core/ChangeLog	2017-01-30 21:02:16 UTC (rev 211384)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-01-30 22:01:07 UTC (rev 211385)
@@ -1,3 +1,91 @@
+2017-01-30  Matt Baker  <mattba...@apple.com>
+
+        Web Inspector: Need some limit on Async Call Stacks for async loops (rAF loops)
+        https://bugs.webkit.org/show_bug.cgi?id=165633
+        <rdar://problem/29738502>
+
+        Reviewed by Joseph Pecoraro.
+
+        This patch limits the memory used by the Inspector backend to store async
+        stack trace data.
+
+        Asynchronous stack traces are stored as a disjoint set of parent pointer
+        trees. Tree nodes represent asynchronous operations, and hold a copy of
+        the stack trace at the time the operation was scheduled. Each tree can
+        be regarded as a set of stack traces, stored as singly linked lists that
+        share part of their structure (specifically their tails). Traces belonging
+        to the same tree will at least share a common root. A stack trace begins
+        at a leaf node and follows the chain of parent pointers to the root of
+        of the tree. Leaf nodes always contain pending asynchronous calls.
+
+        When an asynchronous operation is scheduled with requestAnimationFrame,
+        setInterval, etc, a node is created containing the current call stack and
+        some bookkeeping data for the operation. An unique identifier comprised
+        of an operation type and callback identifier is mapped to the node. If
+        scheduling the callback was itself the result of an asynchronous call,
+        the node becomes a child of the node associated with that call, otherwise
+        it becomes the root of a new tree.
+
+        A node is either `pending`, `active`, `dispatched`, or `canceled`. Nodes
+        start out as pending. After a callback for a pending node is dispatched
+        the node is marked as such, unless it is a repeating callback such as
+        setInterval, in which case it remains pending. Once a node is no longer
+        pending it is removed, as long as it has no children. Since nodes are
+        reference counted, it is a property of the stack trace tree that nodes
+        that are no longer pending and have no children pointing to them will be
+        automatically pruned from the tree.
+
+        If an async operation is canceled (e.g. cancelTimeout), the associated
+        node is marked as such. If the callback is not being dispatched at the
+        time, and has no children, it is removed.
+
+        Because async operations can be chained indefinitely, stack traces are
+        limited to a maximum depth. The depth of a stack trace is equal to the
+        sum of the depths of its nodes, with a node's depth equal to the number
+        of frames in its associated call stack. For any stack trace,
+
+            S = { sšŸ¶, sšŸ·, …, sš‘˜ }, with endpoints sšŸ¶, sš‘˜
+            depth(S) = depth(sšŸ¶) + depth(sšŸ·) + … + depth(sš‘˜)
+
+        A stack trace is truncated when it exceeds the maximum depth. Truncation
+        occurs on node boundaries, not call frames, consequently the maximum depth
+        is more of a target than a guarantee:
+
+            d = maximum stack trace depth
+            for all S, depth(S) ≤ d + depth(sš‘˜)
+
+        Because nodes can belong to multiple stack traces, it may be necessary
+        to clone the tail of a stack trace being truncated to prevent other traces
+        from being effected.
+
+        * CMakeLists.txt:
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * inspector/AsyncStackTrace.cpp: Added.
+        (Inspector::AsyncStackTrace::create):
+        (Inspector::AsyncStackTrace::AsyncStackTrace):
+        (Inspector::AsyncStackTrace::~AsyncStackTrace):
+        (Inspector::AsyncStackTrace::isPending):
+        (Inspector::AsyncStackTrace::isLocked):
+        (Inspector::AsyncStackTrace::willDispatchAsyncCall):
+        (Inspector::AsyncStackTrace::didDispatchAsyncCall):
+        (Inspector::AsyncStackTrace::didCancelAsyncCall):
+        (Inspector::AsyncStackTrace::buildInspectorObject):
+        (Inspector::AsyncStackTrace::truncate):
+        (Inspector::AsyncStackTrace::remove):
+        * inspector/AsyncStackTrace.h:
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::didScheduleAsyncCall):
+        (Inspector::InspectorDebuggerAgent::didCancelAsyncCall):
+        (Inspector::InspectorDebuggerAgent::willDispatchAsyncCall):
+        (Inspector::InspectorDebuggerAgent::didDispatchAsyncCall):
+        (Inspector::InspectorDebuggerAgent::didPause):
+        (Inspector::InspectorDebuggerAgent::clearAsyncStackTraceData):
+        (Inspector::InspectorDebuggerAgent::buildAsyncStackTrace): Deleted.
+        (Inspector::InspectorDebuggerAgent::refAsyncCallData): Deleted.
+        (Inspector::InspectorDebuggerAgent::derefAsyncCallData): Deleted.
+        * inspector/agents/InspectorDebuggerAgent.h:
+        * inspector/protocol/Console.json:
+
 2017-01-30  Ryan Haddad  <ryanhad...@apple.com>
 
         Unreviewed, rolling out r211345.

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (211384 => 211385)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2017-01-30 21:02:16 UTC (rev 211384)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2017-01-30 22:01:07 UTC (rev 211385)
@@ -1376,6 +1376,8 @@
 		65C0285D1717966800351E35 /* ARMv7DOpcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 65C0285B1717966800351E35 /* ARMv7DOpcode.h */; };
 		65FB5117184EEE7000C12B70 /* ProtoCallFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65FB5116184EE9BC00C12B70 /* ProtoCallFrame.cpp */; };
 		65FB63A41C8EA09C0020719B /* YarrCanonicalizeUnicode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65A946141C8E9F6F00A7209A /* YarrCanonicalizeUnicode.cpp */; };
+		6A38CFA91E32B5AB0060206F /* AsyncStackTrace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6A38CFA71E32B58B0060206F /* AsyncStackTrace.cpp */; };
+		6A38CFAA1E32B5AB0060206F /* AsyncStackTrace.h in Headers */ = {isa = PBXBuildFile; fileRef = 6A38CFA81E32B58B0060206F /* AsyncStackTrace.h */; };
 		6AD2CB4D19B9140100065719 /* DebuggerEvalEnabler.h in Headers */ = {isa = PBXBuildFile; fileRef = 6AD2CB4C19B9140100065719 /* DebuggerEvalEnabler.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		70113D4B1A8DB093003848C4 /* IteratorOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 70113D491A8DB093003848C4 /* IteratorOperations.cpp */; };
 		70113D4C1A8DB093003848C4 /* IteratorOperations.h in Headers */ = {isa = PBXBuildFile; fileRef = 70113D4A1A8DB093003848C4 /* IteratorOperations.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -3839,6 +3841,8 @@
 		65EA73630BAE35D1001BB560 /* CommonIdentifiers.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CommonIdentifiers.h; sourceTree = "<group>"; };
 		65FB5115184EE8F800C12B70 /* ProtoCallFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProtoCallFrame.h; sourceTree = "<group>"; };
 		65FB5116184EE9BC00C12B70 /* ProtoCallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProtoCallFrame.cpp; sourceTree = "<group>"; };
+		6A38CFA71E32B58B0060206F /* AsyncStackTrace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AsyncStackTrace.cpp; sourceTree = "<group>"; };
+		6A38CFA81E32B58B0060206F /* AsyncStackTrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AsyncStackTrace.h; sourceTree = "<group>"; };
 		6AD2CB4C19B9140100065719 /* DebuggerEvalEnabler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebuggerEvalEnabler.h; sourceTree = "<group>"; };
 		6BA93C9590484C5BAD9316EA /* JSScriptFetcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSScriptFetcher.h; sourceTree = "<group>"; };
 		70113D491A8DB093003848C4 /* IteratorOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IteratorOperations.cpp; sourceTree = "<group>"; };
@@ -5029,13 +5033,13 @@
 			children = (
 				0F9327591C20BCBA00CF6564 /* dynbench */,
 				0FF922CF14F46B130041A24E /* JSCLLIntOffsetsExtractor */,
+				141211200A48793C00480255 /* minidom */,
 				0F6183431C45F62A0072450B /* testair */,
+				14BD59BF0A3E8F9000BAF59C /* testapi */,
+				0FEC85AD1BDB5CF10080FF74 /* testb3 */,
 				6511230514046A4C002B101D /* testRegExp */,
 				932F5BD90822A1C700736975 /* _javascript_Core.framework */,
 				932F5BE10822A1C700736975 /* jsc */,
-				141211200A48793C00480255 /* minidom */,
-				14BD59BF0A3E8F9000BAF59C /* testapi */,
-				0FEC85AD1BDB5CF10080FF74 /* testb3 */,
 			);
 			name = Products;
 			sourceTree = "<group>";
@@ -5256,10 +5260,10 @@
 				0FEC84C01BDACDAC0080FF74 /* B3Common.h */,
 				0FEC84C11BDACDAC0080FF74 /* B3Commutativity.cpp */,
 				0FEC84C21BDACDAC0080FF74 /* B3Commutativity.h */,
-				7919B77F1E03559C005BEED8 /* B3Compile.h */,
-				795F099C1E03600500BBE37F /* B3Compile.cpp */,
 				0F338DFF1BF0276C0013C88F /* B3Compilation.cpp */,
 				0F338E001BF0276C0013C88F /* B3Compilation.h */,
+				795F099C1E03600500BBE37F /* B3Compile.cpp */,
+				7919B77F1E03559C005BEED8 /* B3Compile.h */,
 				0F86AE1F1C5311C5006BE8EC /* B3ComputeDivisionMagic.h */,
 				0FEC84C31BDACDAC0080FF74 /* B3Const32Value.cpp */,
 				0FEC84C41BDACDAC0080FF74 /* B3Const32Value.h */,
@@ -6365,9 +6369,9 @@
 				E178633F0D9BEC0000D74E75 /* InitializeThreading.h */,
 				E35E035D1B7AB43E0073AD2A /* InspectorInstrumentationObject.cpp */,
 				E35E035E1B7AB43E0073AD2A /* InspectorInstrumentationObject.h */,
-				A7A8AF2B17ADB5F3005AB174 /* Int8Array.h */,
 				A7A8AF2C17ADB5F3005AB174 /* Int16Array.h */,
 				A7A8AF2D17ADB5F3005AB174 /* Int32Array.h */,
+				A7A8AF2B17ADB5F3005AB174 /* Int8Array.h */,
 				BC9BB95B0E19680600DF8855 /* InternalFunction.cpp */,
 				BC11667A0E199C05008066DD /* InternalFunction.h */,
 				A1B9E2331B4E0D6700BC7FED /* IntlCollator.cpp */,
@@ -6462,9 +6466,9 @@
 				BC756FC60E2031B200DE7D12 /* JSGlobalObjectFunctions.cpp */,
 				BC756FC70E2031B200DE7D12 /* JSGlobalObjectFunctions.h */,
 				79B819921DD25CF500DDC714 /* JSGlobalObjectInlines.h */,
-				0F2B66C917B6B5AB00A7AE3F /* JSInt8Array.h */,
 				0F2B66CA17B6B5AB00A7AE3F /* JSInt16Array.h */,
 				0F2B66CB17B6B5AB00A7AE3F /* JSInt32Array.h */,
+				0F2B66C917B6B5AB00A7AE3F /* JSInt8Array.h */,
 				E33F507E1B8429A400413856 /* JSInternalPromise.cpp */,
 				E33F507F1B8429A400413856 /* JSInternalPromise.h */,
 				E33F50761B84225700413856 /* JSInternalPromiseConstructor.cpp */,
@@ -6552,10 +6556,10 @@
 				53F256E11B87E28000B4B768 /* JSTypedArrayViewPrototype.cpp */,
 				53917E7C1B791106000EBD33 /* JSTypedArrayViewPrototype.h */,
 				6507D2970E871E4A00D7D896 /* JSTypeInfo.h */,
+				0F2B66D417B6B5AB00A7AE3F /* JSUint16Array.h */,
+				0F2B66D517B6B5AB00A7AE3F /* JSUint32Array.h */,
 				0F2B66D217B6B5AB00A7AE3F /* JSUint8Array.h */,
 				0F2B66D317B6B5AB00A7AE3F /* JSUint8ClampedArray.h */,
-				0F2B66D417B6B5AB00A7AE3F /* JSUint16Array.h */,
-				0F2B66D517B6B5AB00A7AE3F /* JSUint32Array.h */,
 				A7CA3AE117DA41AE006538AF /* JSWeakMap.cpp */,
 				A7CA3AE217DA41AE006538AF /* JSWeakMap.h */,
 				709FB8611AE335C60039D069 /* JSWeakSet.cpp */,
@@ -6762,11 +6766,11 @@
 				0F2D4DE019832D91007D4B19 /* TypeProfilerLog.h */,
 				0F2D4DE319832D91007D4B19 /* TypeSet.cpp */,
 				0F2D4DE419832D91007D4B19 /* TypeSet.h */,
-				A7A8AF3017ADB5F3005AB174 /* Uint8Array.h */,
-				A7A8AF3117ADB5F3005AB174 /* Uint8ClampedArray.h */,
 				A7A8AF3217ADB5F3005AB174 /* Uint16Array.h */,
 				866739D113BFDE710023D87C /* Uint16WithFraction.h */,
 				A7A8AF3317ADB5F3005AB174 /* Uint32Array.h */,
+				A7A8AF3017ADB5F3005AB174 /* Uint8Array.h */,
+				A7A8AF3117ADB5F3005AB174 /* Uint8ClampedArray.h */,
 				0FE050231AA9095600D33B33 /* VarOffset.cpp */,
 				0FE050241AA9095600D33B33 /* VarOffset.h */,
 				E18E3A570DF9278C00D90B34 /* VM.cpp */,
@@ -7553,6 +7557,8 @@
 				A532438D185696CA002ED692 /* protocol */,
 				A5BA15E01823409D00A82E69 /* remote */,
 				A532438E185696CE002ED692 /* scripts */,
+				6A38CFA71E32B58B0060206F /* AsyncStackTrace.cpp */,
+				6A38CFA81E32B58B0060206F /* AsyncStackTrace.h */,
 				A5FD0077189B051000633231 /* ConsoleMessage.cpp */,
 				A5FD0078189B051000633231 /* ConsoleMessage.h */,
 				A57D23EF1891B5B40031C7FA /* ContentSearchUtilities.cpp */,
@@ -7908,6 +7914,7 @@
 				A784A26111D16622005776AC /* ASTBuilder.h in Headers */,
 				5B70CFE21DB69E6600EC23F9 /* AsyncFunctionConstructor.h in Headers */,
 				5B70CFE01DB69E6600EC23F9 /* AsyncFunctionPrototype.h in Headers */,
+				6A38CFAA1E32B5AB0060206F /* AsyncStackTrace.h in Headers */,
 				0F7CF9571DC125900098CC12 /* AtomicsObject.h in Headers */,
 				A5EA70E719F5B1010098F5EC /* AugmentableInspectorController.h in Headers */,
 				A5EA70E819F5B1010098F5EC /* AugmentableInspectorControllerClient.h in Headers */,
@@ -7930,6 +7937,7 @@
 				0FEC850A1BDACDAC0080FF74 /* B3Common.h in Headers */,
 				0FEC850C1BDACDAC0080FF74 /* B3Commutativity.h in Headers */,
 				0F338E0C1BF0276C0013C88F /* B3Compilation.h in Headers */,
+				7919B7801E03559C005BEED8 /* B3Compile.h in Headers */,
 				0F86AE201C5311C5006BE8EC /* B3ComputeDivisionMagic.h in Headers */,
 				0FEC850E1BDACDAC0080FF74 /* B3Const32Value.h in Headers */,
 				0FEC85101BDACDAC0080FF74 /* B3Const64Value.h in Headers */,
@@ -8029,7 +8037,6 @@
 				0FB7F39815ED8E4600F167B2 /* ButterflyInlines.h in Headers */,
 				C2FCAE1117A9C24E0034C735 /* BytecodeBasicBlock.h in Headers */,
 				0F21C27F14BEAA8200ADC64B /* BytecodeConventions.h in Headers */,
-				0F1FB3931E177A7200A9BE50 /* VisitingTimeout.h in Headers */,
 				969A07230ED1CE3300F1F681 /* BytecodeGenerator.h in Headers */,
 				E328DAE81D38D005001A2529 /* BytecodeGeneratorification.h in Headers */,
 				E328DAE91D38D005001A2529 /* BytecodeGraph.h in Headers */,
@@ -8055,7 +8062,6 @@
 				FE80C1971D775CDD008510C0 /* CatchScope.h in Headers */,
 				0F24E54217EA9F5900ABB217 /* CCallHelpers.h in Headers */,
 				0F070A471D543A8B006E7232 /* CellContainer.h in Headers */,
-				ADE8029A1E08F1DE0058DE78 /* WebAssemblyLinkErrorConstructor.h in Headers */,
 				0F070A481D543A90006E7232 /* CellContainerInlines.h in Headers */,
 				0F1C3DDA1BBCE09E00E523E4 /* CellState.h in Headers */,
 				BC6AAAE50E1F426500AD87D8 /* ClassInfo.h in Headers */,
@@ -8093,6 +8099,7 @@
 				A55714BE1CD8049F0004D2C6 /* ConsoleObject.h in Headers */,
 				A5FD0074189B038C00633231 /* ConsoleTypes.h in Headers */,
 				0FFC99D1184EC8AD009C10AB /* ConstantMode.h in Headers */,
+				0F7DF1341E2970D70095951B /* ConstraintVolatility.h in Headers */,
 				E354622B1B6065D100545386 /* ConstructAbility.h in Headers */,
 				BC18C3F60E16F5CD00B34460 /* ConstructData.h in Headers */,
 				A57D23F21891B5B40031C7FA /* ContentSearchUtilities.h in Headers */,
@@ -8114,7 +8121,6 @@
 				BCD203E80E1718F4002C7E82 /* DatePrototype.lut.h in Headers */,
 				BC18C3FA0E16F5CD00B34460 /* Debugger.h in Headers */,
 				BC18C3FB0E16F5CD00B34460 /* DebuggerCallFrame.h in Headers */,
-				0F7DF1351E2970DC0095951B /* MarkedSpaceInlines.h in Headers */,
 				6AD2CB4D19B9140100065719 /* DebuggerEvalEnabler.h in Headers */,
 				A5FC84B21D1DDAD6006B5C46 /* DebuggerLocation.h in Headers */,
 				A5A1A0941D8CB33E004C2EB8 /* DebuggerParseData.h in Headers */,
@@ -8139,7 +8145,6 @@
 				0F2DD8141AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.h in Headers */,
 				0F485322187750560083B687 /* DFGArithMode.h in Headers */,
 				0F05C3B41683CF9200BAF45B /* DFGArrayifySlowPathGenerator.h in Headers */,
-				0F4F82881E2FFDE00075184C /* JSSegmentedVariableObjectSubspace.h in Headers */,
 				0F63948515E4811B006A597C /* DFGArrayMode.h in Headers */,
 				A7D9A29517A0BC7400EE2618 /* DFGAtTailAbstractState.h in Headers */,
 				0F666EC71835672B00D017F1 /* DFGAvailability.h in Headers */,
@@ -8164,7 +8169,6 @@
 				0F3B3A281544C997003ED0FF /* DFGCFGSimplificationPhase.h in Headers */,
 				0F9D36951AE9CC33000D4DFB /* DFGCleanUpPhase.h in Headers */,
 				A77A424017A0BBFD00A8DB81 /* DFGClobberize.h in Headers */,
-				AD7438C01E0457A400FD0C2A /* WasmSignature.h in Headers */,
 				A77A424217A0BBFD00A8DB81 /* DFGClobberSet.h in Headers */,
 				0F3C1F1B1B868E7900ABB08B /* DFGClobbersExitState.h in Headers */,
 				0F04396E1B03DC0B009598B7 /* DFGCombinedLiveness.h in Headers */,
@@ -8204,7 +8208,6 @@
 				0F9D339717FFC4E60073C2BC /* DFGFlushedAt.h in Headers */,
 				A7D89CF817A0B8CC00773AD8 /* DFGFlushFormat.h in Headers */,
 				0F2DD8151AB3D8BE00BBB8E8 /* DFGForAllKills.h in Headers */,
-				0F4F828C1E31B9760075184C /* StochasticSpaceTimeMutatorScheduler.h in Headers */,
 				0F69CC89193AC60A0045759E /* DFGFrozenValue.h in Headers */,
 				86EC9DC61328DF82002B2AD7 /* DFGGenerationInfo.h in Headers */,
 				86EC9DC81328DF82002B2AD7 /* DFGGraph.h in Headers */,
@@ -8258,7 +8261,6 @@
 				0FC0977114693AF500CF2442 /* DFGOSRExitCompiler.h in Headers */,
 				0F7025AA1714B0FC00382C0E /* DFGOSRExitCompilerCommon.h in Headers */,
 				0F392C8A1B46188400844728 /* DFGOSRExitFuzz.h in Headers */,
-				0F7DF13F1E2AFC4D0095951B /* JSStringSubspace.h in Headers */,
 				0FEFC9AB1681A3B600567F53 /* DFGOSRExitJumpPlaceholder.h in Headers */,
 				0F235BEE17178E7300690C7F /* DFGOSRExitPreparation.h in Headers */,
 				0F6237981AE45CA700D402EA /* DFGPhantomInsertionPhase.h in Headers */,
@@ -8265,6 +8267,7 @@
 				0FFFC95C14EF90AF00C72532 /* DFGPhase.h in Headers */,
 				0F2B9CEB19D0BA7D00B1D1B5 /* DFGPhiChildren.h in Headers */,
 				A78A977B179738B8009DF744 /* DFGPlan.h in Headers */,
+				0F1FB3961E1AF7E100A9BE50 /* DFGPlanInlines.h in Headers */,
 				DC00039319D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h in Headers */,
 				0FBE0F7516C1DB0B0082C5E8 /* DFGPredictionInjectionPhase.h in Headers */,
 				0FFFC95E14EF90B700C72532 /* DFGPredictionPropagationPhase.h in Headers */,
@@ -8295,6 +8298,7 @@
 				0F2FCCFF18A60070001A27F8 /* DFGThreadData.h in Headers */,
 				0FC097A2146B28CC00CF2442 /* DFGThunks.h in Headers */,
 				0FD8A32817D51F5700CA2C40 /* DFGTierUpCheckInjectionPhase.h in Headers */,
+				ADFF2F701E319DE3001EA54E /* DFGTierUpEntryTrigger.h in Headers */,
 				0FD8A32A17D51F5700CA2C40 /* DFGToFTLDeferredCompilationCallback.h in Headers */,
 				0FD8A32C17D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.h in Headers */,
 				0FE7211E193B9C590031F6ED /* DFGTransition.h in Headers */,
@@ -8312,6 +8316,7 @@
 				0FFFC96014EF90BD00C72532 /* DFGVirtualRegisterAllocationPhase.h in Headers */,
 				0FC97F4218202119002C9B26 /* DFGWatchpointCollectionPhase.h in Headers */,
 				0FDB2CE8174830A2007B3C1B /* DFGWorklist.h in Headers */,
+				0F1FB3971E1AF7E300A9BE50 /* DFGWorklistInlines.h in Headers */,
 				0FE050181AA9091100D33B33 /* DirectArguments.h in Headers */,
 				0FE050161AA9091100D33B33 /* DirectArgumentsOffset.h in Headers */,
 				969A07980ED1D3AE00F1F681 /* DirectEvalCodeCache.h in Headers */,
@@ -8418,7 +8423,6 @@
 				52B310FB1974AE610080857C /* FunctionHasExecutedCache.h in Headers */,
 				FE4BFF2C1AD476E700088F87 /* FunctionOverrides.h in Headers */,
 				BC18C4050E16F5CD00B34460 /* FunctionPrototype.h in Headers */,
-				7919B7801E03559C005BEED8 /* B3Compile.h in Headers */,
 				62D2D3901ADF103F000206C1 /* FunctionRareData.h in Headers */,
 				FEA0C4031CDD7D1D00481991 /* FunctionWhitelist.h in Headers */,
 				2AACE63D18CA5A0300ED0191 /* GCActivityCallback.h in Headers */,
@@ -8434,10 +8438,8 @@
 				A54E8EB018BFFBBB00556D28 /* GCSegmentedArray.h in Headers */,
 				A54E8EB118BFFBBE00556D28 /* GCSegmentedArrayInlines.h in Headers */,
 				0F86A26F1D6F7B3300CB0C92 /* GCTypeMap.h in Headers */,
-				0F7DF1381E2970E40095951B /* SubspaceInlines.h in Headers */,
 				9959E9311BD18272001AA413 /* generate-combined-inspector-json.py in Headers */,
 				C4703CC0192844960013FBEA /* generate-inspector-protocol-bindings.py in Headers */,
-				0F7DF1461E2BEF6A0095951B /* MarkedAllocatorInlines.h in Headers */,
 				99DA00AF1BD5994E00F4575C /* generate-js-builtins.py in Headers */,
 				A5EA70EC19F5B3EA0098F5EC /* generate_cpp_alternate_backend_dispatcher_header.py in Headers */,
 				A5EF9B141A1D43F600702E90 /* generate_cpp_backend_dispatcher_header.py in Headers */,
@@ -8472,7 +8474,6 @@
 				0F0332C418B01763005F979A /* GetByIdVariant.h in Headers */,
 				7964656A1B952FF0003059EE /* GetPutInfo.h in Headers */,
 				14AD910E1DCA92940014F9FE /* GlobalCodeBlock.h in Headers */,
-				79DAE27A1E03C82200B526AA /* WasmExceptionType.h in Headers */,
 				0F24E54417EA9F5900ABB217 /* GPRInfo.h in Headers */,
 				142E3134134FF0A600AFADB5 /* Handle.h in Headers */,
 				C283190016FE4B7D00157BFD /* HandleBlock.h in Headers */,
@@ -8539,7 +8540,6 @@
 				A5339EC61BB399A60054F005 /* InspectorHeapAgent.h in Headers */,
 				E35E03601B7AB43E0073AD2A /* InspectorInstrumentationObject.h in Headers */,
 				E33B3E261B7ABD750048DB2E /* InspectorInstrumentationObject.lut.h in Headers */,
-				ADE802991E08F1DE0058DE78 /* JSWebAssemblyLinkError.h in Headers */,
 				A532438C18568335002ED692 /* InspectorProtocolObjects.h in Headers */,
 				A55D93AC18514F7900400DED /* InspectorProtocolTypes.h in Headers */,
 				A50E4B6218809DD50068A46D /* InspectorRuntimeAgent.h in Headers */,
@@ -8569,7 +8569,6 @@
 				A1D793011B43864B004516F5 /* IntlNumberFormatPrototype.h in Headers */,
 				A125846F1B45A36000CC7F6C /* IntlNumberFormatPrototype.lut.h in Headers */,
 				A12BBFF21B044A8B00664B69 /* IntlObject.h in Headers */,
-				0F1FB3971E1AF7E300A9BE50 /* DFGWorklistInlines.h in Headers */,
 				708EBE241CE8F35800453146 /* IntlObjectInlines.h in Headers */,
 				860BD801148EA6F200112B2F /* Intrinsic.h in Headers */,
 				8B9F6D561D5912FA001C739F /* IterationKind.h in Headers */,
@@ -8600,7 +8599,6 @@
 				FE187A021BFBE5610038BBCA /* JITMulGenerator.h in Headers */,
 				FE99B2491C24C3D300C82159 /* JITNegGenerator.h in Headers */,
 				0F24E54D17EE274900ABB217 /* JITOperations.h in Headers */,
-				0F7DF1371E2970E10095951B /* Subspace.h in Headers */,
 				FE3A06C01C11041A00390FDD /* JITRightShiftGenerator.h in Headers */,
 				0F766D3115AA8112008F363E /* JITStubRoutine.h in Headers */,
 				0F766D2C15A8CC3A008F363E /* JITStubRoutineSet.h in Headers */,
@@ -8646,6 +8644,7 @@
 				996B731C1BDA08DD00331B84 /* JSDataViewPrototype.lut.h in Headers */,
 				978801411471AD920041B016 /* JSDateMath.h in Headers */,
 				C2A7F688160432D400F76B98 /* JSDestructibleObject.h in Headers */,
+				0F7DF13C1E2971130095951B /* JSDestructibleObjectSubspace.h in Headers */,
 				FE384EE61ADDB7AD0055DE2C /* JSDollarVM.h in Headers */,
 				FE384EE81ADDB7AD0055DE2C /* JSDollarVMPrototype.h in Headers */,
 				BC18C42D0E16F5CD00B34460 /* JSEnvironmentRecord.h in Headers */,
@@ -8655,9 +8654,7 @@
 				0F2B66EF17B6B5AB00A7AE3F /* JSFloat32Array.h in Headers */,
 				0F2B66F017B6B5AB00A7AE3F /* JSFloat64Array.h in Headers */,
 				BC18C41F0E16F5CD00B34460 /* JSFunction.h in Headers */,
-				0F660E3A1E0517C10031462C /* MarkingConstraintSet.h in Headers */,
 				A72028BA1797603D0098028C /* JSFunctionInlines.h in Headers */,
-				0F660E381E0517BB0031462C /* MarkingConstraint.h in Headers */,
 				70B7919C1C024A49002481E2 /* JSGeneratorFunction.h in Headers */,
 				0F2B66F117B6B5AB00A7AE3F /* JSGenericTypedArrayView.h in Headers */,
 				0F2B66F217B6B5AB00A7AE3F /* JSGenericTypedArrayViewConstructor.h in Headers */,
@@ -8718,7 +8715,6 @@
 				7C184E1F17BEE22E007CB63A /* JSPromisePrototype.h in Headers */,
 				996B731F1BDA08EF00331B84 /* JSPromisePrototype.lut.h in Headers */,
 				2A05ABD61961DF2400341750 /* JSPropertyNameEnumerator.h in Headers */,
-				0F7DF13C1E2971130095951B /* JSDestructibleObjectSubspace.h in Headers */,
 				E3EF88751B66DF23003F26CB /* JSPropertyNameIterator.h in Headers */,
 				862553D216136E1A009F17D0 /* JSProxy.h in Headers */,
 				A552C3801ADDB8FE00139726 /* JSRemoteInspector.h in Headers */,
@@ -8725,11 +8721,13 @@
 				9928FF3C18AC4AEC00B8CF12 /* JSReplayInputs.h in Headers */,
 				BC18C4260E16F5CD00B34460 /* JSRetainPtr.h in Headers */,
 				14874AE615EBDE4A002E3587 /* JSScope.h in Headers */,
+				9064337DD4B0402BAF34A592 /* JSScriptFetcher.h in Headers */,
 				A7C0C4AC168103020017011D /* JSScriptRefPrivate.h in Headers */,
 				0F919D11157F332C004A4E7D /* JSSegmentedVariableObject.h in Headers */,
+				0F4F82881E2FFDE00075184C /* JSSegmentedVariableObjectSubspace.h in Headers */,
 				A7299D9E17D12837005F5FF9 /* JSSet.h in Headers */,
-				0F7DF1341E2970D70095951B /* ConstraintVolatility.h in Headers */,
 				A790DD70182F499700588807 /* JSSetIterator.h in Headers */,
+				BDFCB2BBE90F41349E1B0BED /* JSSourceCode.h in Headers */,
 				BC18C4270E16F5CD00B34460 /* JSString.h in Headers */,
 				86E85539111B9968001AF51E /* JSStringBuilder.h in Headers */,
 				FEFD6FC61D5E7992008F2F0B /* JSStringInlines.h in Headers */,
@@ -8738,6 +8736,7 @@
 				BC18C4280E16F5CD00B34460 /* JSStringRef.h in Headers */,
 				BC18C4290E16F5CD00B34460 /* JSStringRefCF.h in Headers */,
 				1A28D4A8177B71C80007FA3C /* JSStringRefPrivate.h in Headers */,
+				0F7DF13F1E2AFC4D0095951B /* JSStringSubspace.h in Headers */,
 				0F919D0D157EE0A2004A4E7D /* JSSymbolTableObject.h in Headers */,
 				70ECA6061AFDBEA200449739 /* JSTemplateRegistryKey.h in Headers */,
 				BC18C42A0E16F5CD00B34460 /* JSType.h in Headers */,
@@ -8766,6 +8765,7 @@
 				AD2FCBE31DB58DAD00B3E736 /* JSWebAssemblyCompileError.h in Headers */,
 				796FB43A1DFF8C3F0039C95D /* JSWebAssemblyHelpers.h in Headers */,
 				AD2FCBE51DB58DAD00B3E736 /* JSWebAssemblyInstance.h in Headers */,
+				ADE802991E08F1DE0058DE78 /* JSWebAssemblyLinkError.h in Headers */,
 				AD2FCBE71DB58DAD00B3E736 /* JSWebAssemblyMemory.h in Headers */,
 				AD2FCC051DB58DAD00B3E736 /* JSWebAssemblyModule.h in Headers */,
 				AD2FCBE91DB58DAD00B3E736 /* JSWebAssemblyRuntimeError.h in Headers */,
@@ -8772,7 +8772,6 @@
 				AD2FCBEB1DB58DAD00B3E736 /* JSWebAssemblyTable.h in Headers */,
 				1442566215EDE98D0066A49B /* JSWithScope.h in Headers */,
 				86E3C619167BABEE006D760A /* JSWrapperMap.h in Headers */,
-				0F1FB38F1E173A6700A9BE50 /* SynchronousStopTheWorldMutatorScheduler.h in Headers */,
 				BC18C42E0E16F5CD00B34460 /* JSWrapperObject.h in Headers */,
 				BCFD8C930EEB2EE700283848 /* JumpTable.h in Headers */,
 				A72FFD64139985A800E5365A /* KeywordLookup.h in Headers */,
@@ -8818,7 +8817,6 @@
 				863B23E00FC6118900703AA4 /* MacroAssemblerCodeRef.h in Headers */,
 				E32AB2441DCD75F400D7533A /* MacroAssemblerHelpers.h in Headers */,
 				86C568E111A213EE0007F7F0 /* MacroAssemblerMIPS.h in Headers */,
-				0F1FB3961E1AF7E100A9BE50 /* DFGPlanInlines.h in Headers */,
 				FE68C6371B90DE040042BCB3 /* MacroAssemblerPrinter.h in Headers */,
 				860161E40F3A83C100F84710 /* MacroAssemblerX86.h in Headers */,
 				860161E50F3A83C100F84710 /* MacroAssemblerX86_64.h in Headers */,
@@ -8828,10 +8826,14 @@
 				A74DEF94182D991400522C22 /* MapIteratorPrototype.h in Headers */,
 				A700873E17CBE8D300C3E643 /* MapPrototype.h in Headers */,
 				C2B916C214DA014E00CBAC86 /* MarkedAllocator.h in Headers */,
+				0F7DF1461E2BEF6A0095951B /* MarkedAllocatorInlines.h in Headers */,
 				142D6F0913539A2800B02E86 /* MarkedBlock.h in Headers */,
 				0F7C5FB81D888A0C0044F5E2 /* MarkedBlockInlines.h in Headers */,
 				141448CB13A176EC00F5BA1A /* MarkedBlockSet.h in Headers */,
 				14D2F3DB139F4BE200491031 /* MarkedSpace.h in Headers */,
+				0F7DF1351E2970DC0095951B /* MarkedSpaceInlines.h in Headers */,
+				0F660E381E0517BB0031462C /* MarkingConstraint.h in Headers */,
+				0F660E3A1E0517C10031462C /* MarkingConstraintSet.h in Headers */,
 				142D6F1213539A4100B02E86 /* MarkStack.h in Headers */,
 				8612E4CD152389EC00C836BE /* MatchResult.h in Headers */,
 				4340A4851A9051AF00D73CCA /* MathCommon.h in Headers */,
@@ -8839,7 +8841,6 @@
 				E328C6C71DA4304500D255FD /* MaxFrameExtentForSlowPathCall.h in Headers */,
 				90213E3E123A40C200D422F3 /* MemoryStatistics.h in Headers */,
 				0FB5467B14F5C7E1002C2989 /* MethodOfGettingAValueProfile.h in Headers */,
-				ADE8029C1E08F1DE0058DE78 /* WebAssemblyLinkErrorPrototype.h in Headers */,
 				7C008CE7187631B600955C24 /* Microtask.h in Headers */,
 				86C568E211A213EE0007F7F0 /* MIPSAssembler.h in Headers */,
 				C4703CD7192844CC0013FBEA /* models.py in Headers */,
@@ -8849,6 +8850,7 @@
 				14AD910F1DCA92940014F9FE /* ModuleProgramCodeBlock.h in Headers */,
 				147341D61DC02EB900AA29BA /* ModuleProgramExecutable.h in Headers */,
 				A79D3ED9C5064DD0A8466A3A /* ModuleScopeData.h in Headers */,
+				0F1FB3991E1F65FB00A9BE50 /* MutatorScheduler.h in Headers */,
 				0FA762071DB9243300B7A2FD /* MutatorState.h in Headers */,
 				BC02E9110E1839DB000F9297 /* NativeErrorConstructor.h in Headers */,
 				BC02E9130E1839DB000F9297 /* NativeErrorPrototype.h in Headers */,
@@ -8978,6 +8980,7 @@
 				A503FA22188EFF6800110F14 /* ScriptDebugListener.h in Headers */,
 				A503FA26188EFFFD00110F14 /* ScriptDebugServer.h in Headers */,
 				147341CE1DC02D7900AA29BA /* ScriptExecutable.h in Headers */,
+				CEAE7D7B889B477BA93ABA6C /* ScriptFetcher.h in Headers */,
 				A55D93A6185012A800400DED /* ScriptFunctionCall.h in Headers */,
 				A54CF2FA184EAEDA00237F19 /* ScriptObject.h in Headers */,
 				A55165D51BDF135A003B75C1 /* ScriptProfilingScope.h in Headers */,
@@ -8997,6 +9000,7 @@
 				FE187A0F1C030D6C0038BBCA /* SnippetOperand.h in Headers */,
 				14201D591DECF26A00904BD3 /* SourceCode.h in Headers */,
 				70B791911C024A13002481E2 /* SourceCodeKey.h in Headers */,
+				2D342F36F7244096804ADB24 /* SourceOrigin.h in Headers */,
 				BC18C4630E16F5CD00B34460 /* SourceProvider.h in Headers */,
 				E49DC16C12EF294E00184A1F /* SourceProviderCache.h in Headers */,
 				E49DC16D12EF295300184A1F /* SourceProviderCacheItem.h in Headers */,
@@ -9011,6 +9015,7 @@
 				A7C1EAF217987AB600299DB2 /* StackVisitor.h in Headers */,
 				14DF04DA16B3996D0016A513 /* StaticPropertyAnalysis.h in Headers */,
 				14CA958B16AB50DE00938A06 /* StaticPropertyAnalyzer.h in Headers */,
+				0F4F828C1E31B9760075184C /* StochasticSpaceTimeMutatorScheduler.h in Headers */,
 				0F7CF9521DC027D90098CC12 /* StopIfNecessaryTimer.h in Headers */,
 				A730B6121250068F009D25B1 /* StrictEvalActivation.h in Headers */,
 				BC18C4660E16F5CD00B34460 /* StringConstructor.h in Headers */,
@@ -9032,8 +9037,9 @@
 				0F766D3915AE4A1F008F363E /* StructureStubClearingWatchpoint.h in Headers */,
 				BCCF0D080EF0AAB900413C8F /* StructureStubInfo.h in Headers */,
 				BC9041480EB9250900FE26FA /* StructureTransitionTable.h in Headers */,
+				0F7DF1371E2970E10095951B /* Subspace.h in Headers */,
+				0F7DF1381E2970E40095951B /* SubspaceInlines.h in Headers */,
 				0F4A38FA1C8E13DF00190318 /* SuperSampler.h in Headers */,
-				0F1FB3991E1F65FB00A9BE50 /* MutatorScheduler.h in Headers */,
 				705B41AC1A6E501E00716757 /* Symbol.h in Headers */,
 				705B41AE1A6E501E00716757 /* SymbolConstructor.h in Headers */,
 				996B73271BDA08EF00331B84 /* SymbolConstructor.lut.h in Headers */,
@@ -9041,6 +9047,7 @@
 				705B41B21A6E501E00716757 /* SymbolPrototype.h in Headers */,
 				996B73281BDA08EF00331B84 /* SymbolPrototype.lut.h in Headers */,
 				BC18C46B0E16F5CD00B34460 /* SymbolTable.h in Headers */,
+				0F1FB38F1E173A6700A9BE50 /* SynchronousStopTheWorldMutatorScheduler.h in Headers */,
 				A784A26411D16622005776AC /* SyntaxChecker.h in Headers */,
 				DC7997831CDE9FA0004D4A09 /* TagRegistersMode.h in Headers */,
 				70ECA6081AFDBEA200449739 /* TemplateRegistry.h in Headers */,
@@ -9096,6 +9103,7 @@
 				0F6C73511AC9F99F00BE1682 /* VariableWriteFireDetail.h in Headers */,
 				0FE0502D1AA9095600D33B33 /* VarOffset.h in Headers */,
 				0F426A491460CBB700131F8F /* VirtualRegister.h in Headers */,
+				0F1FB3931E177A7200A9BE50 /* VisitingTimeout.h in Headers */,
 				0F952AA11DF7860900E06FBD /* VisitRaceKey.h in Headers */,
 				BC18C4200E16F5CD00B34460 /* VM.h in Headers */,
 				658D3A5619638268003C45D6 /* VMEntryRecord.h in Headers */,
@@ -9104,6 +9112,7 @@
 				53F40E931D5A4AB30099A1B6 /* WasmB3IRGenerator.h in Headers */,
 				AD4B1DFA1DF244E20071AE32 /* WasmBinding.h in Headers */,
 				53FD04D41D7AB291003287D3 /* WasmCallingConvention.h in Headers */,
+				79DAE27A1E03C82200B526AA /* WasmExceptionType.h in Headers */,
 				7BC547D31B6959A100959B58 /* WasmFormat.h in Headers */,
 				53F40E8B1D5901BB0099A1B6 /* WasmFunctionParser.h in Headers */,
 				535557141D9D9EA5006D583B /* WasmMemory.h in Headers */,
@@ -9114,6 +9123,7 @@
 				53F40E8D1D5901F20099A1B6 /* WasmParser.h in Headers */,
 				531374BD1D5CE67600AF7A0B /* WasmPlan.h in Headers */,
 				53F40E851D58F9770099A1B6 /* WasmSections.h in Headers */,
+				AD7438C01E0457A400FD0C2A /* WasmSignature.h in Headers */,
 				53FF7F991DBFCD9000A26CCC /* WasmValidate.h in Headers */,
 				FED94F2F171E3E2300BE77A4 /* Watchdog.h in Headers */,
 				0F919D2615853CE3004A4E7D /* Watchpoint.h in Headers */,
@@ -9141,6 +9151,8 @@
 				AD2FCC181DB59CB200B3E736 /* WebAssemblyInstanceConstructor.lut.h in Headers */,
 				AD2FCBF31DB58DAD00B3E736 /* WebAssemblyInstancePrototype.h in Headers */,
 				AD2FCC191DB59CB200B3E736 /* WebAssemblyInstancePrototype.lut.h in Headers */,
+				ADE8029A1E08F1DE0058DE78 /* WebAssemblyLinkErrorConstructor.h in Headers */,
+				ADE8029C1E08F1DE0058DE78 /* WebAssemblyLinkErrorPrototype.h in Headers */,
 				AD2FCBF51DB58DAD00B3E736 /* WebAssemblyMemoryConstructor.h in Headers */,
 				AD2FCC1A1DB59CB200B3E736 /* WebAssemblyMemoryConstructor.lut.h in Headers */,
 				AD2FCBF71DB58DAD00B3E736 /* WebAssemblyMemoryPrototype.h in Headers */,
@@ -9172,10 +9184,6 @@
 				86704B8812DBA33700A9FE7B /* YarrParser.h in Headers */,
 				86704B8A12DBA33700A9FE7B /* YarrPattern.h in Headers */,
 				86704B4312DB8A8100A9FE7B /* YarrSyntaxChecker.h in Headers */,
-				2D342F36F7244096804ADB24 /* SourceOrigin.h in Headers */,
-				BDFCB2BBE90F41349E1B0BED /* JSSourceCode.h in Headers */,
-				9064337DD4B0402BAF34A592 /* JSScriptFetcher.h in Headers */,
-				CEAE7D7B889B477BA93ABA6C /* ScriptFetcher.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -9727,6 +9735,7 @@
 				0F24E54017EA9F5900ABB217 /* AssemblyHelpers.cpp in Sources */,
 				5B70CFE31DB69E6600EC23F9 /* AsyncFunctionConstructor.cpp in Sources */,
 				5B70CFE11DB69E6600EC23F9 /* AsyncFunctionPrototype.cpp in Sources */,
+				6A38CFA91E32B5AB0060206F /* AsyncStackTrace.cpp in Sources */,
 				0F7CF9561DC1258D0098CC12 /* AtomicsObject.cpp in Sources */,
 				0FEC84FE1BDACDAC0080FF74 /* B3ArgumentRegValue.cpp in Sources */,
 				0FEC85001BDACDAC0080FF74 /* B3BasicBlock.cpp in Sources */,
@@ -9739,6 +9748,7 @@
 				0FEC85091BDACDAC0080FF74 /* B3Common.cpp in Sources */,
 				0FEC850B1BDACDAC0080FF74 /* B3Commutativity.cpp in Sources */,
 				0F338E0B1BF0276C0013C88F /* B3Compilation.cpp in Sources */,
+				795F099D1E03600500BBE37F /* B3Compile.cpp in Sources */,
 				0FEC850D1BDACDAC0080FF74 /* B3Const32Value.cpp in Sources */,
 				0FEC850F1BDACDAC0080FF74 /* B3Const64Value.cpp in Sources */,
 				0FEC85111BDACDAC0080FF74 /* B3ConstDoubleValue.cpp in Sources */,
@@ -9800,8 +9810,6 @@
 				0F64B2711A784BAF006E4E66 /* BinarySwitch.cpp in Sources */,
 				14280863107EC11A0013E7B2 /* BooleanConstructor.cpp in Sources */,
 				14280864107EC11A0013E7B2 /* BooleanObject.cpp in Sources */,
-				0F4F82871E2FFDDD0075184C /* JSSegmentedVariableObjectSubspace.cpp in Sources */,
-				ADB6F67D1E15D7600082F384 /* WasmPageCount.cpp in Sources */,
 				14280865107EC11A0013E7B2 /* BooleanPrototype.cpp in Sources */,
 				DE26E9071CB5DEFB00D2BE82 /* BuiltinExecutableCreator.cpp in Sources */,
 				A7D801A41880D66E0026C39B /* BuiltinExecutables.cpp in Sources */,
@@ -9846,7 +9854,6 @@
 				A7E5A3A71797432D00E893C0 /* CompilationResult.cpp in Sources */,
 				147F39C2107EC37600427A48 /* Completion.cpp in Sources */,
 				0F6FC750196110A800E1D02D /* ComplexGetStatus.cpp in Sources */,
-				0F1FB38E1E173A6500A9BE50 /* SynchronousStopTheWorldMutatorScheduler.cpp in Sources */,
 				146B16D812EB5B59001BEC1B /* ConservativeRoots.cpp in Sources */,
 				A5B6A74D18C6DBA600F11E91 /* ConsoleClient.cpp in Sources */,
 				A5FD0079189B051000633231 /* ConsoleMessage.cpp in Sources */,
@@ -9862,7 +9869,6 @@
 				147F39C4107EC37600427A48 /* DateConversion.cpp in Sources */,
 				147F39C5107EC37600427A48 /* DateInstance.cpp in Sources */,
 				147F39C6107EC37600427A48 /* DatePrototype.cpp in Sources */,
-				0F660E391E0517BF0031462C /* MarkingConstraintSet.cpp in Sources */,
 				14280823107EC02C0013E7B2 /* Debugger.cpp in Sources */,
 				149559EE0DDCDDF700648087 /* DebuggerCallFrame.cpp in Sources */,
 				A5FC84B31D1DDAD9006B5C46 /* DebuggerLocation.cpp in Sources */,
@@ -9944,7 +9950,6 @@
 				A7D89CFB17A0B8CC00773AD8 /* DFGLivenessAnalysisPhase.cpp in Sources */,
 				0FF0F19916B729F6005DF95B /* DFGLongLivedState.cpp in Sources */,
 				A767B5B517A0B9650063D940 /* DFGLoopPreHeaderCreationPhase.cpp in Sources */,
-				ADE8029E1E08F2280058DE78 /* WebAssemblyLinkErrorConstructor.cpp in Sources */,
 				79F8FC1E1B9FED0F00CA66AB /* DFGMaximalFlushInsertionPhase.cpp in Sources */,
 				0F5874ED194FEB1200AAB2C1 /* DFGMayExit.cpp in Sources */,
 				0F1725FF1B48719A00AC3A55 /* DFGMinifiedGraph.cpp in Sources */,
@@ -9983,7 +9988,6 @@
 				0FB17662196B8F9E0091052A /* DFGPureValue.cpp in Sources */,
 				0F3A1BF91A9ECB7D000DE01A /* DFGPutStackSinkingPhase.cpp in Sources */,
 				0F2FCCFB18A60070001A27F8 /* DFGSafepoint.cpp in Sources */,
-				795F099D1E03600500BBE37F /* B3Compile.cpp in Sources */,
 				86EC9DD21328DF82002B2AD7 /* DFGSpeculativeJIT.cpp in Sources */,
 				86880F1F14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp in Sources */,
 				86880F4D14353B2100B08D42 /* DFGSpeculativeJIT64.cpp in Sources */,
@@ -9995,12 +9999,10 @@
 				0F7F988B1D9596C500F4F12E /* DFGStoreBarrierClusteringPhase.cpp in Sources */,
 				0F9E32631B05AB0400801ED5 /* DFGStoreBarrierInsertionPhase.cpp in Sources */,
 				0FC20CB51852E2C600C9E954 /* DFGStrengthReductionPhase.cpp in Sources */,
-				0F7DF13B1E2971110095951B /* JSDestructibleObjectSubspace.cpp in Sources */,
 				0F893BDB1936E23C001211F4 /* DFGStructureAbstractValue.cpp in Sources */,
 				0F2FCCFE18A60070001A27F8 /* DFGThreadData.cpp in Sources */,
 				0FC097A1146B28CA00CF2442 /* DFGThunks.cpp in Sources */,
 				0FD8A32717D51F5700CA2C40 /* DFGTierUpCheckInjectionPhase.cpp in Sources */,
-				0F4F828B1E31B9740075184C /* StochasticSpaceTimeMutatorScheduler.cpp in Sources */,
 				0FD8A32917D51F5700CA2C40 /* DFGToFTLDeferredCompilationCallback.cpp in Sources */,
 				0FD8A32B17D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.cpp in Sources */,
 				0FE7211D193B9C590031F6ED /* DFGTransition.cpp in Sources */,
@@ -10207,7 +10209,6 @@
 				5B70CFDF1DB69E6600EC23F9 /* JSAsyncFunction.cpp in Sources */,
 				1421359B0A677F4F00A8195E /* JSBase.cpp in Sources */,
 				86FA9E91142BBB2E001773B7 /* JSBoundFunction.cpp in Sources */,
-				0F7DF1401E2AFC500095951B /* JSStringSubspace.cpp in Sources */,
 				1440F8AF0A508D200005F061 /* JSCallbackConstructor.cpp in Sources */,
 				1440F8920A508B100005F061 /* JSCallbackFunction.cpp in Sources */,
 				14ABDF600A437FEF00ECCA01 /* JSCallbackObject.cpp in Sources */,
@@ -10223,6 +10224,7 @@
 				0F2B66EB17B6B5AB00A7AE3F /* JSDataView.cpp in Sources */,
 				0F2B66ED17B6B5AB00A7AE3F /* JSDataViewPrototype.cpp in Sources */,
 				978801401471AD920041B016 /* JSDateMath.cpp in Sources */,
+				0F7DF13B1E2971110095951B /* JSDestructibleObjectSubspace.cpp in Sources */,
 				FE384EE51ADDB7AD0055DE2C /* JSDollarVM.cpp in Sources */,
 				FE384EE71ADDB7AD0055DE2C /* JSDollarVMPrototype.cpp in Sources */,
 				147F39D7107EC37600427A48 /* JSEnvironmentRecord.cpp in Sources */,
@@ -10235,8 +10237,6 @@
 				A5C3A1A518C0490200C9593A /* JSGlobalObjectConsoleClient.cpp in Sources */,
 				A59455921824744700CC3843 /* JSGlobalObjectDebuggable.cpp in Sources */,
 				A57D23E91891B0770031C7FA /* JSGlobalObjectDebuggerAgent.cpp in Sources */,
-				0F7DF1361E2970DF0095951B /* Subspace.cpp in Sources */,
-				ADE8029B1E08F1DE0058DE78 /* WebAssemblyLinkErrorPrototype.cpp in Sources */,
 				14E9D17B107EC469004DDA21 /* JSGlobalObjectFunctions.cpp in Sources */,
 				A51007C0187CC3C600B38879 /* JSGlobalObjectInspectorController.cpp in Sources */,
 				A50E4B6318809DD50068A46D /* JSGlobalObjectRuntimeAgent.cpp in Sources */,
@@ -10273,15 +10273,19 @@
 				A552C37F1ADDB8FE00139726 /* JSRemoteInspector.cpp in Sources */,
 				9928FF3B18AC4AEC00B8CF12 /* JSReplayInputs.cpp in Sources */,
 				14874AE515EBDE4A002E3587 /* JSScope.cpp in Sources */,
+				14815F5F991C46BEB98D0016 /* JSScriptFetcher.cpp in Sources */,
 				A7C0C4AD1681067E0017011D /* JSScriptRef.cpp in Sources */,
 				0F919D10157F3329004A4E7D /* JSSegmentedVariableObject.cpp in Sources */,
+				0F4F82871E2FFDDD0075184C /* JSSegmentedVariableObjectSubspace.cpp in Sources */,
 				A7299D9D17D12837005F5FF9 /* JSSet.cpp in Sources */,
 				A790DD6F182F499700588807 /* JSSetIterator.cpp in Sources */,
+				FA3AB211C8494524AB390267 /* JSSourceCode.cpp in Sources */,
 				147F39D5107EC37600427A48 /* JSString.cpp in Sources */,
 				70EC0EC21AA0D7DA00B6AAFA /* JSStringIterator.cpp in Sources */,
 				2600B5A6152BAAA70091EE5F /* JSStringJoiner.cpp in Sources */,
 				1482B74E0A43032800517CFC /* JSStringRef.cpp in Sources */,
 				146AAB380B66A94400E55F16 /* JSStringRefCF.cpp in Sources */,
+				0F7DF1401E2AFC500095951B /* JSStringSubspace.cpp in Sources */,
 				0F919D0C157EE09F004A4E7D /* JSSymbolTableObject.cpp in Sources */,
 				70ECA6051AFDBEA200449739 /* JSTemplateRegistryKey.cpp in Sources */,
 				53486BBB1C18E84500F6F3AF /* JSTypedArray.cpp in Sources */,
@@ -10340,6 +10344,8 @@
 				C2B916C514DA040C00CBAC86 /* MarkedAllocator.cpp in Sources */,
 				142D6F0813539A2800B02E86 /* MarkedBlock.cpp in Sources */,
 				14D2F3DA139F4BE200491031 /* MarkedSpace.cpp in Sources */,
+				0F660E371E0517B90031462C /* MarkingConstraint.cpp in Sources */,
+				0F660E391E0517BF0031462C /* MarkingConstraintSet.cpp in Sources */,
 				142D6F1113539A4100B02E86 /* MarkStack.cpp in Sources */,
 				DC69AA661CF7A1F200C6272F /* MatchResult.cpp in Sources */,
 				4340A4841A9051AF00D73CCA /* MathCommon.cpp in Sources */,
@@ -10350,6 +10356,7 @@
 				E355F3521B7DC85300C50DC5 /* ModuleLoaderPrototype.cpp in Sources */,
 				14AD91181DCA97FD0014F9FE /* ModuleProgramCodeBlock.cpp in Sources */,
 				147341E41DC2CE9600AA29BA /* ModuleProgramExecutable.cpp in Sources */,
+				0F1FB3901E173A6B00A9BE50 /* MutatorScheduler.cpp in Sources */,
 				0FA762061DB9243100B7A2FD /* MutatorState.cpp in Sources */,
 				14469DE0107EC7E700650446 /* NativeErrorConstructor.cpp in Sources */,
 				14469DE1107EC7E700650446 /* NativeErrorPrototype.cpp in Sources */,
@@ -10461,11 +10468,11 @@
 				0FD82E86141F3FF100179C94 /* SpeculatedType.cpp in Sources */,
 				0F6DB7EA1D6124B800CDBF8E /* StackFrame.cpp in Sources */,
 				A7C1EAF117987AB600299DB2 /* StackVisitor.cpp in Sources */,
+				0F4F828B1E31B9740075184C /* StochasticSpaceTimeMutatorScheduler.cpp in Sources */,
 				0F7CF9531DC027DB0098CC12 /* StopIfNecessaryTimer.cpp in Sources */,
 				A730B6131250068F009D25B1 /* StrictEvalActivation.cpp in Sources */,
 				14469DEB107EC7E700650446 /* StringConstructor.cpp in Sources */,
 				70EC0EC61AA0D7DA00B6AAFA /* StringIteratorPrototype.cpp in Sources */,
-				0F1FB3901E173A6B00A9BE50 /* MutatorScheduler.cpp in Sources */,
 				14469DEC107EC7E700650446 /* StringObject.cpp in Sources */,
 				14469DED107EC7E700650446 /* StringPrototype.cpp in Sources */,
 				9335F24D12E6765B002B5553 /* StringRecursionChecker.cpp in Sources */,
@@ -10476,6 +10483,7 @@
 				0FB438A319270B1D00E1FBC9 /* StructureSet.cpp in Sources */,
 				0F766D3815AE4A1C008F363E /* StructureStubClearingWatchpoint.cpp in Sources */,
 				BCCF0D0C0EF0B8A500413C8F /* StructureStubInfo.cpp in Sources */,
+				0F7DF1361E2970DF0095951B /* Subspace.cpp in Sources */,
 				0F4A38F91C8E13DF00190318 /* SuperSampler.cpp in Sources */,
 				705B41AB1A6E501E00716757 /* Symbol.cpp in Sources */,
 				705B41AD1A6E501E00716757 /* SymbolConstructor.cpp in Sources */,
@@ -10482,6 +10490,7 @@
 				705B41AF1A6E501E00716757 /* SymbolObject.cpp in Sources */,
 				705B41B11A6E501E00716757 /* SymbolPrototype.cpp in Sources */,
 				0F919D2815856773004A4E7D /* SymbolTable.cpp in Sources */,
+				0F1FB38E1E173A6500A9BE50 /* SynchronousStopTheWorldMutatorScheduler.cpp in Sources */,
 				DC7997841CDE9FA2004D4A09 /* TagRegistersMode.cpp in Sources */,
 				70ECA6071AFDBEA200449739 /* TemplateRegistry.cpp in Sources */,
 				78274D8E4C4D4FCD9A1DC6E6 /* TemplateRegistryKey.cpp in Sources */,
@@ -10517,7 +10526,6 @@
 				0F24E55817F74EDB00ABB217 /* ValueRecovery.cpp in Sources */,
 				79EE0BFF1B4AFB85000385C9 /* VariableEnvironment.cpp in Sources */,
 				0F6C73501AC9F99F00BE1682 /* VariableWriteFireDetail.cpp in Sources */,
-				0F660E371E0517B90031462C /* MarkingConstraint.cpp in Sources */,
 				0FE0502C1AA9095600D33B33 /* VarOffset.cpp in Sources */,
 				0F20C2591A8013AB00DA3229 /* VirtualRegister.cpp in Sources */,
 				0F952AA21DF7860D00E06FBD /* VisitRaceKey.cpp in Sources */,
@@ -10530,12 +10538,13 @@
 				535557161D9DFA32006D583B /* WasmMemory.cpp in Sources */,
 				79B759741DFA4C600052174C /* WasmMemoryInformation.cpp in Sources */,
 				53F40E971D5A7BEC0099A1B6 /* WasmModuleParser.cpp in Sources */,
+				ADB6F67D1E15D7600082F384 /* WasmPageCount.cpp in Sources */,
 				531374BF1D5CE95000AF7A0B /* WasmPlan.cpp in Sources */,
+				AD7438C11E0457AA00FD0C2A /* WasmSignature.cpp in Sources */,
 				53FF7F9B1DBFD2B900A26CCC /* WasmValidate.cpp in Sources */,
 				FED94F2E171E3E2300BE77A4 /* Watchdog.cpp in Sources */,
 				0F919D2515853CE0004A4E7D /* Watchpoint.cpp in Sources */,
 				1ACF7377171CA6FB00C9BB1E /* Weak.cpp in Sources */,
-				AD7438C11E0457AA00FD0C2A /* WasmSignature.cpp in Sources */,
 				14E84F9E14EE1ACC00D6D5D4 /* WeakBlock.cpp in Sources */,
 				14F7256514EE265E00B1652B /* WeakHandleOwner.cpp in Sources */,
 				A7CA3AE317DA41AE006538AF /* WeakMapConstructor.cpp in Sources */,
@@ -10549,6 +10558,8 @@
 				AD4937D31DDD27DE0077C807 /* WebAssemblyFunction.cpp in Sources */,
 				AD2FCBF01DB58DAD00B3E736 /* WebAssemblyInstanceConstructor.cpp in Sources */,
 				AD2FCBF21DB58DAD00B3E736 /* WebAssemblyInstancePrototype.cpp in Sources */,
+				ADE8029E1E08F2280058DE78 /* WebAssemblyLinkErrorConstructor.cpp in Sources */,
+				ADE8029B1E08F1DE0058DE78 /* WebAssemblyLinkErrorPrototype.cpp in Sources */,
 				AD2FCBF41DB58DAD00B3E736 /* WebAssemblyMemoryConstructor.cpp in Sources */,
 				AD2FCBF61DB58DAD00B3E736 /* WebAssemblyMemoryPrototype.cpp in Sources */,
 				AD2FCC001DB58DAD00B3E736 /* WebAssemblyModuleConstructor.cpp in Sources */,
@@ -10568,8 +10579,6 @@
 				86704B8612DBA33700A9FE7B /* YarrJIT.cpp in Sources */,
 				86704B8912DBA33700A9FE7B /* YarrPattern.cpp in Sources */,
 				86704B4212DB8A8100A9FE7B /* YarrSyntaxChecker.cpp in Sources */,
-				FA3AB211C8494524AB390267 /* JSSourceCode.cpp in Sources */,
-				14815F5F991C46BEB98D0016 /* JSScriptFetcher.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Added: trunk/Source/_javascript_Core/inspector/AsyncStackTrace.cpp (0 => 211385)


--- trunk/Source/_javascript_Core/inspector/AsyncStackTrace.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/inspector/AsyncStackTrace.cpp	2017-01-30 22:01:07 UTC (rev 211385)
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2017 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. AND ITS CONTRIBUTORS ``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 ITS 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 "AsyncStackTrace.h"
+
+#include "InspectorValues.h"
+#include "ScriptCallStack.h"
+
+namespace Inspector {
+
+RefPtr<AsyncStackTrace> AsyncStackTrace::create(RefPtr<ScriptCallStack> callStack, bool singleShot, RefPtr<AsyncStackTrace> parent)
+{
+    ASSERT(callStack && callStack->size());
+    return adoptRef(*new AsyncStackTrace(WTFMove(callStack), singleShot, WTFMove(parent)));
+}
+
+AsyncStackTrace::AsyncStackTrace(RefPtr<ScriptCallStack> callStack, bool singleShot, RefPtr<AsyncStackTrace> parent)
+    : m_callStack(callStack)
+    , m_parent(parent)
+    , m_singleShot(singleShot)
+{
+    if (m_parent)
+        m_parent->m_childCount++;
+}
+
+AsyncStackTrace::~AsyncStackTrace()
+{
+    if (m_parent)
+        remove();
+    ASSERT(!m_childCount);
+}
+
+bool AsyncStackTrace::isPending() const
+{
+    return m_state == State::Pending;
+}
+
+bool AsyncStackTrace::isLocked() const
+{
+    return m_state == State::Pending || m_state == State::Active || m_childCount > 1;
+}
+
+void AsyncStackTrace::willDispatchAsyncCall(size_t maxDepth)
+{
+    ASSERT(m_state == State::Pending);
+    m_state = State::Active;
+
+    truncate(maxDepth);
+}
+
+void AsyncStackTrace::didDispatchAsyncCall()
+{
+    ASSERT(m_state == State::Active || m_state == State::Canceled);
+
+    if (m_state == State::Active && !m_singleShot) {
+        m_state = State::Pending;
+        return;
+    }
+
+    m_state = State::Dispatched;
+
+    if (!m_childCount)
+        remove();
+}
+
+void AsyncStackTrace::didCancelAsyncCall()
+{
+    if (m_state == State::Canceled)
+        return;
+
+    if (m_state == State::Pending && !m_childCount)
+        remove();
+
+    m_state = State::Canceled;
+}
+
+RefPtr<Inspector::Protocol::Console::StackTrace> AsyncStackTrace::buildInspectorObject() const
+{
+    RefPtr<Inspector::Protocol::Console::StackTrace> topStackTrace;
+    RefPtr<Inspector::Protocol::Console::StackTrace> previousStackTrace;
+
+    auto* stackTrace = this;
+    while (stackTrace) {
+        auto callStack = stackTrace->m_callStack;
+        ASSERT(callStack && callStack->size());
+
+        RefPtr<Inspector::Protocol::Console::StackTrace> protocolObject = Inspector::Protocol::Console::StackTrace::create()
+            .setCallFrames(callStack->buildInspectorArray())
+            .release();
+
+        if (stackTrace->m_truncated)
+            protocolObject->setTruncated(true);
+        if (callStack->at(0).isNative())
+            protocolObject->setTopCallFrameIsBoundary(true);
+
+        if (!topStackTrace)
+            topStackTrace = protocolObject;
+
+        if (previousStackTrace)
+            previousStackTrace->setParentStackTrace(protocolObject);
+
+        previousStackTrace = protocolObject;
+        stackTrace = stackTrace->m_parent.get();
+    }
+
+    return topStackTrace;
+}
+
+void AsyncStackTrace::truncate(size_t maxDepth)
+{
+    AsyncStackTrace* lastUnlockedAncestor = nullptr;
+    size_t depth = 0;
+
+    auto* newStackTraceRoot = this;
+    while (newStackTraceRoot) {
+        depth += newStackTraceRoot->m_callStack->size();
+        if (depth >= maxDepth)
+            break;
+
+        auto* parent = newStackTraceRoot->m_parent.get();
+        if (!lastUnlockedAncestor && parent && parent->isLocked())
+            lastUnlockedAncestor = newStackTraceRoot;
+
+        newStackTraceRoot = parent;
+    }
+
+    if (!newStackTraceRoot || !newStackTraceRoot->m_parent)
+        return;
+
+    if (!lastUnlockedAncestor) {
+        // No locked nodes belong to the trace. The subtree at the new root
+        // is moved to a new tree, and marked as truncated if necessary.
+        newStackTraceRoot->m_truncated = true;
+        newStackTraceRoot->remove();
+        return;
+    }
+
+    // The new root has a locked descendent. Since truncating a stack trace
+    // cannot mutate locked nodes or their ancestors, a new tree is created by
+    // cloning the locked portion of the trace (the path from the locked node
+    // to the new root). The subtree rooted at the last unlocked ancestor is
+    // then appended to the new tree.
+    auto* currentNode = lastUnlockedAncestor;
+    while (currentNode->m_parent) {
+        auto& parentNode = currentNode->m_parent;
+        currentNode->m_parent = AsyncStackTrace::create(parentNode->m_callStack, true, parentNode->m_parent);
+        currentNode = currentNode->m_parent.get();
+
+        if (parentNode.get() == newStackTraceRoot)
+            break;
+    }
+
+    currentNode->m_truncated = true;
+    currentNode->remove();
+
+    // Decrement the child count of the first locked ancestor after removing its subtree.
+    auto& firstLockedAncestor = lastUnlockedAncestor->m_parent;
+    firstLockedAncestor->m_childCount--;
+}
+
+void AsyncStackTrace::remove()
+{
+    if (!m_parent)
+        return;
+
+    ASSERT(m_parent->m_childCount);
+    m_parent->m_childCount--;
+    m_parent = nullptr;
+}
+
+} // namespace Inspector

Copied: trunk/Source/_javascript_Core/inspector/AsyncStackTrace.h (from rev 211382, trunk/Source/WebInspectorUI/UserInterface/Views/ThreadTreeElement.css) (0 => 211385)


--- trunk/Source/_javascript_Core/inspector/AsyncStackTrace.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/inspector/AsyncStackTrace.h	2017-01-30 22:01:07 UTC (rev 211385)
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2017 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. AND ITS CONTRIBUTORS ``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 ITS 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 "InspectorProtocolObjects.h"
+#include <wtf/Forward.h>
+#include <wtf/RefCounted.h>
+
+namespace Inspector {
+
+class ScriptCallStack;
+
+class JS_EXPORT_PRIVATE AsyncStackTrace : public RefCounted<AsyncStackTrace> {
+public:
+    enum class State {
+        Pending,
+        Active,
+        Dispatched,
+        Canceled,
+    };
+
+    static RefPtr<AsyncStackTrace> create(RefPtr<ScriptCallStack>, bool singleShot, RefPtr<AsyncStackTrace> parent);
+
+    bool isPending() const;
+    bool isLocked() const;
+
+    void willDispatchAsyncCall(size_t maxDepth);
+    void didDispatchAsyncCall();
+    void didCancelAsyncCall();
+
+    RefPtr<Inspector::Protocol::Console::StackTrace> buildInspectorObject() const;
+
+    ~AsyncStackTrace();
+
+private:
+    AsyncStackTrace(RefPtr<ScriptCallStack>, bool, RefPtr<AsyncStackTrace>);
+
+    void truncate(size_t maxDepth);
+    void remove();
+
+    RefPtr<ScriptCallStack> m_callStack;
+    RefPtr<AsyncStackTrace> m_parent;
+    unsigned m_childCount { 0 };
+    State m_state { State::Pending };
+    bool m_truncated { false };
+    bool m_singleShot { true };
+};
+
+} // namespace Inspector

Modified: trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp (211384 => 211385)


--- trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp	2017-01-30 21:02:16 UTC (rev 211384)
+++ trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp	2017-01-30 22:01:07 UTC (rev 211385)
@@ -30,6 +30,7 @@
 #include "config.h"
 #include "InspectorDebuggerAgent.h"
 
+#include "AsyncStackTrace.h"
 #include "ContentSearchUtilities.h"
 #include "InjectedScript.h"
 #include "InjectedScriptManager.h"
@@ -212,40 +213,6 @@
     return injectedScript.wrapObject(exception, InspectorDebuggerAgent::backtraceObjectGroup)->openAccessors();
 }
 
-RefPtr<Inspector::Protocol::Console::StackTrace> InspectorDebuggerAgent::buildAsyncStackTrace(const AsyncCallIdentifier& identifier)
-{
-    RefPtr<Inspector::Protocol::Console::StackTrace> topStackTrace;
-    RefPtr<Inspector::Protocol::Console::StackTrace> previousStackTrace;
-
-    auto iterator = m_asyncCallIdentifierToData.find(identifier);
-    auto end = m_asyncCallIdentifierToData.end();
-    while (iterator != end) {
-        const auto& callData = iterator->value;
-        ASSERT(callData.callStack && callData.callStack->size());
-        if (!callData.callStack || !callData.callStack->size())
-            break;
-
-        RefPtr<Inspector::Protocol::Console::StackTrace> stackTrace = Inspector::Protocol::Console::StackTrace::create()
-            .setCallFrames(callData.callStack->buildInspectorArray())
-            .release();
-
-        if (callData.callStack->at(0).isNative())
-            stackTrace->setTopCallFrameIsBoundary(true);
-        if (!topStackTrace)
-            topStackTrace = stackTrace;
-        if (previousStackTrace)
-            previousStackTrace->setParentStackTrace(stackTrace);
-
-        if (!callData.parentAsyncCallIdentifier)
-            break;
-
-        previousStackTrace = stackTrace;
-        iterator = m_asyncCallIdentifierToData.find(callData.parentAsyncCallIdentifier.value());
-    }
-
-    return topStackTrace;
-}
-
 void InspectorDebuggerAgent::handleConsoleAssert(const String& message)
 {
     if (!m_scriptDebugServer.breakpointsActive())
@@ -268,10 +235,17 @@
     if (!callStack || !callStack->size())
         return;
 
-    if (m_currentAsyncCallIdentifier)
-        refAsyncCallData(m_currentAsyncCallIdentifier.value());
+    RefPtr<AsyncStackTrace> parentStackTrace;
+    if (m_currentAsyncCallIdentifier) {
+        auto it = m_pendingAsyncCalls.find(m_currentAsyncCallIdentifier.value());
+        ASSERT(it != m_pendingAsyncCalls.end());
+        parentStackTrace = it->value;
+    }
 
-    m_asyncCallIdentifierToData.set(std::make_pair(asyncCallType, callbackIdentifier), AsyncCallData(callStack, m_currentAsyncCallIdentifier, singleShot));
+    auto identifier = std::make_pair(asyncCallType, callbackIdentifier);
+    auto asyncStackTrace = AsyncStackTrace::create(WTFMove(callStack), singleShot, WTFMove(parentStackTrace));
+
+    m_pendingAsyncCalls.set(identifier, WTFMove(asyncStackTrace));
 }
 
 void InspectorDebuggerAgent::didCancelAsyncCall(int asyncCallType, int callbackIdentifier)
@@ -279,8 +253,18 @@
     if (!m_asyncStackTraceDepth)
         return;
 
-    const auto asyncCallIdentifier = std::make_pair(asyncCallType, callbackIdentifier);
-    derefAsyncCallData(asyncCallIdentifier);
+    auto identifier = std::make_pair(asyncCallType, callbackIdentifier);
+    auto it = m_pendingAsyncCalls.find(identifier);
+    if (it == m_pendingAsyncCalls.end())
+        return;
+
+    auto& asyncStackTrace = it->value;
+    asyncStackTrace->didCancelAsyncCall();
+
+    if (m_currentAsyncCallIdentifier && m_currentAsyncCallIdentifier.value() == identifier)
+        return;
+
+    m_pendingAsyncCalls.remove(identifier);
 }
 
 void InspectorDebuggerAgent::willDispatchAsyncCall(int asyncCallType, int callbackIdentifier)
@@ -293,12 +277,15 @@
 
     // A call can be scheduled before the Inspector is opened, or while async stack
     // traces are disabled. If no call data exists, do nothing.
-    auto asyncCallIdentifier = std::make_pair(asyncCallType, callbackIdentifier);
-    if (!m_asyncCallIdentifierToData.contains(asyncCallIdentifier))
+    auto identifier = std::make_pair(asyncCallType, callbackIdentifier);
+    auto it = m_pendingAsyncCalls.find(identifier);
+    if (it == m_pendingAsyncCalls.end())
         return;
 
-    m_currentAsyncCallIdentifier = WTFMove(asyncCallIdentifier);
-    refAsyncCallData(asyncCallIdentifier);
+    auto& asyncStackTrace = it->value;
+    asyncStackTrace->willDispatchAsyncCall(m_asyncStackTraceDepth);
+
+    m_currentAsyncCallIdentifier = identifier;
 }
 
 void InspectorDebuggerAgent::didDispatchAsyncCall()
@@ -309,8 +296,17 @@
     if (!m_currentAsyncCallIdentifier)
         return;
 
-    derefAsyncCallData(m_currentAsyncCallIdentifier.value());
+    auto identifier = m_currentAsyncCallIdentifier.value();
+    auto it = m_pendingAsyncCalls.find(identifier);
+    ASSERT(it != m_pendingAsyncCalls.end());
+
+    auto& asyncStackTrace = it->value;
+    asyncStackTrace->didDispatchAsyncCall();
+
     m_currentAsyncCallIdentifier = std::nullopt;
+
+    if (!asyncStackTrace->isPending())
+        m_pendingAsyncCalls.remove(identifier);
 }
 
 static Ref<InspectorObject> buildObjectForBreakpointCookie(const String& url, int lineNumber, int columnNumber, const String& condition, RefPtr<InspectorArray>& actions, bool isRegex, bool autoContinue, unsigned ignoreCount)
@@ -1001,8 +997,11 @@
     m_enablePauseWhenIdle = false;
 
     RefPtr<Inspector::Protocol::Console::StackTrace> asyncStackTrace;
-    if (m_currentAsyncCallIdentifier)
-        asyncStackTrace = buildAsyncStackTrace(m_currentAsyncCallIdentifier.value());
+    if (m_currentAsyncCallIdentifier) {
+        auto it = m_pendingAsyncCalls.find(m_currentAsyncCallIdentifier.value());
+        if (it != m_pendingAsyncCalls.end())
+            asyncStackTrace = it->value->buildInspectorObject();
+    }
 
     m_frontendDispatcher->paused(currentCallFrames(injectedScript), m_breakReason, m_breakAuxData, asyncStackTrace);
 
@@ -1138,33 +1137,8 @@
 
 void InspectorDebuggerAgent::clearAsyncStackTraceData()
 {
-    m_asyncCallIdentifierToData.clear();
+    m_pendingAsyncCalls.clear();
     m_currentAsyncCallIdentifier = std::nullopt;
 }
 
-void InspectorDebuggerAgent::refAsyncCallData(const AsyncCallIdentifier& identifier)
-{
-    auto iterator = m_asyncCallIdentifierToData.find(identifier);
-    if (iterator == m_asyncCallIdentifierToData.end())
-        return;
-
-    iterator->value.referenceCount++;
-}
-
-void InspectorDebuggerAgent::derefAsyncCallData(const AsyncCallIdentifier& identifier)
-{
-    auto iterator = m_asyncCallIdentifierToData.find(identifier);
-    if (iterator == m_asyncCallIdentifierToData.end())
-        return;
-
-    auto& asyncCallData = iterator->value;
-    asyncCallData.referenceCount--;
-    if (asyncCallData.referenceCount)
-        return;
-
-    if (asyncCallData.parentAsyncCallIdentifier)
-        derefAsyncCallData(asyncCallData.parentAsyncCallIdentifier.value());
-    m_asyncCallIdentifierToData.remove(identifier);
-}
-
 } // namespace Inspector

Modified: trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.h (211384 => 211385)


--- trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.h	2017-01-30 21:02:16 UTC (rev 211384)
+++ trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.h	2017-01-30 22:01:07 UTC (rev 211385)
@@ -44,12 +44,12 @@
 
 namespace Inspector {
 
+class AsyncStackTrace;
 class InjectedScript;
 class InjectedScriptManager;
 class InspectorArray;
 class InspectorObject;
 class ScriptDebugServer;
-struct AsyncCallData;
 typedef String ErrorString;
 
 class JS_EXPORT_PRIVATE InspectorDebuggerAgent : public InspectorAgentBase, public ScriptDebugListener, public DebuggerBackendDispatcherHandler {
@@ -164,30 +164,11 @@
 
     typedef std::pair<int, int> AsyncCallIdentifier;
 
-    RefPtr<Inspector::Protocol::Console::StackTrace> buildAsyncStackTrace(const AsyncCallIdentifier&);
-    void refAsyncCallData(const AsyncCallIdentifier&);
-    void derefAsyncCallData(const AsyncCallIdentifier&);
-
     typedef HashMap<JSC::SourceID, Script> ScriptsMap;
     typedef HashMap<String, Vector<JSC::BreakpointID>> BreakpointIdentifierToDebugServerBreakpointIDsMap;
     typedef HashMap<String, RefPtr<InspectorObject>> BreakpointIdentifierToBreakpointMap;
     typedef HashMap<JSC::BreakpointID, String> DebugServerBreakpointIDToBreakpointIdentifier;
 
-    struct AsyncCallData {
-        AsyncCallData(RefPtr<ScriptCallStack> callStack, std::optional<AsyncCallIdentifier> parentAsyncCallIdentifier, bool singleShot)
-            : callStack(callStack)
-            , parentAsyncCallIdentifier(parentAsyncCallIdentifier)
-            , referenceCount(singleShot ? 0 : 1)
-        {
-        }
-
-        AsyncCallData() = default;
-
-        RefPtr<ScriptCallStack> callStack;
-        std::optional<AsyncCallIdentifier> parentAsyncCallIdentifier { std::nullopt };
-        unsigned referenceCount { 0 };
-    };
-
     InjectedScriptManager& m_injectedScriptManager;
     std::unique_ptr<DebuggerFrontendDispatcher> m_frontendDispatcher;
     RefPtr<DebuggerBackendDispatcher> m_backendDispatcher;
@@ -204,7 +185,7 @@
     RefPtr<InspectorObject> m_breakAuxData;
     ShouldDispatchResumed m_conditionToDispatchResumed { ShouldDispatchResumed::No };
     bool m_enablePauseWhenIdle { false };
-    HashMap<AsyncCallIdentifier, AsyncCallData> m_asyncCallIdentifierToData;
+    HashMap<AsyncCallIdentifier, RefPtr<AsyncStackTrace>> m_pendingAsyncCalls;
     std::optional<AsyncCallIdentifier> m_currentAsyncCallIdentifier { std::nullopt };
     bool m_enabled { false };
     bool m_javaScriptPauseScheduled { false };

Modified: trunk/Source/_javascript_Core/inspector/protocol/Console.json (211384 => 211385)


--- trunk/Source/_javascript_Core/inspector/protocol/Console.json	2017-01-30 21:02:16 UTC (rev 211384)
+++ trunk/Source/_javascript_Core/inspector/protocol/Console.json	2017-01-30 22:01:07 UTC (rev 211385)
@@ -40,6 +40,7 @@
             "properties": [
                 { "name": "callFrames", "type": "array", "items": { "$ref": "CallFrame" } },
                 { "name": "topCallFrameIsBoundary", "type": "boolean", "optional": true, "description": "Whether the first item in <code>callFrames</code> is the native function that scheduled the asynchronous operation (e.g. setTimeout)." },
+                { "name": "truncated", "type": "boolean", "optional": true, "description": "Whether one or more frames have been truncated from the bottom of the stack." },
                 { "name": "parentStackTrace", "$ref": "StackTrace", "optional": true, "description": "Parent StackTrace." }
             ]
         }

Modified: trunk/Source/WebInspectorUI/ChangeLog (211384 => 211385)


--- trunk/Source/WebInspectorUI/ChangeLog	2017-01-30 21:02:16 UTC (rev 211384)
+++ trunk/Source/WebInspectorUI/ChangeLog	2017-01-30 22:01:07 UTC (rev 211385)
@@ -1,3 +1,31 @@
+2017-01-30  Matt Baker  <mattba...@apple.com>
+
+        Web Inspector: Need some limit on Async Call Stacks for async loops (rAF loops)
+        https://bugs.webkit.org/show_bug.cgi?id=165633
+        <rdar://problem/29738502>
+
+        Reviewed by Joseph Pecoraro.
+
+        * Localizations/en.lproj/localizedStrings.js:
+        Text for "Truncated" marker tree element.
+
+        * UserInterface/Models/StackTrace.js:
+        (WebInspector.StackTrace):
+        (WebInspector.StackTrace.fromPayload):
+        (WebInspector.StackTrace.prototype.get truncated):
+        Plumbing for new Console.StackTrace property `truncated`.
+
+        * UserInterface/Views/ThreadTreeElement.css:
+        (.tree-outline > .item.thread + ol > .item.truncated-call-frames):
+        (.tree-outline > .item.thread + ol > .item.truncated-call-frames .icon):
+        Styles for "Truncated" marker tree element.
+
+        * UserInterface/Views/ThreadTreeElement.js:
+        (WebInspector.ThreadTreeElement.prototype.refresh):
+        Append "Truncated" marker tree element if necessary.
+
+        * Versions/Inspector-iOS-10.3.json:
+
 2017-01-30  Ryan Haddad  <ryanhad...@apple.com>
 
         Unreviewed, rolling out r211345.

Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (211384 => 211385)


--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js	2017-01-30 21:02:16 UTC (rev 211384)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js	2017-01-30 22:01:07 UTC (rev 211385)
@@ -125,6 +125,7 @@
 localizedStrings["Busy"] = "Busy";
 localizedStrings["CSP Hash"] = "CSP Hash";
 localizedStrings["Cached"] = "Cached";
+localizedStrings["Call Frames Truncated"] = "Call Frames Truncated";
 localizedStrings["Call Stack"] = "Call Stack";
 localizedStrings["Call Trees"] = "Call Trees";
 localizedStrings["Calls"] = "Calls";

Modified: trunk/Source/WebInspectorUI/UserInterface/Models/StackTrace.js (211384 => 211385)


--- trunk/Source/WebInspectorUI/UserInterface/Models/StackTrace.js	2017-01-30 21:02:16 UTC (rev 211384)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/StackTrace.js	2017-01-30 22:01:07 UTC (rev 211385)
@@ -25,7 +25,7 @@
 
 WebInspector.StackTrace = class StackTrace extends WebInspector.Object
 {
-    constructor(callFrames, topCallFrameIsBoundary)
+    constructor(callFrames, topCallFrameIsBoundary, truncated, parentStackTrace)
     {
         super();
 
@@ -33,7 +33,8 @@
 
         this._callFrames = callFrames;
         this._topCallFrameIsBoundary = topCallFrameIsBoundary || false;
-        this._parentStackTrace = null;
+        this._truncated = truncated || false;
+        this._parentStackTrace = parentStackTrace || null;
     }
 
     // Static
@@ -45,7 +46,7 @@
 
         while (payload) {
             let callFrames = payload.callFrames.map((x) => WebInspector.CallFrame.fromPayload(target, x));
-            let stackTrace = new WebInspector.StackTrace(callFrames, payload.topCallFrameIsBoundary);
+            let stackTrace = new WebInspector.StackTrace(callFrames, payload.topCallFrameIsBoundary, payload.truncated);
             if (!result)
                 result = stackTrace;
             if (previousStackTrace)
@@ -169,5 +170,6 @@
     }
 
     get topCallFrameIsBoundary() { return this._topCallFrameIsBoundary; }
+    get truncated() { return this._truncated; }
     get parentStackTrace() { return this._parentStackTrace; }
 };

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ThreadTreeElement.css (211384 => 211385)


--- trunk/Source/WebInspectorUI/UserInterface/Views/ThreadTreeElement.css	2017-01-30 21:02:16 UTC (rev 211384)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ThreadTreeElement.css	2017-01-30 22:01:07 UTC (rev 211385)
@@ -50,3 +50,18 @@
 .tree-outline > .item.thread:hover .status-button.resume {
     display: inline-block;
 }
+
+.tree-outline > .item.thread + ol > .item.truncated-call-frames {
+    color: var(--text-color-gray-medium);
+    border-top: dashed 0.5px var(--border-color);
+    margin-left: 31px;
+    margin-right: 6px;
+    padding-left: 0;
+    cursor: default;
+}
+
+.tree-outline > .item.thread + ol > .item.truncated-call-frames .icon {
+    margin-left: 0;
+    content: url(../Images/Function.svg);
+    opacity: 0.6;
+}

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ThreadTreeElement.js (211384 => 211385)


--- trunk/Source/WebInspectorUI/UserInterface/Views/ThreadTreeElement.js	2017-01-30 21:02:16 UTC (rev 211384)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ThreadTreeElement.js	2017-01-30 22:01:07 UTC (rev 211385)
@@ -92,6 +92,12 @@
             for (let i = startIndex; i < currentStackTrace.callFrames.length; ++i)
                 this.appendChild(new WebInspector.CallFrameTreeElement(currentStackTrace.callFrames[i]));
 
+            if (currentStackTrace.truncated) {
+                let truncatedTreeElement = new WebInspector.GeneralTreeElement("truncated-call-frames", WebInspector.UIString("Call Frames Truncated"));
+                truncatedTreeElement.selectable = false;
+                this.appendChild(truncatedTreeElement);
+            }
+
             currentStackTrace = currentStackTrace.parentStackTrace;
         }
 

Modified: trunk/Source/WebInspectorUI/Versions/Inspector-iOS-10.3.json (211384 => 211385)


--- trunk/Source/WebInspectorUI/Versions/Inspector-iOS-10.3.json	2017-01-30 21:02:16 UTC (rev 211384)
+++ trunk/Source/WebInspectorUI/Versions/Inspector-iOS-10.3.json	2017-01-30 22:01:07 UTC (rev 211385)
@@ -587,6 +587,7 @@
             "properties": [
                 { "name": "callFrames", "type": "array", "items": { "$ref": "CallFrame" } },
                 { "name": "topCallFrameIsBoundary", "type": "boolean", "optional": true, "description": "Whether the first item in <code>callFrames</code> is the native function that scheduled the asynchronous operation (e.g. setTimeout)." },
+                { "name": "truncated", "type": "boolean", "optional": true, "description": "Whether one or more frames have been truncated from the bottom of the stack." },
                 { "name": "parentStackTrace", "$ref": "StackTrace", "optional": true, "description": "Parent StackTrace." }
             ]
         }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to