diff --git a/js/src/jit/Bailouts.cpp b/js/src/jit/Bailouts.cpp index 23675a89d79..2daf8612e42 100644 --- a/js/src/jit/Bailouts.cpp +++ b/js/src/jit/Bailouts.cpp @@ -50,31 +50,17 @@ jit::Bailout(BailoutStack *sp, BaselineBailoutInfo **bailoutInfo) MOZ_ASSERT(IsBaselineEnabled(cx)); *bailoutInfo = nullptr; - bool poppedLastSPSFrame = false; uint32_t retval = BailoutIonToBaseline(cx, bailoutData.activation(), iter, false, bailoutInfo, - /* excInfo = */ nullptr, &poppedLastSPSFrame); + /* excInfo = */ nullptr); MOZ_ASSERT(retval == BAILOUT_RETURN_OK || retval == BAILOUT_RETURN_FATAL_ERROR || retval == BAILOUT_RETURN_OVERRECURSED); MOZ_ASSERT_IF(retval == BAILOUT_RETURN_OK, *bailoutInfo != nullptr); if (retval != BAILOUT_RETURN_OK) { - // If the bailout failed, then bailout trampoline will pop the - // current frame and jump straight to exception handling code when - // this function returns. Any SPS entry pushed for this frame will - // be silently forgotten. - // - // We call ExitScript here to ensure that if the ionScript had SPS - // instrumentation, then the SPS entry for it is popped. - // - // However, if the bailout was during argument check, then a - // pseudostack frame would not have been pushed in the first - // place, so don't pop anything in that case. - bool popSPSFrame = iter.ionScript()->hasSPSInstrumentation() && - (SnapshotIterator(iter).bailoutKind() != Bailout_ArgumentCheck) && - !poppedLastSPSFrame; JSScript *script = iter.script(); - probes::ExitScript(cx, script, script->functionNonDelazifying(), popSPSFrame); + probes::ExitScript(cx, script, script->functionNonDelazifying(), + /* popSPSFrame = */ false); EnsureExitFrame(iter.jsFrame()); } @@ -140,9 +126,8 @@ jit::InvalidationBailout(InvalidationBailoutStack *sp, size_t *frameSizeOut, MOZ_ASSERT(IsBaselineEnabled(cx)); *bailoutInfo = nullptr; - bool poppedLastSPSFrame = false; uint32_t retval = BailoutIonToBaseline(cx, bailoutData.activation(), iter, true, bailoutInfo, - /* excInfo = */ nullptr, &poppedLastSPSFrame); + /* excInfo = */ nullptr); MOZ_ASSERT(retval == BAILOUT_RETURN_OK || retval == BAILOUT_RETURN_FATAL_ERROR || retval == BAILOUT_RETURN_OVERRECURSED); @@ -160,11 +145,9 @@ jit::InvalidationBailout(InvalidationBailoutStack *sp, size_t *frameSizeOut, // However, if the bailout was during argument check, then a // pseudostack frame would not have been pushed in the first // place, so don't pop anything in that case. - bool popSPSFrame = iter.ionScript()->hasSPSInstrumentation() && - (SnapshotIterator(iter).bailoutKind() != Bailout_ArgumentCheck) && - !poppedLastSPSFrame; JSScript *script = iter.script(); - probes::ExitScript(cx, script, script->functionNonDelazifying(), popSPSFrame); + probes::ExitScript(cx, script, script->functionNonDelazifying(), + /* popSPSFrame = */ false); JitFrameLayout *frame = iter.jsFrame(); JitSpew(JitSpew_IonInvalidate, "Bailout failed (%s): converting to exit frame", @@ -207,7 +190,7 @@ uint32_t jit::ExceptionHandlerBailout(JSContext *cx, const InlineFrameIterator &frame, ResumeFromException *rfe, const ExceptionBailoutInfo &excInfo, - bool *overrecursed, bool *poppedLastSPSFrameOut) + bool *overrecursed) { // We can be propagating debug mode exceptions without there being an // actual exception pending. For instance, when we return false from an @@ -224,7 +207,7 @@ jit::ExceptionHandlerBailout(JSContext *cx, const InlineFrameIterator &frame, BaselineBailoutInfo *bailoutInfo = nullptr; uint32_t retval = BailoutIonToBaseline(cx, bailoutData.activation(), iter, true, - &bailoutInfo, &excInfo, poppedLastSPSFrameOut); + &bailoutInfo, &excInfo); if (retval == BAILOUT_RETURN_OK) { MOZ_ASSERT(bailoutInfo); diff --git a/js/src/jit/Bailouts.h b/js/src/jit/Bailouts.h index c07f092b44f..aaf6cc5e8e6 100644 --- a/js/src/jit/Bailouts.h +++ b/js/src/jit/Bailouts.h @@ -209,7 +209,7 @@ class ExceptionBailoutInfo uint32_t ExceptionHandlerBailout(JSContext *cx, const InlineFrameIterator &frame, ResumeFromException *rfe, const ExceptionBailoutInfo &excInfo, - bool *overrecursed, bool *poppedLastSPSFrameOut); + bool *overrecursed); uint32_t FinishBailoutToBaseline(BaselineBailoutInfo *bailoutInfo); diff --git a/js/src/jit/BaselineBailouts.cpp b/js/src/jit/BaselineBailouts.cpp index 8609a3a56a0..f5b29abd9e8 100644 --- a/js/src/jit/BaselineBailouts.cpp +++ b/js/src/jit/BaselineBailouts.cpp @@ -551,16 +551,13 @@ InitFromBailout(JSContext *cx, HandleScript caller, jsbytecode *callerPC, HandleFunction fun, HandleScript script, IonScript *ionScript, SnapshotIterator &iter, bool invalidate, BaselineStackBuilder &builder, AutoValueVector &startFrameFormals, MutableHandleFunction nextCallee, - jsbytecode **callPC, const ExceptionBailoutInfo *excInfo, - bool *poppedLastSPSFrameOut) + jsbytecode **callPC, const ExceptionBailoutInfo *excInfo) { // The Baseline frames we will reconstruct on the heap are not rooted, so GC // must be suppressed here. MOZ_ASSERT(cx->mainThread().suppressGC); MOZ_ASSERT(script->hasBaselineScript()); - MOZ_ASSERT(poppedLastSPSFrameOut); - MOZ_ASSERT(!*poppedLastSPSFrameOut); // Are we catching an exception? bool catchingException = excInfo && excInfo->catchingException(); @@ -626,16 +623,6 @@ InitFromBailout(JSContext *cx, HandleScript caller, jsbytecode *callerPC, uint32_t flags = 0; - // If SPS Profiler is enabled, mark the frame as having pushed an SPS entry. - // This may be wrong for the last frame of ArgumentCheck bailout, but - // that will be fixed later. - if (ionScript->hasSPSInstrumentation()) { - if (callerPC == nullptr) { - JitSpew(JitSpew_BaselineBailouts, " Setting SPS flag on top frame!"); - flags |= BaselineFrame::HAS_PUSHED_SPS_FRAME; - } - } - // 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 // don't rematerialize the Ion frame via the Debugger. @@ -1098,35 +1085,6 @@ InitFromBailout(JSContext *cx, HandleScript caller, jsbytecode *callerPC, opReturnAddr = baselineScript->prologueEntryAddr(); JitSpew(JitSpew_BaselineBailouts, " Resuming into prologue."); - // If bailing into prologue, HAS_PUSHED_SPS_FRAME should not be set on frame. - blFrame->unsetPushedSPSFrame(); - - if (cx->runtime()->spsProfiler.enabled()) { - // 1. If resuming into inline code, then the top SPS entry will be - // for the outermost caller, and will have an uninitialized PC. - // This will be fixed up later in BailoutIonToBaseline. - // - // 2. If resuming into top-level code prologue, with ArgumentCheck, - // no SPS entry will have been pushed. Can be left alone. - // - // 3. If resuming into top-level code prologue, without ArgumentCheck, - // an SPS entry will have been pushed, and needs to be popped. - // - // 4. If resuming into top-level code main body, an SPS entry will - // have been pushed, and can be left alone. - // - // Only need to handle case 3 here. - if (!caller && bailoutKind != Bailout_ArgumentCheck) { - JitSpew(JitSpew_BaselineBailouts, - " Popping SPS entry for outermost frame"); - cx->runtime()->spsProfiler.exit(script, fun); - - // Notify caller that the last SPS frame was popped, so not - // to do it again. - if (poppedLastSPSFrameOut) - *poppedLastSPSFrameOut = true; - } - } } else { opReturnAddr = nativeCodeForPC; } @@ -1135,16 +1093,6 @@ InitFromBailout(JSContext *cx, HandleScript caller, jsbytecode *callerPC, } if (cx->runtime()->spsProfiler.enabled()) { - if (blFrame->hasPushedSPSFrame()) { - // Set PC index to 0 for the innermost frame to match what the - // interpreter and Baseline do: they update the SPS pc for - // JSOP_CALL ops but set it to 0 when running other ops. Ion code - // can set the pc to NullPCIndex and this will confuse SPS when - // Baseline calls into the VM at non-CALL ops and re-enters JS. - JitSpew(JitSpew_BaselineBailouts, " Setting PCidx for last frame to 0"); - cx->runtime()->spsProfiler.updatePC(script, script->code()); - } - // Register bailout with profiler. const char *filename = script->filename(); if (filename == nullptr) @@ -1381,14 +1329,11 @@ InitFromBailout(JSContext *cx, HandleScript caller, jsbytecode *callerPC, uint32_t jit::BailoutIonToBaseline(JSContext *cx, JitActivation *activation, JitFrameIterator &iter, bool invalidate, BaselineBailoutInfo **bailoutInfo, - const ExceptionBailoutInfo *excInfo, bool *poppedLastSPSFrameOut) + const ExceptionBailoutInfo *excInfo) { MOZ_ASSERT(bailoutInfo != nullptr); MOZ_ASSERT(*bailoutInfo == nullptr); - MOZ_ASSERT(poppedLastSPSFrameOut); - MOZ_ASSERT(!*poppedLastSPSFrameOut); - TraceLoggerThread *logger = TraceLoggerForMainThread(cx->runtime()); TraceLogStopEvent(logger, TraceLogger_IonMonkey); TraceLogStartEvent(logger, TraceLogger_Baseline); @@ -1492,9 +1437,6 @@ jit::BailoutIonToBaseline(JSContext *cx, JitActivation *activation, JitFrameIter RootedFunction fun(cx, callee); AutoValueVector startFrameFormals(cx); - RootedScript topCaller(cx); - jsbytecode *topCallerPC = nullptr; - gc::AutoSuppressGC suppress(cx); while (true) { @@ -1524,8 +1466,7 @@ jit::BailoutIonToBaseline(JSContext *cx, JitActivation *activation, JitFrameIter RootedFunction nextCallee(cx, nullptr); if (!InitFromBailout(cx, caller, callerPC, fun, scr, iter.ionScript(), snapIter, invalidate, builder, startFrameFormals, - &nextCallee, &callPC, passExcInfo ? excInfo : nullptr, - poppedLastSPSFrameOut)) + &nextCallee, &callPC, passExcInfo ? excInfo : nullptr)) { return BAILOUT_RETURN_FATAL_ERROR; } @@ -1545,24 +1486,12 @@ jit::BailoutIonToBaseline(JSContext *cx, JitActivation *activation, JitFrameIter fun = nextCallee; scr = fun->existingScriptForInlinedFunction(); - // Save top caller info for adjusting SPS frames later. - if (!topCaller) { - MOZ_ASSERT(frameNo == 0); - topCaller = caller; - topCallerPC = callerPC; - } - frameNo++; snapIter.nextInstruction(); } JitSpew(JitSpew_BaselineBailouts, " Done restoring frames"); - // If there were multiple inline frames unpacked, then the current top SPS frame - // is for the outermost caller, and has an uninitialized PC. Initialize it now. - if (frameNo > 0) - cx->runtime()->spsProfiler.updatePC(topCaller, topCallerPC); - BailoutKind bailoutKind = snapIter.bailoutKind(); if (!startFrameFormals.empty()) { diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index f88f1a0a742..154b871239e 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -175,7 +175,6 @@ BaselineCompiler::compile() prologueOffset_.fixup(&masm); epilogueOffset_.fixup(&masm); - spsPushToggleOffset_.fixup(&masm); profilerEnterFrameToggleOffset_.fixup(&masm); profilerExitFrameToggleOffset_.fixup(&masm); #ifdef JS_TRACE_LOGGING @@ -190,7 +189,6 @@ BaselineCompiler::compile() mozilla::UniquePtr > baselineScript( BaselineScript::New(script, prologueOffset_.offset(), epilogueOffset_.offset(), - spsPushToggleOffset_.offset(), profilerEnterFrameToggleOffset_.offset(), profilerExitFrameToggleOffset_.offset(), traceLoggerEnterToggleOffset_.offset(), @@ -246,10 +244,6 @@ BaselineCompiler::compile() if (cx->zone()->needsIncrementalBarrier()) baselineScript->toggleBarriers(true); - // All SPS instrumentation is emitted toggled off. Toggle them on if needed. - if (cx->runtime()->spsProfiler.enabled()) - baselineScript->toggleSPS(true); - #ifdef JS_TRACE_LOGGING // Initialize the tracelogger instrumentation. baselineScript->initTraceLogger(cx->runtime(), script); @@ -422,9 +416,6 @@ BaselineCompiler::emitPrologue() if (!emitArgumentTypeChecks()) return false; - if (!emitSPSPush()) - return false; - return true; } @@ -442,9 +433,6 @@ BaselineCompiler::emitEpilogue() return false; #endif - // Pop SPS frame if necessary - emitSPSPop(); - masm.mov(BaselineFrameReg, BaselineStackReg); masm.pop(BaselineFrameReg); @@ -839,35 +827,6 @@ BaselineCompiler::emitTraceLoggerExit() } #endif -bool -BaselineCompiler::emitSPSPush() -{ - // Enter the IC, guarded by a toggled jump (initially disabled). - Label noPush; - CodeOffsetLabel toggleOffset = masm.toggledJump(&noPush); - MOZ_ASSERT(frame.numUnsyncedSlots() == 0); - ICProfiler_Fallback::Compiler compiler(cx); - if (!emitNonOpIC(compiler.getStub(&stubSpace_))) - return false; - masm.bind(&noPush); - - // Store the start offset in the appropriate location. - MOZ_ASSERT(spsPushToggleOffset_.offset() == 0); - spsPushToggleOffset_ = toggleOffset; - return true; -} - -void -BaselineCompiler::emitSPSPop() -{ - // If profiler entry was pushed on this frame, pop it. - Label noPop; - masm.branchTest32(Assembler::Zero, frame.addressOfFlags(), - Imm32(BaselineFrame::HAS_PUSHED_SPS_FRAME), &noPop); - masm.spsPopFrameSafe(&cx->runtime()->spsProfiler, R1.scratchReg()); - masm.bind(&noPop); -} - void BaselineCompiler::emitProfilerEnterFrame() { diff --git a/js/src/jit/BaselineCompiler.h b/js/src/jit/BaselineCompiler.h index 75bdfa66e0b..50d6c4dfe76 100644 --- a/js/src/jit/BaselineCompiler.h +++ b/js/src/jit/BaselineCompiler.h @@ -256,8 +256,6 @@ class BaselineCompiler : public BaselineCompilerSpecific bool emitDebugTrap(); bool emitTraceLoggerEnter(); bool emitTraceLoggerExit(); - bool emitSPSPush(); - void emitSPSPop(); void emitProfilerEnterFrame(); void emitProfilerExitFrame(); diff --git a/js/src/jit/BaselineFrame.cpp b/js/src/jit/BaselineFrame.cpp index eeedb40933f..29f7367b4d7 100644 --- a/js/src/jit/BaselineFrame.cpp +++ b/js/src/jit/BaselineFrame.cpp @@ -172,19 +172,6 @@ BaselineFrame::initForOsr(InterpreterFrame *fp, uint32_t numStackValues) 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); @@ -195,6 +182,8 @@ BaselineFrame::initForOsr(InterpreterFrame *fp, uint32_t numStackValues) *valueSlot(i) = fp->slots()[i]; if (fp->isDebuggee()) { + JSContext *cx = GetJSContextFromJitCode(); + // For debuggee frames, update any Debugger.Frame objects for the // InterpreterFrame to point to the BaselineFrame. diff --git a/js/src/jit/BaselineFrame.h b/js/src/jit/BaselineFrame.h index 4bb3e0b0dc9..30a42f4719f 100644 --- a/js/src/jit/BaselineFrame.h +++ b/js/src/jit/BaselineFrame.h @@ -56,9 +56,6 @@ class BaselineFrame // Eval frame, see the "eval frames" comment. EVAL = 1 << 7, - // Frame has profiler entry pushed. - HAS_PUSHED_SPS_FRAME = 1 << 8, - // Frame has over-recursed on an early check. OVER_RECURSED = 1 << 9, @@ -308,18 +305,6 @@ class BaselineFrame return evalScript_; } - bool hasPushedSPSFrame() const { - return flags_ & HAS_PUSHED_SPS_FRAME; - } - - void setPushedSPSFrame() { - flags_ |= HAS_PUSHED_SPS_FRAME; - } - - void unsetPushedSPSFrame() { - flags_ &= ~HAS_PUSHED_SPS_FRAME; - } - bool overRecursed() const { return flags_ & OVER_RECURSED; } diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 1fba957d3da..ed463635863 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -297,11 +297,6 @@ ICStub::trace(JSTracer *trc) MarkTypeObject(trc, &updateStub->type(), "baseline-update-typeobject"); break; } - case ICStub::Profiler_PushFunction: { - ICProfiler_PushFunction *pushFunStub = toProfiler_PushFunction(); - MarkScript(trc, &pushFunStub->script(), "baseline-profilerpushfunction-stub-script"); - break; - } case ICStub::GetName_Global: { ICGetName_Global *globalStub = toGetName_Global(); MarkShape(trc, &globalStub->shape(), "baseline-global-stub-shape"); @@ -723,66 +718,6 @@ ICStubCompiler::leaveStubFrame(MacroAssembler &masm, bool calledIntoIon) EmitLeaveStubFrame(masm, calledIntoIon); } -void -ICStubCompiler::guardProfilingEnabled(MacroAssembler &masm, Register scratch, Label *skip) -{ - // This should only be called from the following stubs. - MOZ_ASSERT(kind == ICStub::Call_Scripted || - kind == ICStub::Call_AnyScripted || - kind == ICStub::Call_Native || - kind == ICStub::Call_ClassHook || - kind == ICStub::Call_ScriptedApplyArray || - kind == ICStub::Call_ScriptedApplyArguments || - kind == ICStub::Call_ScriptedFunCall || - kind == ICStub::GetProp_CallScripted || - kind == ICStub::GetProp_CallNative || - kind == ICStub::GetProp_CallNativePrototype || - kind == ICStub::GetProp_CallDOMProxyNative || - kind == ICStub::GetElem_NativePrototypeCallNative || - kind == ICStub::GetElem_NativePrototypeCallScripted || - kind == ICStub::GetProp_CallDOMProxyWithGenerationNative || - kind == ICStub::GetProp_DOMProxyShadowed || - kind == ICStub::SetProp_CallScripted || - kind == ICStub::SetProp_CallNative); - - // Guard on bit in frame that indicates if the SPS frame was pushed in the first - // place. This code is expected to be called from within a stub that has already - // entered a stub frame. - MOZ_ASSERT(entersStubFrame_); - masm.loadPtr(Address(BaselineFrameReg, 0), scratch); - masm.branchTest32(Assembler::Zero, - Address(scratch, BaselineFrame::reverseOffsetOfFlags()), - Imm32(BaselineFrame::HAS_PUSHED_SPS_FRAME), - skip); - - // Check if profiling is enabled - uint32_t *enabledAddr = cx->runtime()->spsProfiler.addressOfEnabled(); - masm.branch32(Assembler::Equal, AbsoluteAddress(enabledAddr), Imm32(0), skip); -} - -void -ICStubCompiler::emitProfilingUpdate(MacroAssembler &masm, Register pcIdx, Register scratch, - uint32_t stubPcOffset) -{ - Label skipProfilerUpdate; - - // Check if profiling is enabled. - guardProfilingEnabled(masm, scratch, &skipProfilerUpdate); - - // Update profiling entry before leaving function. - masm.load32(Address(BaselineStubReg, stubPcOffset), pcIdx); - masm.spsUpdatePCIdx(&cx->runtime()->spsProfiler, pcIdx, scratch); - - masm.bind(&skipProfilerUpdate); -} - -void -ICStubCompiler::emitProfilingUpdate(MacroAssembler &masm, GeneralRegisterSet regs, - uint32_t stubPcOffset) -{ - emitProfilingUpdate(masm, regs.takeAny(), regs.takeAny(), stubPcOffset); -} - inline bool ICStubCompiler::emitPostWriteBarrierSlot(MacroAssembler &masm, Register obj, ValueOperand val, Register scratch, GeneralRegisterSet saveRegs) @@ -863,16 +798,9 @@ EnsureCanEnterIon(JSContext *cx, ICWarmUpCounter_Fallback *stub, BaselineFrame * if (isLoopEntry) { IonScript *ion = script->ionScript(); - MOZ_ASSERT(cx->runtime()->spsProfiler.enabled() == ion->hasSPSInstrumentation()); + MOZ_ASSERT(cx->runtime()->spsProfiler.enabled() == ion->hasProfilingInstrumentation()); MOZ_ASSERT(ion->osrPc() == pc); - // If the baseline frame's SPS handling doesn't match up with the Ion code's SPS - // handling, don't OSR. - if (frame->hasPushedSPSFrame() != ion->hasSPSInstrumentation()) { - JitSpew(JitSpew_BaselineOSR, " OSR crosses SPS handling boundaries, skipping!"); - return true; - } - JitSpew(JitSpew_BaselineOSR, " OSR possible!"); *jitcodePtr = ion->method()->raw() + ion->osrEntryOffset(); } @@ -1104,99 +1032,6 @@ ICWarmUpCounter_Fallback::Compiler::generateStubCode(MacroAssembler &masm) return true; } -// -// ICProfile_Fallback -// - -static bool -DoProfilerFallback(JSContext *cx, BaselineFrame *frame, ICProfiler_Fallback *stub) -{ - RootedScript script(cx, frame->script()); - RootedFunction func(cx, frame->maybeFun()); - mozilla::DebugOnly icEntry = stub->icEntry(); - - FallbackICSpew(cx, stub, "Profiler"); - - SPSProfiler *profiler = &cx->runtime()->spsProfiler; - - // Manually enter SPS this time. - MOZ_ASSERT(profiler->enabled()); - if (!cx->runtime()->spsProfiler.enter(script, func)) - return false; - frame->setPushedSPSFrame(); - - // Unlink any existing PushFunction stub (which may hold stale 'const char *' to - // the profile string. - MOZ_ASSERT_IF(icEntry->firstStub() != stub, - icEntry->firstStub()->isProfiler_PushFunction() && - icEntry->firstStub()->next() == stub); - stub->unlinkStubsWithKind(cx, ICStub::Profiler_PushFunction); - MOZ_ASSERT(icEntry->firstStub() == stub); - - // Generate the string to use to identify this stack frame. - const char *string = profiler->profileString(script, func); - if (string == nullptr) - return false; - - JitSpew(JitSpew_BaselineIC, " Generating Profiler_PushFunction stub for %s:%d", - script->filename(), script->lineno()); - - // Create a new optimized stub. - ICProfiler_PushFunction::Compiler compiler(cx, string, script); - ICStub *optStub = compiler.getStub(compiler.getStubSpace(script)); - if (!optStub) - return false; - stub->addNewStub(optStub); - - return true; -} - -typedef bool (*DoProfilerFallbackFn)(JSContext *, BaselineFrame *frame, ICProfiler_Fallback *); -static const VMFunction DoProfilerFallbackInfo = - FunctionInfo(DoProfilerFallback, TailCall); - -bool -ICProfiler_Fallback::Compiler::generateStubCode(MacroAssembler &masm) -{ - EmitRestoreTailCallReg(masm); - - masm.push(BaselineStubReg); // Push stub. - masm.pushBaselineFramePtr(BaselineFrameReg, R0.scratchReg()); // Push frame. - - return tailCallVM(DoProfilerFallbackInfo, masm); -} - -bool -ICProfiler_PushFunction::Compiler::generateStubCode(MacroAssembler &masm) -{ - - Register scratch = R0.scratchReg(); - Register scratch2 = R1.scratchReg(); - - // Profiling should be enabled if we ever reach here. -#ifdef DEBUG - Label spsEnabled; - uint32_t *enabledAddr = cx->runtime()->spsProfiler.addressOfEnabled(); - masm.branch32(Assembler::NotEqual, AbsoluteAddress(enabledAddr), Imm32(0), &spsEnabled); - masm.assumeUnreachable("Profiling should have been enabled."); - masm.bind(&spsEnabled); -#endif - - // Push SPS entry. - masm.spsPushFrame(&cx->runtime()->spsProfiler, - Address(BaselineStubReg, ICProfiler_PushFunction::offsetOfStr()), - Address(BaselineStubReg, ICProfiler_PushFunction::offsetOfScript()), - scratch, - scratch2); - - // Mark frame as having profiler entry pushed. - Address flagsOffset(BaselineFrameReg, BaselineFrame::reverseOffsetOfFlags()); - masm.or32(Imm32(BaselineFrame::HAS_PUSHED_SPS_FRAME), flagsOffset); - - EmitReturnFromIC(masm); - - return true; -} // // TypeMonitor_Fallback @@ -4229,9 +4064,6 @@ ICGetElemNativeCompiler::emitCallNative(MacroAssembler &masm, Register objReg) regs.add(objReg); - // Profiler hook. - emitProfilingUpdate(masm, regs, ICGetElemNativeGetterStub::offsetOfPCOffset()); - // Call helper. if (!callVM(DoCallNativeGetterInfo, masm)) return false; @@ -4297,16 +4129,6 @@ ICGetElemNativeCompiler::emitCallScripted(MacroAssembler &masm, Register objReg) } masm.bind(&noUnderflow); - - // If needed, update SPS Profiler frame entry. At this point, callee and scratch can - // be clobbered. - { - GeneralRegisterSet availRegs = availableGeneralRegs(0); - availRegs.take(ArgumentsRectifierReg); - availRegs.take(code); - emitProfilingUpdate(masm, availRegs, ICGetElemNativeGetterStub::offsetOfPCOffset()); - } - masm.callJit(code); leaveStubFrame(masm, true); @@ -7463,16 +7285,6 @@ ICGetProp_CallScripted::Compiler::generateStubCode(MacroAssembler &masm) } masm.bind(&noUnderflow); - - // If needed, update SPS Profiler frame entry. At this point, callee and scratch can - // be clobbered. - { - GeneralRegisterSet availRegs = availableGeneralRegs(0); - availRegs.take(ArgumentsRectifierReg); - availRegs.take(code); - emitProfilingUpdate(masm, availRegs, ICGetProp_CallScripted::offsetOfPCOffset()); - } - masm.callJit(code); leaveStubFrame(masm, true); @@ -7534,9 +7346,6 @@ ICGetProp_CallNative::Compiler::generateStubCode(MacroAssembler &masm) if (!inputDefinitelyObject_) regs.add(R0); - // If needed, update SPS Profiler frame entry. - emitProfilingUpdate(masm, regs, ICGetProp_CallNative::offsetOfPCOffset()); - if (!callVM(DoCallNativeGetterInfo, masm)) return false; leaveStubFrame(masm); @@ -7606,9 +7415,6 @@ ICGetProp_CallNativePrototype::Compiler::generateStubCode(MacroAssembler &masm) else regs.add(objReg); - // If needed, update SPS Profiler frame entry. - emitProfilingUpdate(masm, regs, ICGetProp_CallNativePrototype::offsetOfPCOffset()); - if (!callVM(DoCallNativeGetterInfo, masm)) return false; leaveStubFrame(masm); @@ -7679,9 +7485,6 @@ ICGetPropCallDOMProxyNativeCompiler::generateStubCode(MacroAssembler &masm, // Don't have to preserve R0 anymore. regs.add(R0); - // If needed, update SPS Profiler frame entry. - emitProfilingUpdate(masm, regs, ICGetProp_CallDOMProxyNative::offsetOfPCOffset()); - if (!callVM(DoCallNativeGetterInfo, masm)) return false; leaveStubFrame(masm); @@ -7814,9 +7617,6 @@ ICGetProp_DOMProxyShadowed::Compiler::generateStubCode(MacroAssembler &masm) // Don't have to preserve R0 anymore. regs.add(R0); - // If needed, update SPS Profiler frame entry. - emitProfilingUpdate(masm, regs, ICGetProp_DOMProxyShadowed::offsetOfPCOffset()); - if (!callVM(ProxyGetInfo, masm)) return false; leaveStubFrame(masm); @@ -8840,16 +8640,6 @@ ICSetProp_CallScripted::Compiler::generateStubCode(MacroAssembler &masm) } masm.bind(&noUnderflow); - - // If needed, update SPS Profiler frame entry. At this point, callee and scratch can - // be clobbered. - { - GeneralRegisterSet availRegs = availableGeneralRegs(0); - availRegs.take(ArgumentsRectifierReg); - availRegs.take(code); - emitProfilingUpdate(masm, availRegs, ICSetProp_CallScripted::offsetOfPCOffset()); - } - masm.callJit(code); leaveStubFrame(masm, true); @@ -8935,9 +8725,6 @@ ICSetProp_CallNative::Compiler::generateStubCode(MacroAssembler &masm) // Don't need to preserve R0 anymore. regs.add(R0); - // If needed, update SPS Profiler frame entry. - emitProfilingUpdate(masm, regs, ICSetProp_CallNative::offsetOfPCOffset()); - if (!callVM(DoCallNativeSetterInfo, masm)) return false; leaveStubFrame(masm); @@ -9486,10 +9273,6 @@ DoCallFallback(JSContext *cx, BaselineFrame *frame, ICCall_Fallback *stub_, uint if (!TryAttachCallStub(cx, stub, script, pc, op, argc, vp, constructing, false, newType)) return false; - // Maybe update PC in profiler entry before leaving this script by call. - if (cx->runtime()->spsProfiler.enabled() && frame->hasPushedSPSFrame()) - cx->runtime()->spsProfiler.updatePC(script, pc); - if (!MaybeCloneFunctionAtCallsite(cx, &callee, script, pc)) return false; @@ -9562,10 +9345,6 @@ DoSpreadCallFallback(JSContext *cx, BaselineFrame *frame, ICCall_Fallback *stub_ return false; } - // Maybe update PC in profiler entry before leaving this script by call. - if (cx->runtime()->spsProfiler.enabled() && frame->hasPushedSPSFrame()) - cx->runtime()->spsProfiler.updatePC(script, pc); - if (!MaybeCloneFunctionAtCallsite(cx, &callee, script, pc)) return false; @@ -10145,18 +9924,6 @@ ICCallScriptedCompiler::generateStubCode(MacroAssembler &masm) } masm.bind(&noUnderflow); - - // If needed, update SPS Profiler frame entry before and after call. - { - MOZ_ASSERT(kind == ICStub::Call_Scripted || kind == ICStub::Call_AnyScripted); - GeneralRegisterSet availRegs = availableGeneralRegs(0); - availRegs.take(ArgumentsRectifierReg); - availRegs.take(code); - emitProfilingUpdate(masm, availRegs, kind == ICStub::Call_Scripted ? - ICCall_Scripted::offsetOfPCOffset() - : ICCall_AnyScripted::offsetOfPCOffset()); - } - masm.callJit(code); // If this is a constructing call, and the callee returns a non-object, replace it with @@ -10417,10 +10184,6 @@ ICCall_Native::Compiler::generateStubCode(MacroAssembler &masm) masm.push(BaselineTailCallReg); masm.enterFakeExitFrame(NativeExitFrameLayout::Token()); - // If needed, update SPS Profiler frame entry. At this point, BaselineTailCallReg - // and scratch can be clobbered. - emitProfilingUpdate(masm, BaselineTailCallReg, scratch, ICCall_Native::offsetOfPCOffset()); - // Execute call. masm.setupUnalignedABICall(3, scratch); masm.loadJSContext(scratch); @@ -10516,10 +10279,6 @@ ICCall_ClassHook::Compiler::generateStubCode(MacroAssembler &masm) masm.push(BaselineTailCallReg); masm.enterFakeExitFrame(NativeExitFrameLayout::Token()); - // If needed, update SPS Profiler frame entry. At this point, BaselineTailCallReg - // and scratch can be clobbered. - emitProfilingUpdate(masm, BaselineTailCallReg, scratch, ICCall_ClassHook::offsetOfPCOffset()); - // Execute call. masm.setupUnalignedABICall(3, scratch); masm.loadJSContext(scratch); @@ -10634,11 +10393,6 @@ ICCall_ScriptedApplyArray::Compiler::generateStubCode(MacroAssembler &masm) masm.bind(&noUnderflow); regs.add(argcReg); - // If needed, update SPS Profiler frame entry. At this point, BaselineTailCallReg - // and scratch can be clobbered. - emitProfilingUpdate(masm, regs.getAny(), scratch, - ICCall_ScriptedApplyArguments::offsetOfPCOffset()); - // Do call masm.callJit(target); leaveStubFrame(masm, true); @@ -10735,11 +10489,6 @@ ICCall_ScriptedApplyArguments::Compiler::generateStubCode(MacroAssembler &masm) masm.bind(&noUnderflow); regs.add(argcReg); - // If needed, update SPS Profiler frame entry. At this point, BaselineTailCallReg - // and scratch can be clobbered. - emitProfilingUpdate(masm, regs.getAny(), scratch, - ICCall_ScriptedApplyArguments::offsetOfPCOffset()); - // Do call masm.callJit(target); leaveStubFrame(masm, true); @@ -10856,16 +10605,6 @@ ICCall_ScriptedFunCall::Compiler::generateStubCode(MacroAssembler &masm) } masm.bind(&noUnderflow); - - // If needed, update SPS Profiler frame entry. - { - // Need to avoid using ArgumentsRectifierReg and code register. - GeneralRegisterSet availRegs = availableGeneralRegs(0); - availRegs.take(ArgumentsRectifierReg); - availRegs.take(code); - emitProfilingUpdate(masm, availRegs, ICCall_ScriptedFunCall::offsetOfPCOffset()); - } - masm.callJit(code); leaveStubFrame(masm, true); @@ -11518,13 +11257,6 @@ ICRetSub_Resume::Compiler::generateStubCode(MacroAssembler &masm) return true; } -ICProfiler_PushFunction::ICProfiler_PushFunction(JitCode *stubCode, const char *str, - HandleScript script) - : ICStub(ICStub::Profiler_PushFunction, stubCode), - str_(str), - script_(script) -{ } - ICTypeMonitor_SingleObject::ICTypeMonitor_SingleObject(JitCode *stubCode, HandleObject obj) : ICStub(TypeMonitor_SingleObject, stubCode), obj_(obj) diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h index 60de69df253..8da23b04f56 100644 --- a/js/src/jit/BaselineIC.h +++ b/js/src/jit/BaselineIC.h @@ -335,9 +335,6 @@ class ICEntry #define IC_STUB_KIND_LIST(_) \ _(WarmUpCounter_Fallback) \ \ - _(Profiler_Fallback) \ - _(Profiler_PushFunction) \ - \ _(TypeMonitor_Fallback) \ _(TypeMonitor_SingleObject) \ _(TypeMonitor_TypeObject) \ @@ -1122,11 +1119,6 @@ class ICStubCompiler // given label. void guardProfilingEnabled(MacroAssembler &masm, Register scratch, Label *skip); - // Higher-level helper to emit an update to the profiler pseudo-stack. - void emitProfilingUpdate(MacroAssembler &masm, Register pcIdx, Register scratch, - uint32_t stubPcOffset); - void emitProfilingUpdate(MacroAssembler &masm, GeneralRegisterSet regs, uint32_t stubPcOffset); - inline GeneralRegisterSet availableGeneralRegs(size_t numInputs) const { GeneralRegisterSet regs(GeneralRegisterSet::All()); MOZ_ASSERT(!regs.has(BaselineStackReg)); @@ -1229,91 +1221,6 @@ class ICWarmUpCounter_Fallback : public ICFallbackStub }; }; -// Profiler_Fallback - -class ICProfiler_Fallback : public ICFallbackStub -{ - friend class ICStubSpace; - - explicit ICProfiler_Fallback(JitCode *stubCode) - : ICFallbackStub(ICStub::Profiler_Fallback, stubCode) - { } - - public: - static inline ICProfiler_Fallback *New(ICStubSpace *space, JitCode *code) { - if (!code) - return nullptr; - return space->allocate(code); - } - - // Compiler for this stub kind. - class Compiler : public ICStubCompiler { - protected: - bool generateStubCode(MacroAssembler &masm); - - public: - explicit Compiler(JSContext *cx) - : ICStubCompiler(cx, ICStub::Profiler_Fallback) - { } - - ICProfiler_Fallback *getStub(ICStubSpace *space) { - return ICProfiler_Fallback::New(space, getStubCode()); - } - }; -}; - -// Profiler_PushFunction - -class ICProfiler_PushFunction : public ICStub -{ - friend class ICStubSpace; - - protected: - const char *str_; - HeapPtrScript script_; - - ICProfiler_PushFunction(JitCode *stubCode, const char *str, HandleScript script); - - public: - static inline ICProfiler_PushFunction *New(ICStubSpace *space, JitCode *code, - const char *str, HandleScript script) - { - if (!code) - return nullptr; - return space->allocate(code, str, script); - } - - HeapPtrScript &script() { - return script_; - } - - static size_t offsetOfStr() { - return offsetof(ICProfiler_PushFunction, str_); - } - static size_t offsetOfScript() { - return offsetof(ICProfiler_PushFunction, script_); - } - - // Compiler for this stub kind. - class Compiler : public ICStubCompiler { - protected: - const char *str_; - RootedScript script_; - bool generateStubCode(MacroAssembler &masm); - - public: - Compiler(JSContext *cx, const char *str, HandleScript script) - : ICStubCompiler(cx, ICStub::Profiler_PushFunction), - str_(str), - script_(cx, script) - { } - - ICProfiler_PushFunction *getStub(ICStubSpace *space) { - return ICProfiler_PushFunction::New(space, getStubCode(), str_, script_); - } - }; -}; - // TypeCheckPrimitiveSetStub // Base class for IC stubs (TypeUpdate or TypeMonitor) that check that a given diff --git a/js/src/jit/BaselineJIT.cpp b/js/src/jit/BaselineJIT.cpp index 8ed6fc947a0..2765e393827 100644 --- a/js/src/jit/BaselineJIT.cpp +++ b/js/src/jit/BaselineJIT.cpp @@ -42,7 +42,6 @@ PCMappingSlotInfo::ToSlotLocation(const StackValue *stackVal) } BaselineScript::BaselineScript(uint32_t prologueOffset, uint32_t epilogueOffset, - uint32_t spsPushToggleOffset, uint32_t profilerEnterToggleOffset, uint32_t profilerExitToggleOffset, uint32_t traceLoggerEnterToggleOffset, @@ -54,10 +53,6 @@ BaselineScript::BaselineScript(uint32_t prologueOffset, uint32_t epilogueOffset, dependentAsmJSModules_(nullptr), prologueOffset_(prologueOffset), epilogueOffset_(epilogueOffset), -#ifdef DEBUG - spsOn_(false), -#endif - spsPushToggleOffset_(spsPushToggleOffset), profilerEnterToggleOffset_(profilerEnterToggleOffset), profilerExitToggleOffset_(profilerExitToggleOffset), #ifdef JS_TRACE_LOGGING @@ -347,7 +342,6 @@ jit::CanEnterBaselineMethod(JSContext *cx, RunState &state) BaselineScript * BaselineScript::New(JSScript *jsscript, uint32_t prologueOffset, uint32_t epilogueOffset, - uint32_t spsPushToggleOffset, uint32_t profilerEnterToggleOffset, uint32_t profilerExitToggleOffset, uint32_t traceLoggerEnterToggleOffset, uint32_t traceLoggerExitToggleOffset, uint32_t postDebugPrologueOffset, @@ -377,7 +371,6 @@ BaselineScript::New(JSScript *jsscript, uint32_t prologueOffset, uint32_t epilog if (!script) return nullptr; new (script) BaselineScript(prologueOffset, epilogueOffset, - spsPushToggleOffset, profilerEnterToggleOffset, profilerExitToggleOffset, traceLoggerEnterToggleOffset, traceLoggerExitToggleOffset, postDebugPrologueOffset); @@ -856,25 +849,6 @@ BaselineScript::toggleDebugTraps(JSScript *script, jsbytecode *pc) } } -void -BaselineScript::toggleSPS(bool enable) -{ - MOZ_ASSERT(enable == !(bool)spsOn_); - - JitSpew(JitSpew_BaselineIC, " toggling SPS %s for BaselineScript %p", - enable ? "on" : "off", this); - - // Toggle the jump - CodeLocationLabel pushToggleLocation(method_, CodeOffsetLabel(spsPushToggleOffset_)); - if (enable) - Assembler::ToggleToCmp(pushToggleLocation); - else - Assembler::ToggleToJmp(pushToggleLocation); -#ifdef DEBUG - spsOn_ = enable; -#endif -} - #ifdef JS_TRACE_LOGGING void BaselineScript::initTraceLogger(JSRuntime *runtime, JSScript *script) @@ -965,7 +939,7 @@ BaselineScript::toggleProfilerInstrumentation(bool enable) if (enable == isProfilerInstrumentationOn()) return; - JitSpew(JitSpew_BaselineIC, " toggling SPS %s for BaselineScript %p", + JitSpew(JitSpew_BaselineIC, " toggling profiling %s for BaselineScript %p", enable ? "on" : "off", this); // Toggle the jump @@ -1077,14 +1051,13 @@ jit::AddSizeOfBaselineData(JSScript *script, mozilla::MallocSizeOf mallocSizeOf, } void -jit::ToggleBaselineSPS(JSRuntime *runtime, bool enable) +jit::ToggleBaselineProfiling(JSRuntime *runtime, bool enable) { for (ZonesIter zone(runtime, SkipAtoms); !zone.done(); zone.next()) { for (gc::ZoneCellIter i(zone, gc::FINALIZE_SCRIPT); !i.done(); i.next()) { JSScript *script = i.get(); if (!script->hasBaselineScript()) continue; - script->baselineScript()->toggleSPS(enable); script->baselineScript()->toggleProfilerInstrumentation(enable); } } diff --git a/js/src/jit/BaselineJIT.h b/js/src/jit/BaselineJIT.h index 8ffc4be91ea..b0a5218b9ba 100644 --- a/js/src/jit/BaselineJIT.h +++ b/js/src/jit/BaselineJIT.h @@ -139,11 +139,7 @@ struct BaselineScript // returned from. uint32_t epilogueOffset_; - // The offsets for the toggledJump instructions for SPS update ICs. -#ifdef DEBUG - mozilla::DebugOnly spsOn_; -#endif - uint32_t spsPushToggleOffset_; + // The offsets for the toggledJump instructions for profiler instrumentation. uint32_t profilerEnterToggleOffset_; uint32_t profilerExitToggleOffset_; @@ -219,7 +215,6 @@ struct BaselineScript public: // Do not call directly, use BaselineScript::New. This is public for cx->new_. BaselineScript(uint32_t prologueOffset, uint32_t epilogueOffset, - uint32_t spsPushToggleOffset, uint32_t profilerEnterToggleOffset, uint32_t profilerExitToggleOffset, uint32_t traceLoggerEnterToggleOffset, @@ -228,7 +223,6 @@ struct BaselineScript static BaselineScript *New(JSScript *jsscript, uint32_t prologueOffset, uint32_t epilogueOffset, uint32_t postDebugPrologueOffset, - uint32_t spsPushToggleOffset, uint32_t profilerEnterToggleOffset, uint32_t profilerExitToggleOffset, uint32_t traceLoggerEnterToggleOffset, @@ -398,7 +392,6 @@ struct BaselineScript // toggle traps at |pc|. void toggleDebugTraps(JSScript *script, jsbytecode *pc); - void toggleSPS(bool enable); void toggleProfilerInstrumentation(bool enable); bool isProfilerInstrumentationOn() const { return flags_ & PROFILER_INSTRUMENTATION_ON; @@ -464,7 +457,7 @@ AddSizeOfBaselineData(JSScript *script, mozilla::MallocSizeOf mallocSizeOf, size size_t *fallbackStubs); void -ToggleBaselineSPS(JSRuntime *runtime, bool enable); +ToggleBaselineProfiling(JSRuntime *runtime, bool enable); void ToggleBaselineTraceLoggerScripts(JSRuntime *runtime, bool enable); @@ -516,8 +509,7 @@ struct BaselineBailoutInfo uint32_t BailoutIonToBaseline(JSContext *cx, JitActivation *activation, JitFrameIterator &iter, bool invalidate, BaselineBailoutInfo **bailoutInfo, - const ExceptionBailoutInfo *exceptionInfo, - bool *poppedLastSPSFrame); + const ExceptionBailoutInfo *exceptionInfo); // Mark baseline scripts on the stack as active, so that they are not discarded // during GC. diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 0a6b38eaf7d..60c82a40f05 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -3653,7 +3653,7 @@ CodeGenerator::emitObjectOrStringResultChecks(LInstruction *lir, MDefinition *mi MOZ_CRASH(); } - masm.callWithABINoProfiling(callee); + masm.callWithABI(callee); restoreVolatile(); masm.bind(&done); @@ -3719,7 +3719,7 @@ CodeGenerator::emitValueResultChecks(LInstruction *lir, MDefinition *mir) masm.loadJSContext(temp2); masm.passABIArg(temp2); masm.passABIArg(temp1); - masm.callWithABINoProfiling(JS_FUNC_TO_DATA_PTR(void *, AssertValidValue)); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, AssertValidValue)); masm.popValue(output); restoreVolatile(); @@ -6932,9 +6932,6 @@ CodeGenerator::generateAsmJS(AsmJSFunctionLabels *labels) { JitSpew(JitSpew_Codegen, "# Emitting asm.js code"); - // AsmJS doesn't do SPS instrumentation. - sps_.disable(); - if (!omitOverRecursedCheck()) labels->overflowThunk.emplace(); @@ -7210,8 +7207,8 @@ CodeGenerator::link(JSContext *cx, types::CompilerConstraintList *constraints) ionScript->setSkipArgCheckEntryOffset(getSkipArgCheckEntryOffset()); // If SPS is enabled, mark IonScript as having been instrumented with SPS - if (sps_.enabled()) - ionScript->setHasSPSInstrumentation(); + if (isProfilerInstrumentationEnabled()) + ionScript->setHasProfilingInstrumentation(); script->setIonScript(cx, ionScript); @@ -8897,49 +8894,6 @@ CodeGenerator::visitSetDOMProperty(LSetDOMProperty *ins) MOZ_ASSERT(masm.framePushed() == initialStack); } -typedef bool(*SPSFn)(JSContext *, HandleScript); -static const VMFunction SPSEnterInfo = FunctionInfo(SPSEnter); -static const VMFunction SPSExitInfo = FunctionInfo(SPSExit); - -void -CodeGenerator::visitProfilerStackOp(LProfilerStackOp *lir) -{ - Register temp = ToRegister(lir->temp()->output()); - - switch (lir->type()) { - case MProfilerStackOp::Enter: - if (gen->options.spsSlowAssertionsEnabled()) { - saveLive(lir); - pushArg(ImmGCPtr(lir->script())); - callVM(SPSEnterInfo, lir); - restoreLive(lir); - sps_.pushManual(lir->script(), masm, temp, /* inlinedFunction = */ false); - } else { - masm.propagateOOM(sps_.push(lir->script(), masm, temp, - /* inlinedFunction = */ false)); - } - return; - - case MProfilerStackOp::Exit: - if (gen->options.spsSlowAssertionsEnabled()) { - saveLive(lir); - pushArg(ImmGCPtr(lir->script())); - // Once we've exited, then we shouldn't emit instrumentation for - // the corresponding reenter() because we no longer have a - // frame. - sps_.skipNextReenter(); - callVM(SPSExitInfo, lir); - restoreLive(lir); - } else { - sps_.pop(masm, temp, /* inlinedFunction = */ false); - } - return; - - default: - MOZ_CRASH("invalid LProfilerStackOp type"); - } -} - class OutOfLineIsCallable : public OutOfLineCodeBase { LIsCallable *ins_; diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h index 7a625b3cef4..60dacf54745 100644 --- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -293,7 +293,6 @@ class CodeGenerator : public CodeGeneratorSpecific void visitInstanceOfO(LInstanceOfO *ins); void visitInstanceOfV(LInstanceOfV *ins); void visitCallInstanceOf(LCallInstanceOf *ins); - void visitProfilerStackOp(LProfilerStackOp *lir); void visitGetDOMProperty(LGetDOMProperty *lir); void visitGetDOMMemberV(LGetDOMMemberV *lir); void visitGetDOMMemberT(LGetDOMMemberT *lir); diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp index c6c22832979..1c2916aecdb 100644 --- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -705,7 +705,7 @@ IonScript::IonScript() invalidateEpilogueOffset_(0), invalidateEpilogueDataOffset_(0), numBailouts_(0), - hasSPSInstrumentation_(false), + hasProfilingInstrumentation_(false), recompiling_(false), runtimeData_(0), runtimeSize_(0), diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 3095731da1e..bddb2aa449c 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -705,8 +705,6 @@ IonBuilder::build() // Emit the start instruction, so we can begin real instructions. current->add(MStart::New(alloc(), MStart::StartType_Default)); - if (instrumentedProfiling()) - current->add(MProfilerStackOp::New(alloc(), script(), MProfilerStackOp::Enter)); // Guard against over-recursion. Do this before we start unboxing, since // this will create an OSI point that will read the incoming argument @@ -4072,9 +4070,6 @@ IonBuilder::processReturn(JSOp op) MOZ_CRASH("unknown return op"); } - if (instrumentedProfiling() && inliningDepth_ == 0) { - current->add(MProfilerStackOp::New(alloc(), script(), MProfilerStackOp::Exit)); - } MReturn *ret = MReturn::New(alloc(), def); current->end(ret); diff --git a/js/src/jit/IonCode.h b/js/src/jit/IonCode.h index c7342f63ed8..3791b071203 100644 --- a/js/src/jit/IonCode.h +++ b/js/src/jit/IonCode.h @@ -193,8 +193,8 @@ struct IonScript // Number of times this script bailed out without invalidation. uint32_t numBailouts_; - // Flag set if IonScript was compiled with SPS profiling enabled. - bool hasSPSInstrumentation_; + // Flag set if IonScript was compiled with profiling enabled. + bool hasProfilingInstrumentation_; // Flag for if this script is getting recompiled. uint32_t recompiling_; @@ -412,14 +412,14 @@ struct IonScript bool bailoutExpected() const { return numBailouts_ > 0; } - void setHasSPSInstrumentation() { - hasSPSInstrumentation_ = true; + void setHasProfilingInstrumentation() { + hasProfilingInstrumentation_ = true; } - void clearHasSPSInstrumentation() { - hasSPSInstrumentation_ = false; + void clearHasProfilingInstrumentation() { + hasProfilingInstrumentation_ = false; } - bool hasSPSInstrumentation() const { - return hasSPSInstrumentation_; + bool hasProfilingInstrumentation() const { + return hasProfilingInstrumentation_; } void setTraceLoggerEvent(TraceLoggerEvent &event) { traceLoggerScriptEvent_ = event; diff --git a/js/src/jit/IonInstrumentation.h b/js/src/jit/IonInstrumentation.h index 05c106178e6..93b96ad40e8 100644 --- a/js/src/jit/IonInstrumentation.h +++ b/js/src/jit/IonInstrumentation.h @@ -19,23 +19,12 @@ typedef SPSInstrumentation BaseInstrumentation; class IonInstrumentation : public BaseInstrumentation { - jsbytecode **trackedPc_; - public: IonInstrumentation(SPSProfiler *profiler, jsbytecode **pc) - : BaseInstrumentation(profiler), - trackedPc_(pc) + : BaseInstrumentation(profiler) { MOZ_ASSERT(pc != nullptr); } - - void leave(MacroAssembler &masm, Register reg, bool inlinedFunction = false) { - BaseInstrumentation::leave(*trackedPc_, masm, reg, inlinedFunction); - } - - bool enterInlineFrame() { - return BaseInstrumentation::enterInlineFrame(*trackedPc_); - } }; } // namespace jit diff --git a/js/src/jit/JitFrames.cpp b/js/src/jit/JitFrames.cpp index cc5245e489e..15a847be70f 100644 --- a/js/src/jit/JitFrames.cpp +++ b/js/src/jit/JitFrames.cpp @@ -379,7 +379,7 @@ CloseLiveIterator(JSContext *cx, const InlineFrameIterator &frame, uint32_t loca static void HandleExceptionIon(JSContext *cx, const InlineFrameIterator &frame, ResumeFromException *rfe, - bool *overrecursed, bool *poppedLastSPSFrameOut) + bool *overrecursed) { RootedScript script(cx, frame.script()); jsbytecode *pc = frame.pc(); @@ -411,8 +411,7 @@ HandleExceptionIon(JSContext *cx, const InlineFrameIterator &frame, ResumeFromEx // to the stack depth at the snapshot, as we could've thrown in the // middle of a call. ExceptionBailoutInfo propagateInfo; - uint32_t retval = ExceptionHandlerBailout(cx, frame, rfe, propagateInfo, overrecursed, - poppedLastSPSFrameOut); + uint32_t retval = ExceptionHandlerBailout(cx, frame, rfe, propagateInfo, overrecursed); if (retval == BAILOUT_RETURN_OK) return; } @@ -454,8 +453,7 @@ HandleExceptionIon(JSContext *cx, const InlineFrameIterator &frame, ResumeFromEx // Bailout at the start of the catch block. jsbytecode *catchPC = script->main() + tn->start + tn->length; ExceptionBailoutInfo excInfo(frame.frameNo(), catchPC, tn->stackDepth); - uint32_t retval = ExceptionHandlerBailout(cx, frame, rfe, excInfo, overrecursed, - poppedLastSPSFrameOut); + uint32_t retval = ExceptionHandlerBailout(cx, frame, rfe, excInfo, overrecursed); if (retval == BAILOUT_RETURN_OK) return; @@ -763,8 +761,7 @@ HandleException(ResumeFromException *rfe) bool invalidated = iter.checkInvalidation(&ionScript); for (;;) { - bool poppedLastSPSFrame = false; - HandleExceptionIon(cx, frames, rfe, &overrecursed, &poppedLastSPSFrame); + HandleExceptionIon(cx, frames, rfe, &overrecursed); if (rfe->kind == ResumeFromException::RESUME_BAILOUT) { if (invalidated) @@ -774,29 +771,13 @@ HandleException(ResumeFromException *rfe) MOZ_ASSERT(rfe->kind == ResumeFromException::RESUME_ENTRY_FRAME); - // Figure out whether SPS frame was pushed for this frame or not. - // Even if profiler is enabled, the frame being popped might have - // been entered prior to SPS being enabled, and thus not have - // a pushed SPS frame. - bool popSPSFrame = cx->runtime()->spsProfiler.enabled(); - if (invalidated) - popSPSFrame = ionScript->hasSPSInstrumentation(); - - // Don't pop an SPS frame for inlined frames, since they are not instrumented. - if (frames.more()) - popSPSFrame = false; - - // Don't pop the last SPS frame if it's already been popped by - // bailing out. - if (poppedLastSPSFrame) - popSPSFrame = false; - // When profiling, each frame popped needs a notification that // the function has exited, so invoke the probe that a function // is exiting. JSScript *script = frames.script(); - probes::ExitScript(cx, script, script->functionNonDelazifying(), popSPSFrame); + probes::ExitScript(cx, script, script->functionNonDelazifying(), + /* popSPSFrame = */ false); if (!frames.more()) { TraceLogStopEvent(logger, TraceLogger_IonMonkey); TraceLogStopEvent(logger, TraceLogger_Scripts); @@ -847,11 +828,7 @@ HandleException(ResumeFromException *rfe) // Unwind profiler pseudo-stack JSScript *script = iter.script(); probes::ExitScript(cx, script, script->functionNonDelazifying(), - iter.baselineFrame()->hasPushedSPSFrame()); - // After this point, any pushed SPS frame would have been popped if it needed - // to be. Unset the flag here so that if we call DebugEpilogue below, - // it doesn't try to pop the SPS frame again. - iter.baselineFrame()->unsetPushedSPSFrame(); + /* popSPSFrame = */ false); if (iter.baselineFrame()->isDebuggee() && !calledDebugEpilogue) { // If we still need to call the DebugEpilogue, we must diff --git a/js/src/jit/LIR-Common.h b/js/src/jit/LIR-Common.h index 2d88ab11296..9bb35c1da27 100644 --- a/js/src/jit/LIR-Common.h +++ b/js/src/jit/LIR-Common.h @@ -6165,28 +6165,6 @@ class LCallInstanceOf : public LCallInstructionHelper<1, BOX_PIECES+1, 0> static const size_t RHS = BOX_PIECES; }; -class LProfilerStackOp : public LInstructionHelper<0, 0, 1> -{ - public: - LIR_HEADER(ProfilerStackOp) - - explicit LProfilerStackOp(const LDefinition &temp) { - setTemp(0, temp); - } - - const LDefinition *temp() { - return getTemp(0); - } - - JSScript *script() { - return mir_->toProfilerStackOp()->script(); - } - - MProfilerStackOp::Type type() { - return mir_->toProfilerStackOp()->type(); - } -}; - class LIsCallable : public LInstructionHelper<1, 1, 0> { public: diff --git a/js/src/jit/LOpcodes.h b/js/src/jit/LOpcodes.h index 2a50bfbbdbd..6df9f485a41 100644 --- a/js/src/jit/LOpcodes.h +++ b/js/src/jit/LOpcodes.h @@ -305,7 +305,6 @@ _(InterruptCheck) \ _(AsmJSInterruptCheck) \ _(InterruptCheckImplicit) \ - _(ProfilerStackOp) \ _(GetDOMProperty) \ _(GetDOMMemberV) \ _(GetDOMMemberT) \ diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index 7d9d705f193..3cb751eb247 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -3492,18 +3492,6 @@ LIRGenerator::visitCallInstanceOf(MCallInstanceOf *ins) assignSafepoint(lir, ins); } -void -LIRGenerator::visitProfilerStackOp(MProfilerStackOp *ins) -{ - LProfilerStackOp *lir = new(alloc()) LProfilerStackOp(temp()); - add(lir, ins); - - // If slow assertions are enabled, then this node will result in a callVM - // out to a C++ function for the assertions, so we will need a safepoint. - if (gen->options.spsSlowAssertionsEnabled()) - assignSafepoint(lir, ins); -} - void LIRGenerator::visitIsCallable(MIsCallable *ins) { diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h index 7c166bdb7fd..d53fd2a2dab 100644 --- a/js/src/jit/Lowering.h +++ b/js/src/jit/Lowering.h @@ -248,7 +248,6 @@ class LIRGenerator : public LIRGeneratorSpecific void visitInArray(MInArray *ins); void visitInstanceOf(MInstanceOf *ins); void visitCallInstanceOf(MCallInstanceOf *ins); - void visitProfilerStackOp(MProfilerStackOp *ins); void visitIsCallable(MIsCallable *ins); void visitIsObject(MIsObject *ins); void visitHasClass(MHasClass *ins); diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 3f82ea68a37..3d726577aee 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -11449,48 +11449,6 @@ class MNewStringObject : StringObject *templateObj() const; }; -// Node that represents that a script has begun executing. This comes at the -// start of the function and is called once per function (including inline -// ones) -class MProfilerStackOp : public MNullaryInstruction -{ - public: - enum Type { - Enter, // a function has begun executing and it is not inline - Exit // any function has exited and is not inline - }; - - private: - JSScript *script_; - Type type_; - - MProfilerStackOp(JSScript *script, Type type) - : script_(script), type_(type) - { - MOZ_ASSERT(script); - setGuard(); - } - - public: - INSTRUCTION_HEADER(ProfilerStackOp) - - static MProfilerStackOp *New(TempAllocator &alloc, JSScript *script, Type type) { - return new(alloc) MProfilerStackOp(script, type); - } - - JSScript *script() { - return script_; - } - - Type type() { - return type_; - } - - AliasSet getAliasSet() const MOZ_OVERRIDE { - return AliasSet::None(); - } -}; - // This is an alias for MLoadFixedSlot. class MEnclosingScope : public MLoadFixedSlot { diff --git a/js/src/jit/MOpcodes.h b/js/src/jit/MOpcodes.h index fd02ef48248..3cb83462d86 100644 --- a/js/src/jit/MOpcodes.h +++ b/js/src/jit/MOpcodes.h @@ -226,7 +226,6 @@ namespace jit { _(CallInstanceOf) \ _(InterruptCheck) \ _(AsmJSInterruptCheck) \ - _(ProfilerStackOp) \ _(GetDOMProperty) \ _(GetDOMMember) \ _(SetDOMProperty) \ diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp index f3328838885..5301dda5a7d 100644 --- a/js/src/jit/MacroAssembler.cpp +++ b/js/src/jit/MacroAssembler.cpp @@ -1314,16 +1314,8 @@ MacroAssembler::handleFailure() { // Re-entry code is irrelevant because the exception will leave the // running function and never come back - if (sps_) - sps_->skipNextReenter(); - leaveSPSFrame(); - JitCode *excTail = GetJitContext()->runtime->jitRuntime()->getExceptionTail(); jump(excTail); - - // Doesn't actually emit code, but balances the leave() - if (sps_) - sps_->reenter(*this, InvalidReg); } #ifdef DEBUG @@ -1345,7 +1337,7 @@ MacroAssembler::assumeUnreachable(const char *output) setupUnalignedABICall(1, temp); movePtr(ImmPtr(output), temp); passABIArg(temp); - callWithABINoProfiling(JS_FUNC_TO_DATA_PTR(void *, AssumeUnreachable_)); + callWithABI(JS_FUNC_TO_DATA_PTR(void *, AssumeUnreachable_)); PopRegsInMask(RegisterSet::Volatile()); } @@ -1373,7 +1365,7 @@ MacroAssembler::printf(const char *output) setupUnalignedABICall(1, temp); movePtr(ImmPtr(output), temp); passABIArg(temp); - callWithABINoProfiling(JS_FUNC_TO_DATA_PTR(void *, Printf0_)); + callWithABI(JS_FUNC_TO_DATA_PTR(void *, Printf0_)); PopRegsInMask(RegisterSet::Volatile()); } @@ -1399,7 +1391,7 @@ MacroAssembler::printf(const char *output, Register value) movePtr(ImmPtr(output), temp); passABIArg(temp); passABIArg(value); - callWithABINoProfiling(JS_FUNC_TO_DATA_PTR(void *, Printf1_)); + callWithABI(JS_FUNC_TO_DATA_PTR(void *, Printf1_)); PopRegsInMask(RegisterSet::Volatile()); } @@ -1422,7 +1414,7 @@ MacroAssembler::tracelogStartId(Register logger, uint32_t textId, bool force) passABIArg(logger); move32(Imm32(textId), temp); passABIArg(temp); - callWithABINoProfiling(JS_FUNC_TO_DATA_PTR(void *, TraceLogStartEventPrivate)); + callWithABI(JS_FUNC_TO_DATA_PTR(void *, TraceLogStartEventPrivate)); PopRegsInMask(RegisterSet::Volatile()); } @@ -1441,7 +1433,7 @@ MacroAssembler::tracelogStartId(Register logger, Register textId) setupUnalignedABICall(2, temp); passABIArg(logger); passABIArg(textId); - callWithABINoProfiling(JS_FUNC_TO_DATA_PTR(void *, TraceLogStartEventPrivate)); + callWithABI(JS_FUNC_TO_DATA_PTR(void *, TraceLogStartEventPrivate)); PopRegsInMask(RegisterSet::Volatile()); } @@ -1462,7 +1454,7 @@ MacroAssembler::tracelogStartEvent(Register logger, Register event) setupUnalignedABICall(2, temp); passABIArg(logger); passABIArg(event); - callWithABINoProfiling(JS_FUNC_TO_DATA_PTR(void *, TraceLogFunc)); + callWithABI(JS_FUNC_TO_DATA_PTR(void *, TraceLogFunc)); PopRegsInMask(RegisterSet::Volatile()); } @@ -1485,7 +1477,7 @@ MacroAssembler::tracelogStopId(Register logger, uint32_t textId, bool force) move32(Imm32(textId), temp); passABIArg(temp); - callWithABINoProfiling(JS_FUNC_TO_DATA_PTR(void *, TraceLogStopEventPrivate)); + callWithABI(JS_FUNC_TO_DATA_PTR(void *, TraceLogStopEventPrivate)); PopRegsInMask(RegisterSet::Volatile()); } @@ -1504,7 +1496,7 @@ MacroAssembler::tracelogStopId(Register logger, Register textId) setupUnalignedABICall(2, temp); passABIArg(logger); passABIArg(textId); - callWithABINoProfiling(JS_FUNC_TO_DATA_PTR(void *, TraceLogStopEventPrivate)); + callWithABI(JS_FUNC_TO_DATA_PTR(void *, TraceLogStopEventPrivate)); PopRegsInMask(RegisterSet::Volatile()); } @@ -2023,58 +2015,6 @@ MacroAssembler::branchEqualTypeIfNeeded(MIRType type, MDefinition *maybeDef, Reg } } - -// If a pseudostack frame has this as its label, its stack pointer -// field points to the registers saved on entry to JIT code. A native -// stack unwinder could use that information to continue unwinding -// past that point. -const char MacroAssembler::enterJitLabel[] = "EnterJIT"; - -// Creates an enterJIT pseudostack frame, as described above. Pushes -// a word to the stack to indicate whether this was done. |framePtr| is -// the pointer to the machine-dependent saved state. -void -MacroAssembler::spsMarkJit(SPSProfiler *p, Register framePtr, Register temp) -{ - Label spsNotEnabled; - uint32_t *enabledAddr = p->addressOfEnabled(); - load32(AbsoluteAddress(enabledAddr), temp); - push(temp); // +4: Did we push an sps frame. - branchTest32(Assembler::Equal, temp, temp, &spsNotEnabled); - - Label stackFull; - // We always need the "safe" versions, because these are used in trampolines - // and won't be regenerated when SPS state changes. - spsProfileEntryAddressSafe(p, 0, temp, &stackFull); - - // Push a C++ frame with non-copy label - storePtr(ImmPtr(enterJitLabel), Address(temp, ProfileEntry::offsetOfLabel())); - storePtr(framePtr, Address(temp, ProfileEntry::offsetOfSpOrScript())); - store32(Imm32(0), Address(temp, ProfileEntry::offsetOfLineOrPc())); - store32(Imm32(ProfileEntry::IS_CPP_ENTRY), Address(temp, ProfileEntry::offsetOfFlags())); - - /* Always increment the stack size, whether or not we actually pushed. */ - bind(&stackFull); - loadPtr(AbsoluteAddress(p->addressOfSizePointer()), temp); - add32(Imm32(1), Address(temp, 0)); - - bind(&spsNotEnabled); -} - -// Pops the word pushed by spsMarkJit and, if spsMarkJit pushed an SPS -// frame, pops it. -void -MacroAssembler::spsUnmarkJit(SPSProfiler *p, Register temp) -{ - Label spsNotEnabled; - pop(temp); // -4: Was the profiler enabled. - branchTest32(Assembler::Equal, temp, temp, &spsNotEnabled); - - spsPopFrameSafe(p, temp); - - bind(&spsNotEnabled); -} - void MacroAssembler::profilerPreCallImpl() { diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index ead3ffabdf8..782b217a876 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -185,27 +185,18 @@ class MacroAssembler : public MacroAssemblerSpecific mozilla::Maybe jitContext_; mozilla::Maybe alloc_; - // SPS instrumentation, only used for Ion caches. - mozilla::Maybe spsInstrumentation_; - jsbytecode *spsPc_; - private: // This field is used to manage profiling instrumentation output. If // provided and enabled, then instrumentation will be emitted around call - // sites. The IonInstrumentation instance is hosted inside of - // CodeGeneratorShared and is the manager of when instrumentation is - // actually emitted or not. If nullptr, then no instrumentation is emitted. - IonInstrumentation *sps_; + // sites. + bool emitProfilingInstrumentation_; // Labels for handling exceptions and failures. NonAssertingLabel failureLabel_; public: - // If instrumentation should be emitted, then the sps parameter should be - // provided, but otherwise it can be safely omitted to prevent all - // instrumentation from being emitted. MacroAssembler() - : sps_(nullptr) + : emitProfilingInstrumentation_(false) { JitContext *jcx = GetJitContext(); JSContext *cx = jcx->cx; @@ -228,7 +219,7 @@ class MacroAssembler : public MacroAssemblerSpecific // (for example, Trampoline-$(ARCH).cpp and IonCaches.cpp). explicit MacroAssembler(JSContext *cx, IonScript *ion = nullptr, JSScript *script = nullptr, jsbytecode *pc = nullptr) - : sps_(nullptr) + : emitProfilingInstrumentation_(false) { constructRoot(cx); jitContext_.emplace(cx, (js::jit::TempAllocator *)nullptr); @@ -240,21 +231,15 @@ class MacroAssembler : public MacroAssemblerSpecific #endif if (ion) { setFramePushed(ion->frameSize()); - if (pc && cx->runtime()->spsProfiler.enabled()) { - // We have to update the SPS pc when this IC stub calls into - // the VM. - spsPc_ = pc; - spsInstrumentation_.emplace(&cx->runtime()->spsProfiler, &spsPc_); - sps_ = spsInstrumentation_.ptr(); - sps_->setPushed(script); - } + if (pc && cx->runtime()->spsProfiler.enabled()) + emitProfilingInstrumentation_ = true; } } // asm.js compilation handles its own JitContext-pushing struct AsmJSToken {}; explicit MacroAssembler(AsmJSToken) - : sps_(nullptr) + : emitProfilingInstrumentation_(false) { #ifdef JS_CODEGEN_ARM initWithAllocator(); @@ -262,8 +247,8 @@ class MacroAssembler : public MacroAssemblerSpecific #endif } - void setInstrumentation(IonInstrumentation *sps) { - sps_ = sps; + void enableProfilingInstrumentation() { + emitProfilingInstrumentation_ = true; } void resetForNewCodeGenerator(TempAllocator &alloc) { @@ -874,51 +859,46 @@ class MacroAssembler : public MacroAssemblerSpecific // they are returning the offset of the assembler just after the call has // been made so that a safepoint can be made at that location. - template - void callWithABINoProfiling(const T &fun, MoveOp::Type result = MoveOp::GENERAL) { - MacroAssemblerSpecific::callWithABI(fun, result); - } - template void callWithABI(const T &fun, MoveOp::Type result = MoveOp::GENERAL) { - leaveSPSFrame(); - callWithABINoProfiling(fun, result); - reenterSPSFrame(); + profilerPreCall(); + MacroAssemblerSpecific::callWithABI(fun, result); + profilerPostReturn(); } // see above comment for what is returned uint32_t callJit(Register callee) { - leaveSPSFrame(); + profilerPreCall(); MacroAssemblerSpecific::callJit(callee); uint32_t ret = currentOffset(); - reenterSPSFrame(); + profilerPostReturn(); return ret; } // see above comment for what is returned uint32_t callWithExitFrame(Label *target) { - leaveSPSFrame(); + profilerPreCall(); MacroAssemblerSpecific::callWithExitFrame(target); uint32_t ret = currentOffset(); - reenterSPSFrame(); + profilerPostReturn(); return ret; } // see above comment for what is returned uint32_t callWithExitFrame(JitCode *target) { - leaveSPSFrame(); + profilerPreCall(); MacroAssemblerSpecific::callWithExitFrame(target); uint32_t ret = currentOffset(); - reenterSPSFrame(); + profilerPostReturn(); return ret; } // see above comment for what is returned uint32_t callWithExitFrame(JitCode *target, Register dynStack) { - leaveSPSFrame(); + profilerPreCall(); MacroAssemblerSpecific::callWithExitFrame(target, dynStack); uint32_t ret = currentOffset(); - reenterSPSFrame(); + profilerPostReturn(); return ret; } @@ -954,165 +934,19 @@ class MacroAssembler : public MacroAssemblerSpecific // These two functions are helpers used around call sites throughout the // assembler. They are called from the above call wrappers to emit the // necessary instrumentation. - void leaveSPSFrame() { - if (!sps_ || !sps_->enabled()) + void profilerPreCall() { + if (!emitProfilingInstrumentation_) return; - // No registers are guaranteed to be available, so push/pop a register - // so we can use one - push(CallTempReg0); - sps_->leave(*this, CallTempReg0); - pop(CallTempReg0); + profilerPreCallImpl(); } - void reenterSPSFrame() { - if (!sps_ || !sps_->enabled()) + void profilerPostReturn() { + if (!emitProfilingInstrumentation_) return; - // Attempt to use a now-free register within a given set, but if the - // architecture being built doesn't have an available register, resort - // to push/pop - GeneralRegisterSet regs(Registers::TempMask & ~Registers::JSCallMask & - ~Registers::CallMask); - if (regs.empty()) { - push(CallTempReg0); - sps_->reenter(*this, CallTempReg0); - pop(CallTempReg0); - } else { - sps_->reenter(*this, regs.getAny()); - } - } - - void spsProfileEntryAddress(SPSProfiler *p, int offset, Register temp, - Label *full) - { - movePtr(ImmPtr(p->sizePointer()), temp); - load32(Address(temp, 0), temp); - if (offset != 0) - add32(Imm32(offset), temp); - branch32(Assembler::GreaterThanOrEqual, temp, Imm32(p->maxSize()), full); - - JS_STATIC_ASSERT(sizeof(ProfileEntry) == (2 * sizeof(void *)) + 8); - if (sizeof(void *) == 4) { - lshiftPtr(Imm32(4), temp); - } else { - lshiftPtr(Imm32(3), temp); - mulBy3(temp, temp); - } - - addPtr(ImmPtr(p->stack()), temp); - } - - // The safe version of the above method refrains from assuming that the fields - // of the SPSProfiler class are going to stay the same across different runs of - // the jitcode. Ion can use the more efficient unsafe version because ion jitcode - // will not survive changes to to the profiler settings. Baseline jitcode, however, - // can span these changes, so any hardcoded field values will be incorrect afterwards. - // All the sps-related methods used by baseline call |spsProfileEntryAddressSafe|. - void spsProfileEntryAddressSafe(SPSProfiler *p, int offset, Register temp, - Label *full) - { - // Load size pointer - loadPtr(AbsoluteAddress(p->addressOfSizePointer()), temp); - - // Load size - load32(Address(temp, 0), temp); - if (offset != 0) - add32(Imm32(offset), temp); - - // Test against max size. - branch32(Assembler::LessThanOrEqual, AbsoluteAddress(p->addressOfMaxSize()), temp, full); - - JS_STATIC_ASSERT(sizeof(ProfileEntry) == (2 * sizeof(void *)) + 8); - if (sizeof(void *) == 4) { - lshiftPtr(Imm32(4), temp); - } else { - lshiftPtr(Imm32(3), temp); - mulBy3(temp, temp); - } - - push(temp); - loadPtr(AbsoluteAddress(p->addressOfStack()), temp); - addPtr(Address(StackPointer, 0), temp); - addPtr(Imm32(sizeof(size_t)), StackPointer); + profilerPostReturnImpl(); } public: - // These functions are needed by the IonInstrumentation interface defined in - // vm/SPSProfiler.h. They will modify the pseudostack provided to SPS to - // perform the actual instrumentation. - - void spsUpdatePCIdx(SPSProfiler *p, int32_t idx, Register temp) { - Label stackFull; - spsProfileEntryAddress(p, -1, temp, &stackFull); - store32(Imm32(idx), Address(temp, ProfileEntry::offsetOfLineOrPc())); - bind(&stackFull); - } - - void spsUpdatePCIdx(SPSProfiler *p, Register idx, Register temp) { - Label stackFull; - spsProfileEntryAddressSafe(p, -1, temp, &stackFull); - store32(idx, Address(temp, ProfileEntry::offsetOfLineOrPc())); - bind(&stackFull); - } - - // spsPushFrame variant for Ion-optimized scripts. - void spsPushFrame(SPSProfiler *p, const char *str, JSScript *s, Register temp) { - Label stackFull; - spsProfileEntryAddress(p, 0, temp, &stackFull); - - // Push a JS frame with a copy label - storePtr(ImmPtr(str), Address(temp, ProfileEntry::offsetOfLabel())); - storePtr(ImmGCPtr(s), Address(temp, ProfileEntry::offsetOfSpOrScript())); - store32(Imm32(ProfileEntry::NullPCOffset), Address(temp, ProfileEntry::offsetOfLineOrPc())); - store32(Imm32(ProfileEntry::FRAME_LABEL_COPY), Address(temp, ProfileEntry::offsetOfFlags())); - - /* Always increment the stack size, whether or not we actually pushed. */ - bind(&stackFull); - movePtr(ImmPtr(p->sizePointer()), temp); - add32(Imm32(1), Address(temp, 0)); - } - - // spsPushFrame variant for Baseline-optimized scripts. - void spsPushFrame(SPSProfiler *p, const Address &str, const Address &script, - Register temp, Register temp2) - { - Label stackFull; - spsProfileEntryAddressSafe(p, 0, temp, &stackFull); - - // Push a JS frame with a copy label - loadPtr(str, temp2); - storePtr(temp2, Address(temp, ProfileEntry::offsetOfLabel())); - - loadPtr(script, temp2); - storePtr(temp2, Address(temp, ProfileEntry::offsetOfSpOrScript())); - - // Store 0 for PCIdx because that's what interpreter does. - // (See probes::EnterScript, which calls spsProfiler.enter, which pushes an entry - // with 0 pcIdx). - store32(Imm32(0), Address(temp, ProfileEntry::offsetOfLineOrPc())); - store32(Imm32(ProfileEntry::FRAME_LABEL_COPY), Address(temp, ProfileEntry::offsetOfFlags())); - - /* Always increment the stack size, whether or not we actually pushed. */ - bind(&stackFull); - movePtr(ImmPtr(p->addressOfSizePointer()), temp); - loadPtr(Address(temp, 0), temp); - add32(Imm32(1), Address(temp, 0)); - } - - void spsPopFrame(SPSProfiler *p, Register temp) { - movePtr(ImmPtr(p->sizePointer()), temp); - add32(Imm32(-1), Address(temp, 0)); - } - - // spsPropFrameSafe does not assume |profiler->sizePointer()| will stay constant. - void spsPopFrameSafe(SPSProfiler *p, Register temp) { - loadPtr(AbsoluteAddress(p->addressOfSizePointer()), temp); - add32(Imm32(-1), Address(temp, 0)); - } - - static const char enterJitLabel[]; - void spsMarkJit(SPSProfiler *p, Register framePtr, Register temp); - void spsUnmarkJit(SPSProfiler *p, Register temp); - void loadBaselineOrIonRaw(Register script, Register dest, Label *failure); void loadBaselineOrIonNoArgCheck(Register callee, Register dest, Label *failure); diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp index 5884d1defc6..8b59c09bef5 100644 --- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -576,19 +576,6 @@ NewStringObject(JSContext *cx, HandleString str) return StringObject::create(cx, str); } -bool -SPSEnter(JSContext *cx, HandleScript script) -{ - return cx->runtime()->spsProfiler.enter(script, script->functionNonDelazifying()); -} - -bool -SPSExit(JSContext *cx, HandleScript script) -{ - cx->runtime()->spsProfiler.exit(script, script->functionNonDelazifying()); - return true; -} - bool OperatorIn(JSContext *cx, HandleValue key, HandleObject obj, bool *out) { @@ -803,15 +790,6 @@ DebugEpilogue(JSContext *cx, BaselineFrame *frame, jsbytecode *pc, bool ok) DebugScopes::onPopStrictEvalScope(frame); } - // If the frame has a pushed SPS frame, make sure to pop it. - if (frame->hasPushedSPSFrame()) { - cx->runtime()->spsProfiler.exit(frame->script(), frame->maybeFun()); - // Unset the pushedSPSFrame flag because DebugEpilogue may get called before - // probes::ExitScript in baseline during exception handling, and we don't - // want to double-pop SPS frames. - frame->unsetPushedSPSFrame(); - } - if (!ok) { // Pop this frame by updating jitTop, so that the exception handling // code will start at the previous frame. diff --git a/js/src/jit/VMFunctions.h b/js/src/jit/VMFunctions.h index 7252bff7344..8f0164d47d9 100644 --- a/js/src/jit/VMFunctions.h +++ b/js/src/jit/VMFunctions.h @@ -679,9 +679,6 @@ JSObject *NewCallObject(JSContext *cx, HandleShape shape, HandleTypeObject type, JSObject *NewSingletonCallObject(JSContext *cx, HandleShape shape, uint32_t lexicalBegin); JSObject *NewStringObject(JSContext *cx, HandleString str); -bool SPSEnter(JSContext *cx, HandleScript script); -bool SPSExit(JSContext *cx, HandleScript script); - bool OperatorIn(JSContext *cx, HandleValue key, HandleObject obj, bool *out); bool OperatorInI(JSContext *cx, uint32_t index, HandleObject obj, bool *out); diff --git a/js/src/jit/arm/Trampoline-arm.cpp b/js/src/jit/arm/Trampoline-arm.cpp index ccc9740b63f..c2394fc8106 100644 --- a/js/src/jit/arm/Trampoline-arm.cpp +++ b/js/src/jit/arm/Trampoline-arm.cpp @@ -36,8 +36,8 @@ GenerateReturn(MacroAssembler &masm, int returnCode, SPSProfiler *prof) // Restore non-volatile floating point registers. masm.transferMultipleByRuns(NonVolatileFloatRegs, IsLoad, StackPointer, IA); - // Unwind the sps mark. - masm.spsUnmarkJit(prof, r8); + // Get rid of padding word. + masm.addPtr(Imm32(sizeof(void*)), sp); // Set up return value masm.ma_mov(Imm32(returnCode), r0); @@ -69,7 +69,8 @@ struct EnterJITStack double d14; double d15; - size_t hasSPSMark; + // Padding. + void *padding; // Non-volatile registers. void *r4; @@ -129,9 +130,8 @@ JitRuntime::generateEnterJIT(JSContext *cx, EnterJitType type) // The 5th argument is located at [sp, 36] masm.finishDataTransfer(); - // Push the EnterJIT sps mark. "Frame pointer" = start of saved core regs. - masm.movePtr(sp, r8); - masm.spsMarkJit(&cx->runtime()->spsProfiler, r8, r9); + // Add padding word. + masm.subPtr(Imm32(sizeof(void*)), sp); // Push the float registers. masm.transferMultipleByRuns(NonVolatileFloatRegs, IsStore, sp, DB); diff --git a/js/src/jit/shared/CodeGenerator-shared.cpp b/js/src/jit/shared/CodeGenerator-shared.cpp index 4d9f50f805e..68647c8984d 100644 --- a/js/src/jit/shared/CodeGenerator-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-shared.cpp @@ -59,7 +59,6 @@ CodeGeneratorShared::CodeGeneratorShared(MIRGenerator *gen, LIRGraph *graph, Mac nativeToBytecodeNumRegions_(0), nativeToBytecodeScriptList_(nullptr), nativeToBytecodeScriptListLength_(0), - sps_(&GetJitContext()->runtime->spsProfiler(), &lastNotInlinedPC_), osrEntryOffset_(0), skipArgCheckEntryOffset_(0), #ifdef CHECK_OSIPOINT_REGISTERS @@ -68,8 +67,8 @@ CodeGeneratorShared::CodeGeneratorShared(MIRGenerator *gen, LIRGraph *graph, Mac frameDepth_(graph->paddedLocalSlotsSize() + graph->argumentsSize()), frameInitialAdjustment_(0) { - if (!gen->compilingAsmJS()) - masm.setInstrumentation(&sps_); + if (gen->isProfilerInstrumentationEnabled()) + masm.enableProfilingInstrumentation(); if (gen->compilingAsmJS()) { // Since asm.js uses the system ABI which does not necessarily use a @@ -107,7 +106,6 @@ CodeGeneratorShared::CodeGeneratorShared(MIRGenerator *gen, LIRGraph *graph, Mac bool CodeGeneratorShared::generateOutOfLineCode() { - JSScript *topScript = sps_.getPushed(); for (size_t i = 0; i < outOfLineCode_.length(); i++) { // Add native => bytecode mapping entries for OOL sites. // Not enabled on asm.js yet since asm doesn't contain bytecode mappings. @@ -123,16 +121,11 @@ CodeGeneratorShared::generateOutOfLineCode() masm.setFramePushed(outOfLineCode_[i]->framePushed()); lastPC_ = outOfLineCode_[i]->pc(); - if (!sps_.prepareForOOL()) - return false; - sps_.setPushed(outOfLineCode_[i]->script()); outOfLineCode_[i]->bind(&masm); oolIns = outOfLineCode_[i]; outOfLineCode_[i]->generate(this); - sps_.finishOOL(); } - sps_.setPushed(topScript); oolIns = nullptr; return true; diff --git a/js/src/jit/shared/CodeGenerator-shared.h b/js/src/jit/shared/CodeGenerator-shared.h index 9c41212259c..a2255d8cf99 100644 --- a/js/src/jit/shared/CodeGenerator-shared.h +++ b/js/src/jit/shared/CodeGenerator-shared.h @@ -113,11 +113,6 @@ class CodeGeneratorShared : public LElementVisitor JSScript **nativeToBytecodeScriptList_; uint32_t nativeToBytecodeScriptListLength_; - // When profiling is enabled, this is the instrumentation manager which - // maintains state of what script is currently being generated (for inline - // scripts) and when instrumentation needs to be emitted or skipped. - IonInstrumentation sps_; - bool isProfilerInstrumentationEnabled() { return gen->isProfilerInstrumentationEnabled(); } diff --git a/js/src/jit/x64/Trampoline-x64.cpp b/js/src/jit/x64/Trampoline-x64.cpp index 41bbff07c70..a9e0a143a73 100644 --- a/js/src/jit/x64/Trampoline-x64.cpp +++ b/js/src/jit/x64/Trampoline-x64.cpp @@ -81,9 +81,6 @@ JitRuntime::generateEnterJIT(JSContext *cx, EnterJitType type) masm.vmovdqa(xmm15, Operand(rsp, 16 * 9)); #endif - // Push the EnterJIT sps mark. - masm.spsMarkJit(&cx->runtime()->spsProfiler, rbp, rbx); - // Save arguments passed in registers needed after function call. masm.push(result); @@ -281,9 +278,6 @@ JitRuntime::generateEnterJIT(JSContext *cx, EnterJitType type) masm.pop(r12); // vp masm.storeValue(JSReturnOperand, Operand(r12, 0)); - // Unwind the sps mark. - masm.spsUnmarkJit(&cx->runtime()->spsProfiler, rbx); - // Restore non-volatile registers. #if defined(_WIN64) masm.vmovdqa(Operand(rsp, 16 * 0), xmm6); diff --git a/js/src/jit/x86/Trampoline-x86.cpp b/js/src/jit/x86/Trampoline-x86.cpp index baddb5a1f39..46f7135a4e2 100644 --- a/js/src/jit/x86/Trampoline-x86.cpp +++ b/js/src/jit/x86/Trampoline-x86.cpp @@ -60,9 +60,6 @@ JitRuntime::generateEnterJIT(JSContext *cx, EnterJitType type) masm.push(esi); masm.push(edi); - // Push the EnterJIT sps mark. - masm.spsMarkJit(&cx->runtime()->spsProfiler, ebp, ebx); - // Keep track of the stack which has to be unwound after returning from the // compiled function. masm.movl(esp, esi); @@ -272,21 +269,18 @@ JitRuntime::generateEnterJIT(JSContext *cx, EnterJitType type) // |ebp| could have been clobbered by the inner function. // Grab the address for the Value result from the argument stack. - // +24 ... arguments ... - // +20 - // +16 ebp <- original %ebp pointing here. - // +12 ebx - // +8 esi - // +4 edi - // +0 hasSPSFrame - masm.loadPtr(Address(esp, ARG_RESULT + 4 * sizeof(void *)), eax); + // +20 ... arguments ... + // +16 + // +12 ebp <- original %ebp pointing here. + // +8 ebx + // +4 esi + // +0 edi + masm.loadPtr(Address(esp, ARG_RESULT + 3 * sizeof(void *)), eax); masm.storeValue(JSReturnOperand, Operand(eax, 0)); /************************************************************** Return stack and registers to correct state **************************************************************/ - // Unwind the sps mark. - masm.spsUnmarkJit(&cx->runtime()->spsProfiler, ebx); // Restore non-volatile registers masm.pop(edi); diff --git a/js/src/vm/SPSProfiler.cpp b/js/src/vm/SPSProfiler.cpp index d7b2f2fb68e..de970b4dc87 100644 --- a/js/src/vm/SPSProfiler.cpp +++ b/js/src/vm/SPSProfiler.cpp @@ -93,7 +93,7 @@ SPSProfiler::enable(bool enabled) * jitcode for scripts with active frames on the stack. These scripts need to have * their profiler state toggled so they behave properly. */ - jit::ToggleBaselineSPS(rt, enabled); + jit::ToggleBaselineProfiling(rt, enabled); /* Update lastProfilingFrame to point to the top-most JS jit-frame currently on * stack. @@ -333,7 +333,6 @@ SPSEntryMarker::SPSEntryMarker(JSRuntime *rt, size_before = *profiler->size_; // We want to push a CPP frame so the profiler can correctly order JS and native stacks. profiler->push("js::RunScript", this, nullptr, nullptr, /* copy = */ false); - // We also want to push a JS frame so the hang monitor can catch script hangs. profiler->push("js::RunScript", nullptr, script, script->code(), /* copy = */ false); } diff --git a/js/src/vm/SPSProfiler.h b/js/src/vm/SPSProfiler.h index 9955d1da501..173037e1018 100644 --- a/js/src/vm/SPSProfiler.h +++ b/js/src/vm/SPSProfiler.h @@ -287,230 +287,19 @@ class SPSEntryMarker template class SPSInstrumentation { - /* Because of inline frames, this is a nested structure in a vector */ - struct FrameState { - JSScript *script; // script for this frame, nullptr if not pushed yet - jsbytecode *pc; // pc at which this frame was left for entry into a callee - bool skipNext; // should the next call to reenter be skipped? - int left; // number of leave() calls made without a matching reenter() - }; - SPSProfiler *profiler_; // Instrumentation location management - Vector frames; - FrameState *frame; - - static void clearFrame(FrameState *frame) { - frame->script = nullptr; - frame->pc = nullptr; - frame->skipNext = false; - frame->left = 0; - } - public: /* * Creates instrumentation which writes information out the the specified * profiler's stack and constituent fields. */ - explicit SPSInstrumentation(SPSProfiler *profiler) - : profiler_(profiler), frame(nullptr) - { - enterInlineFrame(nullptr); - } + explicit SPSInstrumentation(SPSProfiler *profiler) : profiler_(profiler) {} /* Small proxies around SPSProfiler */ bool enabled() { return profiler_ && profiler_->enabled(); } SPSProfiler *profiler() { MOZ_ASSERT(enabled()); return profiler_; } void disable() { profiler_ = nullptr; } - - /* Signals an inline function returned, reverting to the previous state */ - void leaveInlineFrame() { - if (!enabled()) - return; - MOZ_ASSERT(frame->left == 0); - MOZ_ASSERT(frame->script != nullptr); - frames.shrinkBy(1); - MOZ_ASSERT(frames.length() > 0); - frame = &frames[frames.length() - 1]; - } - - /* Saves the current state and assumes a fresh one for the inline function */ - bool enterInlineFrame(jsbytecode *callerPC) { - if (!enabled()) - return true; - MOZ_ASSERT_IF(frames.empty(), callerPC == nullptr); - - MOZ_ASSERT_IF(frame != nullptr, frame->script != nullptr); - MOZ_ASSERT_IF(frame != nullptr, frame->left == 1); - if (!frames.empty()) { - MOZ_ASSERT(frame == &frames[frames.length() - 1]); - frame->pc = callerPC; - } - if (!frames.growBy(1)) - return false; - frame = &frames[frames.length() - 1]; - clearFrame(frame); - return true; - } - - /* Prepares the instrumenter state for generating OOL code, by - * setting up the frame state to seem as if there are exactly - * two pushed frames: a frame for the top-level script, and - * a frame for the OOL code being generated. Any - * vm-calls from the OOL code will "leave" the OOL frame and - * return back to it. - */ - bool prepareForOOL() { - if (!enabled()) - return true; - MOZ_ASSERT(!frames.empty()); - if (frames.length() >= 2) { - frames.shrinkBy(frames.length() - 2); - - } else { // frames.length() == 1 - if (!frames.growBy(1)) - return false; - } - frames[0].pc = frames[0].script->code(); - frame = &frames[1]; - clearFrame(frame); - return true; - } - void finishOOL() { - if (!enabled()) - return; - MOZ_ASSERT(!frames.empty()); - frames.shrinkBy(frames.length() - 1); - } - - /* Number of inline frames currently active (doesn't include original one) */ - unsigned inliningDepth() { - return frames.length() - 1; - } - - /* - * When debugging or with slow assertions, sometimes a C++ method will be - * invoked to perform the pop operation from the SPS stack. When we leave - * JIT code, we need to record the current PC, but upon reentering JIT - * code, no update back to nullptr should happen. This method exists to - * flag this behavior. The next leave() will emit instrumentation, but the - * following reenter() will be a no-op. - */ - void skipNextReenter() { - /* If we've left the frame, the reenter will be skipped anyway */ - if (!enabled() || frame->left != 0) - return; - MOZ_ASSERT(frame->script); - MOZ_ASSERT(!frame->skipNext); - frame->skipNext = true; - } - - /* - * In some cases, a frame needs to be flagged as having been pushed, but no - * instrumentation should be emitted. This updates internal state to flag - * that further instrumentation should actually be emitted. - */ - void setPushed(JSScript *script) { - if (!enabled()) - return; - MOZ_ASSERT(frame->left == 0); - frame->script = script; - } - - JSScript *getPushed() { - if (!enabled()) - return nullptr; - return frame->script; - } - - /* - * Flags entry into a JS function for the first time. Before this is called, - * no instrumentation is emitted, but after this instrumentation is emitted. - */ - bool push(JSScript *script, Assembler &masm, Register scratch, bool inlinedFunction = false) { - if (!enabled()) - return true; - if (!inlinedFunction) { - const char *string = profiler_->profileString(script, script->functionNonDelazifying()); - if (string == nullptr) - return false; - masm.spsPushFrame(profiler_, string, script, scratch); - } - setPushed(script); - return true; - } - - /* - * Signifies that C++ performed the push() for this function. C++ always - * sets the current PC to something non-null, however, so as soon as JIT - * code is reentered this updates the current pc to nullptr. - */ - void pushManual(JSScript *script, Assembler &masm, Register scratch, - bool inlinedFunction = false) - { - if (!enabled()) - return; - - if (!inlinedFunction) - masm.spsUpdatePCIdx(profiler_, ProfileEntry::NullPCOffset, scratch); - - setPushed(script); - } - - /* - * Signals that the current function is leaving for a function call. This - * can happen both on JS function calls and also calls to C++. This - * internally manages how many leave() calls have been seen, and only the - * first leave() emits instrumentation. Similarly, only the last - * corresponding reenter() actually emits instrumentation. - */ - void leave(jsbytecode *pc, Assembler &masm, Register scratch, bool inlinedFunction = false) { - if (enabled() && frame->script && frame->left++ == 0) { - jsbytecode *updatePC = pc; - JSScript *script = frame->script; - if (!inlinedFunction) { - // We may be leaving an inlined frame for entry into a C++ frame. - // Use the top script's pc offset instead of the innermost script's. - if (inliningDepth() > 0) { - MOZ_ASSERT(frames[0].pc); - updatePC = frames[0].pc; - script = frames[0].script; - } - } - - if (!inlinedFunction) - masm.spsUpdatePCIdx(profiler_, script->pcToOffset(updatePC), scratch); - } - } - - /* - * Flags that the leaving of the current function has returned. This tracks - * state with leave() to only emit instrumentation at proper times. - */ - void reenter(Assembler &masm, Register scratch, bool inlinedFunction = false) { - if (!enabled() || !frame->script || frame->left-- != 1) - return; - if (frame->skipNext) { - frame->skipNext = false; - } else { - if (!inlinedFunction) - masm.spsUpdatePCIdx(profiler_, ProfileEntry::NullPCOffset, scratch); - } - } - - /* - * Signifies exiting a JS frame, popping the SPS entry. Because there can be - * multiple return sites of a function, this does not cease instrumentation - * emission. - */ - void pop(Assembler &masm, Register scratch, bool inlinedFunction = false) { - if (enabled()) { - MOZ_ASSERT(frame->left == 0); - MOZ_ASSERT(frame->script); - if (!inlinedFunction) - masm.spsPopFrame(profiler_, scratch); - } - } }; diff --git a/js/src/vm/Stack.cpp b/js/src/vm/Stack.cpp index 2643115ee1d..d8c3fd8b3fd 100644 --- a/js/src/vm/Stack.cpp +++ b/js/src/vm/Stack.cpp @@ -1373,7 +1373,8 @@ AbstractFramePtr::hasPushedSPSFrame() const { if (isInterpreterFrame()) return asInterpreterFrame()->hasPushedSPSFrame(); - return asBaselineFrame()->hasPushedSPSFrame(); + MOZ_ASSERT(isBaselineFrame()); + return false; } jit::JitActivation::JitActivation(JSContext *cx, bool active)