Bug 1234280 - Handle oom in CodeGeneratorShared::allocateData. r=jandem, a=sledru
☠☠ backed out by e8a90620c0d4 ☠ ☠
authorBenjamin Bouvier <benj@benj.me>
Thu, 24 Dec 2015 09:51:30 +0100
changeset 305997 486e6901c1d903047b9b55a1ca59978f07ac6cef
parent 305996 906fc0cacd8dda27c68cbd514daf3700df32855a
child 305998 e03e0c167f4732373d1ce5569d38065c19aa5f98
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem, sledru
bugs1234280
milestone44.0
Bug 1234280 - Handle oom in CodeGeneratorShared::allocateData. r=jandem, a=sledru
js/src/jit/CodeGenerator.cpp
js/src/jit/shared/CodeGenerator-shared.cpp
js/src/jit/shared/CodeGenerator-shared.h
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -8534,17 +8534,19 @@ const VMFunction GetPropertyIC::UpdateIn
 void
 CodeGenerator::visitGetPropertyIC(OutOfLineUpdateCache* ool, DataPtr<GetPropertyIC>& ic)
 {
     LInstruction* lir = ool->lir();
 
     if (ic->idempotent()) {
         size_t numLocs;
         CacheLocationList& cacheLocs = lir->mirRaw()->toGetPropertyCache()->location();
-        size_t locationBase = addCacheLocations(cacheLocs, &numLocs);
+        size_t locationBase;
+        if (!addCacheLocations(cacheLocs, &numLocs, &locationBase))
+            return;
         ic->setLocationInfo(locationBase, numLocs);
     }
 
     saveLive(lir);
 
     pushArg(ic->id());
     pushArg(ic->object());
     pushArg(Imm32(ool->getCacheIndex()));
--- a/js/src/jit/shared/CodeGenerator-shared.cpp
+++ b/js/src/jit/shared/CodeGenerator-shared.cpp
@@ -1614,31 +1614,34 @@ CodeGeneratorShared::jumpToBlock(MBasicB
 
         masm.propagateOOM(patchableBackedges_.append(PatchableBackedgeInfo(backedge, mir->lir()->label(), oolEntry)));
     } else {
         masm.j(cond, mir->lir()->label());
     }
 }
 #endif
 
-size_t
-CodeGeneratorShared::addCacheLocations(const CacheLocationList& locs, size_t* numLocs)
+MOZ_WARN_UNUSED_RESULT bool
+CodeGeneratorShared::addCacheLocations(const CacheLocationList& locs, size_t* numLocs,
+                                       size_t* curIndex)
 {
     size_t firstIndex = runtimeData_.length();
     size_t numLocations = 0;
     for (CacheLocationList::iterator iter = locs.begin(); iter != locs.end(); iter++) {
         // allocateData() ensures that sizeof(CacheLocation) is word-aligned.
         // If this changes, we will need to pad to ensure alignment.
-        size_t curIndex = allocateData(sizeof(CacheLocation));
-        new (&runtimeData_[curIndex]) CacheLocation(iter->pc, iter->script);
+        if (!allocateData(sizeof(CacheLocation), curIndex))
+            return false;
+        new (&runtimeData_[*curIndex]) CacheLocation(iter->pc, iter->script);
         numLocations++;
     }
     MOZ_ASSERT(numLocations != 0);
     *numLocs = numLocations;
-    return firstIndex;
+    *curIndex = firstIndex;
+    return true;
 }
 
 ReciprocalMulConstants
 CodeGeneratorShared::computeDivisionConstants(uint32_t d, int maxLog) {
     MOZ_ASSERT(maxLog >= 2 && maxLog <= 32);
     // In what follows, 0 < d < 2^maxLog and d is not a power of 2.
     MOZ_ASSERT(d < (uint64_t(1) << maxLog) && (d & (d - 1)) != 0);
 
--- a/js/src/jit/shared/CodeGenerator-shared.h
+++ b/js/src/jit/shared/CodeGenerator-shared.h
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jit_shared_CodeGenerator_shared_h
 #define jit_shared_CodeGenerator_shared_h
 
 #include "mozilla/Alignment.h"
 #include "mozilla/Move.h"
+#include "mozilla/TypeTraits.h"
 
 #include "jit/JitFrames.h"
 #include "jit/LIR.h"
 #include "jit/MacroAssembler.h"
 #include "jit/MIRGenerator.h"
 #include "jit/MIRGraph.h"
 #include "jit/OptimizationTracking.h"
 #include "jit/Safepoints.h"
@@ -213,25 +214,16 @@ class CodeGeneratorShared : public LElem
         return frameClass_ == FrameSizeClass::None() ? frameDepth_ : frameClass_.frameSize();
     }
 
     inline Operand ToOperand(const LAllocation& a);
     inline Operand ToOperand(const LAllocation* a);
     inline Operand ToOperand(const LDefinition* def);
 
   protected:
