summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp')
-rw-r--r--Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp276
1 files changed, 207 insertions, 69 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp b/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp
index 9f84a2968..c63f53f60 100644
--- a/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,16 +28,21 @@
#if ENABLE(DFG_JIT)
-#include "Arguments.h"
+#include "DFGJITCode.h"
#include "DFGOperations.h"
+#include "JIT.h"
#include "JSCJSValueInlines.h"
-#include "Operations.h"
+#include "JSCInlines.h"
+#include "StructureStubInfo.h"
namespace JSC { namespace DFG {
void handleExitCounts(CCallHelpers& jit, const OSRExitBase& exit)
{
jit.add32(AssemblyHelpers::TrustedImm32(1), AssemblyHelpers::AbsoluteAddress(&exit.m_count));
+
+ if (!exitKindMayJettison(exit.m_kind))
+ return;
jit.move(AssemblyHelpers::TrustedImmPtr(jit.codeBlock()), GPRInfo::regT0);
@@ -52,20 +57,55 @@ void handleExitCounts(CCallHelpers& jit, const OSRExitBase& exit)
AssemblyHelpers::GreaterThanOrEqual,
AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecuteCounter()),
AssemblyHelpers::TrustedImm32(0));
+
+ // We want to figure out if there's a possibility that we're in a loop. For the outermost
+ // code block in the inline stack, we handle this appropriately by having the loop OSR trigger
+ // check the exit count of the replacement of the CodeBlock from which we are OSRing. The
+ // problem is the inlined functions, which might also have loops, but whose baseline versions
+ // don't know where to look for the exit count. Figure out if those loops are severe enough
+ // that we had tried to OSR enter. If so, then we should use the loop reoptimization trigger.
+ // Otherwise, we should use the normal reoptimization trigger.
+
+ AssemblyHelpers::JumpList loopThreshold;
+
+ for (InlineCallFrame* inlineCallFrame = exit.m_codeOrigin.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame->directCaller.inlineCallFrame) {
+ loopThreshold.append(
+ jit.branchTest8(
+ AssemblyHelpers::NonZero,
+ AssemblyHelpers::AbsoluteAddress(
+ inlineCallFrame->baselineCodeBlock->ownerScriptExecutable()->addressOfDidTryToEnterInLoop())));
+ }
+
+ jit.move(
+ AssemblyHelpers::TrustedImm32(jit.codeBlock()->exitCountThresholdForReoptimization()),
+ GPRInfo::regT1);
+
+ if (!loopThreshold.empty()) {
+ AssemblyHelpers::Jump done = jit.jump();
+
+ loopThreshold.link(&jit);
+ jit.move(
+ AssemblyHelpers::TrustedImm32(
+ jit.codeBlock()->exitCountThresholdForReoptimizationFromLoop()),
+ GPRInfo::regT1);
- tooFewFails = jit.branch32(AssemblyHelpers::BelowOrEqual, GPRInfo::regT2, AssemblyHelpers::TrustedImm32(jit.codeBlock()->exitCountThresholdForReoptimization()));
+ done.link(&jit);
+ }
+
+ tooFewFails = jit.branch32(AssemblyHelpers::BelowOrEqual, GPRInfo::regT2, GPRInfo::regT1);
reoptimizeNow.link(&jit);
// Reoptimize as soon as possible.
#if !NUMBER_OF_ARGUMENT_REGISTERS
jit.poke(GPRInfo::regT0);
+ jit.poke(AssemblyHelpers::TrustedImmPtr(&exit), 1);
#else
jit.move(GPRInfo::regT0, GPRInfo::argumentGPR0);
- ASSERT(GPRInfo::argumentGPR0 != GPRInfo::regT1);
+ jit.move(AssemblyHelpers::TrustedImmPtr(&exit), GPRInfo::argumentGPR1);
#endif
- jit.move(AssemblyHelpers::TrustedImmPtr(bitwise_cast<void*>(triggerReoptimizationNow)), GPRInfo::regT1);
- jit.call(GPRInfo::regT1);
+ jit.move(AssemblyHelpers::TrustedImmPtr(bitwise_cast<void*>(triggerReoptimizationNow)), GPRInfo::nonArgGPR0);
+ jit.call(GPRInfo::nonArgGPR0);
AssemblyHelpers::Jump doneAdjusting = jit.jump();
tooFewFails.link(&jit);
@@ -74,105 +114,203 @@ void handleExitCounts(CCallHelpers& jit, const OSRExitBase& exit)
int32_t activeThreshold =
jit.baselineCodeBlock()->adjustedCounterValue(
Options::thresholdForOptimizeAfterLongWarmUp());
- int32_t targetValue = ExecutionCounter::applyMemoryUsageHeuristicsAndConvertToInt(
+ int32_t targetValue = applyMemoryUsageHeuristicsAndConvertToInt(
activeThreshold, jit.baselineCodeBlock());
- int32_t clippedValue =
- ExecutionCounter::clippedThreshold(jit.codeBlock()->globalObject(), targetValue);
+ int32_t clippedValue;
+ switch (jit.codeBlock()->jitType()) {
+ case JITCode::DFGJIT:
+ clippedValue = BaselineExecutionCounter::clippedThreshold(jit.codeBlock()->globalObject(), targetValue);
+ break;
+ case JITCode::FTLJIT:
+ clippedValue = UpperTierExecutionCounter::clippedThreshold(jit.codeBlock()->globalObject(), targetValue);
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+#if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
+ clippedValue = 0; // Make some compilers, and mhahnenberg, happy.
+#endif
+ break;
+ }
jit.store32(AssemblyHelpers::TrustedImm32(-clippedValue), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecuteCounter()));
jit.store32(AssemblyHelpers::TrustedImm32(activeThreshold), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecutionActiveThreshold()));
- jit.store32(AssemblyHelpers::TrustedImm32(ExecutionCounter::formattedTotalCount(clippedValue)), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecutionTotalCount()));
+ jit.store32(AssemblyHelpers::TrustedImm32(formattedTotalExecutionCount(clippedValue)), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecutionTotalCount()));
doneAdjusting.link(&jit);
}
void reifyInlinedCallFrames(CCallHelpers& jit, const OSRExitBase& exit)
{
+ // FIXME: We shouldn't leave holes on the stack when performing an OSR exit
+ // in presence of inlined tail calls.
+ // https://bugs.webkit.org/show_bug.cgi?id=147511
ASSERT(jit.baselineCodeBlock()->jitType() == JITCode::BaselineJIT);
- jit.storePtr(AssemblyHelpers::TrustedImmPtr(jit.baselineCodeBlock()), AssemblyHelpers::addressFor((VirtualRegister)JSStack::CodeBlock));
-
- CodeOrigin codeOrigin;
- for (codeOrigin = exit.m_codeOrigin; codeOrigin.inlineCallFrame; codeOrigin = codeOrigin.inlineCallFrame->caller) {
- InlineCallFrame* inlineCallFrame = codeOrigin.inlineCallFrame;
- CodeBlock* baselineCodeBlock = jit.baselineCodeBlockFor(codeOrigin);
- CodeBlock* baselineCodeBlockForCaller = jit.baselineCodeBlockFor(inlineCallFrame->caller);
- unsigned callBytecodeIndex = inlineCallFrame->caller.bytecodeIndex;
- CallLinkInfo& callLinkInfo = baselineCodeBlockForCaller->getCallLinkInfo(callBytecodeIndex);
-
- void* jumpTarget = callLinkInfo.callReturnLocation.executableAddress();
+ jit.storePtr(AssemblyHelpers::TrustedImmPtr(jit.baselineCodeBlock()), AssemblyHelpers::addressFor((VirtualRegister)CallFrameSlot::codeBlock));
- GPRReg callerFrameGPR;
- if (inlineCallFrame->caller.inlineCallFrame) {
- jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame->caller.inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT3);
+ const CodeOrigin* codeOrigin;
+ for (codeOrigin = &exit.m_codeOrigin; codeOrigin && codeOrigin->inlineCallFrame; codeOrigin = codeOrigin->inlineCallFrame->getCallerSkippingTailCalls()) {
+ InlineCallFrame* inlineCallFrame = codeOrigin->inlineCallFrame;
+ CodeBlock* baselineCodeBlock = jit.baselineCodeBlockFor(*codeOrigin);
+ InlineCallFrame::Kind trueCallerCallKind;
+ CodeOrigin* trueCaller = inlineCallFrame->getCallerSkippingTailCalls(&trueCallerCallKind);
+ GPRReg callerFrameGPR = GPRInfo::callFrameRegister;
+
+ if (!trueCaller) {
+ ASSERT(inlineCallFrame->isTail());
+ jit.loadPtr(AssemblyHelpers::Address(GPRInfo::callFrameRegister, CallFrame::returnPCOffset()), GPRInfo::regT3);
+ jit.storePtr(GPRInfo::regT3, AssemblyHelpers::addressForByteOffset(inlineCallFrame->returnPCOffset()));
+ jit.loadPtr(AssemblyHelpers::Address(GPRInfo::callFrameRegister, CallFrame::callerFrameOffset()), GPRInfo::regT3);
callerFrameGPR = GPRInfo::regT3;
- } else
- callerFrameGPR = GPRInfo::callFrameRegister;
-
+ } else {
+ CodeBlock* baselineCodeBlockForCaller = jit.baselineCodeBlockFor(*trueCaller);
+ unsigned callBytecodeIndex = trueCaller->bytecodeIndex;
+ void* jumpTarget = nullptr;
+
+ switch (trueCallerCallKind) {
+ case InlineCallFrame::Call:
+ case InlineCallFrame::Construct:
+ case InlineCallFrame::CallVarargs:
+ case InlineCallFrame::ConstructVarargs:
+ case InlineCallFrame::TailCall:
+ case InlineCallFrame::TailCallVarargs: {
+ CallLinkInfo* callLinkInfo =
+ baselineCodeBlockForCaller->getCallLinkInfoForBytecodeIndex(callBytecodeIndex);
+ RELEASE_ASSERT(callLinkInfo);
+
+ jumpTarget = callLinkInfo->callReturnLocation().executableAddress();
+ break;
+ }
+
+ case InlineCallFrame::GetterCall:
+ case InlineCallFrame::SetterCall: {
+ StructureStubInfo* stubInfo =
+ baselineCodeBlockForCaller->findStubInfo(CodeOrigin(callBytecodeIndex));
+ RELEASE_ASSERT(stubInfo);
+
+ jumpTarget = stubInfo->doneLocation().executableAddress();
+ break;
+ }
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+
+ if (trueCaller->inlineCallFrame) {
+ jit.addPtr(
+ AssemblyHelpers::TrustedImm32(trueCaller->inlineCallFrame->stackOffset * sizeof(EncodedJSValue)),
+ GPRInfo::callFrameRegister,
+ GPRInfo::regT3);
+ callerFrameGPR = GPRInfo::regT3;
+ }
+
+ jit.storePtr(AssemblyHelpers::TrustedImmPtr(jumpTarget), AssemblyHelpers::addressForByteOffset(inlineCallFrame->returnPCOffset()));
+ }
+
+ jit.storePtr(AssemblyHelpers::TrustedImmPtr(baselineCodeBlock), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + CallFrameSlot::codeBlock)));
+
+ // Restore the inline call frame's callee save registers.
+ // If this inlined frame is a tail call that will return back to the original caller, we need to
+ // copy the prior contents of the tag registers already saved for the outer frame to this frame.
+ jit.emitSaveOrCopyCalleeSavesFor(
+ baselineCodeBlock,
+ static_cast<VirtualRegister>(inlineCallFrame->stackOffset),
+ trueCaller ? AssemblyHelpers::UseExistingTagRegisterContents : AssemblyHelpers::CopyBaselineCalleeSavedRegistersFromBaseFrame,
+ GPRInfo::regT2);
+
+ if (!inlineCallFrame->isVarargs())
+ jit.store32(AssemblyHelpers::TrustedImm32(inlineCallFrame->arguments.size()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + CallFrameSlot::argumentCount)));
#if USE(JSVALUE64)
- jit.storePtr(AssemblyHelpers::TrustedImmPtr(baselineCodeBlock), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::CodeBlock)));
- if (!inlineCallFrame->isClosureCall)
- jit.store64(AssemblyHelpers::TrustedImm64(JSValue::encode(JSValue(inlineCallFrame->calleeConstant()->scope()))), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ScopeChain)));
jit.store64(callerFrameGPR, AssemblyHelpers::addressForByteOffset(inlineCallFrame->callerFrameOffset()));
- jit.storePtr(AssemblyHelpers::TrustedImmPtr(jumpTarget), AssemblyHelpers::addressForByteOffset(inlineCallFrame->returnPCOffset()));
- uint32_t locationBits = CallFrame::Location::encodeAsBytecodeOffset(codeOrigin.bytecodeIndex);
- jit.store32(AssemblyHelpers::TrustedImm32(locationBits), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ArgumentCount)));
- jit.store32(AssemblyHelpers::TrustedImm32(inlineCallFrame->arguments.size()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ArgumentCount)));
+ uint32_t locationBits = CallSiteIndex(codeOrigin->bytecodeIndex).bits();
+ jit.store32(AssemblyHelpers::TrustedImm32(locationBits), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + CallFrameSlot::argumentCount)));
if (!inlineCallFrame->isClosureCall)
- jit.store64(AssemblyHelpers::TrustedImm64(JSValue::encode(JSValue(inlineCallFrame->calleeConstant()))), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::Callee)));
-
- // Leave the captured arguments in regT3.
- if (baselineCodeBlock->usesArguments())
- jit.loadPtr(AssemblyHelpers::addressFor(VirtualRegister(inlineCallFrame->stackOffset + unmodifiedArgumentsRegister(baselineCodeBlock->argumentsRegister()).offset())), GPRInfo::regT3);
+ jit.store64(AssemblyHelpers::TrustedImm64(JSValue::encode(JSValue(inlineCallFrame->calleeConstant()))), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + CallFrameSlot::callee)));
#else // USE(JSVALUE64) // so this is the 32-bit part
- jit.storePtr(AssemblyHelpers::TrustedImmPtr(baselineCodeBlock), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::CodeBlock)));
- jit.store32(AssemblyHelpers::TrustedImm32(JSValue::CellTag), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ScopeChain)));
- if (!inlineCallFrame->isClosureCall)
- jit.storePtr(AssemblyHelpers::TrustedImmPtr(inlineCallFrame->calleeConstant()->scope()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ScopeChain)));
jit.storePtr(callerFrameGPR, AssemblyHelpers::addressForByteOffset(inlineCallFrame->callerFrameOffset()));
- jit.storePtr(AssemblyHelpers::TrustedImmPtr(jumpTarget), AssemblyHelpers::addressForByteOffset(inlineCallFrame->returnPCOffset()));
- Instruction* instruction = baselineCodeBlock->instructions().begin() + codeOrigin.bytecodeIndex;
- uint32_t locationBits = CallFrame::Location::encodeAsBytecodeInstruction(instruction);
- jit.store32(AssemblyHelpers::TrustedImm32(locationBits), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ArgumentCount)));
- jit.store32(AssemblyHelpers::TrustedImm32(inlineCallFrame->arguments.size()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ArgumentCount)));
- jit.store32(AssemblyHelpers::TrustedImm32(JSValue::CellTag), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::Callee)));
+ Instruction* instruction = baselineCodeBlock->instructions().begin() + codeOrigin->bytecodeIndex;
+ uint32_t locationBits = CallSiteIndex(instruction).bits();
+ jit.store32(AssemblyHelpers::TrustedImm32(locationBits), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + CallFrameSlot::argumentCount)));
+ jit.store32(AssemblyHelpers::TrustedImm32(JSValue::CellTag), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + CallFrameSlot::callee)));
if (!inlineCallFrame->isClosureCall)
- jit.storePtr(AssemblyHelpers::TrustedImmPtr(inlineCallFrame->calleeConstant()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::Callee)));
-
- // Leave the captured arguments in regT3.
- if (baselineCodeBlock->usesArguments())
- jit.loadPtr(AssemblyHelpers::payloadFor(VirtualRegister(inlineCallFrame->stackOffset + unmodifiedArgumentsRegister(baselineCodeBlock->argumentsRegister()).offset())), GPRInfo::regT3);
+ jit.storePtr(AssemblyHelpers::TrustedImmPtr(inlineCallFrame->calleeConstant()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + CallFrameSlot::callee)));
#endif // USE(JSVALUE64) // ending the #else part, so directly above is the 32-bit part
-
- if (baselineCodeBlock->usesArguments()) {
- AssemblyHelpers::Jump noArguments = jit.branchTestPtr(AssemblyHelpers::Zero, GPRInfo::regT3);
- jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
- jit.storePtr(GPRInfo::regT0, AssemblyHelpers::Address(GPRInfo::regT3, Arguments::offsetOfRegisters()));
- noArguments.link(&jit);
- }
}
+ // Don't need to set the toplevel code origin if we only did inline tail calls
+ if (codeOrigin) {
#if USE(JSVALUE64)
- uint32_t locationBits = CallFrame::Location::encodeAsBytecodeOffset(codeOrigin.bytecodeIndex);
+ uint32_t locationBits = CallSiteIndex(codeOrigin->bytecodeIndex).bits();
#else
- Instruction* instruction = jit.baselineCodeBlock()->instructions().begin() + codeOrigin.bytecodeIndex;
- uint32_t locationBits = CallFrame::Location::encodeAsBytecodeInstruction(instruction);
+ Instruction* instruction = jit.baselineCodeBlock()->instructions().begin() + codeOrigin->bytecodeIndex;
+ uint32_t locationBits = CallSiteIndex(instruction).bits();
+#endif
+ jit.store32(AssemblyHelpers::TrustedImm32(locationBits), AssemblyHelpers::tagFor((VirtualRegister)(CallFrameSlot::argumentCount)));
+ }
+}
+
+static void osrWriteBarrier(CCallHelpers& jit, GPRReg owner, GPRReg scratch)
+{
+ AssemblyHelpers::Jump ownerIsRememberedOrInEden = jit.barrierBranchWithoutFence(owner);
+
+ // We need these extra slots because setupArgumentsWithExecState will use poke on x86.
+#if CPU(X86)
+ jit.subPtr(MacroAssembler::TrustedImm32(sizeof(void*) * 3), MacroAssembler::stackPointerRegister);
+#endif
+
+ jit.setupArgumentsWithExecState(owner);
+ jit.move(MacroAssembler::TrustedImmPtr(reinterpret_cast<void*>(operationOSRWriteBarrier)), scratch);
+ jit.call(scratch);
+
+#if CPU(X86)
+ jit.addPtr(MacroAssembler::TrustedImm32(sizeof(void*) * 3), MacroAssembler::stackPointerRegister);
#endif
- jit.store32(AssemblyHelpers::TrustedImm32(locationBits), AssemblyHelpers::tagFor((VirtualRegister)(JSStack::ArgumentCount)));
+
+ ownerIsRememberedOrInEden.link(&jit);
}
void adjustAndJumpToTarget(CCallHelpers& jit, const OSRExitBase& exit)
{
+ jit.memoryFence();
+
+ jit.move(
+ AssemblyHelpers::TrustedImmPtr(
+ jit.codeBlock()->baselineAlternative()), GPRInfo::argumentGPR1);
+ osrWriteBarrier(jit, GPRInfo::argumentGPR1, GPRInfo::nonArgGPR0);
+
+ // We barrier all inlined frames -- and not just the current inline stack --
+ // because we don't know which inlined function owns the value profile that
+ // we'll update when we exit. In the case of "f() { a(); b(); }", if both
+ // a and b are inlined, we might exit inside b due to a bad value loaded
+ // from a.
+ // FIXME: MethodOfGettingAValueProfile should remember which CodeBlock owns
+ // the value profile.
+ InlineCallFrameSet* inlineCallFrames = jit.codeBlock()->jitCode()->dfgCommon()->inlineCallFrames.get();
+ if (inlineCallFrames) {
+ for (InlineCallFrame* inlineCallFrame : *inlineCallFrames) {
+ jit.move(
+ AssemblyHelpers::TrustedImmPtr(
+ inlineCallFrame->baselineCodeBlock.get()), GPRInfo::argumentGPR1);
+ osrWriteBarrier(jit, GPRInfo::argumentGPR1, GPRInfo::nonArgGPR0);
+ }
+ }
+
if (exit.m_codeOrigin.inlineCallFrame)
jit.addPtr(AssemblyHelpers::TrustedImm32(exit.m_codeOrigin.inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister);
- CodeBlock* baselineCodeBlock = jit.baselineCodeBlockFor(exit.m_codeOrigin);
- Vector<BytecodeAndMachineOffset>& decodedCodeMap = jit.decodedCodeMapFor(baselineCodeBlock);
+ CodeBlock* codeBlockForExit = jit.baselineCodeBlockFor(exit.m_codeOrigin);
+ Vector<BytecodeAndMachineOffset>& decodedCodeMap = jit.decodedCodeMapFor(codeBlockForExit);
BytecodeAndMachineOffset* mapping = binarySearch<BytecodeAndMachineOffset, unsigned>(decodedCodeMap, decodedCodeMap.size(), exit.m_codeOrigin.bytecodeIndex, BytecodeAndMachineOffset::getBytecodeIndex);
ASSERT(mapping);
ASSERT(mapping->m_bytecodeIndex == exit.m_codeOrigin.bytecodeIndex);
- void* jumpTarget = baselineCodeBlock->jitCode()->executableAddressAtOffset(mapping->m_machineCodeOffset);
+ void* jumpTarget = codeBlockForExit->jitCode()->executableAddressAtOffset(mapping->m_machineCodeOffset);
+
+ jit.addPtr(AssemblyHelpers::TrustedImm32(JIT::stackPointerOffsetFor(codeBlockForExit) * sizeof(Register)), GPRInfo::callFrameRegister, AssemblyHelpers::stackPointerRegister);
+ if (exit.isExceptionHandler()) {
+ // Since we're jumping to op_catch, we need to set callFrameForCatch.
+ jit.storePtr(GPRInfo::callFrameRegister, jit.vm()->addressOfCallFrameForCatch());
+ }
jit.move(AssemblyHelpers::TrustedImmPtr(jumpTarget), GPRInfo::regT2);
jit.jump(GPRInfo::regT2);