Bug 1002795 - Remove profileInlineFrames option. r=h4writer
authorKannan Vijayan <kvijayan@mozilla.com>
Tue, 29 Apr 2014 12:28:36 -0400
changeset 181110 c5edc4d488cbea6ac87c31ef192064b604e199db
parent 181109 31d08ac9bebed1cde25e581e26edb330593c31dc
child 181111 2b041298914b297598fc5a421ddba8d1ceac933b
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewersh4writer
bugs1002795
milestone32.0a1
Bug 1002795 - Remove profileInlineFrames option. r=h4writer
js/src/jit/BaselineBailouts.cpp
js/src/jit/CodeGenerator.cpp
js/src/jit/IonFrames.cpp
js/src/jit/JitOptions.cpp
js/src/jit/JitOptions.h
js/src/vm/SPSProfiler.h
--- a/js/src/jit/BaselineBailouts.cpp
+++ b/js/src/jit/BaselineBailouts.cpp
@@ -553,19 +553,16 @@ InitFromBailout(JSContext *cx, HandleScr
 
     // 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) {
             IonSpew(IonSpew_BaselineBailouts, "      Setting SPS flag on top frame!");
             flags |= BaselineFrame::HAS_PUSHED_SPS_FRAME;
-        } else if (js_JitOptions.profileInlineFrames) {
-            IonSpew(IonSpew_BaselineBailouts, "      Setting SPS flag on inline frame!");
-            flags |= BaselineFrame::HAS_PUSHED_SPS_FRAME;
         }
     }
 
     // Initialize BaselineFrame's scopeChain and argsObj
     JSObject *scopeChain = nullptr;
     Value returnValue;
     ArgumentsObject *argsObj = nullptr;
     BailoutKind bailoutKind = iter.bailoutKind();
@@ -983,65 +980,34 @@ InitFromBailout(JSContext *cx, HandleScr
                 JS_ASSERT(numUnsynced == 0);
                 opReturnAddr = baselineScript->prologueEntryAddr();
                 IonSpew(IonSpew_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()) {
-                    if (js_JitOptions.profileInlineFrames) {
-                        // If SPS is enabled, there are two corner cases to handle:
-                        //  1. If resuming into the prologue, and innermost frame is an inlined
-                        //     frame, and bailout is because of argument check failure, then:
-                        //          Top SPS profiler entry would be for caller frame.
-                        //          Ion would not have set the PC index field on that frame
-                        //              (since this bailout happens before MFunctionBoundary).
-                        //          Make sure that's done now.
-                        //  2. If resuming into the prologue, and the bailout is NOT because of an
-                        //     argument check, then:
-                        //          Top SPS profiler entry would be for callee frame.
-                        //          Ion would already have pushed an SPS entry for this frame.
-                        //          The pc for this entry would be set to nullptr.
-                        //          Make sure it's set to script->pc.
-                        if (caller && bailoutKind == Bailout_ArgumentCheck) {
-                            IonSpew(IonSpew_BaselineBailouts, "      Setting PCidx on innermost "
-                                    "inlined frame's parent's SPS entry (%s:%d) (pcIdx=%d)!",
-                                    caller->filename(), caller->lineno(),
-                                    caller->pcToOffset(callerPC));
-                            cx->runtime()->spsProfiler.updatePC(caller, callerPC);
-
-                        } else if (bailoutKind != Bailout_ArgumentCheck) {
-                            IonSpew(IonSpew_BaselineBailouts,
-                                    "      Popping SPS entry for innermost inlined frame");
-                            cx->runtime()->spsProfiler.exit(script, fun);
-                        }
-
-                    } else {
-                        // If not profiling inline frames, then this is logically simpler.
-                        //
-                        // 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) {
-                            IonSpew(IonSpew_BaselineBailouts,
-                                    "      Popping SPS entry for outermost frame");
-                            cx->runtime()->spsProfiler.exit(script, fun);
-                        }
+                    // 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) {
+                        IonSpew(IonSpew_BaselineBailouts,
+                                "      Popping SPS entry for outermost frame");
+                        cx->runtime()->spsProfiler.exit(script, fun);
                     }
                 }
             } else {
                 opReturnAddr = nativeCodeForPC;
             }
             builder.setResumeAddr(opReturnAddr);
             IonSpew(IonSpew_BaselineBailouts, "      Set resumeAddr=%p", opReturnAddr);
         }
@@ -1448,20 +1414,19 @@ jit::BailoutIonToBaseline(JSContext *cx,
         }
 
         frameNo++;
 
         snapIter.nextInstruction();
     }
     IonSpew(IonSpew_BaselineBailouts, "  Done restoring frames");
 
