Title: [201465] trunk
Revision
201465
Author
sbar...@apple.com
Date
2016-05-27 13:26:06 -0700 (Fri, 27 May 2016)

Log Message

ShadowChicken/DebuggerCallFrame don't properly handle when the entry stack frame is a tail deleted frame
https://bugs.webkit.org/show_bug.cgi?id=158131

Reviewed by Yusuke Suzuki.

Source/_javascript_Core:

There were bugs both in DebuggerCallFrame and ShadowChicken when the entry stack
frame(s) are tail deleted.

DebuggerCallFrame had an assertion saying that the entry frame shouldn't be
tail deleted. This is clearly wrong. The following program proves that this assertion
was misguided:
```
"use strict";
setTimeout(function foo() { return bar(); }, 0);
```

ShadowChicken had a very subtle bug when creating the shadow stack when 
the entry frames of the stack were tail deleted. Because it places frames into its shadow
stack by walking the machine frame and looking up entries in the log,
the machine frame doesn't have any notion of those tail deleted frames
at the entry of execution. ShadowChicken would never find those frames
because it would look for tail deleted frames *before* consulting the
current machine frame. This is wrong because if the entry frames
are tail deleted, then there is no machine frame for them because there
is no machine frame before them! Therefore, we must search for tail deleted
frames *after* consulting a machine frame. This is sound because we will always
have at least one machine frame on the stack (when we are using StackVisitor on a valid ExecState).
So when we consult the machine frame that is the entry frame on the machine stack,
we will search for tail deleted frames that come before it in the shadow stack.
This will allow us to find those tail deleted frames that are the entry frames
for the shadow stack.

* debugger/DebuggerCallFrame.cpp:
(JSC::DebuggerCallFrame::create):
* interpreter/ShadowChicken.cpp:
(JSC::ShadowChicken::Packet::dump):
(JSC::ShadowChicken::update):
(JSC::ShadowChicken::dump):

LayoutTests:

* inspector/debugger/resources/tail-deleted-frames-from-vm-entry.js: Added.
(timeout):
(bar):
* inspector/debugger/tail-deleted-frames-from-vm-entry-expected.txt: Added.
* inspector/debugger/tail-deleted-frames-from-vm-entry.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (201464 => 201465)


--- trunk/LayoutTests/ChangeLog	2016-05-27 20:22:12 UTC (rev 201464)
+++ trunk/LayoutTests/ChangeLog	2016-05-27 20:26:06 UTC (rev 201465)
@@ -1,3 +1,16 @@
+2016-05-27  Saam barati  <sbar...@apple.com>
+
+        ShadowChicken/DebuggerCallFrame don't properly handle when the entry stack frame is a tail deleted frame
+        https://bugs.webkit.org/show_bug.cgi?id=158131
+
+        Reviewed by Yusuke Suzuki.
+
+        * inspector/debugger/resources/tail-deleted-frames-from-vm-entry.js: Added.
+        (timeout):
+        (bar):
+        * inspector/debugger/tail-deleted-frames-from-vm-entry-expected.txt: Added.
+        * inspector/debugger/tail-deleted-frames-from-vm-entry.html: Added.
+
 2016-05-27  Joanmarie Diggs  <jdi...@igalia.com>
 
         AX: [ATK] accessibility/gtk/no-notification-for-unrendered-iframe-children.html began failing after r201416

Added: trunk/LayoutTests/inspector/debugger/resources/tail-deleted-frames-from-vm-entry.js (0 => 201465)


--- trunk/LayoutTests/inspector/debugger/resources/tail-deleted-frames-from-vm-entry.js	                        (rev 0)
+++ trunk/LayoutTests/inspector/debugger/resources/tail-deleted-frames-from-vm-entry.js	2016-05-27 20:26:06 UTC (rev 201465)
@@ -0,0 +1,9 @@
+"use strict";
+function timeout(foo = 25) {
+    return bar();
+}
+function bar(i = 9) {
+    if (i > 0)
+        return bar(i - 1);
+    return 25;
+}

