bool BaselineFrame::initForOsr(InterpreterFrame *fp, uint32_t numStackValues) { mozilla::PodZero(this); scopeChain_ = fp->scopeChain(); if (fp->hasCallObjUnchecked()) flags_ |= BaselineFrame::HAS_CALL_OBJ; if (fp->isEvalFrame()) { flags_ |= BaselineFrame::EVAL; evalScript_ = fp->script(); } if (fp->script()->needsArgsObj() && fp->hasArgsObj()) { flags_ |= BaselineFrame::HAS_ARGS_OBJ; argsObj_ = &fp->argsObj(); } if (fp->hasHookData()) { flags_ |= BaselineFrame::HAS_HOOK_DATA; hookData_ = fp->hookData(); } if (fp->hasReturnValue()) setReturnValue(fp->returnValue()); if (fp->hasPushedSPSFrame()) flags_ |= BaselineFrame::HAS_PUSHED_SPS_FRAME; frameSize_ = BaselineFrame::FramePointerOffset + BaselineFrame::Size() + numStackValues * sizeof(Value); JS_ASSERT(numValueSlots() == numStackValues); for (uint32_t i = 0; i < numStackValues; i++) *valueSlot(i) = fp->slots()[i]; JSContext *cx = GetJSContextFromJitCode(); if (cx->compartment()->debugMode()) { // In debug mode, update any Debugger.Frame objects for the // InterpreterFrame to point to the BaselineFrame. // The caller pushed a fake return address. ScriptFrameIter, used by the // debugger, wants a valid return address, but it's okay to just pick one. // In debug mode there's always at least 1 ICEntry (since there are always // debug prologue/epilogue calls). IonFrameIterator iter(cx); JS_ASSERT(iter.returnAddress() == nullptr); BaselineScript *baseline = fp->script()->baselineScript(); iter.current()->setReturnAddress(baseline->returnAddressForIC(baseline->icEntry(0))); if (!Debugger::handleBaselineOsr(cx, fp, this)) return false; } return true; }
bool BaselineFrame::initForOsr(InterpreterFrame* fp, uint32_t numStackValues) { mozilla::PodZero(this); envChain_ = fp->environmentChain(); if (fp->hasInitialEnvironmentUnchecked()) flags_ |= BaselineFrame::HAS_INITIAL_ENV; if (fp->script()->needsArgsObj() && fp->hasArgsObj()) { flags_ |= BaselineFrame::HAS_ARGS_OBJ; argsObj_ = &fp->argsObj(); } if (fp->hasReturnValue()) setReturnValue(fp->returnValue()); frameSize_ = BaselineFrame::FramePointerOffset + BaselineFrame::Size() + numStackValues * sizeof(Value); MOZ_ASSERT(numValueSlots() == numStackValues); for (uint32_t i = 0; i < numStackValues; i++) *valueSlot(i) = fp->slots()[i]; if (fp->isDebuggee()) { JSContext* cx = GetJSContextFromMainThread(); // For debuggee frames, update any Debugger.Frame objects for the // InterpreterFrame to point to the BaselineFrame. // The caller pushed a fake return address. ScriptFrameIter, used by the // debugger, wants a valid return address, but it's okay to just pick one. // In debug mode there's always at least 1 ICEntry (since there are always // debug prologue/epilogue calls). JitFrameIterator iter(cx); MOZ_ASSERT(iter.returnAddress() == nullptr); BaselineScript* baseline = fp->script()->baselineScript(); iter.current()->setReturnAddress(baseline->returnAddressForIC(baseline->icEntry(0))); if (!Debugger::handleBaselineOsr(cx, fp, this)) return false; setIsDebuggee(); } return true; }
bool BaselineFrame::initForOsr(InterpreterFrame *fp, uint32_t numStackValues) { mozilla::PodZero(this); scopeChain_ = fp->scopeChain(); if (fp->hasCallObjUnchecked()) flags_ |= BaselineFrame::HAS_CALL_OBJ; if (fp->isEvalFrame()) { flags_ |= BaselineFrame::EVAL; evalScript_ = fp->script(); } if (fp->script()->needsArgsObj() && fp->hasArgsObj()) { flags_ |= BaselineFrame::HAS_ARGS_OBJ; argsObj_ = &fp->argsObj(); } if (fp->hasReturnValue()) setReturnValue(fp->returnValue()); // If the interpreter pushed an SPS frame when it entered the function, the // interpreter will pop it after the OSR trampoline returns. In order for // the Baseline frame to have its SPS flag set, it must have its own SPS // frame, which the Baseline code will pop on return. Note that the // profiler may have been enabled or disabled after the function was entered // but before OSR. JSContext *cx = GetJSContextFromJitCode(); SPSProfiler *p = &(cx->runtime()->spsProfiler); if (p->enabled()) { p->enter(fp->script(), fp->maybeFun()); flags_ |= BaselineFrame::HAS_PUSHED_SPS_FRAME; } frameSize_ = BaselineFrame::FramePointerOffset + BaselineFrame::Size() + numStackValues * sizeof(Value); MOZ_ASSERT(numValueSlots() == numStackValues); for (uint32_t i = 0; i < numStackValues; i++) *valueSlot(i) = fp->slots()[i]; if (cx->compartment()->debugMode()) { // In debug mode, update any Debugger.Frame objects for the // InterpreterFrame to point to the BaselineFrame. // The caller pushed a fake return address. ScriptFrameIter, used by the // debugger, wants a valid return address, but it's okay to just pick one. // In debug mode there's always at least 1 ICEntry (since there are always // debug prologue/epilogue calls). JitFrameIterator iter(cx); MOZ_ASSERT(iter.returnAddress() == nullptr); BaselineScript *baseline = fp->script()->baselineScript(); iter.current()->setReturnAddress(baseline->returnAddressForIC(baseline->icEntry(0))); if (!Debugger::handleBaselineOsr(cx, fp, this)) return false; } return true; }