Bug 1467496 - Simplify JSOP_LOOPENTRY handling in IonBuilder. r=bhackett
authorJan de Mooij <jdemooij@mozilla.com>
Mon, 11 Jun 2018 10:17:58 -0700
changeset 422295 c9ee5976668480a59f1d5431f62e64e73ff936bc
parent 422294 63daa6667de73b5847988f6efeb9675ef3a18af9
child 422296 383b08391cb8044547e34378371e0fe4fd97eeaa
child 422309 62ab31ea0ec73e72a1ea9d44c9c4b003813b6724
push id104202
push userjandemooij@gmail.com
push dateMon, 11 Jun 2018 17:18:35 +0000
treeherdermozilla-inbound@c9ee59766684 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbhackett
bugs1467496
milestone62.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 1467496 - Simplify JSOP_LOOPENTRY handling in IonBuilder. r=bhackett
js/src/jit/IonBuilder.cpp
js/src/jit/IonBuilder.h
js/src/jit/IonControlFlow.cpp
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -1630,18 +1630,17 @@ IonBuilder::blockIsOSREntry(const CFGBlo
     }
 
     if (block->stopPc() == block->startPc() && block->stopIns()->isBackEdge()) {
         // An empty block with only a backedge can never be a loop entry.
         return false;
     }
 
     MOZ_ASSERT(*info().osrPc() == JSOP_LOOPENTRY);