-    // If there were multiple inline frames unpacked, and inline frame profiling
-    // is off, then the current top SPS frame is for the outermost caller, and
-    // has an uninitialized PC.  Initialize it now.
-    if (frameNo > 0 && !js_JitOptions.profileInlineFrames)
+    // 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()) {
         // Set the first frame's formals, see the comment in InitFromBailout.
         Value *argv = builder.startFrame()->argv() + 1; // +1 to skip |this|.
         mozilla::PodCopy(argv, startFrameFormals.begin(), startFrameFormals.length());
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -8048,17 +8048,17 @@ CodeGenerator::visitProfilerStackOp(LPro
 
             sps_.leave(masm, temp, /* inlinedFunction = */ true);
             if (!sps_.enterInlineFrame())
                 return false;
             // fallthrough
 
         case MProfilerStackOp::Enter:
             if (gen->options.spsSlowAssertionsEnabled()) {
-                if (!inlinedFunction || js_JitOptions.profileInlineFrames) {
+                if (!inlinedFunction) {
                     saveLive(lir);
                     pushArg(ImmGCPtr(lir->script()));
                     if (!callVM(SPSEnterInfo, lir))
                         return false;
                     restoreLive(lir);
                 }
                 sps_.pushManual(lir->script(), masm, temp, /* inlinedFunction = */ inlinedFunction);
                 return true;
@@ -8071,17 +8071,17 @@ CodeGenerator::visitProfilerStackOp(LPro
             // maintain the state of inline frames currently active and then
             // reenter the caller
             sps_.leaveInlineFrame();
             sps_.reenter(masm, temp, /* inlinedFunction = */ true);
             return true;
 
         case MProfilerStackOp::Exit:
             if (gen->options.spsSlowAssertionsEnabled()) {
-                if (!inlinedFunction || js_JitOptions.profileInlineFrames) {
+                if (!inlinedFunction) {
                     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();
                     if (!callVM(SPSExitInfo, lir))
                         return false;
--- a/js/src/jit/IonFrames.cpp
+++ b/js/src/jit/IonFrames.cpp
@@ -626,19 +626,18 @@ HandleException(ResumeFromException *rfe
                 // 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();
 
-                // If inline-frames are not profiled, then don't pop an SPS frame
-                // for them.
-                if (frames.more() && !js_JitOptions.profileInlineFrames)
+                // Don't pop an SPS frame for inlined frames, since they are not instrumented.
+                if (frames.more())
                     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);
                 if (!frames.more())
--- a/js/src/jit/JitOptions.cpp
+++ b/js/src/jit/JitOptions.cpp
@@ -105,19 +105,16 @@ JitOptions::JitOptions()
     //
     // The default for this was arrived at empirically via benchmarking.
     // We may want to tune it further after other optimizations have gone
     // in.
     smallFunctionMaxBytecodeLength_ = 100;
 
     // How many uses of a parallel kernel before we attempt compilation.
     usesBeforeCompilePar = 1;
-
-    // Whether to profile inlined functions in Ion or not.
-    profileInlineFrames = false;
 }
 
 bool
 JitOptions::isSmallFunction(JSScript *script) const
 {
     return script->length() <= smallFunctionMaxBytecodeLength_;
 }
 
--- a/js/src/jit/JitOptions.h
+++ b/js/src/jit/JitOptions.h
@@ -64,17 +64,16 @@ struct JitOptions
     bool osr;
     uint32_t baselineUsesBeforeCompile;
     uint32_t exceptionBailoutThreshold;
     uint32_t frequentBailoutThreshold;
     uint32_t maxStackArgs;
     uint32_t osrPcMismatchesBeforeRecompile;
     uint32_t smallFunctionMaxBytecodeLength_;
     uint32_t usesBeforeCompilePar;
-    bool profileInlineFrames;
 
     JitOptions();
     bool isSmallFunction(JSScript *script) const;
     void setEagerCompilation();
     void setUsesBeforeCompile(uint32_t useCount);
     void resetUsesBeforeCompile();
 };
 
--- a/js/src/vm/SPSProfiler.h
+++ b/js/src/vm/SPSProfiler.h
@@ -410,109 +410,94 @@ class SPSInstrumentation
 
     /*
      * 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;
-#ifdef JS_ION
-        if (!inlinedFunction || jit::js_JitOptions.profileInlineFrames) {
-#endif
+        if (!inlinedFunction) {
             const char *string = profiler_->profileString(script, script->functionNonDelazifying());
             if (string == nullptr)
                 return false;
             masm.spsPushFrame(profiler_, string, script, scratch);
-#ifdef JS_ION
         }
-#endif
         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;
 
-#ifdef JS_ION
-        if (!inlinedFunction || jit::js_JitOptions.profileInlineFrames)
-#endif
+        if (!inlinedFunction)
             masm.spsUpdatePCIdx(profiler_, ProfileEntry::NullPCIndex, 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;
-#ifdef JS_ION
             if (!inlinedFunction) {
-                // We may be leaving an inlined frame for entry into a C++
-                // frame.  If profileInlineFrames is turned off, use the top
-                // script's pc offset instead of the innermost script's.
-                if (!jit::js_JitOptions.profileInlineFrames && inliningDepth() > 0) {
+                // 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) {
                     JS_ASSERT(frames[0].pc);
                     updatePC = frames[0].pc;
                     script = frames[0].script;
                 }
             }
-#endif
 
-#ifdef JS_ION
-            if (!inlinedFunction || jit::js_JitOptions.profileInlineFrames)
-#endif
+            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 {
-#ifdef JS_ION
-             if (!inlinedFunction || jit::js_JitOptions.profileInlineFrames)
-#endif
+             if (!inlinedFunction)
                  masm.spsUpdatePCIdx(profiler_, ProfileEntry::NullPCIndex, 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()) {
             JS_ASSERT(frame->left == 0);
             JS_ASSERT(frame->script);
-#ifdef JS_ION
-            if (!inlinedFunction || jit::js_JitOptions.profileInlineFrames)
-#endif
+            if (!inlinedFunction)
                 masm.spsPopFrame(profiler_, scratch);
         }
     }
 };
 
 } /* namespace js */
 
 #endif /* vm_SPSProfiler_h */