Bug 1329096 - Wasm baseline, remove the label pool and use NonAssertingLabel instead. r=luke
authorLars T Hansen <lhansen@mozilla.com>
Wed, 18 Jan 2017 20:11:32 +0100
changeset 375105 082be147ff94724672c59bb62ef47d8c086cd191
parent 375104 9042d15381359dc12bbce404f157cdde53e359eb
child 375106 3112cbcca0f41c1fff13a287d71a61267111edbb
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1329096
milestone53.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 1329096 - Wasm baseline, remove the label pool and use NonAssertingLabel instead. r=luke
js/src/wasm/WasmBaselineCompile.cpp
--- a/js/src/wasm/WasmBaselineCompile.cpp
+++ b/js/src/wasm/WasmBaselineCompile.cpp
@@ -266,36 +266,17 @@ class BaseCompiler
       public:
         ScratchI32(BaseCompiler& bc) {}
         operator Register() const {
             MOZ_CRASH("BaseCompiler platform hook - ScratchI32");
         }
     };
 #endif
 
-    // A Label in the code, allocated out of a temp pool in the
-    // TempAllocator attached to the compilation.
-
-    struct PooledLabel : public Label, public TempObject, public InlineListNode<PooledLabel>
-    {
-        PooledLabel() : f(nullptr) {}
-        explicit PooledLabel(BaseCompiler* f) : f(f) {}
-        BaseCompiler* f;
-    };
-
-    typedef Vector<PooledLabel*, 8, SystemAllocPolicy> LabelVector;
-
-    struct UniquePooledLabelFreePolicy
-    {
-        void operator()(PooledLabel* p) {
-            p->f->freeLabel(p);
-        }
-    };
-
-    typedef UniquePtr<PooledLabel, UniquePooledLabelFreePolicy> UniquePooledLabel;
+    typedef Vector<NonAssertingLabel, 8, SystemAllocPolicy> LabelVector;
 
     // The strongly typed register wrappers have saved my bacon a few
     // times; though they are largely redundant they stay, for now.
 
     struct RegI32 : public Register
     {
         RegI32() : Register(Register::Invalid()) {}
         explicit RegI32(Register reg) : Register(reg) {}
@@ -390,26 +371,24 @@ class BaseCompiler
         uint32_t offs() const { MOZ_ASSERT(offs_ != UINT32_MAX); return offs_; }
     };
 
     // Control node, representing labels and stack heights at join points.
 
     struct Control
     {
         Control()
-            : label(nullptr),
-              otherLabel(nullptr),
-              framePushed(0),
-              stackSize(0),
+            : framePushed(UINT32_MAX),
+              stackSize(UINT32_MAX),
               deadOnArrival(false),
               deadThenBranch(false)
         {}
 
-        PooledLabel* label;
-        PooledLabel* otherLabel;        // Used for the "else" branch of if-then-else
+        NonAssertingLabel label;        // The "exit" label
+        NonAssertingLabel otherLabel;   // Used for the "else" branch of if-then-else
         uint32_t framePushed;           // From masm
         uint32_t stackSize;             // Value stack height
         bool deadOnArrival;             // deadCode_ was set on entry to the region
         bool deadThenBranch;            // deadCode_ was set on exit from "then"
     };
 
     struct BaseCompilePolicy : OpIterPolicy
     {
@@ -529,18 +508,16 @@ class BaseCompiler
     MacroAssembler&             masm;            // No '_' suffix - too tedious...
 
     AllocatableGeneralRegisterSet availGPR_;
     AllocatableFloatRegisterSet availFPU_;
 #ifdef DEBUG
     bool                        scratchRegisterTaken_;
 #endif
 
-    TempObjectPool<PooledLabel> labelPool_;
-
     Vector<Local, 8, SystemAllocPolicy> localInfo_;
     Vector<OutOfLineCode*, 8, SystemAllocPolicy> outOfLine_;
 
     // Index into localInfo_ of the special local used for saving the TLS
     // pointer. This follows the function's real arguments and locals.
     uint32_t                    tlsSlot_;
 
     // On specific platforms we sometimes need to use specific registers.
@@ -2049,64 +2026,42 @@ class BaseCompiler
     Stk& peek(uint32_t relativeDepth) {
         return stk_[stk_.length()-1-relativeDepth];
     }
 
     ////////////////////////////////////////////////////////////
     //
     // Control stack
 
-    void initControl(Control& item, UniquePooledLabel* label, UniquePooledLabel* otherLabel = nullptr)
+    void initControl(Control& item)
     {
+        // Make sure the constructor was run properly
+        MOZ_ASSERT(item.framePushed == UINT32_MAX && item.stackSize == UINT32_MAX);
+
         item.framePushed = masm.framePushed();
         item.stackSize = stk_.length();
-        item.label = label->release();
-        if (otherLabel)
-            item.otherLabel = otherLabel->release();
         item.deadOnArrival = deadCode_;
     }
 
-    void freeControl(Control& item) {
-        if (item.label)
-            freeLabel(item.label);
-        if (item.otherLabel)
-            freeLabel(item.otherLabel);
-    }
-
     Control& controlItem() {
         return iter_.controlItem();
     }
 
     Control& controlItem(uint32_t relativeDepth) {
         return iter_.controlItem(relativeDepth);
     }
 
     Control& controlOutermost() {
         return iter_.controlOutermost();
     }
 
     ////////////////////////////////////////////////////////////
     //
     // Labels
 
-    MOZ_MUST_USE PooledLabel* newLabel() {
-        // TODO / INVESTIGATE (Bug 1316819): allocate() is fallible, but we can
-        // probably rely on an infallible allocator here.  That would simplify
-        // code later.
-        PooledLabel* candidate = labelPool_.allocate();
-        if (!candidate)
-            return nullptr;
-        return new (candidate) PooledLabel(this);
-    }
-
-    void freeLabel(PooledLabel* label) {
-        label->~PooledLabel();
-        labelPool_.free(label);
-    }
-
     void insertBreakablePoint(CallSiteDesc::Kind kind) {
         const uint32_t offset = iter_.currentOffset();
         masm.nopPatchableToCall(CallSiteDesc(offset, kind));
     }
 
     //////////////////////////////////////////////////////////////////////
     //
     // Function prologue and epilogue.
@@ -2588,17 +2543,17 @@ class BaseCompiler
         masm.flush();
 
         masm.bind(theTable);
 
 #if defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_ARM)
         for (uint32_t i = 0; i < labels.length(); i++) {
             CodeLabel cl;
             masm.writeCodePointer(cl.patchAt());
-            cl.target()->bind(labels[i]->offset());
+            cl.target()->bind(labels[i].offset());
             masm.addCodeLabel(cl);
         }
 #else
         MOZ_CRASH("BaseCompiler platform hook: jumpTable");
 #endif
     }
 
     void tableSwitch(Label* theTable, RegI32 switchValue, Label* dispatchCode) {
@@ -5457,24 +5412,21 @@ BaseCompiler::emitBranchPerform(BranchSt
 //  - The exit value is always in a designated join register (type dependent).
 
 bool
 BaseCompiler::emitBlock()
 {
     if (!iter_.readBlock())
         return false;
 
-    UniquePooledLabel blockEnd(newLabel());
-    if (!blockEnd)
-        return false;
-
     if (!deadCode_)
         sync();                    // Simplifies branching out from block
 
-    initControl(controlItem(), &blockEnd);
+    initControl(controlItem());
+
     return true;
 }
 
 void
 BaseCompiler::endBlock(ExprType type)
 {
     Control& block = controlItem();
 
@@ -5483,49 +5435,43 @@ BaseCompiler::endBlock(ExprType type)
     if (!deadCode_)
         r = popJoinRegUnlessVoid(type);
 
     // Leave the block.
     popStackOnBlockExit(block.framePushed);
     popValueStackTo(block.stackSize);
 
     // Bind after cleanup: branches out will have popped the stack.
-    if (block.label->used()) {
-        masm.bind(block.label);
+    if (block.label.used()) {
+        masm.bind(&block.label);
         // No value was provided by the fallthrough but the branch out will
         // have stored one in joinReg, so capture that.
         if (deadCode_)
             r = captureJoinRegUnlessVoid(type);
         deadCode_ = false;
     }
 
-    freeControl(block);
-
     // Retain the value stored in joinReg by all paths, if there are any.
     if (!deadCode_)
         pushJoinRegUnlessVoid(r);
 }
 
 bool
 BaseCompiler::emitLoop()
 {
     if (!iter_.readLoop())
         return false;
 
-    UniquePooledLabel blockCont(newLabel());
-    if (!blockCont)
-        return false;
-
     if (!deadCode_)
         sync();                    // Simplifies branching out from block
 
-    initControl(controlItem(), &blockCont);
+    initControl(controlItem());
 
     if (!deadCode_) {
-        masm.bind(controlItem(0).label);
+        masm.bind(&controlItem(0).label);
         addInterruptCheck();
     }
 
     return true;
 }
 
 void
 BaseCompiler::endLoop(ExprType type)
@@ -5534,18 +5480,16 @@ BaseCompiler::endLoop(ExprType type)
 
     AnyReg r;
     if (!deadCode_)
         r = popJoinRegUnlessVoid(type);
 
     popStackOnBlockExit(block.framePushed);
     popValueStackTo(block.stackSize);
 
-    freeControl(block);
-
     // Retain the value stored in joinReg by all paths.
     if (!deadCode_)
         pushJoinRegUnlessVoid(r);
 }
 
 // The bodies of the "then" and "else" arms can be arbitrary sequences
 // of expressions, they push control and increment the nesting and can
 // even be targeted by jumps.  A branch to the "if" block branches to
@@ -5562,57 +5506,47 @@ BaseCompiler::endLoop(ExprType type)
 
 bool
 BaseCompiler::emitIf()
 {
     Nothing unused_cond;
     if (!iter_.readIf(&unused_cond))
         return false;
 
-    UniquePooledLabel endLabel(newLabel());
-    if (!endLabel)
-        return false;
-
-    UniquePooledLabel elseLabel(newLabel());
-    if (!elseLabel)
-        return false;
-
-    BranchState b(elseLabel.get(), BranchState::NoPop, InvertBranch(true));
+    BranchState b(&controlItem().otherLabel, BranchState::NoPop, InvertBranch(true));
     if (!deadCode_) {
         emitBranchSetup(&b);
         sync();
     } else {
         resetLatentOp();
     }
 
-    initControl(controlItem(), &endLabel, &elseLabel);
+    initControl(controlItem());
 
     if (!deadCode_)
         emitBranchPerform(&b);
 
     return true;
 }
 
 void
 BaseCompiler::endIfThen()
 {
     Control& ifThen = controlItem();
 
     popStackOnBlockExit(ifThen.framePushed);
     popValueStackTo(ifThen.stackSize);
 
-    if (ifThen.otherLabel->used())
-        masm.bind(ifThen.otherLabel);
-
-    if (ifThen.label->used())
-        masm.bind(ifThen.label);
+    if (ifThen.otherLabel.used())
+        masm.bind(&ifThen.otherLabel);
+
+    if (ifThen.label.used())
+        masm.bind(&ifThen.label);
 
     deadCode_ = ifThen.deadOnArrival;
-
-    freeControl(ifThen);
 }
 
 bool
 BaseCompiler::emitElse()
 {
     ExprType thenType;
     Nothing unused_thenValue;
 
@@ -5630,20 +5564,20 @@ BaseCompiler::emitElse()
     AnyReg r;
     if (!deadCode_)
         r = popJoinRegUnlessVoid(thenType);
 
     popStackOnBlockExit(ifThenElse.framePushed);
     popValueStackTo(ifThenElse.stackSize);
 
     if (!deadCode_)
-        masm.jump(ifThenElse.label);
-
-    if (ifThenElse.otherLabel->used())
-        masm.bind(ifThenElse.otherLabel);
+        masm.jump(&ifThenElse.label);
+
+    if (ifThenElse.otherLabel.used())
+        masm.bind(&ifThenElse.otherLabel);
 
     // Reset to the "else" branch.
 
     if (!deadCode_)
         freeJoinRegUnlessVoid(r);
 
     deadCode_ = ifThenElse.deadOnArrival;
 
@@ -5664,32 +5598,30 @@ BaseCompiler::endIfThenElse(ExprType typ
     AnyReg r;
 
     if (!deadCode_)
         r = popJoinRegUnlessVoid(type);
 
     popStackOnBlockExit(ifThenElse.framePushed);
     popValueStackTo(ifThenElse.stackSize);
 
-    if (ifThenElse.label->used())
-        masm.bind(ifThenElse.label);
+    if (ifThenElse.label.used())
+        masm.bind(&ifThenElse.label);
 
     bool joinLive = !ifThenElse.deadOnArrival &&
-                    (!ifThenElse.deadThenBranch || !deadCode_ || ifThenElse.label->bound());
+                    (!ifThenElse.deadThenBranch || !deadCode_ || ifThenElse.label.bound());
 
     if (joinLive) {
         // No value was provided by the "then" path but capture the one
         // provided by the "else" path.
         if (deadCode_)
             r = captureJoinRegUnlessVoid(type);
         deadCode_ = false;
     }
 
-    freeControl(ifThenElse);
-
     if (!deadCode_)
         pushJoinRegUnlessVoid(r);
 }
 
 bool
 BaseCompiler::emitEnd()
 {
     LabelKind kind;
@@ -5727,17 +5659,17 @@ BaseCompiler::emitBr()
     Control& target = controlItem(relativeDepth);
 
     // Save any value in the designated join register, where the
     // normal block exit code will also leave it.
 
     AnyReg r = popJoinRegUnlessVoid(type);
 
     popStackBeforeBranch(target.framePushed);
-    masm.jump(target.label);
+    masm.jump(&target.label);
 
     // The register holding the join value is free for the remainder
     // of this block.
 
     freeJoinRegUnlessVoid(r);
 
     deadCode_ = true;
 
@@ -5755,17 +5687,17 @@ BaseCompiler::emitBrIf()
 
     if (deadCode_) {
         resetLatentOp();
         return true;
     }
 
     Control& target = controlItem(relativeDepth);
 
-    BranchState b(target.label, target.framePushed, InvertBranch(false), type);
+    BranchState b(&target.label, target.framePushed, InvertBranch(false), type);
     emitBranchSetup(&b);
     emitBranchPerform(&b);
 
     return true;
 }
 
 bool
 BaseCompiler::emitBrTable()
@@ -5809,36 +5741,32 @@ BaseCompiler::emitBrTable()
     AnyReg r = popJoinRegUnlessVoid(type);
 
     Label dispatchCode;
     masm.branch32(Assembler::Below, rc, Imm32(tableLength), &dispatchCode);
 
     // This is the out-of-range stub.  rc is dead here but we don't need it.
 
     popStackBeforeBranch(controlItem(defaultDepth).framePushed);
-    masm.jump(controlItem(defaultDepth).label);
+    masm.jump(&controlItem(defaultDepth).label);
 
     // Emit stubs.  rc is dead in all of these but we don't need it.
     //
     // The labels in the vector are in the TempAllocator and will
     // be freed by and by.
     //
     // TODO / OPTIMIZE (Bug 1316804): Branch directly to the case code if we
     // can, don't emit an intermediate stub.
 
     for (uint32_t i = 0; i < tableLength; i++) {
-        PooledLabel* stubLabel = newLabel();
-        if (!stubLabel)
-            return false;
-
-        stubs.infallibleAppend(stubLabel);
-        masm.bind(stubLabel);
+        stubs.infallibleEmplaceBack(NonAssertingLabel());
+        masm.bind(&stubs.back());
         uint32_t k = depths[i];
         popStackBeforeBranch(controlItem(k).framePushed);
-        masm.jump(controlItem(k).label);
+        masm.jump(&controlItem(k).label);
     }
 
     // Emit table.
 
     Label theTable;
     jumpTable(stubs, &theTable);
 
     // Emit indirect jump.  rc is live here.
@@ -5847,19 +5775,16 @@ BaseCompiler::emitBrTable()
 
     deadCode_ = true;
 
     // Clean up.
 
     freeI32(rc);
     freeJoinRegUnlessVoid(r);
 
-    for (uint32_t i = 0; i < tableLength; i++)
-        freeLabel(stubs[i]);
-
     return true;
 }
 
 bool
 BaseCompiler::emitDrop()
 {
     if (!iter_.readDrop())
         return false;
@@ -7672,21 +7597,17 @@ BaseCompiler::emitFunction()
 {
     const Sig& sig = func_.sig();
 
     if (!iter_.readFunctionStart(sig.ret()))
         return false;
 
     beginFunction();
 
-    UniquePooledLabel functionEnd(newLabel());
-    if (!functionEnd)
-        return false;
-
-    initControl(controlItem(), &functionEnd);
+    initControl(controlItem());
 
     if (!emitBody())
         return false;
 
     if (!deadCode_)
         doReturn(sig.ret(), PopStack(false));
 
     if (!iter_.readFunctionEnd())
@@ -7765,18 +7686,16 @@ BaseCompiler::BaseCompiler(const ModuleE
     availGPR_.take(HeapLenReg);
     availGPR_.take(GlobalReg);
 #elif defined(JS_CODEGEN_X86)
     availGPR_.take(ScratchRegX86);
 #elif defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
     availGPR_.take(HeapReg);
     availGPR_.take(GlobalReg);
 #endif
-
-    labelPool_.setAllocator(alloc_);
 }
 
 bool
 BaseCompiler::init()
 {
     if (!SigDD_.append(ValType::F64) || !SigDD_.append(ValType::F64))
         return false;
     if (!SigD_.append(ValType::F64))