Use the right JSOP_CALLEE when inlining (bug 842300, r=nbp, a=bbajaj).
authorDavid Anderson <danderson@mozilla.com>
Thu, 07 Mar 2013 08:52:00 -0500
changeset 132378 333a93611b4aabe1ef52ffb5abc72d68d42c0a9c
parent 132377 b37f5b5a758962f7708c360e6fc160d834623f9a
child 132379 a64ef5e8030c528d57b917aa7b1bcbe84d5492ef
push id2323
push userbbajaj@mozilla.com
push dateMon, 01 Apr 2013 19:47:02 +0000
treeherdermozilla-beta@7712be144d91 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp, bbajaj
bugs842300
milestone21.0a2
Use the right JSOP_CALLEE when inlining (bug 842300, r=nbp, a=bbajaj).
js/src/ion/IonBuilder.cpp
js/src/ion/IonBuilder.h
--- a/js/src/ion/IonBuilder.cpp
+++ b/js/src/ion/IonBuilder.cpp
@@ -35,17 +35,17 @@ IonBuilder::IonBuilder(JSContext *cx, Te
     backgroundCodegen_(NULL),
     recompileInfo(cx->compartment->types.compiledInfo),
     cx(cx),
     abortReason_(AbortReason_Disable),
     loopDepth_(loopDepth),
     callerResumePoint_(NULL),
     callerBuilder_(NULL),
     oracle(oracle),
-    inliningDepth(inliningDepth),
+    inliningDepth_(inliningDepth),
     failedBoundsCheck_(info->script()->failedBoundsCheck),
     failedShapeGuard_(info->script()->failedShapeGuard),
     lazyArguments_(NULL)
 {
     script_.init(info->script());
     pc = info->startPC();
 }
 
@@ -425,17 +425,17 @@ IonBuilder::buildInline(IonBuilder *call
 
     // All further instructions generated in from this scope should be
     // considered as part of the function that we're inlining. We also need to
     // keep track of the inlining depth because all scripts inlined on the same
     // level contiguously have only one Inline_Exit node.
     if (instrumentedProfiling())
         predecessor->add(MFunctionBoundary::New(script(),
                                                 MFunctionBoundary::Inline_Enter,
-                                                inliningDepth));
+                                                inliningDepth_));
 
     predecessor->end(MGoto::New(current));
     if (!current->addPredecessorWithoutPhis(predecessor))
         return false;
 
     // Save the actual arguments the caller used to call this inlined call,
     // to shortcut operations on "arguments" in the inlined call.
     JS_ASSERT(inlinedArguments_.length() == 0);
