Bug 1330667: IonMonkey - Create a new constant for every optimized arguments use, r=jandem a=gchang
authorHannes Verschore <hv1989@gmail.com>
Thu, 16 Feb 2017 17:57:22 +0100
changeset 376349 94debbbf7e5a08a93acfac75f2d7436df6d10cbf
parent 376348 9352ff3f0da2997e2174bc9e9142e341b5bfc3c6
child 376350 8d0c434a75426db2555c7e226a1fa38d93940622
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem, gchang
bugs1330667
milestone53.0a2
Bug 1330667: IonMonkey - Create a new constant for every optimized arguments use, r=jandem a=gchang
js/src/jit/IonBuilder.cpp
js/src/jit/IonBuilder.h
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -153,17 +153,19 @@ IonBuilder::IonBuilder(JSContext* analys
     inspector(inspector),
     inliningDepth_(inliningDepth),
     inlinedBytecodeLength_(0),
     numLoopRestarts_(0),
     failedBoundsCheck_(info->script()->failedBoundsCheck()),
     failedShapeGuard_(info->script()->failedShapeGuard()),
     failedLexicalCheck_(info->script()->failedLexicalCheck()),
     nonStringIteration_(false),
-    lazyArguments_(nullptr),
+#ifdef DEBUG
+    hasLazyArguments_(false),
+#endif
     inlineCallInfo_(nullptr),
     maybeFallbackFunctionGetter_(nullptr)
 {
     script_ = info->script();
     scriptHasIonScript_ = script_->hasIonScript();
     pc = info->startPC();
 
     MOZ_ASSERT(script()->hasBaselineScript() == (info->analysisMode() != Analysis_ArgumentsUsage));
@@ -826,21 +828,21 @@ IonBuilder::build()
             continue;
 
         MResumePoint* entryRpCopy = MResumePoint::Copy(alloc(), current->entryResumePoint());
         if (!entryRpCopy)
             return abort(AbortReason::Alloc);
         ins->setResumePoint(entryRpCopy);
     }
 
+#ifdef DEBUG
     // lazyArguments should never be accessed in |argsObjAliasesFormals| scripts.
-    if (info().hasArguments() && !info().argsObjAliasesFormals()) {
-        lazyArguments_ = MConstant::New(alloc(), MagicValue(JS_OPTIMIZED_ARGUMENTS));
-        current->add(lazyArguments_);
-    }
+    if (info().hasArguments() && !info().argsObjAliasesFormals())
+        hasLazyArguments_ = true;
+#endif
 
     insertRecompileCheck();
 
     MOZ_TRY(traverseBytecode());
 
     // Discard unreferenced & pre-allocated resume points.
     replaceMaybeFallbackFunctionGetter(nullptr);
 
@@ -982,20 +984,20 @@ IonBuilder::buildInline(IonBuilder* call
     initLocals();
 
     JitSpew(JitSpew_Inlining, "Inline entry block MResumePoint %p, %u stack slots",
             (void*) current->entryResumePoint(), current->entryResumePoint()->stackDepth());
 
     // +2 for the env chain and |this|, maybe another +1 for arguments object slot.
     MOZ_ASSERT(current->entryResumePoint()->stackDepth() == info().totalSlots());
 
-    if (script_->argumentsHasVarBinding()) {
-        lazyArguments_ = MConstant::New(alloc(), MagicValue(JS_OPTIMIZED_ARGUMENTS));
-        current->add(lazyArguments_);
-    }
+#ifdef DEBUG
+    if (script_->argumentsHasVarBinding())
+        hasLazyArguments_ = true;
+#endif
 
     insertRecompileCheck();
 
     // Initialize the env chain now that all resume points operands are
     // initialized.
     MOZ_TRY(initEnvironmentChain(callInfo.fun()));
 
     MOZ_TRY(traverseBytecode());
@@ -1252,20 +1254,24 @@ IonBuilder::addOsrValueTypeBarrier(uint3
         MConstant* c = MConstant::New(alloc(), UndefinedValue());
         osrBlock->insertBefore(osrBlock->lastIns(), c);
         osrBlock->rewriteSlot(slot, c);
         def = c;
         break;
       }
 
       case MIRType::MagicOptimizedArguments:
-        MOZ_ASSERT(lazyArguments_);
-        osrBlock->rewriteSlot(slot, lazyArguments_);
-        def = lazyArguments_;
+      {
+        MOZ_ASSERT(hasLazyArguments_);
+        MConstant* lazyArg = MConstant::New(alloc(), MagicValue(JS_OPTIMIZED_ARGUMENTS));
+        osrBlock->insertBefore(osrBlock->lastIns(), lazyArg);
+        osrBlock->rewriteSlot(slot, lazyArg);
+        def = lazyArg;
         break;
+      }
 
       default:
         break;
     }
 
     MOZ_ASSERT(def == osrBlock->getSlot(slot));
     return Ok();
 }
@@ -9259,18 +9265,21 @@ IonBuilder::jsop_length_fastPath()
 
 AbortReasonOr<Ok>
 IonBuilder::jsop_arguments()
 {
     if (info().needsArgsObj()) {
         current->push(current->argumentsObject());
         return Ok();
     }
-    MOZ_ASSERT(lazyArguments_);
-    current->push(lazyArguments_);
+
+    MOZ_ASSERT(hasLazyArguments_);
+    MConstant* lazyArg = MConstant::New(alloc(), MagicValue(JS_OPTIMIZED_ARGUMENTS));
+    current->add(lazyArg);
+    current->push(lazyArg);
     return Ok();
 }
 
 AbortReasonOr<Ok>
 IonBuilder::jsop_newtarget()
 {
     if (!info().funMaybeLazy()) {
         MOZ_ASSERT(!info().script()->isForEval());
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -1066,19 +1066,20 @@ class IonBuilder
 
     // True if script->failedLexicalCheck_ is set for the current script or
     // an outer script.
     bool failedLexicalCheck_;
 
     // Has an iterator other than 'for in'.
     bool nonStringIteration_;
 
-    // If this script can use a lazy arguments object, it will be pre-created
-    // here.
-    MInstruction* lazyArguments_;
+#ifdef DEBUG
+    // If this script uses the lazy arguments object.
+    bool hasLazyArguments_;
+#endif
 
     // If this is an inline builder, the call info for the builder.
     const CallInfo* inlineCallInfo_;
 
     // When compiling a call with multiple targets, we are first creating a
     // MGetPropertyCache.  This MGetPropertyCache is following the bytecode, and
     // is used to recover the JSFunction.  In some cases, the Type of the object
     // which own the property is enough for dispatching to the right function.