Added: trunk/LayoutTests/inspector/debugger/tail-deleted-frames-from-vm-entry-expected.txt (0 => 201465)


--- trunk/LayoutTests/inspector/debugger/tail-deleted-frames-from-vm-entry-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/inspector/debugger/tail-deleted-frames-from-vm-entry-expected.txt	2016-05-27 20:26:06 UTC (rev 201465)
@@ -0,0 +1,191 @@
+Testing that we keep around tail deleted frames that are entry frames.
+
+Starting Test
+
+
+------------------------------------
+Hit breakpoint at line: 7, column: 4
+------------------------------------
+Expected frame: {"functionName":"bar","scope":["i",0],"isTailDeleted":false}
+PASS: Function name: bar is correct.
+PASS: Tail deleted expectation correct: false
+Expected frame: {"functionName":"bar","scope":["i",1],"isTailDeleted":true}
+PASS: Function name: bar is correct.
+PASS: Tail deleted expectation correct: true
+Expected frame: {"functionName":"bar","scope":["i",2],"isTailDeleted":true}
+PASS: Function name: bar is correct.
+PASS: Tail deleted expectation correct: true
+Expected frame: {"functionName":"bar","scope":["i",3],"isTailDeleted":true}
+PASS: Function name: bar is correct.
+PASS: Tail deleted expectation correct: true
+Expected frame: {"functionName":"bar","scope":["i",4],"isTailDeleted":true}
+PASS: Function name: bar is correct.
+PASS: Tail deleted expectation correct: true
+Expected frame: {"functionName":"bar","scope":["i",5],"isTailDeleted":true}
+PASS: Function name: bar is correct.
+PASS: Tail deleted expectation correct: true
+Expected frame: {"functionName":"bar","scope":["i",6],"isTailDeleted":true}
+PASS: Function name: bar is correct.
+PASS: Tail deleted expectation correct: true
+Expected frame: {"functionName":"bar","scope":["i",7],"isTailDeleted":true}
+PASS: Function name: bar is correct.
+PASS: Tail deleted expectation correct: true
+Expected frame: {"functionName":"bar","scope":["i",8],"isTailDeleted":true}
+PASS: Function name: bar is correct.
+PASS: Tail deleted expectation correct: true
+Expected frame: {"functionName":"bar","scope":["i",9],"isTailDeleted":true}
+PASS: Function name: bar is correct.
+PASS: Tail deleted expectation correct: true
+Expected frame: {"functionName":"timeout","scope":["foo",25],"isTailDeleted":true}
+PASS: Function name: timeout is correct.
+PASS: Tail deleted expectation correct: true
+Looking at frame number: 0
+    variable 'i': {"_type":"number","_description":"0","_hasChildren":false,"_value":0}
+PASS: Variable is a number.
+PASS: Found scope value: 0
+PASS: Did not find variable we were looking for: i
+Looking at frame number: 1
+    variable 'i': {"_type":"number","_description":"1","_hasChildren":false,"_value":1}
+PASS: Variable is a number.
+PASS: Found scope value: 1
+PASS: Did not find variable we were looking for: i
+Looking at frame number: 2
+    variable 'i': {"_type":"number","_description":"2","_hasChildren":false,"_value":2}
+PASS: Variable is a number.
+PASS: Found scope value: 2
+PASS: Did not find variable we were looking for: i
+Looking at frame number: 3
+    variable 'i': {"_type":"number","_description":"3","_hasChildren":false,"_value":3}
+PASS: Variable is a number.
+PASS: Found scope value: 3
+PASS: Did not find variable we were looking for: i
+Looking at frame number: 4
+    variable 'i': {"_type":"number","_description":"4","_hasChildren":false,"_value":4}
+PASS: Variable is a number.
+PASS: Found scope value: 4
+PASS: Did not find variable we were looking for: i
+Looking at frame number: 5
+    variable 'i': {"_type":"number","_description":"5","_hasChildren":false,"_value":5}
+PASS: Variable is a number.
+PASS: Found scope value: 5
+PASS: Did not find variable we were looking for: i
+Looking at frame number: 6
+    variable 'i': {"_type":"number","_description":"6","_hasChildren":false,"_value":6}
+PASS: Variable is a number.
+PASS: Found scope value: 6
+PASS: Did not find variable we were looking for: i
+Looking at frame number: 7
+    variable 'i': {"_type":"number","_description":"7","_hasChildren":false,"_value":7}
+PASS: Variable is a number.
+PASS: Found scope value: 7
+PASS: Did not find variable we were looking for: i
+Looking at frame number: 8
+    variable 'i': {"_type":"number","_description":"8","_hasChildren":false,"_value":8}
+PASS: Variable is a number.
+PASS: Found scope value: 8
+PASS: Did not find variable we were looking for: i
+Looking at frame number: 9
+    variable 'i': {"_type":"number","_description":"9","_hasChildren":false,"_value":9}
+PASS: Variable is a number.
+PASS: Found scope value: 9
+PASS: Did not find variable we were looking for: i
+Looking at frame number: 10
+    variable 'foo': {"_type":"number","_description":"25","_hasChildren":false,"_value":25}
+PASS: Variable is a number.
+PASS: Found scope value: 25
+PASS: Did not find variable we were looking for: foo
+
+
+------------------------------------
+Hit breakpoint at line: 7, column: 4
+------------------------------------
+Expected frame: {"functionName":"bar","scope":["i",0],"isTailDeleted":false}
+PASS: Function name: bar is correct.
+PASS: Tail deleted expectation correct: false
+Expected frame: {"functionName":"bar","scope":["i",1],"isTailDeleted":true}
+PASS: Function name: bar is correct.
+PASS: Tail deleted expectation correct: true
+Expected frame: {"functionName":"bar","scope":["i",2],"isTailDeleted":true}
+PASS: Function name: bar is correct.
+PASS: Tail deleted expectation correct: true
+Expected frame: {"functionName":"bar","scope":["i",3],"isTailDeleted":true}
+PASS: Function name: bar is correct.
+PASS: Tail deleted expectation correct: true
+Expected frame: {"functionName":"bar","scope":["i",4],"isTailDeleted":true}
+PASS: Function name: bar is correct.
+PASS: Tail deleted expectation correct: true
+Expected frame: {"functionName":"bar","scope":["i",5],"isTailDeleted":true}
+PASS: Function name: bar is correct.
+PASS: Tail deleted expectation correct: true
+Expected frame: {"functionName":"bar","scope":["i",6],"isTailDeleted":true}
+PASS: Function name: bar is correct.
+PASS: Tail deleted expectation correct: true
+Expected frame: {"functionName":"bar","scope":["i",7],"isTailDeleted":true}
+PASS: Function name: bar is correct.
+PASS: Tail deleted expectation correct: true
+Expected frame: {"functionName":"bar","scope":["i",8],"isTailDeleted":true}
+PASS: Function name: bar is correct.
+PASS: Tail deleted expectation correct: true
+Expected frame: {"functionName":"bar","scope":["i",9],"isTailDeleted":true}
+PASS: Function name: bar is correct.
+PASS: Tail deleted expectation correct: true
+Expected frame: {"functionName":"timeout","scope":["foo",25],"isTailDeleted":true}
+PASS: Function name: timeout is correct.
+PASS: Tail deleted expectation correct: true
+Looking at frame number: 0
+    variable 'i': {"_type":"number","_description":"0","_hasChildren":false,"_value":0}
+PASS: Variable is a number.
+PASS: Found scope value: 0
+PASS: Did not find variable we were looking for: i
+Looking at frame number: 1
+    variable 'i': {"_type":"number","_description":"1","_hasChildren":false,"_value":1}
+PASS: Variable is a number.
+PASS: Found scope value: 1
+PASS: Did not find variable we were looking for: i
+Looking at frame number: 2
+    variable 'i': {"_type":"number","_description":"2","_hasChildren":false,"_value":2}
+PASS: Variable is a number.
+PASS: Found scope value: 2
+PASS: Did not find variable we were looking for: i
+Looking at frame number: 3
+    variable 'i': {"_type":"number","_description":"3","_hasChildren":false,"_value":3}
+PASS: Variable is a number.
+PASS: Found scope value: 3
+PASS: Did not find variable we were looking for: i
+Looking at frame number: 4
+    variable 'i': {"_type":"number","_description":"4","_hasChildren":false,"_value":4}
+PASS: Variable is a number.
+PASS: Found scope value: 4
+PASS: Did not find variable we were looking for: i
+Looking at frame number: 5
+    variable 'i': {"_type":"number","_description":"5","_hasChildren":false,"_value":5}
+PASS: Variable is a number.
+PASS: Found scope value: 5
+PASS: Did not find variable we were looking for: i
+Looking at frame number: 6
+    variable 'i': {"_type":"number","_description":"6","_hasChildren":false,"_value":6}
+PASS: Variable is a number.
+PASS: Found scope value: 6
+PASS: Did not find variable we were looking for: i
+Looking at frame number: 7
+    variable 'i': {"_type":"number","_description":"7","_hasChildren":false,"_value":7}
+PASS: Variable is a number.
+PASS: Found scope value: 7
+PASS: Did not find variable we were looking for: i
+Looking at frame number: 8
+    variable 'i': {"_type":"number","_description":"8","_hasChildren":false,"_value":8}
+PASS: Variable is a number.
+PASS: Found scope value: 8
+PASS: Did not find variable we were looking for: i
+Looking at frame number: 9
+    variable 'i': {"_type":"number","_description":"9","_hasChildren":false,"_value":9}
+PASS: Variable is a number.
+PASS: Found scope value: 9
+PASS: Did not find variable we were looking for: i
+Looking at frame number: 10
+    variable 'foo': {"_type":"number","_description":"25","_hasChildren":false,"_value":25}
+PASS: Variable is a number.
+PASS: Found scope value: 25
+PASS: Did not find variable we were looking for: foo
+Tests done
+

