- Revision
- 160808
- Author
- [email protected]
- Date
- 2013-12-18 16:48:54 -0800 (Wed, 18 Dec 2013)
Log Message
CStack: Fix LLINT to baseline JIT OSR.
https://bugs.webkit.org/show_bug.cgi?id=125957.
Reviewed by Michael Saboff.
1. In LLINT prologue code, when taking the OSR path, we don't actually
need the OSR slow path function to return the new stackPointer value.
Instead, the OSR prep code in the prologue needs to restore the
previous sp because we are going to jump to the prologue of the
target codeBlock, which will assume that the stack pointer to be
pointing to the top of the caller frame.
To do this, we simply set stackPointer to the "new" callFrameRegister
before we pop the "old" callFrame address into the callFrameRegister.
2. In the LLINT checkSwitchToJITForLoop() macro, if we're going to take
the OSR path, we'll need to set the stackPointer to the new topOfFrame
for the target codeBlock. Hence, we make llint_loop_osr return
exec->topOfFrame() for this purpose.
3. Previously, CallFrame::topOfFrame() (renamed from CallFrame::frameExtent())
would return the address of the slot past the top of the frame. It now
returns the slot at the top of the frame as it should.
* interpreter/CallFrame.cpp:
(JSC::CallFrame::topOfFrameInternal):
* interpreter/CallFrame.h:
(JSC::ExecState::topOfFrame):
* interpreter/JSStack.cpp:
(JSC::JSStack::disableErrorStackReserve):
* interpreter/JSStackInlines.h:
(JSC::JSStack::getTopOfFrame):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::entryOSR):
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
Modified Paths
Diff
Modified: branches/jsCStack/Source/_javascript_Core/ChangeLog (160807 => 160808)
--- branches/jsCStack/Source/_javascript_Core/ChangeLog 2013-12-19 00:42:51 UTC (rev 160807)
+++ branches/jsCStack/Source/_javascript_Core/ChangeLog 2013-12-19 00:48:54 UTC (rev 160808)
@@ -1,3 +1,44 @@
+2013-12-18 Mark Lam <[email protected]>
+
+ CStack: Fix LLINT to baseline JIT OSR.
+ https://bugs.webkit.org/show_bug.cgi?id=125957.
+
+ Reviewed by Michael Saboff.
+
+ 1. In LLINT prologue code, when taking the OSR path, we don't actually
+ need the OSR slow path function to return the new stackPointer value.
+ Instead, the OSR prep code in the prologue needs to restore the
+ previous sp because we are going to jump to the prologue of the
+ target codeBlock, which will assume that the stack pointer to be
+ pointing to the top of the caller frame.
+
+ To do this, we simply set stackPointer to the "new" callFrameRegister
+ before we pop the "old" callFrame address into the callFrameRegister.
+
+ 2. In the LLINT checkSwitchToJITForLoop() macro, if we're going to take
+ the OSR path, we'll need to set the stackPointer to the new topOfFrame
+ for the target codeBlock. Hence, we make llint_loop_osr return
+ exec->topOfFrame() for this purpose.
+
+ 3. Previously, CallFrame::topOfFrame() (renamed from CallFrame::frameExtent())
+ would return the address of the slot past the top of the frame. It now
+ returns the slot at the top of the frame as it should.
+
+ * interpreter/CallFrame.cpp:
+ (JSC::CallFrame::topOfFrameInternal):
+ * interpreter/CallFrame.h:
+ (JSC::ExecState::topOfFrame):
+ * interpreter/JSStack.cpp:
+ (JSC::JSStack::disableErrorStackReserve):
+ * interpreter/JSStackInlines.h:
+ (JSC::JSStack::getTopOfFrame):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::entryOSR):
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+
2013-12-18 Michael Saboff <[email protected]>
CStack Branch: getHostCallReturnValue shouldn't pop the callFrame
Modified: branches/jsCStack/Source/_javascript_Core/interpreter/CallFrame.cpp (160807 => 160808)
--- branches/jsCStack/Source/_javascript_Core/interpreter/CallFrame.cpp 2013-12-19 00:42:51 UTC (rev 160807)
+++ branches/jsCStack/Source/_javascript_Core/interpreter/CallFrame.cpp 2013-12-19 00:48:54 UTC (rev 160808)
@@ -116,11 +116,11 @@
return CodeOrigin(locationAsBytecodeOffset());
}
-Register* CallFrame::frameExtentInternal()
+Register* CallFrame::topOfFrameInternal()
{
CodeBlock* codeBlock = this->codeBlock();
ASSERT(codeBlock);
- return registers() + virtualRegisterForLocal(codeBlock->frameRegisterCount()).offset();
+ return registers() + virtualRegisterForLocal(codeBlock->frameRegisterCount() - 1).offset();
}
JSGlobalObject* CallFrame::vmEntryGlobalObject()
Modified: branches/jsCStack/Source/_javascript_Core/interpreter/CallFrame.h (160807 => 160808)
--- branches/jsCStack/Source/_javascript_Core/interpreter/CallFrame.h 2013-12-19 00:42:51 UTC (rev 160807)
+++ branches/jsCStack/Source/_javascript_Core/interpreter/CallFrame.h 2013-12-19 00:48:54 UTC (rev 160808)
@@ -177,15 +177,13 @@
// CodeOrigin(0) if we're in native code.
CodeOrigin codeOrigin();
- Register* frameExtent()
+ Register* topOfFrame()
{
if (isVMEntrySentinel() || !codeBlock())
- return registers() - 1;
- return frameExtentInternal();
+ return registers();
+ return topOfFrameInternal();
}
- Register* frameExtentInternal();
-
#if USE(JSVALUE32_64)
Instruction* currentVPC() const
{
@@ -319,6 +317,8 @@
ExecState();
~ExecState();
+ Register* topOfFrameInternal();
+
// The following are for internal use in debugging and verification
// code only and not meant as an API for general usage:
Modified: branches/jsCStack/Source/_javascript_Core/interpreter/JSStack.cpp (160807 => 160808)
--- branches/jsCStack/Source/_javascript_Core/interpreter/JSStack.cpp 2013-12-19 00:42:51 UTC (rev 160807)
+++ branches/jsCStack/Source/_javascript_Core/interpreter/JSStack.cpp 2013-12-19 00:48:54 UTC (rev 160808)
@@ -170,7 +170,7 @@
// enabled the reserve was not previously in use. Hence, it is safe to
// shrink back to that m_useableEnd.
if (m_end < m_useableEnd) {
- ASSERT(m_topCallFrame->frameExtent() >= m_useableEnd);
+ ASSERT(m_topCallFrame->topOfFrame() > m_useableEnd);
shrink(m_useableEnd);
}
}
Modified: branches/jsCStack/Source/_javascript_Core/interpreter/JSStackInlines.h (160807 => 160808)
--- branches/jsCStack/Source/_javascript_Core/interpreter/JSStackInlines.h 2013-12-19 00:42:51 UTC (rev 160807)
+++ branches/jsCStack/Source/_javascript_Core/interpreter/JSStackInlines.h 2013-12-19 00:48:54 UTC (rev 160808)
@@ -37,7 +37,7 @@
{
if (UNLIKELY(!frame))
return getBaseOfStack();
- return frame->frameExtent();
+ return frame->topOfFrame() - 1;
}
inline Register* JSStack::getTopOfStack()
Modified: branches/jsCStack/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (160807 => 160808)
--- branches/jsCStack/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2013-12-19 00:42:51 UTC (rev 160807)
+++ branches/jsCStack/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2013-12-19 00:48:54 UTC (rev 160808)
@@ -332,15 +332,15 @@
if (!shouldJIT(exec)) {
codeBlock->dontJITAnytimeSoon();
- LLINT_RETURN_TWO(0, exec);
+ LLINT_RETURN_TWO(0, 0);
}
if (!jitCompileAndSetHeuristics(codeBlock, exec))
- LLINT_RETURN_TWO(0, exec);
+ LLINT_RETURN_TWO(0, 0);
if (kind == Prologue)
- LLINT_RETURN_TWO(codeBlock->jitCode()->executableAddress(), exec);
+ LLINT_RETURN_TWO(codeBlock->jitCode()->executableAddress(), 0);
ASSERT(kind == ArityCheck);
- LLINT_RETURN_TWO(codeBlock->jitCodeWithArityCheck().executableAddress(), exec);
+ LLINT_RETURN_TWO(codeBlock->jitCodeWithArityCheck().executableAddress(), 0);
}
LLINT_SLOW_PATH_DECL(entry_osr)
@@ -380,11 +380,11 @@
if (!shouldJIT(exec)) {
codeBlock->dontJITAnytimeSoon();
- LLINT_RETURN_TWO(0, exec);
+ LLINT_RETURN_TWO(0, 0);
}
if (!jitCompileAndSetHeuristics(codeBlock, exec))
- LLINT_RETURN_TWO(0, exec);
+ LLINT_RETURN_TWO(0, 0);
ASSERT(codeBlock->jitType() == JITCode::BaselineJIT);
@@ -397,7 +397,7 @@
void* jumpTarget = codeBlock->jitCode()->executableAddressAtOffset(mapping->m_machineCodeOffset);
ASSERT(jumpTarget);
- LLINT_RETURN_TWO(jumpTarget, exec);
+ LLINT_RETURN_TWO(jumpTarget, exec->topOfFrame());
}
LLINT_SLOW_PATH_DECL(replace)
Modified: branches/jsCStack/Source/_javascript_Core/llint/LowLevelInterpreter.asm (160807 => 160808)
--- branches/jsCStack/Source/_javascript_Core/llint/LowLevelInterpreter.asm 2013-12-19 00:42:51 UTC (rev 160807)
+++ branches/jsCStack/Source/_javascript_Core/llint/LowLevelInterpreter.asm 2013-12-19 00:48:54 UTC (rev 160808)
@@ -366,9 +366,9 @@
baddis 5, CodeBlock::m_llintExecuteCounter + ExecutionCounter::m_counter[t1], .continue
cCall2(osrSlowPath, cfr, PC)
btpz t0, .recover
- # FIXME: Turn off OSR entry
- # pop cfr # pop the callerFrame since we will jump to a function that wants to save it
- # jmp t0
+ move cfr, sp # restore the previous sp
+ pop cfr # pop the callerFrame since we will jump to a function that wants to save it
+ jmp t0
.recover:
codeBlockGetter(t1)
.continue:
Modified: branches/jsCStack/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm (160807 => 160808)
--- branches/jsCStack/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm 2013-12-19 00:42:51 UTC (rev 160807)
+++ branches/jsCStack/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm 2013-12-19 00:48:54 UTC (rev 160808)
@@ -407,8 +407,8 @@
macro ()
storei PC, ArgumentCount + TagOffset[cfr]
cCall2(_llint_loop_osr, cfr, PC)
- move t1, cfr
btpz t0, .recover
+ move t1, sp
jmp t0
.recover:
loadi ArgumentCount + TagOffset[cfr], PC
Modified: branches/jsCStack/Source/_javascript_Core/llint/LowLevelInterpreter64.asm (160807 => 160808)
--- branches/jsCStack/Source/_javascript_Core/llint/LowLevelInterpreter64.asm 2013-12-19 00:42:51 UTC (rev 160807)
+++ branches/jsCStack/Source/_javascript_Core/llint/LowLevelInterpreter64.asm 2013-12-19 00:48:54 UTC (rev 160808)
@@ -349,10 +349,9 @@
storei PC, ArgumentCount + TagOffset[cfr]
prepareStateForCCall()
cCall2(_llint_loop_osr, cfr, PC)
- move t1, cfr
btpz t0, .recover
- # FIXME: CStack - Turn OSR entry back on
- # jmp t0
+ move t1, sp
+ jmp t0
.recover:
move t3, PB
loadi ArgumentCount + TagOffset[cfr], PC