-    // Skip over the LOOPENTRY to match.
-    return GetNextPc(info().osrPc()) == entryPc;
+    return info().osrPc() == entryPc;
 }
 
 AbortReasonOr<Ok>
 IonBuilder::visitGoto(CFGGoto* ins)
 {
     // Test if this potentially was a fake loop and create OSR entry if that is
     // the case.
     const CFGBlock* successor = ins->getSuccessor(0);
@@ -1736,27 +1735,28 @@ IonBuilder::visitLoopEntry(CFGLoopEntry*
         return abort(AbortReason::Alloc);
 #endif
 
     MOZ_TRY(analyzeNewLoopTypes(cfgCurrent));
 
     setCurrent(header);
     pc = header->pc();
 
-    initLoopEntry();
-    return Ok();
-}
-
-bool
-IonBuilder::initLoopEntry()
-{
+    return Ok();
+}
+
+AbortReasonOr<Ok>
+IonBuilder::jsop_loopentry()
+{
+    MOZ_ASSERT(*pc == JSOP_LOOPENTRY);
+
     current->add(MInterruptCheck::New(alloc()));
     insertRecompileCheck();
 
-    return true;
+    return Ok();
 }
 
 AbortReasonOr<Ok>
 IonBuilder::visitControlInstruction(CFGControlInstruction* ins, bool* restarted)
 {
     switch (ins->type()) {
       case CFGControlInstruction::Type_Test:
         return visitTest(ins->toTest());
@@ -1804,17 +1804,16 @@ IonBuilder::inspectOpcode(JSOp op)
       case JSOP_RETURN:
       case JSOP_RETRVAL:
       case JSOP_AND:
       case JSOP_OR:
       case JSOP_TRY:
       case JSOP_THROW:
       case JSOP_GOTO:
       case JSOP_CONDSWITCH:
-      case JSOP_LOOPENTRY:
       case JSOP_TABLESWITCH:
       case JSOP_CASE:
       case JSOP_DEFAULT:
         // Control flow opcodes should be handled in the ControlFlowGenerator.
         MOZ_CRASH("Shouldn't encounter this opcode.");
 
       case JSOP_BITNOT:
         return jsop_bitnot();
@@ -2372,17 +2371,20 @@ IonBuilder::inspectOpcode(JSOp op)
         // TODO: Investigate dynamic checks.
         MDefinition* arr = current->peek(-1);
         arr->setImplicitlyUsedUnchecked();
         pushConstant(BooleanValue(false));
         return Ok();
       }
 
       case JSOP_IMPORTMETA:
-          return jsop_importmeta();
+        return jsop_importmeta();
+
+      case JSOP_LOOPENTRY:
+        return jsop_loopentry();
 
       // ===== NOT Yet Implemented =====
       // Read below!
 
       // With
       case JSOP_ENTERWITH:
       case JSOP_LEAVEWITH:
 
@@ -2501,17 +2503,16 @@ IonBuilder::restartLoop(const CFGBlock* 
 
     loopDepth_ = header->loopDepth();
 
     // Don't specializePhis(), as the header has been visited before and the
     // phis have already had their type set.
     setCurrent(header);
     pc = header->pc();
 
-    initLoopEntry();
     return Ok();
 }
 
 AbortReasonOr<Ok>
 IonBuilder::replaceTypeSet(MDefinition* subject, TemporaryTypeSet* type, MTest* test)
 {
     if (type->unknown())
         return Ok();
@@ -6630,17 +6631,18 @@ IonBuilder::newBlockAfter(MBasicBlock* a
     graph().insertBlockAfter(at, block);
     return block;
 }
 
 AbortReasonOr<MBasicBlock*>
 IonBuilder::newOsrPreheader(MBasicBlock* predecessor, jsbytecode* loopEntry,
                             jsbytecode* beforeLoopEntry)
 {
-    MOZ_ASSERT(loopEntry == GetNextPc(info().osrPc()));
+    MOZ_ASSERT(JSOp(*loopEntry) == JSOP_LOOPENTRY);
+    MOZ_ASSERT(loopEntry == info().osrPc());
 
     // Create two blocks: one for the OSR entry with no predecessors, one for
     // the preheader, which has the OSR entry block as a predecessor. The
     // OSR block is always the second block (with id 1).
     MBasicBlock* osrBlock;
     MOZ_TRY_VAR(osrBlock, newBlockAfter(*graph().begin(), predecessor->stackDepth(), loopEntry));
     MBasicBlock* preheader;
     MOZ_TRY_VAR(preheader, newBlock(predecessor, loopEntry));
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -120,17 +120,16 @@ class IonBuilder
     // body has been processed.
     AbortReasonOr<Ok> addOsrValueTypeBarrier(uint32_t slot, MInstruction** def,
                                              MIRType type, TemporaryTypeSet* typeSet);
     AbortReasonOr<Ok> maybeAddOsrTypeBarriers();
 
     // Restarts processing of a loop if the type information at its header was
     // incomplete.
     AbortReasonOr<Ok> restartLoop(const CFGBlock* header);
-    bool initLoopEntry();
 
     // Please see the Big Honkin' Comment about how resume points work in
     // IonBuilder.cpp, near the definition for this function.
     AbortReasonOr<Ok> resume(MInstruction* ins, jsbytecode* pc, MResumePoint::Mode mode);
     AbortReasonOr<Ok> resumeAt(MInstruction* ins, jsbytecode* pc);
     AbortReasonOr<Ok> resumeAfter(MInstruction* ins);
     AbortReasonOr<Ok> maybeInsertResume();
 
@@ -504,16 +503,17 @@ class IonBuilder
     AbortReasonOr<Ok> jsop_funapplyarguments(uint32_t argc);
     AbortReasonOr<Ok> jsop_funapplyarray(uint32_t argc);
     AbortReasonOr<Ok> jsop_spreadcall();
     AbortReasonOr<Ok> jsop_call(uint32_t argc, bool constructing, bool ignoresReturnValue);
     AbortReasonOr<Ok> jsop_eval(uint32_t argc);
     AbortReasonOr<Ok> jsop_label();
     AbortReasonOr<Ok> jsop_andor(JSOp op);
     AbortReasonOr<Ok> jsop_dup2();
+    AbortReasonOr<Ok> jsop_loopentry();
     AbortReasonOr<Ok> jsop_loophead(jsbytecode* pc);
     AbortReasonOr<Ok> jsop_compare(JSOp op);
     AbortReasonOr<Ok> jsop_compare(JSOp op, MDefinition* left, MDefinition* right);
     AbortReasonOr<Ok> getStaticName(bool* emitted, JSObject* staticObject, PropertyName* name,
                                     MDefinition* lexicalCheck = nullptr);
     AbortReasonOr<Ok> loadStaticSlot(JSObject* staticObject, BarrierKind barrier,
                                      TemporaryTypeSet* types, uint32_t slot);
     AbortReasonOr<Ok> setStaticName(JSObject* staticObject, PropertyName* name);
--- a/js/src/jit/IonControlFlow.cpp
+++ b/js/src/jit/IonControlFlow.cpp
@@ -928,17 +928,17 @@ ControlFlowGenerator::processWhileOrForI
 
     // Skip past the JSOP_LOOPHEAD for the body start.
     jsbytecode* loopHead = GetNextPc(pc);
     jsbytecode* bodyStart = GetNextPc(loopHead);
     jsbytecode* bodyEnd = pc + GetJumpOffset(pc);
     jsbytecode* exitpc = GetNextPc(ifne);
     jsbytecode* continuepc = pc;
 
-    CFGBlock* header = CFGBlock::New(alloc(), GetNextPc(loopEntry));
+    CFGBlock* header = CFGBlock::New(alloc(), loopEntry);
 
     CFGLoopEntry* ins = CFGLoopEntry::New(alloc(), header, stackPhiCount);
     if (LoopEntryCanIonOsr(loopEntry))
         ins->setCanOsr();
 
     if (SN_TYPE(sn) == SRC_FOR_IN)
         ins->setIsForIn();
 
@@ -1476,17 +1476,17 @@ ControlFlowGenerator::processForLoop(JSO
     }
     jsbytecode* loopHead = bodyStart;
     MOZ_ASSERT(JSOp(*bodyStart) == JSOP_LOOPHEAD);
     MOZ_ASSERT(ifne + GetJumpOffset(ifne) == bodyStart);
     bodyStart = GetNextPc(bodyStart);
 
     MOZ_ASSERT(JSOp(*loopEntry) == JSOP_LOOPENTRY);
 
-    CFGBlock* header = CFGBlock::New(alloc(), GetNextPc(loopEntry));
+    CFGBlock* header = CFGBlock::New(alloc(), loopEntry);
 
     CFGLoopEntry* ins = CFGLoopEntry::New(alloc(), header, 0);
     if (LoopEntryCanIonOsr(loopEntry))
         ins->setCanOsr();
 
     current->setStopIns(ins);
     current->setStopPc(pc);
 
@@ -1544,17 +1544,17 @@ ControlFlowGenerator::processDoWhileLoop
 
     // Verify that the IFNE goes back to a loophead op.
     jsbytecode* loopHead = GetNextPc(pc);
     MOZ_ASSERT(JSOp(*loopHead) == JSOP_LOOPHEAD);
     MOZ_ASSERT(loopHead == ifne + GetJumpOffset(ifne));
 
     jsbytecode* loopEntry = GetNextPc(loopHead);
 
-    CFGBlock* header = CFGBlock::New(alloc(), GetNextPc(loopEntry));
+    CFGBlock* header = CFGBlock::New(alloc(), loopEntry);
 
     CFGLoopEntry* ins = CFGLoopEntry::New(alloc(), header, 0);
     if (LoopEntryCanIonOsr(loopEntry))
         ins->setCanOsr();
 
     current->setStopIns(ins);
     current->setStopPc(pc);