Bug 843866: IonMonkey: Make sure inference ran before inlining empty script, r=jandem
authorHannes Verschore <hv1989@gmail.com>
Tue, 26 Feb 2013 11:20:03 +0100
changeset 123002 30b241b25c29ba9cd46a12e1bce21b34049e4a7d
parent 123001 32b80ae899a1108c86ddddde17b1618107625593
child 123003 daf9be11ed489acf65df67a5d5c9f045e3a7eacd
push id1387
push userphilringnalda@gmail.com
push dateTue, 26 Feb 2013 22:32:56 +0000
treeherderfx-team@ad4cc4e97774 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs843866
milestone22.0a1
Bug 843866: IonMonkey: Make sure inference ran before inlining empty script, r=jandem
js/src/ion/IonBuilder.cpp
js/src/ion/TypeOracle.cpp
js/src/jit-test/tests/ion/bug843866.js
--- a/js/src/ion/IonBuilder.cpp
+++ b/js/src/ion/IonBuilder.cpp
@@ -3232,24 +3232,22 @@ IonBuilder::makeInliningDecision(AutoObj
     //  3. Do not inline functions which are not called as frequently as their
     //     callers.
 
     uint32_t callerUses = script()->getUseCount();
 
     uint32_t totalSize = 0;
     uint32_t maxInlineDepth = js_IonOptions.maxInlineDepth;
     bool allFunctionsAreSmall = true;
-    RootedFunction target(cx);
-    RootedScript targetScript(cx);
     for (size_t i = 0; i < targets.length(); i++) {
-        target = targets[i]->toFunction();
+        JSFunction *target = targets[i]->toFunction();
         if (!target->isInterpreted())
             return false;
 
-        targetScript = target->nonLazyScript();
+        JSScript *targetScript = target->nonLazyScript();
         uint32_t calleeUses = targetScript->getUseCount();
 
         totalSize += targetScript->length;
         if (totalSize > js_IonOptions.inlineMaxTotalBytecodeLength)
             return false;
 
         if (targetScript->length > js_IonOptions.smallFunctionMaxBytecodeLength)
             allFunctionsAreSmall = false;
@@ -3276,16 +3274,17 @@ IonBuilder::makeInliningDecision(AutoObj
     if (!oracle->canInlineCall(scriptRoot, pc)) {
         IonSpew(IonSpew_Inlining, "Cannot inline due to uninlineable call site");
         return false;
     }
 
     JSOp op = JSOp(*pc);
     for (size_t i = 0; i < targets.length(); i++) {
         JSFunction *target = targets[i]->toFunction();
+        JSScript *targetScript = target->nonLazyScript();
 
         if (!canInlineTarget(target)) {
             IonSpew(IonSpew_Inlining, "Decided not to inline");
             return false;
         }
 
         // For fun.apply we need to make sure the types of the argument is a subset
         // of the types used in the callee. Because adding a typeset in the callee,
--- a/js/src/ion/TypeOracle.cpp
+++ b/js/src/ion/TypeOracle.cpp
@@ -598,19 +598,21 @@ TypeInferenceOracle::callArgsBarrier(Han
 }
 
 bool
 TypeInferenceOracle::canEnterInlinedFunction(RawScript caller, jsbytecode *pc, RawFunction target)
 {
     AssertCanGC();
     RootedScript targetScript(cx, target->nonLazyScript());
 
-    // Always permit the empty script.
-    if (targetScript->length == 1)
-        return true;
+    // Make sure empty script has type information, to allow inlining in more cases.
+    if (targetScript->length == 1) {
+        if (!targetScript->ensureRanInference(cx))
+            return false;
+    }
 
     if (!targetScript->hasAnalysis() ||
         !targetScript->analysis()->ranInference() ||
         !targetScript->analysis()->ranSSA())
     {
         return false;
     }
 
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug843866.js
@@ -0,0 +1,8 @@
+function g(f) {}
+function f(b) {
+  g.apply(null, arguments);
+
+  if (b < 10)
+    f(b+1);
+}
+f(0);