@@ -1026,17 +1026,21 @@ IonBuilder::inspectOpcode(JSOp op)
       case JSOP_NOT:
         return jsop_not();
 
       case JSOP_THIS:
         return jsop_this();
 
       case JSOP_CALLEE:
       {
-        MCallee *callee = MCallee::New();
+        MInstruction *callee;
+        if (inliningDepth_ == 0)
+            callee = MCallee::New();
+        else
+            callee = MConstant::New(ObjectValue(*info().fun()));
         current->add(callee);
         current->push(callee);
         return true;
       }
 
       case JSOP_GETPROP:
       case JSOP_CALLPROP:
       {
@@ -2951,17 +2955,17 @@ IonBuilder::inlineScriptedCall(HandleFun
     MIRGraphExits saveExits;
     AutoAccumulateExits aae(graph(), saveExits);
 
     TypeInferenceOracle oracle;
     if (!oracle.init(cx, calleeScript))
         return false;
 
     IonBuilder inlineBuilder(cx, &temp(), &graph(), &oracle,
-                             info, inliningDepth + 1, loopDepth_);
+                             info, inliningDepth_ + 1, loopDepth_);
 
     // Build the graph.
     if (!inlineBuilder.buildInline(this, resumePoint, callInfo)) {
         JS_ASSERT(calleeScript->hasAnalysis());
 
         // Inlining the callee failed. Disable inlining the function
         if (inlineBuilder.abortReason_ == AbortReason_Disable)
             calleeScript->analysis()->setIonUninlineable();
@@ -3092,17 +3096,17 @@ IonBuilder::jsop_call_inline(HandleFunct
     MIRGraphExits saveExits;
     AutoAccumulateExits aae(graph(), saveExits);
 
     TypeInferenceOracle oracle;
     if (!oracle.init(cx, calleeScript))
         return false;
 
     IonBuilder inlineBuilder(cx, &temp(), &graph(), &oracle,
-                             info, inliningDepth + 1, loopDepth_);
+                             info, inliningDepth_ + 1, loopDepth_);
 
     // Create new |this| on the caller-side for inlined constructors.
     if (callInfo.constructing()) {
         MDefinition *thisDefn = createThis(callee, callInfo.fun());
         if (!thisDefn)
             return false;
         callInfo.setThis(thisDefn);
     }
@@ -3173,17 +3177,17 @@ IonBuilder::makeInliningDecision(AutoObj
         {
             IonSpew(IonSpew_Inlining, "Not inlining, callee is not hot");
             return false;
         }
     }
     if (allFunctionsAreSmall)
         maxInlineDepth = js_IonOptions.smallFunctionMaxInlineDepth;
 
-    if (inliningDepth >= maxInlineDepth)
+    if (inliningDepth_ >= maxInlineDepth)
         return false;
 
     if (script()->getUseCount() < js_IonOptions.usesBeforeInlining()) {
         IonSpew(IonSpew_Inlining, "Not inlining, caller is not hot");
         return false;
     }
 
     RootedScript scriptRoot(cx, script());
@@ -3972,17 +3976,17 @@ IonBuilder::jsop_funapplyarguments(uint3
 
     // Extract call target.
     types::StackTypeSet *funTypes = oracle->getCallArg(script(), argc, 0, pc);
     RootedObject funobj(cx, (funTypes) ? funTypes->getSingleton() : NULL);
     RootedFunction target(cx, (funobj && funobj->isFunction()) ? funobj->toFunction() : NULL);
 
     // When this script isn't inlined, use MApplyArgs,
     // to copy the arguments from the stack and call the function
-    if (inliningDepth == 0) {
+    if (inliningDepth_ == 0) {
 
         // Vp
         MPassArg *passVp = current->pop()->toPassArg();
         passVp->replaceAllUsesWith(passVp->getArgument());
         passVp->block()->discard(passVp);
 
         // This
         MPassArg *passThis = current->pop()->toPassArg();
@@ -4010,17 +4014,17 @@ IonBuilder::jsop_funapplyarguments(uint3
 
         types::StackTypeSet *barrier;
         types::StackTypeSet *types = oracle->returnTypeSet(script(), pc, &barrier);
         return pushTypeBarrier(apply, types, barrier);
     }
 
     // When inlining we have the arguments the function gets called with
     // and can optimize even more, by just calling the functions with the args.
-    JS_ASSERT(inliningDepth > 0);
+    JS_ASSERT(inliningDepth_ > 0);
 
     CallInfo callInfo(cx, false);
 
     // Vp
     MPassArg *passVp = current->pop()->toPassArg();
     passVp->replaceAllUsesWith(passVp->getArgument());
     passVp->block()->discard(passVp);
 
@@ -4872,17 +4876,17 @@ IonBuilder::maybeInsertResume()
 }
 
 void
 IonBuilder::insertRecompileCheck()
 {
     if (!inliningEnabled())
         return;
 
-    if (inliningDepth > 0)
+    if (inliningDepth_ > 0)
         return;
 
     // Don't recompile if we are already inlining.
     if (script()->getUseCount() >= js_IonOptions.usesBeforeInlining())
         return;
 
     // Don't recompile if the oracle cannot provide inlining information
     // or if the script has no calls.
@@ -5879,31 +5883,31 @@ IonBuilder::jsop_arguments()
 bool
 IonBuilder::jsop_arguments_length()
 {
     // Type Inference has guaranteed this is an optimized arguments object.
     MDefinition *args = current->pop();
     args->setFoldedUnchecked();
 
     // We don't know anything from the callee
-    if (inliningDepth == 0) {
+    if (inliningDepth_ == 0) {
         MInstruction *ins = MArgumentsLength::New();
         current->add(ins);
         current->push(ins);
         return true;
     }
 
     // We are inlining and know the number of arguments the callee pushed
     return pushConstant(Int32Value(inlinedArguments_.length()));
 }
 
 bool
 IonBuilder::jsop_arguments_getelem()
 {
-    if (inliningDepth != 0)
+    if (inliningDepth_ != 0)
         return abort("NYI inlined get argument element");
 
     RootedScript scriptRoot(cx, script());
     types::StackTypeSet *barrier = oracle->propertyReadBarrier(scriptRoot, pc);
     types::StackTypeSet *types = oracle->propertyRead(script(), pc);
 
     MDefinition *idx = current->pop();
 
--- a/js/src/ion/IonBuilder.h
+++ b/js/src/ion/IonBuilder.h
@@ -515,17 +515,17 @@ class IonBuilder : public MIRGenerator
 
     Vector<CFGState, 8, IonAllocPolicy> cfgStack_;
     Vector<ControlFlowInfo, 4, IonAllocPolicy> loops_;
     Vector<ControlFlowInfo, 0, IonAllocPolicy> switches_;
     Vector<ControlFlowInfo, 2, IonAllocPolicy> labels_;
     Vector<MInstruction *, 2, IonAllocPolicy> iterators_;
     TypeOracle *oracle;
 
-    size_t inliningDepth;
+    size_t inliningDepth_;
     Vector<MDefinition *, 0, IonAllocPolicy> inlinedArguments_;
 
     // True if script->failedBoundsCheck is set for the current script or
     // an outer script.
     bool failedBoundsCheck_;
 
     // True if script->failedShapeGuard is set for the current script or
     // an outer script.