Added: trunk/LayoutTests/inspector/debugger/tail-deleted-frames-from-vm-entry.html (0 => 201465)


--- trunk/LayoutTests/inspector/debugger/tail-deleted-frames-from-vm-entry.html	                        (rev 0)
+++ trunk/LayoutTests/inspector/debugger/tail-deleted-frames-from-vm-entry.html	2016-05-27 20:26:06 UTC (rev 201465)
@@ -0,0 +1,95 @@
+<!doctype html>
+<html>
+<head>
+<script type="text/_javascript_" src=""
+<script type="text/_javascript_" src=""
+<script type="text/_javascript_" src=""
+<script>
+
+function test()
+{
+    let scriptObject;
+
+    function startTest() {
+        InspectorTest.log("Starting Test");
+        // 0 based indices.
+        let testInfo = {line: 7, column: 4};
+        let location = scriptObject.createSourceCodeLocation(testInfo.line, testInfo.column);
+        let breakpoint = new WebInspector.Breakpoint(location);
+        WebInspector.debuggerManager.addBreakpoint(breakpoint);
+        InspectorTest.evaluateInPage("setTimeout(timeout, 0);");
+    }
+
+    WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.CallFramesDidChange, function(event) {
+        var activeCallFrame = WebInspector.debuggerManager.activeCallFrame;
+
+        if (!activeCallFrame)
+            return;
+
+        var stopLocation = "line: " + activeCallFrame.sourceCodeLocation.lineNumber + ", column: " + activeCallFrame.sourceCodeLocation.columnNumber;
+
+        InspectorTest.log("\n\n------------------------------------");
+        InspectorTest.log("Hit breakpoint at " + stopLocation);
+        InspectorTest.log("------------------------------------");
+
+        // top down list
+        let expectedFrames = [];
+        for (let i = 0; i < 10; i++)
+            expectedFrames.push({functionName: 'bar', scope: ['i', i], isTailDeleted: i > 0 ? true : false});
+        expectedFrames.push({functionName: 'timeout', scope: ['foo', 25], isTailDeleted: true});
+
+        InspectorTest.assert(WebInspector.debuggerManager.callFrames.length >= expectedFrames.length);
+
+        for (let i = 0; i < expectedFrames.length; i++) {
+            let callFrame = WebInspector.debuggerManager.callFrames[i];
+            let expectedFrame = expectedFrames[i];
+            InspectorTest.log("Expected frame: " + JSON.stringify(expectedFrame));
+            InspectorTest.expectThat(callFrame.functionName === expectedFrame.functionName, `Function name: ${callFrame.functionName} is correct.`);
+
+            InspectorTest.expectThat(callFrame.isTailDeleted === expectedFrame.isTailDeleted, `Tail deleted expectation correct: ${callFrame.isTailDeleted}`);
+            let scope = callFrame.scopeChain[1];
+
+            scope.objects[0].getAllPropertyDescriptors(function(properties) {
+                let found = false;
+                let variableName = expectedFrame.scope[0];
+                let variableValue = expectedFrame.scope[1];
+                for (let propertyDescriptor of properties) {
+                    if (propertyDescriptor.name === variableName) {
+                        found = true;
+                        InspectorTest.log("Looking at frame number: " + i);
+                        InspectorTest.log(`    variable '${variableName}': ${JSON.stringify(propertyDescriptor.value)}`);
+                        InspectorTest.expectThat(propertyDescriptor.value.type === 'number', "Variable is a number.");
+                        InspectorTest.expectThat(propertyDescriptor.value.value === variableValue, `Found scope value: ${variableValue}`);
+                    }
+                }
+                InspectorTest.expectThat(!!found, `Did not find variable we were looking for: ${variableName}`);
+            });
+        }
+
+        WebInspector.debuggerManager.resume();
+    });
+
+    WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.Resumed, function(event) {
+        InspectorTest.log("Tests done");
+        InspectorTest.completeTest();
+    });
+
+    WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.ScriptAdded, function(event) {
+        eventScriptObject = event.data.script;
+        
+        if (/tail-deleted-frames-from-vm-entry\.js$/.test(eventScriptObject.url)) {
+            scriptObject = eventScriptObject;
+            startTest();
+            return;
+        }
+
+    });
+
+    InspectorTest.reloadPage();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+    <p>Testing that we keep around tail deleted frames that are entry frames. </p>
+</body>
+</html>

