Bug 937540 part 10 - Use placement new syntax for PendingMove. r=luke
authorJan de Mooij <jdemooij@mozilla.com>
Fri, 06 Dec 2013 19:31:57 +0100
changeset 174956 2f8a83944e7149d76b94c7bfa85c3495bf9a5097
parent 174955 60e84998a0a2aebe31cae479c8f079547cc72c61
child 174957 1ba23d5502e130bd79f124412dede38be9ce86df
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs937540
milestone28.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 937540 part 10 - Use placement new syntax for PendingMove. r=luke
js/src/jit/AsmJS.cpp
js/src/jit/IonAllocPolicy.h
js/src/jit/IonMacroAssembler.h
js/src/jit/MoveResolver.h
--- a/js/src/jit/AsmJS.cpp
+++ b/js/src/jit/AsmJS.cpp
@@ -4976,16 +4976,23 @@ CheckFunction(ModuleCompiler &m, LifoAll
     return true;
 }
 
 static bool
 GenerateCode(ModuleCompiler &m, ModuleCompiler::Func &func, MIRGenerator &mir, LIRGraph &lir)
 {
     int64_t before = PRMJ_Now();
 
+    // A single MacroAssembler is reused for all function compilations so
+    // that there is a single linear code segment for each module. To avoid
+    // spiking memory, a LifoAllocScope in the caller frees all MIR/LIR
+    // after each function is compiled. This method is responsible for cleaning
+    // out any dangling pointers that the MacroAssembler may have kept.
+    m.masm().resetForNewCodeGenerator(mir.alloc());
+
     m.masm().bind(func.code());
 
     ScopedJSDeletePtr<CodeGenerator> codegen(jit::GenerateCode(&mir, &lir, &m.masm()));
     if (!codegen)
         return m.fail(nullptr, "internal codegen failure (probably out of memory)");
 
     if (!m.collectAccesses(mir))
         return false;
@@ -5006,23 +5013,16 @@ GenerateCode(ModuleCompiler &m, ModuleCo
         if (!m.trackPerfProfiledBlocks(mir.perfSpewer(), func, m.masm().size()))
             return false;
     } else if (PerfFuncEnabled()) {
         if (!m.trackPerfProfiledFunction(func, m.masm().size()))
             return false;
     }
 #endif
 
-    // A single MacroAssembler is reused for all function compilations so
-    // that there is a single linear code segment for each module. To avoid
-    // spiking memory, a LifoAllocScope in the caller frees all MIR/LIR
-    // after each function is compiled. This method is responsible for cleaning
-    // out any dangling pointers that the MacroAssembler may have kept.
-    m.masm().resetForNewCodeGenerator();
-
     // Align internal function headers.
     m.masm().align(CodeAlignment);
 
     func.accumulateCompileTime((PRMJ_Now() - before) / PRMJ_USEC_PER_MSEC);
     if (!m.maybeReportCompileTime(func))
         return false;
 
     // Unlike regular IonMonkey which links and generates a new IonCode for
@@ -6397,16 +6397,18 @@ static bool
 FinishModule(ModuleCompiler &m,
              ScopedJSDeletePtr<AsmJSModule> *module,
              AsmJSStaticLinkData *linkData)
 {
     LifoAlloc lifo(LIFO_ALLOC_PRIMARY_CHUNK_SIZE);
     TempAllocator alloc(&lifo);
     IonContext ionContext(m.cx(), &alloc);
 
+    m.masm().resetForNewCodeGenerator(alloc);
+
     if (!GenerateStubs(m))
         return false;
 
     return m.extractModule(module, linkData);
 }
 
 static bool
 CheckModule(ExclusiveContext *cx, AsmJSParser &parser, ParseNode *stmtList,
--- a/js/src/jit/IonAllocPolicy.h
+++ b/js/src/jit/IonAllocPolicy.h
@@ -171,37 +171,34 @@ struct TempObject
     template <class T>
     inline void *operator new(size_t nbytes, T *pos) {
         static_assert(mozilla::IsConvertible<T*, TempObject*>::value,
                       "Placement new argument type must inherit from TempObject");
         return pos;
     }
 };
 
-// Deprecated, don't use for (new) classes. Will be removed when all classes have
-// been converted to placement new/TempObject (bug 937540).
-struct OldTempObject
-  : public TempObject
-{
-    using TempObject::operator new;
-
-    inline void *operator new(size_t nbytes) {
-        return GetIonContext()->temp->allocateInfallible(nbytes);
-    }
-};
-
 template <typename T>
 class TempObjectPool
 {
+    TempAllocator *alloc_;
     InlineForwardList<T> freed_;
 
   public:
+    TempObjectPool()
+      : alloc_(nullptr)
+    {}
+    void setAllocator(TempAllocator &alloc) {
+        JS_ASSERT(freed_.empty());
+        alloc_ = &alloc;
+    }
     T *allocate() {
+        JS_ASSERT(alloc_);
         if (freed_.empty())
-            return new T();
+            return new(*alloc_) T();
         return freed_.popFront();
     }
     void free(T *obj) {
         freed_.pushFront(obj);
     }
     void clear() {
         freed_.clear();
     }
--- a/js/src/jit/IonMacroAssembler.h
+++ b/js/src/jit/IonMacroAssembler.h
@@ -188,41 +188,44 @@ class MacroAssembler : public MacroAssem
     // If instrumentation should be emitted, then the sps parameter should be
     // provided, but otherwise it can be safely omitted to prevent all
     // instrumentation from being emitted.
     MacroAssembler()
       : enoughMemory_(true),
         embedsNurseryPointers_(false),
         sps_(nullptr)
     {
-        JSContext *cx = GetIonContext()->cx;
+        IonContext *icx = GetIonContext();
+        JSContext *cx = icx->cx;
         if (cx)
             constructRoot(cx);
 
-        if (!GetIonContext()->temp) {
+        if (!icx->temp) {
             JS_ASSERT(cx);
             alloc_.construct(cx);
         }
 
+        moveResolver_.setAllocator(*icx->temp);
 #ifdef JS_CPU_ARM
         initWithAllocator();
-        m_buffer.id = GetIonContext()->getNextAssemblerId();
+        m_buffer.id = icx->getNextAssemblerId();
 #endif
     }
 
     // This constructor should only be used when there is no IonContext active
     // (for example, Trampoline-$(ARCH).cpp and IonCaches.cpp).
     MacroAssembler(JSContext *cx)
       : enoughMemory_(true),
         embedsNurseryPointers_(false),
         sps_(nullptr)
     {
         constructRoot(cx);
         ionContext_.construct(cx, (js::jit::TempAllocator *)nullptr);
         alloc_.construct(cx);
+        moveResolver_.setAllocator(*ionContext_.ref().temp);
 #ifdef JS_CPU_ARM
         initWithAllocator();
         m_buffer.id = GetIonContext()->getNextAssemblerId();
 #endif
     }
 
     // asm.js compilation handles its own IonContet-pushing
     struct AsmJSToken {};
@@ -232,38 +235,24 @@ class MacroAssembler : public MacroAssem
         sps_(nullptr)
     {
 #ifdef JS_CPU_ARM
         initWithAllocator();
         m_buffer.id = 0;
 #endif
     }
 
-    MacroAssembler(JSContext *cx, IonScript *ion)
-      : enoughMemory_(true),
-        embedsNurseryPointers_(false),
-        sps_(nullptr)
-    {
-        constructRoot(cx);
-         ionContext_.construct(cx, (js::jit::TempAllocator *)nullptr);
-         alloc_.construct(cx);
-#ifdef JS_CPU_ARM
-         initWithAllocator();
-         m_buffer.id = GetIonContext()->getNextAssemblerId();
-#endif
-        setFramePushed(ion->frameSize());
-    }
-
     void setInstrumentation(IonInstrumentation *sps) {
         sps_ = sps;
     }
 
-    void resetForNewCodeGenerator() {
+    void resetForNewCodeGenerator(TempAllocator &alloc) {
         setFramePushed(0);
         moveResolver_.clearTempObjectPool();
+        moveResolver_.setAllocator(alloc);
     }
 
     void constructRoot(JSContext *cx) {
         autoRooter_.construct(cx, this);
     }
 
     MoveResolver &moveResolver() {
         return moveResolver_;
--- a/js/src/jit/MoveResolver.h
+++ b/js/src/jit/MoveResolver.h
@@ -152,17 +152,17 @@ class MoveResolver
         Kind kind() const {
             return kind_;
         }
     };
 
   private:
     struct PendingMove
       : public Move,
-        public OldTempObject,
+        public TempObject,
         public InlineListNode<PendingMove>
     {
         PendingMove()
         { }
         PendingMove(const MoveOperand &from, const MoveOperand &to, Kind kind)
           : Move(from, to, kind, false)
         { }
         
@@ -210,14 +210,17 @@ class MoveResolver
         return orderedMoves_[i];
     }
     bool hasCycles() const {
         return hasCycles_;
     }
     void clearTempObjectPool() {
         movePool_.clear();
     }
+    void setAllocator(TempAllocator &alloc) {
+        movePool_.setAllocator(alloc);
+    }
 };
 
 } // namespace jit
 } // namespace js
 
 #endif /* jit_MoveResolver_h */