-    // Ensure the cache is an IonCache while expecting the size of the derived
-    // class. We only need the cache list at GC time. Everyone else can just take
-    // runtimeData offsets.
-    size_t allocateCache(const IonCache&, size_t size) {
-        size_t dataOffset = allocateData(size);
-        masm.propagateOOM(cacheList_.append(dataOffset));
-        return dataOffset;
-    }
-
 #ifdef CHECK_OSIPOINT_REGISTERS
     void resetOsiPointRegs(LSafepoint* safepoint);
     bool shouldVerifyOsiPointRegs(LSafepoint* safepoint);
     void verifyOsiPointRegs(LSafepoint* safepoint);
 #endif
 
     bool addNativeToBytecodeEntry(const BytecodeSite* site);
     void dumpNativeToBytecodeEntries();
@@ -266,27 +258,33 @@ class CodeGeneratorShared : public LElem
             return lookup();
         }
         T * operator*() {
             return lookup();
         }
     };
 
   protected:
-
-    size_t allocateData(size_t size) {
+    MOZ_WARN_UNUSED_RESULT
+    bool allocateData(size_t size, size_t* offset) {
         MOZ_ASSERT(size % sizeof(void*) == 0);
-        size_t dataOffset = runtimeData_.length();
+        *offset = runtimeData_.length();
         masm.propagateOOM(runtimeData_.appendN(0, size));
-        return dataOffset;
+        return !masm.oom();
     }
 
+    // Ensure the cache is an IonCache while expecting the size of the derived
+    // class. We only need the cache list at GC time. Everyone else can just take
+    // runtimeData offsets.
     template <typename T>
     inline size_t allocateCache(const T& cache) {
-        size_t index = allocateCache(cache, sizeof(mozilla::AlignedStorage2<T>));
+        static_assert(mozilla::IsBaseOf<IonCache, T>::value, "T must inherit from IonCache");
+        size_t index;
+        masm.propagateOOM(allocateData(sizeof(mozilla::AlignedStorage2<T>), &index));
+        masm.propagateOOM(cacheList_.append(index));
         if (masm.oom())
             return SIZE_MAX;
         // Use the copy constructor on the allocated space.
         MOZ_ASSERT(index == cacheList_.back());
         new (&runtimeData_[index]) T(cache);
         return index;
     }
 
@@ -446,17 +444,17 @@ class CodeGeneratorShared : public LElem
 
     void callVM(const VMFunction& f, LInstruction* ins, const Register* dynStack = nullptr);
 
     template <class ArgSeq, class StoreOutputTo>
     inline OutOfLineCode* oolCallVM(const VMFunction& fun, LInstruction* ins, const ArgSeq& args,
                                     const StoreOutputTo& out);
 
     void addCache(LInstruction* lir, size_t cacheIndex);
-    size_t addCacheLocations(const CacheLocationList& locs, size_t* numLocs);
+    bool addCacheLocations(const CacheLocationList& locs, size_t* numLocs, size_t* offset);
     ReciprocalMulConstants computeDivisionConstants(uint32_t d, int maxLog);
 
   protected:
     bool generatePrologue();
     bool generateEpilogue();
 
     void addOutOfLineCode(OutOfLineCode* code, const MInstruction* mir);
     void addOutOfLineCode(OutOfLineCode* code, const BytecodeSite* site);