Modified: trunk/Source/_javascript_Core/ChangeLog (201464 => 201465)


--- trunk/Source/_javascript_Core/ChangeLog	2016-05-27 20:22:12 UTC (rev 201464)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-05-27 20:26:06 UTC (rev 201465)
@@ -1,3 +1,44 @@
+2016-05-27  Saam barati  <sbar...@apple.com>
+
+        ShadowChicken/DebuggerCallFrame don't properly handle when the entry stack frame is a tail deleted frame
+        https://bugs.webkit.org/show_bug.cgi?id=158131
+
+        Reviewed by Yusuke Suzuki.
+
+        There were bugs both in DebuggerCallFrame and ShadowChicken when the entry stack
+        frame(s) are tail deleted.
+
+        DebuggerCallFrame had an assertion saying that the entry frame shouldn't be
+        tail deleted. This is clearly wrong. The following program proves that this assertion
+        was misguided:
+        ```
+        "use strict";
+        setTimeout(function foo() { return bar(); }, 0);
+        ```
+
+        ShadowChicken had a very subtle bug when creating the shadow stack when 
+        the entry frames of the stack were tail deleted. Because it places frames into its shadow
+        stack by walking the machine frame and looking up entries in the log,
+        the machine frame doesn't have any notion of those tail deleted frames
+        at the entry of execution. ShadowChicken would never find those frames
+        because it would look for tail deleted frames *before* consulting the
+        current machine frame. This is wrong because if the entry frames
+        are tail deleted, then there is no machine frame for them because there
+        is no machine frame before them! Therefore, we must search for tail deleted
+        frames *after* consulting a machine frame. This is sound because we will always
+        have at least one machine frame on the stack (when we are using StackVisitor on a valid ExecState).
+        So when we consult the machine frame that is the entry frame on the machine stack,
+        we will search for tail deleted frames that come before it in the shadow stack.
+        This will allow us to find those tail deleted frames that are the entry frames
+        for the shadow stack.
+
+        * debugger/DebuggerCallFrame.cpp:
+        (JSC::DebuggerCallFrame::create):
+        * interpreter/ShadowChicken.cpp:
+        (JSC::ShadowChicken::Packet::dump):
+        (JSC::ShadowChicken::update):
+        (JSC::ShadowChicken::dump):
+
 2016-05-27  Chris Dumez  <cdu...@apple.com>
 
         WorkQueue::dispatch() / RunLoop::dispatch() should not copy captured lambda variables

