зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1567438 part 8 - Change Ion bailouts to resume in the interpreter instead of JIT. r=tcampbell CLOSED TREE
There will be more clean up in later patches. Differential Revision: https://phabricator.services.mozilla.com//D38867 --HG-- extra : histedit_source : 8d89fd848656af43e7dc1eae03c857d7cde6e559
This commit is contained in:
Родитель
1be9c38c19
Коммит
2daa53384a
|
@ -129,15 +129,9 @@ struct BaselineStackBuilder {
|
|||
header_->incomingStack = reinterpret_cast<uint8_t*>(frame_);
|
||||
header_->copyStackTop = buffer_ + bufferTotal_;
|
||||
header_->copyStackBottom = header_->copyStackTop;
|
||||
header_->setR0 = 0;
|
||||
header_->valueR0 = UndefinedValue();
|
||||
header_->setR1 = 0;
|
||||
header_->valueR1 = UndefinedValue();
|
||||
header_->resumeFramePtr = nullptr;
|
||||
header_->resumeAddr = nullptr;
|
||||
header_->resumePC = nullptr;
|
||||
header_->monitorPC = nullptr;
|
||||
header_->monitorValue = UndefinedValue();
|
||||
header_->tryPC = nullptr;
|
||||
header_->faultPC = nullptr;
|
||||
header_->numFrames = 0;
|
||||
|
@ -287,36 +281,13 @@ struct BaselineStackBuilder {
|
|||
return result;
|
||||
}
|
||||
|
||||
void popValueInto(PCMappingSlotInfo::SlotLocation loc) {
|
||||
MOZ_ASSERT(PCMappingSlotInfo::ValidSlotLocation(loc));
|
||||
switch (loc) {
|
||||
case PCMappingSlotInfo::SlotInR0:
|
||||
header_->setR0 = 1;
|
||||
header_->valueR0 = popValue();
|
||||
break;
|
||||
case PCMappingSlotInfo::SlotInR1:
|
||||
header_->setR1 = 1;
|
||||
header_->valueR1 = popValue();
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT(loc == PCMappingSlotInfo::SlotIgnore);
|
||||
popValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void setResumeFramePtr(void* resumeFramePtr) {
|
||||
header_->resumeFramePtr = resumeFramePtr;
|
||||
}
|
||||
|
||||
void setResumeAddr(void* resumeAddr) { header_->resumeAddr = resumeAddr; }
|
||||
|
||||
void setResumePC(jsbytecode* pc) { header_->resumePC = pc; }
|
||||
|
||||
void setMonitorPCAndValue(jsbytecode* pc, Value val) {
|
||||
header_->monitorPC = pc;
|
||||
header_->monitorValue = val;
|
||||
}
|
||||
void setMonitorPC(jsbytecode* pc) { header_->monitorPC = pc; }
|
||||
|
||||
template <typename T>
|
||||
BufferPointer<T> pointerAtStackOffset(size_t offset) {
|
||||
|
@ -694,7 +665,7 @@ static bool InitFromBailout(JSContext* cx, size_t frameNo, HandleFunction fun,
|
|||
BufferPointer<BaselineFrame> blFrame =
|
||||
builder.pointerAtStackOffset<BaselineFrame>(0);
|
||||
|
||||
uint32_t flags = 0;
|
||||
uint32_t flags = BaselineFrame::RUNNING_IN_INTERPRETER;
|
||||
|
||||
// If we are bailing to a script whose execution is observed, mark the
|
||||
// baseline frame as a debuggee frame. This is to cover the case where we
|
||||
|
@ -1053,8 +1024,7 @@ static bool InitFromBailout(JSContext* cx, size_t frameNo, HandleFunction fun,
|
|||
MOZ_ASSERT(blFrame->numValueSlots() <= script->nslots());
|
||||
|
||||
// If we are resuming at a LOOPENTRY op, resume at the next op to avoid
|
||||
// a bailout -> enter Ion -> bailout loop with --ion-eager. See also
|
||||
// ThunkToInterpreter.
|
||||
// a bailout -> enter Ion -> bailout loop with --ion-eager.
|
||||
//
|
||||
// The algorithm below is the "tortoise and the hare" algorithm. See bug
|
||||
// 994444 for more explanation.
|
||||
|
@ -1077,7 +1047,6 @@ static bool InitFromBailout(JSContext* cx, size_t frameNo, HandleFunction fun,
|
|||
}
|
||||
|
||||
const uint32_t pcOff = script->pcToOffset(pc);
|
||||
BaselineScript* baselineScript = script->baselineScript();
|
||||
JitScript* jitScript = script->jitScript();
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -1128,6 +1097,9 @@ static bool InitFromBailout(JSContext* cx, size_t frameNo, HandleFunction fun,
|
|||
BailoutKindString(bailoutKind));
|
||||
#endif
|
||||
|
||||
const BaselineInterpreter& baselineInterp =
|
||||
cx->runtime()->jitRuntime()->baselineInterpreter();
|
||||
|
||||
// If this was the last inline frame, or we are bailing out to a catch or
|
||||
// finally block in this frame, then unpacking is almost done.
|
||||
if (!iter.moreFrames() || catchingException) {
|
||||
|
@ -1141,76 +1113,33 @@ static bool InitFromBailout(JSContext* cx, size_t frameNo, HandleFunction fun,
|
|||
// value directly.
|
||||
if ((CodeSpec[op].format & JOF_TYPESET) &&
|
||||
!propagatingIonExceptionForDebugMode) {
|
||||
builder.setMonitorPCAndValue(pc, blFrame->topStackValue());
|
||||
builder.setMonitorPC(pc);
|
||||
}
|
||||
pc = GetNextPc(pc);
|
||||
}
|
||||
|
||||
builder.setResumePC(pc);
|
||||
builder.setResumeFramePtr(prevFramePtr);
|
||||
|
||||
// If needed, initialize BaselineBailoutInfo's valueR0 and/or valueR1 with
|
||||
// the top stack values.
|
||||
//
|
||||
// Note that we use the 'maybe' variant of nativeCodeForPC because
|
||||
// of exception propagation for debug mode. See note below.
|
||||
PCMappingSlotInfo slotInfo;
|
||||
uint8_t* nativeCodeForPC;
|
||||
|
||||
if (propagatingIonExceptionForDebugMode) {
|
||||
uint8_t* resumeAddr;
|
||||
if (isPrologueBailout) {
|
||||
JitSpew(JitSpew_BaselineBailouts, " Resuming into prologue.");
|
||||
MOZ_ASSERT(pc == script->code());
|
||||
blFrame->setInterpreterFieldsForPrologueBailout(script);
|
||||
resumeAddr = baselineInterp.bailoutPrologueEntryAddr();
|
||||
} else if (propagatingIonExceptionForDebugMode) {
|
||||
// When propagating an exception for debug mode, set the
|
||||
// resume pc to the throwing pc, so that Debugger hooks report
|
||||
// the correct pc offset of the throwing op instead of its
|
||||
// successor (this pc will be used as the BaselineFrame's
|
||||
// override pc).
|
||||
// successor.
|
||||
jsbytecode* throwPC = script->offsetToPC(iter.pcOffset());
|
||||
builder.setResumePC(throwPC);
|
||||
|
||||
// Note that we never resume at this pc, it is set for the sake
|
||||
// of frame iterators giving the correct answer.
|
||||
PCMappingSlotInfo unused;
|
||||
nativeCodeForPC =
|
||||
baselineScript->nativeCodeForPC(script, throwPC, &unused);
|
||||
blFrame->setInterpreterFields(script, throwPC);
|
||||
resumeAddr = baselineInterp.interpretOpAddr().value;
|
||||
} else {
|
||||
nativeCodeForPC = baselineScript->nativeCodeForPC(script, pc, &slotInfo);
|
||||
blFrame->setInterpreterFields(script, pc);
|
||||
resumeAddr = baselineInterp.interpretOpAddr().value;
|
||||
}
|
||||
MOZ_ASSERT(nativeCodeForPC);
|
||||
|
||||
unsigned numUnsynced = slotInfo.numUnsynced();
|
||||
|
||||
MOZ_ASSERT(numUnsynced <= 2);
|
||||
PCMappingSlotInfo::SlotLocation loc1, loc2;
|
||||
if (numUnsynced > 0) {
|
||||
loc1 = slotInfo.topSlotLocation();
|
||||
JitSpew(JitSpew_BaselineBailouts,
|
||||
" Popping top stack value into %d.", (int)loc1);
|
||||
builder.popValueInto(loc1);
|
||||
}
|
||||
if (numUnsynced > 1) {
|
||||
loc2 = slotInfo.nextSlotLocation();
|
||||
JitSpew(JitSpew_BaselineBailouts,
|
||||
" Popping next stack value into %d.", (int)loc2);
|
||||
MOZ_ASSERT_IF(loc1 != PCMappingSlotInfo::SlotIgnore, loc1 != loc2);
|
||||
builder.popValueInto(loc2);
|
||||
}
|
||||
|
||||
// Need to adjust the frameSize for the frame to match the values popped
|
||||
// into registers.
|
||||
frameSize -= sizeof(Value) * numUnsynced;
|
||||
blFrame->setFrameSize(frameSize);
|
||||
JitSpew(JitSpew_BaselineBailouts, " Adjusted framesize -= %d: %d",
|
||||
int(sizeof(Value) * numUnsynced), int(frameSize));
|
||||
|
||||
uint8_t* opReturnAddr;
|
||||
if (isPrologueBailout) {
|
||||
MOZ_ASSERT(numUnsynced == 0);
|
||||
opReturnAddr = baselineScript->bailoutPrologueEntryAddr();
|
||||
JitSpew(JitSpew_BaselineBailouts, " Resuming into prologue.");
|
||||
} else {
|
||||
opReturnAddr = nativeCodeForPC;
|
||||
}
|
||||
builder.setResumeAddr(opReturnAddr);
|
||||
JitSpew(JitSpew_BaselineBailouts, " Set resumeAddr=%p", opReturnAddr);
|
||||
builder.setResumeAddr(resumeAddr);
|
||||
JitSpew(JitSpew_BaselineBailouts, " Set resumeAddr=%p", resumeAddr);
|
||||
|
||||
if (cx->runtime()->geckoProfiler().enabled()) {
|
||||
// Register bailout with profiler.
|
||||
|
@ -1234,6 +1163,10 @@ static bool InitFromBailout(JSContext* cx, size_t frameNo, HandleFunction fun,
|
|||
return true;
|
||||
}
|
||||
|
||||
// This is an outer frame for an inlined getter/setter/call.
|
||||
|
||||
blFrame->setInterpreterFields(script, pc);
|
||||
|
||||
// Write out descriptor of BaselineJS frame.
|
||||
size_t baselineFrameDescr = MakeFrameDescriptor(
|
||||
(uint32_t)builder.framePushed(), FrameType::BaselineJS,
|
||||
|
@ -1247,10 +1180,8 @@ static bool InitFromBailout(JSContext* cx, size_t frameNo, HandleFunction fun,
|
|||
ICEntry& icEntry = jitScript->icEntryFromPCOffset(pcOff);
|
||||
MOZ_ASSERT(IsInlinableFallback(icEntry.fallbackStub()));
|
||||
|
||||
RetAddrEntry& retAddrEntry =
|
||||
baselineScript->retAddrEntryFromPCOffset(pcOff, RetAddrEntry::Kind::IC);
|
||||
if (!builder.writePtr(baselineScript->returnAddressForEntry(retAddrEntry),
|
||||
"ReturnAddr")) {
|
||||
uint8_t* retAddr = baselineInterp.retAddrForIC(JSOp(*pc));
|
||||
if (!builder.writePtr(retAddr, "ReturnAddr")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1906,12 +1837,7 @@ bool jit::FinishBailoutToBaseline(BaselineBailoutInfo* bailoutInfo) {
|
|||
|
||||
JitSpew(JitSpew_BaselineBailouts, " Done restoring frames");
|
||||
|
||||
// The current native code pc may not have a corresponding ICEntry, so we
|
||||
// store the bytecode pc in the frame for frame iterators. This pc is
|
||||
// cleared at the end of this function. If we return false, we don't clear
|
||||
// it: the exception handler also needs it and will clear it for us.
|
||||
BaselineFrame* topFrame = GetTopBaselineFrame(cx);
|
||||
topFrame->setOverridePc(bailoutInfo->resumePC);
|
||||
|
||||
jsbytecode* faultPC = bailoutInfo->faultPC;
|
||||
jsbytecode* tryPC = bailoutInfo->tryPC;
|
||||
|
@ -1923,7 +1849,6 @@ bool jit::FinishBailoutToBaseline(BaselineBailoutInfo* bailoutInfo) {
|
|||
uint8_t* incomingStack = bailoutInfo->incomingStack;
|
||||
|
||||
jsbytecode* monitorPC = bailoutInfo->monitorPC;
|
||||
RootedValue monitorValue(cx, bailoutInfo->monitorValue);
|
||||
|
||||
// We have to get rid of the rematerialized frame, whether it is
|
||||
// restored or unwound.
|
||||
|
@ -1956,7 +1881,7 @@ bool jit::FinishBailoutToBaseline(BaselineBailoutInfo* bailoutInfo) {
|
|||
// Monitor the top stack value if we are resuming after a JOF_TYPESET op.
|
||||
if (monitorPC) {
|
||||
MOZ_ASSERT(CodeSpec[*monitorPC].format & JOF_TYPESET);
|
||||
MOZ_ASSERT(GetNextPc(monitorPC) == topFrame->overridePc());
|
||||
MOZ_ASSERT(GetNextPc(monitorPC) == topFrame->interpreterPC());
|
||||
|
||||
RootedScript script(cx, topFrame->script());
|
||||
uint32_t monitorOffset = script->pcToOffset(monitorPC);
|
||||
|
@ -1968,8 +1893,8 @@ bool jit::FinishBailoutToBaseline(BaselineBailoutInfo* bailoutInfo) {
|
|||
// particular script/pc location.
|
||||
if (fallbackStub->isMonitoredFallback()) {
|
||||
ICMonitoredFallbackStub* stub = fallbackStub->toMonitoredFallbackStub();
|
||||
if (!TypeMonitorResult(cx, stub, topFrame, script, monitorPC,
|
||||
monitorValue)) {
|
||||
RootedValue val(cx, topFrame->topStackValue());
|
||||
if (!TypeMonitorResult(cx, stub, topFrame, script, monitorPC, val)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -2164,8 +2089,5 @@ bool jit::FinishBailoutToBaseline(BaselineBailoutInfo* bailoutInfo) {
|
|||
}
|
||||
|
||||
CheckFrequentBailouts(cx, outerScript, bailoutKind);
|
||||
|
||||
// We're returning to JIT code, so we should clear the override pc.
|
||||
topFrame->clearOverridePc();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -292,8 +292,7 @@ MethodStatus BaselineCompiler::compile() {
|
|||
}
|
||||
|
||||
UniquePtr<BaselineScript> baselineScript(
|
||||
BaselineScript::New(script, bailoutPrologueOffset_.offset(),
|
||||
warmUpCheckPrologueOffset_.offset(),
|
||||
BaselineScript::New(script, warmUpCheckPrologueOffset_.offset(),
|
||||
profilerEnterFrameToggleOffset_.offset(),
|
||||
profilerExitFrameToggleOffset_.offset(),
|
||||
handler.retAddrEntries().length(),
|
||||
|
@ -6808,8 +6807,8 @@ bool BaselineCodeGen<Handler>::emitPrologue() {
|
|||
}
|
||||
#endif
|
||||
|
||||
// Record prologue offset for Ion bailouts.
|
||||
bailoutPrologueOffset_ = CodeOffset(masm.currentOffset());
|
||||
// Ion prologue bailouts will enter here in the Baseline Interpreter.
|
||||
masm.bind(&bailoutPrologue_);
|
||||
|
||||
frame.assertSyncedStack();
|
||||
|
||||
|
@ -7089,6 +7088,11 @@ bool BaselineInterpreterGenerator::emitInterpreterLoop() {
|
|||
restoreInterpreterPCReg();
|
||||
masm.jump(&interpretOpAfterDebugTrap);
|
||||
|
||||
// External entry point for Ion prologue bailouts.
|
||||
bailoutPrologueOffset_ = CodeOffset(masm.currentOffset());
|
||||
restoreInterpreterPCReg();
|
||||
masm.jump(&bailoutPrologue_);
|
||||
|
||||
// Emit code for JSOP_UNUSED* ops.
|
||||
Label invalidOp;
|
||||
masm.bind(&invalidOp);
|
||||
|
@ -7220,6 +7224,7 @@ bool BaselineInterpreterGenerator::generate(BaselineInterpreter& interpreter) {
|
|||
|
||||
interpreter.init(
|
||||
code, interpretOpOffset_, interpretOpNoDebugTrapOffset_,
|
||||
bailoutPrologueOffset_.offset(),
|
||||
profilerEnterFrameToggleOffset_.offset(),
|
||||
profilerExitFrameToggleOffset_.offset(),
|
||||
std::move(handler.debugInstrumentationOffsets()),
|
||||
|
|
|
@ -285,6 +285,9 @@ class BaselineCodeGen {
|
|||
|
||||
NonAssertingLabel postBarrierSlot_;
|
||||
|
||||
// Prologue code where we resume for Ion prologue bailouts.
|
||||
NonAssertingLabel bailoutPrologue_;
|
||||
|
||||
CodeOffset profilerEnterFrameToggleOffset_;
|
||||
CodeOffset profilerExitFrameToggleOffset_;
|
||||
|
||||
|
|
|
@ -440,11 +440,10 @@ bool jit::BaselineCompileFromBaselineInterpreter(JSContext* cx,
|
|||
}
|
||||
|
||||
BaselineScript* BaselineScript::New(
|
||||
JSScript* jsscript, uint32_t bailoutPrologueOffset,
|
||||
uint32_t warmUpCheckPrologueOffset, uint32_t profilerEnterToggleOffset,
|
||||
uint32_t profilerExitToggleOffset, size_t retAddrEntries,
|
||||
size_t pcMappingIndexEntries, size_t pcMappingSize, size_t resumeEntries,
|
||||
size_t traceLoggerToggleOffsetEntries) {
|
||||
JSScript* jsscript, uint32_t warmUpCheckPrologueOffset,
|
||||
uint32_t profilerEnterToggleOffset, uint32_t profilerExitToggleOffset,
|
||||
size_t retAddrEntries, size_t pcMappingIndexEntries, size_t pcMappingSize,
|
||||
size_t resumeEntries, size_t traceLoggerToggleOffsetEntries) {
|
||||
static const unsigned DataAlignment = sizeof(uintptr_t);
|
||||
|
||||
size_t retAddrEntriesSize = retAddrEntries * sizeof(RetAddrEntry);
|
||||
|
@ -472,8 +471,8 @@ BaselineScript* BaselineScript::New(
|
|||
return nullptr;
|
||||
}
|
||||
new (script)
|
||||
BaselineScript(bailoutPrologueOffset, warmUpCheckPrologueOffset,
|
||||
profilerEnterToggleOffset, profilerExitToggleOffset);
|
||||
BaselineScript(warmUpCheckPrologueOffset, profilerEnterToggleOffset,
|
||||
profilerExitToggleOffset);
|
||||
|
||||
size_t offsetCursor = sizeof(BaselineScript);
|
||||
MOZ_ASSERT(offsetCursor == AlignBytes(sizeof(BaselineScript), DataAlignment));
|
||||
|
@ -1115,6 +1114,7 @@ void jit::ToggleBaselineTraceLoggerEngine(JSRuntime* runtime, bool enable) {
|
|||
|
||||
void BaselineInterpreter::init(JitCode* code, uint32_t interpretOpOffset,
|
||||
uint32_t interpretOpNoDebugTrapOffset,
|
||||
uint32_t bailoutPrologueOffset,
|
||||
uint32_t profilerEnterToggleOffset,
|
||||
uint32_t profilerExitToggleOffset,
|
||||
CodeOffsetVector&& debugInstrumentationOffsets,
|
||||
|
@ -1125,6 +1125,7 @@ void BaselineInterpreter::init(JitCode* code, uint32_t interpretOpOffset,
|
|||
code_ = code;
|
||||
interpretOpOffset_ = interpretOpOffset;
|
||||
interpretOpNoDebugTrapOffset_ = interpretOpNoDebugTrapOffset;
|
||||
bailoutPrologueOffset_ = bailoutPrologueOffset;
|
||||
profilerEnterToggleOffset_ = profilerEnterToggleOffset;
|
||||
profilerExitToggleOffset_ = profilerExitToggleOffset;
|
||||
debugInstrumentationOffsets_ = std::move(debugInstrumentationOffsets);
|
||||
|
|
|
@ -201,10 +201,6 @@ struct BaselineScript final {
|
|||
// Code pointer containing the actual method.
|
||||
HeapPtr<JitCode*> method_ = nullptr;
|
||||
|
||||
// Early Ion bailouts will enter at this address. This is after frame
|
||||
// construction and before environment chain is initialized.
|
||||
uint32_t bailoutPrologueOffset_;
|
||||
|
||||
// Baseline Interpreter can enter Baseline Compiler code at this address. This
|
||||
// is right after the warm-up counter check in the prologue.
|
||||
uint32_t warmUpCheckPrologueOffset_;
|
||||
|
@ -264,24 +260,19 @@ struct BaselineScript final {
|
|||
|
||||
// Use BaselineScript::New to create new instances. It will properly
|
||||
// allocate trailing objects.
|
||||
BaselineScript(uint32_t bailoutPrologueOffset,
|
||||
uint32_t warmUpCheckPrologueOffset,
|
||||
BaselineScript(uint32_t warmUpCheckPrologueOffset,
|
||||
uint32_t profilerEnterToggleOffset,
|
||||
uint32_t profilerExitToggleOffset)
|
||||
: bailoutPrologueOffset_(bailoutPrologueOffset),
|
||||
warmUpCheckPrologueOffset_(warmUpCheckPrologueOffset),
|
||||
: warmUpCheckPrologueOffset_(warmUpCheckPrologueOffset),
|
||||
profilerEnterToggleOffset_(profilerEnterToggleOffset),
|
||||
profilerExitToggleOffset_(profilerExitToggleOffset) {}
|
||||
|
||||
public:
|
||||
static BaselineScript* New(JSScript* jsscript, uint32_t bailoutPrologueOffset,
|
||||
uint32_t warmUpCheckPrologueOffset,
|
||||
uint32_t profilerEnterToggleOffset,
|
||||
uint32_t profilerExitToggleOffset,
|
||||
size_t retAddrEntries,
|
||||
size_t pcMappingIndexEntries, size_t pcMappingSize,
|
||||
size_t resumeEntries,
|
||||
size_t traceLoggerToggleOffsetEntries);
|
||||
static BaselineScript* New(
|
||||
JSScript* jsscript, uint32_t warmUpCheckPrologueOffset,
|
||||
uint32_t profilerEnterToggleOffset, uint32_t profilerExitToggleOffset,
|
||||
size_t retAddrEntries, size_t pcMappingIndexEntries, size_t pcMappingSize,
|
||||
size_t resumeEntries, size_t traceLoggerToggleOffsetEntries);
|
||||
|
||||
static void Trace(JSTracer* trc, BaselineScript* script);
|
||||
static void Destroy(FreeOp* fop, BaselineScript* script);
|
||||
|
@ -300,9 +291,6 @@ struct BaselineScript final {
|
|||
return flags_ & HAS_DEBUG_INSTRUMENTATION;
|
||||
}
|
||||
|
||||
uint8_t* bailoutPrologueEntryAddr() const {
|
||||
return method_->raw() + bailoutPrologueOffset_;
|
||||
}
|
||||
uint8_t* warmUpCheckPrologueAddr() const {
|
||||
return method_->raw() + warmUpCheckPrologueOffset_;
|
||||
}
|
||||
|
@ -478,27 +466,15 @@ struct BaselineBailoutInfo {
|
|||
uint8_t* copyStackTop;
|
||||
uint8_t* copyStackBottom;
|
||||
|
||||
// Fields to store the top-of-stack baseline values that are held
|
||||
// in registers. The setR0 and setR1 fields are flags indicating
|
||||
// whether each one is initialized.
|
||||
uint32_t setR0;
|
||||
Value valueR0;
|
||||
uint32_t setR1;
|
||||
Value valueR1;
|
||||
|
||||
// The value of the frame pointer register on resume.
|
||||
void* resumeFramePtr;
|
||||
|
||||
// The native code address to resume into.
|
||||
void* resumeAddr;
|
||||
|
||||
// The bytecode pc where we will resume.
|
||||
jsbytecode* resumePC;
|
||||
|
||||
// If non-null, we have to type monitor the top stack value for this pc (we
|
||||
// resume right after it).
|
||||
jsbytecode* monitorPC;
|
||||
Value monitorValue;
|
||||
|
||||
// The bytecode pc of try block and fault block.
|
||||
jsbytecode* tryPC;
|
||||
|
@ -552,6 +528,10 @@ class BaselineInterpreter {
|
|||
// Like interpretOpOffset_ but skips the debug trap for the current op.
|
||||
uint32_t interpretOpNoDebugTrapOffset_ = 0;
|
||||
|
||||
// Early Ion bailouts will enter at this address. This is after frame
|
||||
// construction and environment initialization.
|
||||
uint32_t bailoutPrologueOffset_ = 0;
|
||||
|
||||
// The offsets for the toggledJump instructions for profiler instrumentation.
|
||||
uint32_t profilerEnterToggleOffset_ = 0;
|
||||
uint32_t profilerExitToggleOffset_ = 0;
|
||||
|
@ -587,7 +567,7 @@ class BaselineInterpreter {
|
|||
|
||||
void init(JitCode* code, uint32_t interpretOpOffset,
|
||||
uint32_t interpretOpNoDebugTrapOffset,
|
||||
uint32_t profilerEnterToggleOffset,
|
||||
uint32_t bailoutPrologueOffset, uint32_t profilerEnterToggleOffset,
|
||||
uint32_t profilerExitToggleOffset,
|
||||
CodeOffsetVector&& debugInstrumentationOffsets,
|
||||
CodeOffsetVector&& debugTrapOffsets,
|
||||
|
@ -606,6 +586,9 @@ class BaselineInterpreter {
|
|||
uint8_t* retAddrForDebugAfterYieldCallVM() const {
|
||||
return codeAtOffset(callVMOffsets_.debugAfterYieldOffset);
|
||||
}
|
||||
uint8_t* bailoutPrologueEntryAddr() const {
|
||||
return codeAtOffset(bailoutPrologueOffset_);
|
||||
}
|
||||
|
||||
uint8_t* retAddrForIC(JSOp op) const;
|
||||
|
||||
|
|
|
@ -1571,8 +1571,6 @@ void MacroAssembler::generateBailoutTail(Register scratch,
|
|||
enterFakeExitFrame(scratch, scratch, ExitFrameType::Bare);
|
||||
|
||||
// Save needed values onto stack temporarily.
|
||||
pushValue(Address(bailoutInfo, offsetof(BaselineBailoutInfo, valueR0)));
|
||||
pushValue(Address(bailoutInfo, offsetof(BaselineBailoutInfo, valueR1)));
|
||||
push(Address(bailoutInfo, offsetof(BaselineBailoutInfo, resumeFramePtr)));
|
||||
push(Address(bailoutInfo, offsetof(BaselineBailoutInfo, resumeAddr)));
|
||||
|
||||
|
@ -1585,15 +1583,11 @@ void MacroAssembler::generateBailoutTail(Register scratch,
|
|||
|
||||
// Restore values where they need to be and resume execution.
|
||||
AllocatableGeneralRegisterSet enterRegs(GeneralRegisterSet::All());
|
||||
enterRegs.take(R0);
|
||||
enterRegs.take(R1);
|
||||
enterRegs.take(BaselineFrameReg);
|
||||
Register jitcodeReg = enterRegs.takeAny();
|
||||
|
||||
pop(jitcodeReg);
|
||||
pop(BaselineFrameReg);
|
||||
popValue(R1);
|
||||
popValue(R0);
|
||||
|
||||
// Discard exit frame.
|
||||
addToStackPtr(Imm32(ExitFrameLayout::SizeWithFooter()));
|
||||
|
|
Загрузка…
Ссылка в новой задаче