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/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("]}");
}