Bug 897866 - Move types::IsInlinableCall() to Ion.h as ion::IsIonInlinablePC() (r=h4writer)
authorEric Faust <efaustbmo@gmail.com>
Thu, 25 Jul 2013 03:49:32 -0700
changeset 139930 d0282b81e0cc15e33595ca442e172034e4963ba3
parent 139929 852cd603e5e0670e6058dfeb6f86d0fe62b1c395
child 139931 fb1a587df374450b5167efd1aad1e28384f975fb
push id25006
push useremorley@mozilla.com
push dateThu, 25 Jul 2013 15:31:33 +0000
treeherdermozilla-central@2e27eaf8ebc2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersh4writer
bugs897866
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 897866 - Move types::IsInlinableCall() to Ion.h as ion::IsIonInlinablePC() (r=h4writer)
js/src/ion/BaselineBailouts.cpp
js/src/ion/Ion.h
js/src/ion/IonBuilder.cpp
js/src/ion/IonFrames.cpp
js/src/jsinferinlines.h
--- a/js/src/ion/BaselineBailouts.cpp
+++ b/js/src/ion/BaselineBailouts.cpp
@@ -1002,17 +1002,17 @@ InitFromBailout(JSContext *cx, HandleScr
 
     // Write previous frame pointer (saved earlier).
     if (!builder.writePtr(prevFramePtr, "PrevFramePtr"))
         return false;
     prevFramePtr = builder.virtualPointerAtStackOffset(0);
 
     // Write out actual arguments (and thisv), copied from unpacked stack of BaselineJS frame.
     // Arguments are reversed on the BaselineJS frame's stack values.
-    JS_ASSERT(isCall || IsGetterPC(pc) || IsSetterPC(pc));
+    JS_ASSERT(IsIonInlinablePC(pc));
     unsigned actualArgc;
     if (needToSaveArgs) {
         // For FUNAPPLY or an accessor, the arguments are not on the stack anymore,
         // but they are copied in a vector and are written here.
         if (op == JSOP_FUNAPPLY)
             actualArgc = blFrame->numActualArgs();
         else
             actualArgc = IsSetterPC(pc);
--- a/js/src/ion/Ion.h
+++ b/js/src/ion/Ion.h
@@ -341,16 +341,24 @@ void FinishOffThreadBuilder(IonBuilder *
 static inline bool
 IsEnabled(JSContext *cx)
 {
     return cx->hasOption(JSOPTION_ION) &&
         cx->hasOption(JSOPTION_BASELINE) &&
         cx->typeInferenceEnabled();
 }
 
+inline bool
+IsIonInlinablePC(jsbytecode *pc) {
+    // CALL, FUNCALL, FUNAPPLY, EVAL, NEW (JOF_INVOKE callsites)
+    // GETPROP, CALLPROP, and LENGTH. (Inlined Getters)
+    // SETPROP, SETNAME, SETGNAME (Inlined Setters)
+    return js_CodeSpec[*pc].format & JOF_INVOKE || IsGetterPC(pc) || IsSetterPC(pc);
+}
+
 void ForbidCompilation(JSContext *cx, JSScript *script);
 void ForbidCompilation(JSContext *cx, JSScript *script, ExecutionMode mode);
 uint32_t UsesBeforeIonRecompile(JSScript *script, jsbytecode *pc);
 
 void PurgeCaches(JSScript *script, JS::Zone *zone);
 size_t SizeOfIonData(JSScript *script, mozilla::MallocSizeOf mallocSizeOf);
 void DestroyIonScripts(FreeOp *fop, JSScript *script);
 void TraceIonScripts(JSTracer* trc, JSScript *script);
--- a/js/src/ion/IonBuilder.cpp
+++ b/js/src/ion/IonBuilder.cpp
@@ -3424,17 +3424,17 @@ class AutoAccumulateExits
         graph_.setExitAccumulator(prev_);
     }
 };
 
 bool
 IonBuilder::inlineScriptedCall(CallInfo &callInfo, JSFunction *target)
 {
     JS_ASSERT(target->isInterpreted());
-    JS_ASSERT(types::IsInlinableCall(pc));
+    JS_ASSERT(IsIonInlinablePC(pc));
 
     // Remove any MPassArgs.
     if (callInfo.isWrapped())
         callInfo.unwrapArgs();
 
     // Ensure sufficient space in the slots: needed for inlining from FUNAPPLY.
     uint32_t depth = current->stackDepth() + callInfo.numFormals();
     if (depth > current->nslots()) {
@@ -4090,17 +4090,17 @@ IonBuilder::inlineTypeObjectFallback(Cal
 }
 
 bool
 IonBuilder::inlineCalls(CallInfo &callInfo, AutoObjectVector &targets,
                         AutoObjectVector &originals, Vector<bool> &choiceSet,
                         MGetPropertyCache *maybeCache)
 {
     // Only handle polymorphic inlining.
-    JS_ASSERT(types::IsInlinableCall(pc));
+    JS_ASSERT(IsIonInlinablePC(pc));
     JS_ASSERT(choiceSet.length() == targets.length());
     JS_ASSERT_IF(!maybeCache, targets.length() >= 2);
     JS_ASSERT_IF(maybeCache, targets.length() >= 1);
 
     MBasicBlock *dispatchBlock = current;
 
     // Unwrap the arguments.
     JS_ASSERT(callInfo.isWrapped());
--- a/js/src/ion/IonFrames.cpp
+++ b/js/src/ion/IonFrames.cpp
@@ -1308,18 +1308,17 @@ InlineFrameIteratorMaybeGC<allowGC>::fin
 #ifdef DEBUG
     numActualArgs_ = 0xbadbad;
 #endif
 
     // This unfortunately is O(n*m), because we must skip over outer frames
     // before reading inner ones.
     unsigned remaining = start_.frameCount() - framesRead_ - 1;
     for (unsigned i = 0; i < remaining; i++) {
-        JS_ASSERT(js_CodeSpec[*pc_].format & JOF_INVOKE ||
-                  IsGetterPC(pc_) || IsSetterPC(pc_));
+        JS_ASSERT(IsIonInlinablePC(pc_));
 
         // Recover the number of actual arguments from the script.
         if (JSOp(*pc_) != JSOP_FUNAPPLY)
             numActualArgs_ = GET_ARGC(pc_);
         if (JSOp(*pc_) == JSOP_FUNCALL) {
             JS_ASSERT(GET_ARGC(pc_) > 0);
             numActualArgs_ = GET_ARGC(pc_) - 1;
         } else if (IsGetterPC(pc_)) {
--- a/js/src/jsinferinlines.h
+++ b/js/src/jsinferinlines.h
@@ -296,34 +296,16 @@ TypeIdString(jsid id)
 {
 #ifdef DEBUG
     return TypeIdStringImpl(id);
 #else
     return "(missing)";
 #endif
 }
 
-/* Assert code to know which PCs are reasonable to be considering inlining on. */
-inline bool
-IsInlinableCall(jsbytecode *pc)
-{
-    JSOp op = JSOp(*pc);
-
-    // CALL, FUNCALL, FUNAPPLY, EVAL (Standard callsites)
-    // NEW (IonMonkey-only callsite)
-    // GETPROP, CALLPROP, and LENGTH. (Inlined Getters)
-    // SETPROP, SETNAME, SETGNAME (Inlined Setters)
-    return op == JSOP_CALL || op == JSOP_FUNCALL || op == JSOP_FUNAPPLY || op == JSOP_EVAL ||
-#ifdef JS_ION
-           op == JSOP_NEW ||
-#endif
-           op == JSOP_GETPROP || op == JSOP_CALLPROP || op == JSOP_LENGTH ||
-           op == JSOP_SETPROP || op == JSOP_SETGNAME || op == JSOP_SETNAME;
-}
-
 /*
  * Structure for type inference entry point functions. All functions which can
  * change type information must use this, and functions which depend on
  * intermediate types (i.e. JITs) can use this to ensure that intermediate
  * information is not collected and does not change.
  *
  * Pins inference results so that intermediate type information, TypeObjects
  * and JSScripts won't be collected during GC. Does additional sanity checking