Bug 798913 - Prevent inlining of overflow of arguments. r=dvander
☠☠ backed out by d9e032542831 ☠ ☠
authorNicolas B. Pierron <nicolas.b.pierron@mozilla.com>
Sun, 07 Oct 2012 20:49:05 -0700
changeset 109611 20899bf876464a1e487e3e8b867e452c740a87db
parent 109610 6c89d2b6ea4bc4b9ce78b4962764156d7c2f717a
child 109612 c9bfb6646f04d7e8d0a9035125ad1c9824b4d493
push id23636
push usergsharp@mozilla.com
push dateMon, 08 Oct 2012 08:08:19 +0000
treeherdermozilla-central@24cf40690042 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdvander
bugs798913
milestone18.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 798913 - Prevent inlining of overflow of arguments. r=dvander
js/src/ion/IonBuilder.cpp
js/src/ion/IonBuilder.h
--- a/js/src/ion/IonBuilder.cpp
+++ b/js/src/ion/IonBuilder.cpp
@@ -2880,17 +2880,17 @@ IonBuilder::jsop_call_inline(HandleFunct
         if (!bottom->addPredecessorWithoutPhis(exitBlock))
             return false;
     }
     JS_ASSERT(!retvalDefns.empty());
     return true;
 }
 
 bool
-IonBuilder::makeInliningDecision(AutoObjectVector &targets)
+IonBuilder::makeInliningDecision(AutoObjectVector &targets, uint32 argc)
 {
     if (inliningDepth >= js_IonOptions.maxInlineDepth)
         return false;
 
     // For "small" functions, we should be more aggressive about inlining.
     // This is based on the following intuition:
     //  1. The call overhead for a small function will likely be a much
     //     higher proportion of the runtime of the function than for larger
@@ -2908,16 +2908,22 @@ IonBuilder::makeInliningDecision(AutoObj
     bool allFunctionsAreSmall = true;
     for (size_t i = 0; i < targets.length(); i++) {
         JSFunction *target = targets[i]->toFunction();
         if (!target->isInterpreted())
             return false;
 
         JSScript *script = target->script();
         uint32_t calleeUses = script->getUseCount();
+
+        if (target->nargs < argc) {
+            IonSpew(IonSpew_Inlining, "Not inlining, overflow of arguments.");
+            return false;
+        }
+
         totalSize += script->length;
         if (totalSize > js_IonOptions.inlineMaxTotalBytecodeLength)
             return false;
 
         if (script->length > js_IonOptions.smallFunctionMaxBytecodeLength)
             allFunctionsAreSmall = false;
 
         if (calleeUses * js_IonOptions.inlineUseCountRatio < callerUses) {
@@ -3705,17 +3711,17 @@ IonBuilder::jsop_call(uint32 argc, bool 
                 return true;
               case InliningStatus_Error:
                 return false;
               case InliningStatus_NotInlined:
                 break;
             }
         }
 
-        if (numTargets > 0 && makeInliningDecision(targets))
+        if (numTargets > 0 && makeInliningDecision(targets, argc))
             return inlineScriptedCall(targets, argc, constructing, types, barrier);
     }
 
     RootedFunction target(cx, NULL);
     if (numTargets == 1)
         target = targets[0]->toFunction();
 
     return makeCallBarrier(target, argc, constructing, types, barrier);
--- a/js/src/ion/IonBuilder.h
+++ b/js/src/ion/IonBuilder.h
@@ -394,17 +394,17 @@ class IonBuilder : public MIRGenerator
 
     InliningStatus inlineNativeCall(JSNative native, uint32 argc, bool constructing);
 
     bool jsop_call_inline(HandleFunction callee, uint32 argc, bool constructing,
                           MConstant *constFun, MBasicBlock *bottom,
                           Vector<MDefinition *, 8, IonAllocPolicy> &retvalDefns);
     bool inlineScriptedCall(AutoObjectVector &targets, uint32 argc, bool constructing,
                             types::StackTypeSet *types, types::StackTypeSet *barrier);
-    bool makeInliningDecision(AutoObjectVector &targets);
+    bool makeInliningDecision(AutoObjectVector &targets, uint32 argc);
 
     MCall *makeCallHelper(HandleFunction target, uint32 argc, bool constructing);
     bool makeCallBarrier(HandleFunction target, uint32 argc, bool constructing,
                          types::StackTypeSet *types, types::StackTypeSet *barrier);
 
     inline bool TestCommonPropFunc(JSContext *cx, types::StackTypeSet *types,
                                    HandleId id, JSFunction **funcp,
                                    bool isGetter, bool *isDOM);