Modified: trunk/Source/_javascript_Core/debugger/DebuggerCallFrame.cpp (201464 => 201465)


--- trunk/Source/_javascript_Core/debugger/DebuggerCallFrame.cpp	2016-05-27 20:22:12 UTC (rev 201464)
+++ trunk/Source/_javascript_Core/debugger/DebuggerCallFrame.cpp	2016-05-27 20:26:06 UTC (rev 201465)
@@ -69,16 +69,15 @@
     });
 
     RELEASE_ASSERT(frames.size());
-    RELEASE_ASSERT(!frames[0].isTailDeleted); // The top frame should never be tail deleted.
-    RELEASE_ASSERT(!frames[frames.size() - 1].isTailDeleted); // The first frame should never be tail deleted.
+    ASSERT(!frames[0].isTailDeleted); // The top frame should never be tail deleted.
 
     RefPtr<DebuggerCallFrame> currentParent = nullptr;
-    ExecState* exec = nullptr;
+    ExecState* exec = callFrame->lexicalGlobalObject()->globalExec();
+    // This walks the stack from the entry stack frame to the top of the stack.
     for (unsigned i = frames.size(); i--; ) {
         const ShadowChicken::Frame& frame = frames[i];
         if (!frame.isTailDeleted)
             exec = frame.frame;
-        ASSERT(exec);
         Ref<DebuggerCallFrame> currentFrame = adoptRef(*new DebuggerCallFrame(exec, frame));
         currentFrame->m_caller = currentParent;
         currentParent = WTFMove(currentFrame);

Modified: trunk/Source/_javascript_Core/interpreter/ShadowChicken.cpp (201464 => 201465)


--- trunk/Source/_javascript_Core/interpreter/ShadowChicken.cpp	2016-05-27 20:22:12 UTC (rev 201464)
+++ trunk/Source/_javascript_Core/interpreter/ShadowChicken.cpp	2016-05-27 20:26:06 UTC (rev 201465)
@@ -50,7 +50,7 @@
     }
     
     if (isTail()) {
-        out.print("tail:{frame = ", RawPointer(frame), "}");
+        out.print("tail-packet:{frame = ", RawPointer(frame), "}");
         return;
     }
     
