Bug 1278303 part 1 - Prevent uses of TempObject new operator on MIR Instructions. r=jandem
authorNicolas B. Pierron <nicolas.b.pierron@mozilla.com>
Wed, 15 Jun 2016 16:27:18 +0000
changeset 301892 9ec710e102b1a5986483d62d598ad45811509b34
parent 301891 c1c123367921d263a301fad9d53c10cd1570c38f
child 301893 b2d1cf0313a3fd2af377bf6e31829636b9257bcd
push id78493
push usernpierron@mozilla.com
push dateWed, 15 Jun 2016 16:28:34 +0000
treeherdermozilla-inbound@87f37f6cde59 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1278303
milestone50.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 1278303 part 1 - Prevent uses of TempObject new operator on MIR Instructions. r=jandem
js/src/jit/LoopUnroller.cpp
js/src/jit/MIR.h
--- a/js/src/jit/LoopUnroller.cpp
+++ b/js/src/jit/LoopUnroller.cpp
@@ -66,17 +66,17 @@ LoopUnroller::getReplacementDefinition(M
 
     DefinitionMap::Ptr p = unrolledDefinitions.lookup(def);
     if (!p) {
         // After phi analysis (TypeAnalyzer::replaceRedundantPhi) the resume
         // point at the start of a block can contain definitions from within
         // the block itself.
         MOZ_ASSERT(def->isConstant());
 
-        MConstant* constant = new(alloc) MConstant(*def->toConstant());
+        MConstant* constant = MConstant::Copy(alloc, def->toConstant());
         oldPreheader->insertBefore(*oldPreheader->begin(), constant);
         return constant;
     }
 
     return p->value();
 }
 
 bool
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -1014,16 +1014,27 @@ class MUseDefIterator
 // An instruction is an SSA name that is inserted into a basic block's IR
 // stream.
 class MInstruction
   : public MDefinition,
     public InlineListNode<MInstruction>
 {
     MResumePoint* resumePoint_;
 
+  protected:
+    // All MInstructions are using the "MFoo::New(alloc)" notation instead of
+    // the TempObject new operator. This code redefines the new operator as
+    // protected, and delegates to the TempObject new operator. Thus, the
+    // following code prevents calls to "new(alloc) MFoo" outside the MFoo
+    // members.
+    template <typename... Args>
+    inline void* operator new(size_t nbytes, Args&&... args) {
+        return TempObject::operator new(nbytes, mozilla::Forward<Args>(args)...);
+    }
+
   public:
     MInstruction()
       : resumePoint_(nullptr)
     { }
 
     // Copying an instruction leaves the block and resume point as empty.
     explicit MInstruction(const MInstruction& other)
       : MDefinition(other),
@@ -1442,16 +1453,19 @@ class MConstant : public MNullaryInstruc
   public:
     INSTRUCTION_HEADER(Constant)
     static MConstant* New(TempAllocator& alloc, const Value& v,
                           CompilerConstraintList* constraints = nullptr);
     static MConstant* NewFloat32(TempAllocator& alloc, double d);
     static MConstant* NewInt64(TempAllocator& alloc, int64_t i);
     static MConstant* NewAsmJS(TempAllocator& alloc, const Value& v, MIRType type);
     static MConstant* NewConstraintlessObject(TempAllocator& alloc, JSObject* v);
+    static MConstant* Copy(TempAllocator& alloc, MConstant* src) {
+        return new(alloc) MConstant(*src);
+    }
 
     // Try to convert this constant to boolean, similar to js::ToBoolean.
     // Returns false if the type is MIRType::Magic*.
     bool MOZ_MUST_USE valueToBoolean(bool* res) const;
 
     // Like valueToBoolean, but returns the result directly instead of using
     // an outparam. Should not be used if this constant might be a magic value.
     bool valueToBooleanInfallible() const {