Bug 1231224 part 2 - Fix MTableSwitch methods to handle OOM. r=h4writer
authorJan de Mooij <jdemooij@mozilla.com>
Thu, 10 Dec 2015 13:22:14 -0500
changeset 310255 a80b9fd6fd19262905118d3d3d839f7d2c499b45
parent 310254 89a198f044bfb22a62ed4b88ee72a009ab9a950f
child 310256 fe63a5b34d53eb3adf3f2fe28e3090a4a8ec9c00
push id5513
push userraliiev@mozilla.com
push dateMon, 25 Jan 2016 13:55:34 +0000
treeherdermozilla-beta@5ee97dd05b5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersh4writer
bugs1231224
milestone45.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 1231224 part 2 - Fix MTableSwitch methods to handle OOM. r=h4writer
js/src/asmjs/WasmIonCompile.cpp
js/src/jit/IonBuilder.cpp
js/src/jit/MIR.h
--- a/js/src/asmjs/WasmIonCompile.cpp
+++ b/js/src/asmjs/WasmIonCompile.cpp
@@ -1124,22 +1124,30 @@ class FunctionCompiler
     }
 
     bool joinSwitch(MBasicBlock* switchBlock, const BlockVector& cases, MBasicBlock* defaultBlock)
     {
         size_t pos = breakableStack_.popCopy();
         if (!switchBlock)
             return true;
         MTableSwitch* mir = switchBlock->lastIns()->toTableSwitch();
-        size_t defaultIndex = mir->addDefault(defaultBlock);
+        size_t defaultIndex;
+        if (!mir->addDefault(defaultBlock, &defaultIndex))
+            return false;
         for (unsigned i = 0; i < cases.length(); i++) {
-            if (!cases[i])
-                mir->addCase(defaultIndex);
-            else
-                mir->addCase(mir->addSuccessor(cases[i]));
+            if (!cases[i]) {
+                if (!mir->addCase(defaultIndex))
+                    return false;
+            } else {
+                size_t caseIndex;
+                if (!mir->addSuccessor(cases[i], &caseIndex))
+                    return false;
+                if (!mir->addCase(caseIndex))
+                    return false;
+            }
         }
         if (curBlock_) {
             MBasicBlock* next;
             if (!newBlock(curBlock_, &next))
                 return false;
             curBlock_->end(MGoto::New(alloc(), next));
             curBlock_ = next;
         }
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -3417,18 +3417,22 @@ IonBuilder::tableSwitch(JSOp op, jssrcno
 
     // Create MIR instruction
     MTableSwitch* tableswitch = MTableSwitch::New(alloc(), ins, low, high);
 
     // Create default case
     MBasicBlock* defaultcase = newBlock(current, defaultpc);
     if (!defaultcase)
         return ControlStatus_Error;
-    tableswitch->addDefault(defaultcase);
-    tableswitch->addBlock(defaultcase);
+
+    if (!tableswitch->addDefault(defaultcase))
+        return ControlStatus_Error;
+
+    if (!tableswitch->addBlock(defaultcase))
+        return ControlStatus_Error;
 
     // Create cases
     jsbytecode* casepc = nullptr;
     for (int i = 0; i < high-low+1; i++) {
         casepc = pc + GET_JUMP_OFFSET(pc2);
 
         MOZ_ASSERT(casepc >= pc && casepc <= exitpc);
         MBasicBlock* caseblock;
@@ -3446,24 +3450,32 @@ IonBuilder::tableSwitch(JSOp op, jssrcno
                 return ControlStatus_Error;
         } else {
             // If this is an actual case (not filled gap),
             // add this block to the list that still needs to get processed.
             caseblock = newBlock(current, casepc);
             if (!caseblock)
                 return ControlStatus_Error;
 
-            tableswitch->addBlock(caseblock);
+            if (!tableswitch->addBlock(caseblock))
+                return ControlStatus_Error;
+
             // Add constant to indicate which case this is for use by
             // processNextTableSwitchCase.
             MConstant* constant = MConstant::New(alloc(), Int32Value(i + low));
             caseblock->add(constant);
         }
 
-        tableswitch->addCase(tableswitch->addSuccessor(caseblock));
+        size_t caseIndex;
+        if (!tableswitch->addSuccessor(caseblock, &caseIndex))
+            return ControlStatus_Error;
+
+        if (!tableswitch->addCase(caseIndex))
+            return ControlStatus_Error;
+
         pc2 += JUMP_OFFSET_LEN;
     }
 
     // Move defaultcase to the end, to maintain RPO.
     graph().moveBlockToEnd(defaultcase);
 
     MOZ_ASSERT(tableswitch->numCases() == (uint32_t)(high - low + 1));
     MOZ_ASSERT(tableswitch->numSuccessors() > 0);
@@ -5879,17 +5891,18 @@ IonBuilder::inlineCalls(CallInfo& callIn
         }
 
         // inlineSingleCall() changed |current| to the inline return block.
         MBasicBlock* inlineReturnBlock = current;
         setCurrent(dispatchBlock);
 
         // Connect the inline path to the returnBlock.
         ObjectGroup* funcGroup = target->isSingleton() ? nullptr : target->group();
-        dispatch->addCase(target, funcGroup, inlineBlock);
+        if (!dispatch->addCase(target, funcGroup, inlineBlock))
+            return false;
 
         MDefinition* retVal = inlineReturnBlock->peek(-1);
         retPhi->addInput(retVal);
         inlineReturnBlock->end(MGoto::New(alloc(), returnBlock));
         if (!returnBlock->addPredecessorWithoutPhis(inlineReturnBlock))
             return false;
     }
 
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -2531,21 +2531,21 @@ class MTableSwitch final
   public:
     INSTRUCTION_HEADER(TableSwitch)
     static MTableSwitch* New(TempAllocator& alloc, MDefinition* ins, int32_t low, int32_t high);
 
     size_t numSuccessors() const override {
         return successors_.length();
     }
 
-    size_t addSuccessor(MBasicBlock* successor) {
+    bool addSuccessor(MBasicBlock* successor, size_t* index) {
         MOZ_ASSERT(successors_.length() < (size_t)(high_ - low_ + 2));
         MOZ_ASSERT(!successors_.empty());
-        successors_.append(successor);
-        return successors_.length() - 1;
+        *index = successors_.length();
+        return successors_.append(successor);
     }
 
     MBasicBlock* getSuccessor(size_t i) const override {
         MOZ_ASSERT(i < numSuccessors());
         return successors_[i];
     }
 
     void replaceSuccessor(size_t i, MBasicBlock* successor) override {
@@ -2576,33 +2576,34 @@ class MTableSwitch final
     MBasicBlock* getCase(size_t i) const {
         return getSuccessor(cases_[i]);
     }
 
     size_t numCases() const {
         return high() - low() + 1;
     }
 
-    size_t addDefault(MBasicBlock* block) {
+    bool addDefault(MBasicBlock* block, size_t* index = nullptr) {
         MOZ_ASSERT(successors_.empty());
-        successors_.append(block);
-        return 0;
-    }
-
-    void addCase(size_t successorIndex) {
-        cases_.append(successorIndex);
+        if (index)
+            *index = 0;
+        return successors_.append(block);
+    }
+
+    bool addCase(size_t successorIndex) {
+        return cases_.append(successorIndex);
     }
 
     MBasicBlock* getBlock(size_t i) const {
         MOZ_ASSERT(i < numBlocks());
         return blocks_[i];
     }
 
-    void addBlock(MBasicBlock* block) {
-        blocks_.append(block);
+    bool addBlock(MBasicBlock* block) {
+        return blocks_.append(block);
     }
 
     MDefinition* getOperand(size_t index) const override {
         MOZ_ASSERT(index == 0);
         return operand_.producer();
     }
 
     size_t numOperands() const override {
@@ -10641,18 +10642,18 @@ class MDispatchInstruction
     MBasicBlock* getSuccessor(size_t i) const final override {
         MOZ_ASSERT(i < numSuccessors());
         if (i == map_.length())
             return fallback_;
         return map_[i].block;
     }
 
   public:
-    void addCase(JSFunction* func, ObjectGroup* funcGroup, MBasicBlock* block) {
-        map_.append(Entry(func, funcGroup, block));
+    bool addCase(JSFunction* func, ObjectGroup* funcGroup, MBasicBlock* block) {
+        return map_.append(Entry(func, funcGroup, block));
     }
     uint32_t numCases() const {
         return map_.length();
     }
     JSFunction* getCase(uint32_t i) const {
         return map_[i].func;
     }
     ObjectGroup* getCaseObjectGroup(uint32_t i) const {