@@ -271,15 +271,36 @@
                 // https://bugs.webkit.org/show_bug.cgi?id=155686
                 return StackVisitor::Continue;
             }
+
             CallFrame* callFrame = visitor->callFrame();
             if (verbose)
                 dataLog("    Examining ", RawPointer(callFrame), "\n");
-            if (!toPush.isEmpty() && indexInLog < logCursorIndex
+            if (callFrame == highestPointSinceLastTime) {
+                if (verbose)
+                    dataLog("    Bailing at ", RawPointer(callFrame), " because it's the highest point since last time.\n");
+                return StackVisitor::Done;
+            }
+
+            bool foundFrame = advanceIndexInLogTo(callFrame, callFrame->callee(), callFrame->callerFrame());
+            bool isTailDeleted = false;
+            JSScope* scope = nullptr;
+            CodeBlock* codeBlock = callFrame->codeBlock();
+            if (codeBlock && codeBlock->wasCompiledWithDebuggingOpcodes() && codeBlock->scopeRegister().isValid()) {
+                scope = callFrame->scope(codeBlock->scopeRegister().offset());
+                RELEASE_ASSERT(scope->inherits(JSScope::info()));
+            } else if (foundFrame) {
+                scope = m_log[indexInLog].scope;
+                if (scope)
+                    RELEASE_ASSERT(scope->inherits(JSScope::info()));
+            }
+            toPush.append(Frame(visitor->callee(), callFrame, isTailDeleted, callFrame->thisValue(), scope, codeBlock, callFrame->callSiteIndex()));
+
+            if (indexInLog < logCursorIndex
                 // This condition protects us from the case where advanceIndexInLogTo didn't find
                 // anything.
                 && m_log[indexInLog].frame == toPush.last().frame) {
                 if (verbose)
-                    dataLog("    Going to loop through things with indexInLog = ", indexInLog, " and push-stack top = ", toPush.last(), "\n");
+                    dataLog("    Going to loop through to find tail deleted frames with indexInLog = ", indexInLog, " and push-stack top = ", toPush.last(), "\n");
                 for (;;) {
                     ASSERT(m_log[indexInLog].frame == toPush.last().frame);
                     
@@ -303,6 +324,8 @@
                     indexInLog--; // Skip over the tail packet.
                     
                     if (!advanceIndexInLogTo(tailPacket.frame, nullptr, nullptr)) {
+                        if (verbose)
+                            dataLog("Can't find prologue packet for tail: ", RawPointer(tailPacket.frame), "\n");
                         // We were unable to locate the prologue packet for this tail packet.
                         // This is rare but can happen in a situation like:
                         // function foo() {
@@ -317,24 +340,7 @@
                     toPush.append(Frame(packet.callee, packet.frame, isTailDeleted, tailPacket.thisValue, tailPacket.scope, tailPacket.codeBlock, tailPacket.callSiteIndex));
                 }
             }
-            if (callFrame == highestPointSinceLastTime) {
-                if (verbose)
-                    dataLog("    Bailing at ", RawPointer(callFrame), " because it's the highest point since last time.\n");
-                return StackVisitor::Done;
-            }
-            bool foundFrame = advanceIndexInLogTo(callFrame, callFrame->callee(), callFrame->callerFrame());
-            bool isTailDeleted = false;
-            JSScope* scope = nullptr;
-            CodeBlock* codeBlock = callFrame->codeBlock();
-            if (codeBlock && codeBlock->wasCompiledWithDebuggingOpcodes() && codeBlock->scopeRegister().isValid()) {
-                scope = callFrame->scope(codeBlock->scopeRegister().offset());
-                RELEASE_ASSERT(scope->inherits(JSScope::info()));
-            } else if (foundFrame) {
-                scope = m_log[indexInLog].scope;
-                if (scope)
-                    RELEASE_ASSERT(scope->inherits(JSScope::info()));
-            }
-            toPush.append(Frame(visitor->callee(), callFrame, isTailDeleted, callFrame->thisValue(), scope, codeBlock, callFrame->callSiteIndex()));
+
             return StackVisitor::Continue;
         });
 
@@ -421,8 +427,9 @@
     
     CommaPrinter comma;
     unsigned limit = static_cast<unsigned>(m_logCursor - m_log);
+    out.print("\n");
     for (unsigned i = 0; i < limit; ++i)
-        out.print(comma, m_log[i]);
+        out.print("\t", comma, m_log[i], "\n");
     out.print("]}");
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to