Bug 1257929 - Add assertions to ensure the safety of entry resume point encoding. r=h4writer
☠☠ backed out by dc60c84a3b2f ☠ ☠
authorNicolas B. Pierron <nicolas.b.pierron@mozilla.com>
Wed, 23 Mar 2016 18:03:11 +0000
changeset 290102 af93bc1552675378ff475ac05466089cc5d596fd
parent 290101 1cbb64847cc9d25d24da267fd3e3a56dd35552b4
child 290103 f379f47e538f513291318b14ab6f21d4142c3a55
push id30114
push usercbook@mozilla.com
push dateThu, 24 Mar 2016 15:15:54 +0000
treeherdermozilla-central@24c5fbde4488 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersh4writer
bugs1257929
milestone48.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 1257929 - Add assertions to ensure the safety of entry resume point encoding. r=h4writer
js/src/jit/IonAnalysis.cpp
js/src/jit/MIRGraph.cpp
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -2260,16 +2260,42 @@ CheckUse(const MDefinition* producer, co
     fprintf(stderr, "==Check Use\n");
     use->producer()->dump(stderr);
     fprintf(stderr, "  index: %" PRIuSIZE "\n", use->consumer()->indexOf(use));
     use->consumer()->dump(stderr);
     fprintf(stderr, "==End\n");
 #endif
     ++*usesBalance;
 }
+
+// To properly encode entry resume points, we have to ensure that all the
+// operands of the entry resume point are located before the safeInsertTop
+// location.
+static void
+AssertOperandsBeforeSafeInsertTop(MResumePoint* resume)
+{
+    MBasicBlock* block = resume->block();
+    if (block == block->graph().osrBlock())
+        return;
+    MInstruction* stop = block->safeInsertTop();
+    for (size_t i = 0, e = resume->numOperands(); i < e; ++i) {
+        MDefinition* def = resume->getOperand(i);
+        if (def->block() != block)
+            continue;
+        if (def->isPhi())
+            continue;
+
+        for (MInstructionIterator ins = block->begin(); true; ins++) {
+            if (*ins == def)
+                break;
+            MOZ_ASSERT(*ins != stop,
+                       "Resume point operand located after the safeInsertTop location");
+        }
+    }
+}
 #endif // DEBUG
 
 void
 jit::AssertBasicGraphCoherency(MIRGraph& graph)
 {
 #ifdef DEBUG
     MOZ_ASSERT(graph.entryBlock()->numPredecessors() == 0);
     MOZ_ASSERT(graph.entryBlock()->phisEmpty());
@@ -2297,23 +2323,24 @@ jit::AssertBasicGraphCoherency(MIRGraph&
                       block->entryResumePoint() != nullptr);
 
         for (size_t i = 0; i < block->numSuccessors(); i++)
             MOZ_ASSERT(CheckSuccessorImpliesPredecessor(*block, block->getSuccessor(i)));
 
         for (size_t i = 0; i < block->numPredecessors(); i++)
             MOZ_ASSERT(CheckPredecessorImpliesSuccessor(*block, block->getPredecessor(i)));
 
-        if (block->entryResumePoint()) {
-            MOZ_ASSERT(!block->entryResumePoint()->instruction());
-            MOZ_ASSERT(block->entryResumePoint()->block() == *block);
+        if (MResumePoint* resume = block->entryResumePoint()) {
+            MOZ_ASSERT(!resume->instruction());
+            MOZ_ASSERT(resume->block() == *block);
+            AssertOperandsBeforeSafeInsertTop(resume);
         }
-        if (block->outerResumePoint()) {
-            MOZ_ASSERT(!block->outerResumePoint()->instruction());
-            MOZ_ASSERT(block->outerResumePoint()->block() == *block);
+        if (MResumePoint* resume = block->outerResumePoint()) {
+            MOZ_ASSERT(!resume->instruction());
+            MOZ_ASSERT(resume->block() == *block);
         }
         for (MResumePointIterator iter(block->resumePointsBegin()); iter != block->resumePointsEnd(); iter++) {
             // We cannot yet assert that is there is no instruction then this is
             // the entry resume point because we are still storing resume points
             // in the InlinePropertyTable.
             MOZ_ASSERT_IF(iter->instruction(), iter->instruction()->block() == *block);
             for (uint32_t i = 0, e = iter->numOperands(); i < e; i++)
                 CheckOperand(*iter, iter->getUseFor(i), &usesBalance);
--- a/js/src/jit/MIRGraph.cpp
+++ b/js/src/jit/MIRGraph.cpp
@@ -907,25 +907,29 @@ MBasicBlock::moveBefore(MInstruction* at
     ins->setBlock(at->block());
     at->block()->instructions_.insertBefore(at, ins);
     ins->setTrackedSite(at->trackedSite());
 }
 
 MInstruction*
 MBasicBlock::safeInsertTop(MDefinition* ins, IgnoreTop ignore)
 {
+    MOZ_ASSERT(graph().osrBlock() != this,
+               "We are not supposed to add any instruction in OSR blocks.");
+
     // Beta nodes and interrupt checks are required to be located at the
     // beginnings of basic blocks, so we must insert new instructions after any
     // such instructions.
     MInstructionIterator insertIter = !ins || ins->isPhi()
                                     ? begin()
                                     : begin(ins->toInstruction());
     while (insertIter->isBeta() ||
            insertIter->isInterruptCheck() ||
            insertIter->isConstant() ||
+           insertIter->isParameter() ||
            (!(ignore & IgnoreRecover) && insertIter->isRecoveredOnBailout()))
     {
         insertIter++;
     }
 
     return *insertIter;
 }