Title: [149404] trunk
- Revision
- 149404
- Author
- [email protected]
- Date
- 2013-04-30 15:15:47 -0700 (Tue, 30 Apr 2013)
Log Message
JSC Stack walking logic craches in the face of inlined functions triggering VM re-entry
https://bugs.webkit.org/show_bug.cgi?id=115449
Reviewed by Geoffrey Garen.
Source/_javascript_Core:
Rename callframeishost to something that makes sense, and fix
getCallerInfo to correctly handle inline functions calling into
the VM.
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::codeOriginForReturn):
Make this more robust in the face of incorrect stack walking
* interpreter/CallFrame.cpp:
(JSC::CallFrame::trueCallerFrame):
Everyone has to perform a codeblock() check before calling this
so we might as well just do it here.
* interpreter/Interpreter.cpp:
(JSC::getCallerInfo):
LayoutTests:
Add tests
* fast/js/script-tests/stack-trace.js:
(dfgTest):
(inlineableThrow):
(dfgThing.get willThrow):
(dfgThing.get willThrowEventually):
(dfgThing.willThrowFunc):
(dfgThing.willThrowEventuallyFunc):
(dfg1):
(dfg2):
(dfg3):
(dfg4):
(dfg5):
(dfg6):
(dfg7):
(dfg8):
(dfg9):
(dfga):
(dfgb):
(dfgc):
* fast/js/stack-trace-expected.txt:
Modified Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (149403 => 149404)
--- trunk/LayoutTests/ChangeLog 2013-04-30 22:10:51 UTC (rev 149403)
+++ trunk/LayoutTests/ChangeLog 2013-04-30 22:15:47 UTC (rev 149404)
@@ -1,3 +1,33 @@
+2013-04-30 Oliver Hunt <[email protected]>
+
+ JSC Stack walking logic craches in the face of inlined functions triggering VM re-entry
+ https://bugs.webkit.org/show_bug.cgi?id=115449
+
+ Reviewed by Geoffrey Garen.
+
+ Add tests
+
+ * fast/js/script-tests/stack-trace.js:
+ (dfgTest):
+ (inlineableThrow):
+ (dfgThing.get willThrow):
+ (dfgThing.get willThrowEventually):
+ (dfgThing.willThrowFunc):
+ (dfgThing.willThrowEventuallyFunc):
+ (dfg1):
+ (dfg2):
+ (dfg3):
+ (dfg4):
+ (dfg5):
+ (dfg6):
+ (dfg7):
+ (dfg8):
+ (dfg9):
+ (dfga):
+ (dfgb):
+ (dfgc):
+ * fast/js/stack-trace-expected.txt:
+
2013-04-30 Roger Fong <[email protected]>
Unreviewed. Rebaseline some tests on AppleWin port after disabling subpixel layout.
Modified: trunk/LayoutTests/fast/js/script-tests/stack-trace.js (149403 => 149404)
--- trunk/LayoutTests/fast/js/script-tests/stack-trace.js 2013-04-30 22:10:51 UTC (rev 149403)
+++ trunk/LayoutTests/fast/js/script-tests/stack-trace.js 2013-04-30 22:15:47 UTC (rev 149404)
@@ -224,4 +224,86 @@
}
}
+function dfgTest(f) {
+ dfgCount = 0;
+ while (dfgCount++ < 1000) {
+ try {
+ f();
+ } catch (e) {
+ printStack(e.stack)
+ return;
+ }
+ }
+}
+
+function inlineableThrow() {
+ if (dfgCount > 500) throw {};
+}
+
+var dfgThing = {
+ get willThrow() {
+ if (dfgCount > 500)
+ throw {};
+ },
+ get willThrowEventually() {
+ inlineableThrow();
+ },
+ willThrowFunc: function () { if (dfgCount > 500) throw {}; },
+ willThrowEventuallyFunc: function () { inlineableThrow(); }
+}
+dfgThing.__defineGetter__("hostWillThrow", hostThrower);
+
+function dfg1() {
+ dfgThing.willThrow
+}
+
+function dfg2() {
+ dfg1();
+}
+
+function dfg3() {
+ dfg2();
+}
+
+function dfg4() {
+ dfgThing.willThrowFunc();
+}
+
+function dfg5() {
+ dfg4();
+}
+
+function dfg6() {
+ dfg5();
+}
+
+function dfg7() {
+ dfgThing.willThrowEventually
+}
+
+function dfg8() {
+ dfg7();
+}
+
+function dfg9() {
+ dfg8();
+}
+
+function dfga() {
+ dfgThing.willThrowEventuallyFunc();
+}
+
+function dfgb() {
+ dfga();
+}
+
+function dfgc() {
+ dfgb();
+}
+
+dfgTest(dfg3)
+dfgTest(dfg6)
+dfgTest(dfg9)
+dfgTest(dfgc)
+
successfullyParsed = true;
Modified: trunk/LayoutTests/fast/js/stack-trace-expected.txt (149403 => 149404)
--- trunk/LayoutTests/fast/js/stack-trace-expected.txt 2013-04-30 22:10:51 UTC (rev 149403)
+++ trunk/LayoutTests/fast/js/stack-trace-expected.txt 2013-04-30 22:15:47 UTC (rev 149404)
@@ -427,4 +427,38 @@
2 f at stack-trace.js:202:9
3 global code at stack-trace.js:208:5
+--> Stack Trace:
+ 0 willThrow at stack-trace.js:246:20
+ 1 dfg1 at stack-trace.js:257:12
+ 2 dfg2 at stack-trace.js:261:8
+ 3 dfg3 at stack-trace.js:265:8
+ 4 dfgTest at stack-trace.js:231:13
+ 5 global code at stack-trace.js:304:7
+--> Stack Trace:
+ 0 willThrowFunc at stack-trace.js:251:61
+ 1 dfg4 at stack-trace.js:269:26
+ 2 dfg5 at stack-trace.js:273:8
+ 3 dfg6 at stack-trace.js:277:8
+ 4 dfgTest at stack-trace.js:231:13
+ 5 global code at stack-trace.js:305:7
+
+--> Stack Trace:
+ 0 inlineableThrow at stack-trace.js:240:32
+ 1 willThrowEventually at stack-trace.js:249:23
+ 2 dfg7 at stack-trace.js:281:12
+ 3 dfg8 at stack-trace.js:285:8
+ 4 dfg9 at stack-trace.js:289:8
+ 5 dfgTest at stack-trace.js:231:13
+ 6 global code at stack-trace.js:306:7
+
+--> Stack Trace:
+ 0 inlineableThrow at stack-trace.js:240:32
+ 1 willThrowEventuallyFunc at stack-trace.js:252:58
+ 2 dfga at stack-trace.js:293:36
+ 3 dfgb at stack-trace.js:297:8
+ 4 dfgc at stack-trace.js:301:8
+ 5 dfgTest at stack-trace.js:231:13
+ 6 global code at stack-trace.js:307:7
+
+
Modified: trunk/Source/_javascript_Core/ChangeLog (149403 => 149404)
--- trunk/Source/_javascript_Core/ChangeLog 2013-04-30 22:10:51 UTC (rev 149403)
+++ trunk/Source/_javascript_Core/ChangeLog 2013-04-30 22:15:47 UTC (rev 149404)
@@ -1,3 +1,24 @@
+2013-04-30 Oliver Hunt <[email protected]>
+
+ JSC Stack walking logic craches in the face of inlined functions triggering VM re-entry
+ https://bugs.webkit.org/show_bug.cgi?id=115449
+
+ Reviewed by Geoffrey Garen.
+
+ Rename callframeishost to something that makes sense, and fix
+ getCallerInfo to correctly handle inline functions calling into
+ the VM.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::codeOriginForReturn):
+ Make this more robust in the face of incorrect stack walking
+ * interpreter/CallFrame.cpp:
+ (JSC::CallFrame::trueCallerFrame):
+ Everyone has to perform a codeblock() check before calling this
+ so we might as well just do it here.
+ * interpreter/Interpreter.cpp:
+ (JSC::getCallerInfo):
+
2013-04-30 Julien Brianceau <[email protected]>
Bug fixing in sh4 base JIT and LLINT.
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (149403 => 149404)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2013-04-30 22:10:51 UTC (rev 149403)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2013-04-30 22:15:47 UTC (rev 149404)
@@ -2747,7 +2747,11 @@
return false;
if (!getJITCode().getExecutableMemory()->contains(returnAddress.value())) {
- codeOrigin = findClosureCallForReturnPC(returnAddress)->codeOrigin();
+ ClosureCallStubRoutine* stub = findClosureCallForReturnPC(returnAddress);
+ ASSERT(stub);
+ if (!stub)
+ return false;
+ codeOrigin = stub->codeOrigin();
return true;
}
Modified: trunk/Source/_javascript_Core/interpreter/CallFrame.cpp (149403 => 149404)
--- trunk/Source/_javascript_Core/interpreter/CallFrame.cpp 2013-04-30 22:10:51 UTC (rev 149403)
+++ trunk/Source/_javascript_Core/interpreter/CallFrame.cpp 2013-04-30 22:15:47 UTC (rev 149404)
@@ -172,6 +172,9 @@
CallFrame* CallFrame::trueCallerFrame()
{
+ if (!codeBlock())
+ return callerFrame()->removeHostCallFrameFlag();
+
// this -> The callee; this is either an inlined callee in which case it already has
// a pointer to the true caller. Otherwise it contains current PC in the machine
// caller.
Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (149403 => 149404)
--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2013-04-30 22:10:51 UTC (rev 149403)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2013-04-30 22:15:47 UTC (rev 149404)
@@ -520,41 +520,33 @@
ASSERT_UNUSED(vm, vm);
bytecodeOffset = 0;
ASSERT(!callFrame->hasHostCallFrameFlag());
- CallFrame* callerFrame = callFrame->codeBlock() ? callFrame->trueCallerFrame() : callFrame->callerFrame()->removeHostCallFrameFlag();
- bool callframeIsHost = callerFrame->addHostCallFrameFlag() == callFrame->callerFrame();
- ASSERT(!callerFrame->hasHostCallFrameFlag());
+ CallFrame* trueCallerFrame = callFrame->trueCallerFrame();
+ bool wasCalledByHost = callFrame->callerFrame()->hasHostCallFrameFlag();
+ ASSERT(!trueCallerFrame->hasHostCallFrameFlag());
- if (callerFrame == CallFrame::noCaller() || !callerFrame || !callerFrame->codeBlock()) {
+ if (trueCallerFrame == CallFrame::noCaller() || !trueCallerFrame || !trueCallerFrame->codeBlock()) {
caller = 0;
- return callerFrame;
+ return trueCallerFrame;
}
- CodeBlock* callerCodeBlock = callerFrame->codeBlock();
+ CodeBlock* callerCodeBlock = trueCallerFrame->codeBlock();
-#if ENABLE(JIT) || ENABLE(LLINT)
if (!callFrame->hasReturnPC())
- callframeIsHost = true;
-#endif
-#if ENABLE(DFG_JIT)
- if (callFrame->isInlineCallFrame())
- callframeIsHost = false;
-#endif
+ wasCalledByHost = true;
- if (callframeIsHost) {
- // Don't need to deal with inline callframes here as by definition we haven't
- // inlined a call with an intervening native call frame.
-#if ENABLE(JIT) || ENABLE(LLINT)
+ if (wasCalledByHost) {
#if ENABLE(DFG_JIT)
if (callerCodeBlock && callerCodeBlock->getJITType() == JITCode::DFGJIT) {
- unsigned codeOriginIndex = callerFrame->codeOriginIndexForDFG();
- bytecodeOffset = callerCodeBlock->codeOrigin(codeOriginIndex).bytecodeIndex;
+ unsigned codeOriginIndex = callFrame->callerFrame()->removeHostCallFrameFlag()->codeOriginIndexForDFG();
+ CodeOrigin origin = callerCodeBlock->codeOrigin(codeOriginIndex);
+ bytecodeOffset = origin.bytecodeIndex;
+ if (InlineCallFrame* inlineCallFrame = origin.inlineCallFrame)
+ callerCodeBlock = inlineCallFrame->baselineCodeBlock();
} else
#endif
- bytecodeOffset = callerFrame->bytecodeOffsetForNonDFGCode();
-#endif
+ bytecodeOffset = trueCallerFrame->bytecodeOffsetForNonDFGCode();
} else {
-#if ENABLE(JIT) || ENABLE(LLINT)
- #if ENABLE(DFG_JIT)
+#if ENABLE(DFG_JIT)
if (callFrame->isInlineCallFrame()) {
InlineCallFrame* icf = callFrame->inlineCallFrame();
bytecodeOffset = icf->caller.bytecodeIndex;
@@ -584,17 +576,16 @@
callerCodeBlock = newCodeBlock;
}
} else
- #endif
+#endif
{
RELEASE_ASSERT(callerCodeBlock);
- bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
+ bytecodeOffset = callerCodeBlock->bytecodeOffset(trueCallerFrame, callFrame->returnPC());
}
-#endif
}
RELEASE_ASSERT(callerCodeBlock);
caller = callerCodeBlock;
- return callerFrame;
+ return trueCallerFrame;
}
static ALWAYS_INLINE const String getSourceURLFromCallFrame(CallFrame* callFrame)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes