Bug 1445235 part 4 - Remove RegisterOrInt32Constant. r=nbp
authorJan de Mooij <jdemooij@mozilla.com>
Wed, 28 Mar 2018 16:07:10 +0200
changeset 410479 70f44f69accd1c20bece0e4d0eeb889e4841d9e7
parent 410478 7aa5b7d5198cc819fef0f5819376f4ef4a820dae
child 410480 0ba5e089f9a0ee441405690395d6058eef2f5b6c
push id33729
push userrgurzau@mozilla.com
push dateWed, 28 Mar 2018 21:55:49 +0000
treeherdermozilla-central@6aa3b57955fe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1445235
milestone61.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 1445235 part 4 - Remove RegisterOrInt32Constant. r=nbp
js/src/jit/CodeGenerator.cpp
js/src/jit/Lowering.cpp
js/src/jit/MacroAssembler-inl.h
js/src/jit/MacroAssembler.h
js/src/jit/RegisterSets.h
js/src/jit/shared/CodeGenerator-shared-inl.h
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -6853,26 +6853,34 @@ CodeGenerator::visitArrowNewTarget(LArro
 
 void
 CodeGenerator::visitArrayLength(LArrayLength* lir)
 {
     Address length(ToRegister(lir->elements()), ObjectElements::offsetOfLength());
     masm.load32(length, ToRegister(lir->output()));
 }
 
+static void
+SetLengthFromIndex(MacroAssembler& masm, const LAllocation* index, const Address& length)
+{
+    if (index->isConstant()) {
+        masm.store32(Imm32(ToInt32(index) + 1), length);
+    } else {
+        Register newLength = ToRegister(index);
+        masm.add32(Imm32(1), newLength);
+        masm.store32(newLength, length);
+        masm.sub32(Imm32(1), newLength);
+    }
+}
+
 void
 CodeGenerator::visitSetArrayLength(LSetArrayLength* lir)
 {
     Address length(ToRegister(lir->elements()), ObjectElements::offsetOfLength());
-    RegisterOrInt32Constant newLength = ToRegisterOrInt32Constant(lir->index());
-
-    masm.inc32(&newLength);
-    masm.store32(newLength, length);
-    // Restore register value if it is used/captured after.
-    masm.dec32(&newLength);
+    SetLengthFromIndex(masm, lir->index(), length);
 }
 
 template <class OrderedHashTable>
 static void
 RangeFront(MacroAssembler&, Register, Register, Register);
 
 template <>
 void
@@ -8893,22 +8901,17 @@ CodeGenerator::visitInitializedLength(LI
     Address initLength(ToRegister(lir->elements()), ObjectElements::offsetOfInitializedLength());
     masm.load32(initLength, ToRegister(lir->output()));
 }
 
 void
 CodeGenerator::visitSetInitializedLength(LSetInitializedLength* lir)
 {
     Address initLength(ToRegister(lir->elements()), ObjectElements::offsetOfInitializedLength());
-    RegisterOrInt32Constant index = ToRegisterOrInt32Constant(lir->index());
-
-    masm.inc32(&index);
-    masm.store32(index, initLength);
-    // Restore register value if it is used/captured after.
-    masm.dec32(&index);
+    SetLengthFromIndex(masm, lir->index(), initLength);
 }
 
 void
 CodeGenerator::visitNotO(LNotO* lir)
 {
     MOZ_ASSERT(lir->mir()->operandMightEmulateUndefined(),
                "This should be constant-folded if the object can't emulate undefined.");
 
@@ -9218,28 +9221,27 @@ CodeGenerator::emitStoreElementHoleT(T* 
     static_assert(std::is_same<T, LStoreElementHoleT>::value || std::is_same<T, LFallibleStoreElementT>::value,
                   "emitStoreElementHoleT called with unexpected argument type");
 
     OutOfLineStoreElementHole* ool =
         new(alloc()) OutOfLineStoreElementHole(lir, current->mir()->strict());
     addOutOfLineCode(ool, lir->mir());
 
     Register elements = ToRegister(lir->elements());
-    const LAllocation* index = lir->index();
-    RegisterOrInt32Constant key = ToRegisterOrInt32Constant(index);
+    Register index = ToRegister(lir->index());
 
     Address initLength(elements, ObjectElements::offsetOfInitializedLength());
-    masm.branch32(Assembler::BelowOrEqual, initLength, key, ool->entry());
+    masm.branch32(Assembler::BelowOrEqual, initLength, index, ool->entry());
 
     if (lir->mir()->needsBarrier())
-        emitPreBarrier(elements, index, 0);
+        emitPreBarrier(elements, lir->index(), 0);
 
     masm.bind(ool->rejoinStore());
     emitStoreElementTyped(lir->value(), lir->mir()->value()->type(), lir->mir()->elementType(),
-                          elements, index, 0);
+                          elements, lir->index(), 0);
 
     masm.bind(ool->rejoin());
 }
 
 void
 CodeGenerator::visitStoreElementHoleT(LStoreElementHoleT* lir)
 {
     emitStoreElementHoleT(lir);
@@ -9251,31 +9253,27 @@ CodeGenerator::emitStoreElementHoleV(T* 
     static_assert(std::is_same<T, LStoreElementHoleV>::value || std::is_same<T, LFallibleStoreElementV>::value,
                   "emitStoreElementHoleV called with unexpected parameter type");
 
     OutOfLineStoreElementHole* ool =
         new(alloc()) OutOfLineStoreElementHole(lir, current->mir()->strict());
     addOutOfLineCode(ool, lir->mir());
 
     Register elements = ToRegister(lir->elements());
-    const LAllocation* index = lir->index();
+    Register index = ToRegister(lir->index());
     const ValueOperand value = ToValue(lir, T::Value);
-    RegisterOrInt32Constant key = ToRegisterOrInt32Constant(index);
 
     Address initLength(elements, ObjectElements::offsetOfInitializedLength());
-    masm.branch32(Assembler::BelowOrEqual, initLength, key, ool->entry());
+    masm.branch32(Assembler::BelowOrEqual, initLength, index, ool->entry());
 
     if (lir->mir()->needsBarrier())
-        emitPreBarrier(elements, index, 0);
+        emitPreBarrier(elements, lir->index(), 0);
 
     masm.bind(ool->rejoinStore());
-    if (index->isConstant())
-        masm.storeValue(value, Address(elements, ToInt32(index) * sizeof(js::Value)));
-    else
-        masm.storeValue(value, BaseIndex(elements, ToRegister(index), TimesEight));
+    masm.storeValue(value, BaseIndex(elements, index, TimesEight));
 
     masm.bind(ool->rejoin());
 }
 
 void
 CodeGenerator::visitStoreElementHoleV(LStoreElementHoleV* lir)
 {
     emitStoreElementHoleV(lir);
@@ -9394,47 +9392,47 @@ CodeGenerator::visitOutOfLineStoreElemen
         index = store->index();
         valueType = store->mir()->value()->type();
         if (store->value()->isConstant())
             value = ConstantOrRegister(store->value()->toConstant()->toJSValue());
         else
             value = TypedOrValueRegister(valueType, ToAnyRegister(store->value()));
     }
 
-    RegisterOrInt32Constant key = ToRegisterOrInt32Constant(index);
+    Register indexReg = ToRegister(index);
 
     // If index == initializedLength, try to bump the initialized length inline.
     // If index > initializedLength, call a stub. Note that this relies on the
     // condition flags sticking from the incoming branch.
     Label callStub;
 #if defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
     // Had to reimplement for MIPS because there are no flags.
     Address initLength(elements, ObjectElements::offsetOfInitializedLength());
-    masm.branch32(Assembler::NotEqual, initLength, key, &callStub);
+    masm.branch32(Assembler::NotEqual, initLength, indexReg, &callStub);
 #else
     masm.j(Assembler::NotEqual, &callStub);
 #endif
 
     // Check array capacity.
     masm.branch32(Assembler::BelowOrEqual, Address(elements, ObjectElements::offsetOfCapacity()),
-                  key, &callStub);
+                  indexReg, &callStub);
 
     // Update initialized length. The capacity guard above ensures this won't overflow,
     // due to MAX_DENSE_ELEMENTS_COUNT.
-    masm.inc32(&key);
-    masm.store32(key, Address(elements, ObjectElements::offsetOfInitializedLength()));
+    masm.add32(Imm32(1), indexReg);
+    masm.store32(indexReg, Address(elements, ObjectElements::offsetOfInitializedLength()));
 
     // Update length if length < initializedLength.
     Label dontUpdate;
     masm.branch32(Assembler::AboveOrEqual, Address(elements, ObjectElements::offsetOfLength()),
-                  key, &dontUpdate);
-    masm.store32(key, Address(elements, ObjectElements::offsetOfLength()));
+                  indexReg, &dontUpdate);
+    masm.store32(indexReg, Address(elements, ObjectElements::offsetOfLength()));
     masm.bind(&dontUpdate);
 
-    masm.dec32(&key);
+    masm.sub32(Imm32(1), indexReg);
 
     if ((ins->isStoreElementHoleT() || ins->isFallibleStoreElementT()) &&
         valueType != MIRType::Double)
     {
         // The inline path for StoreElementHoleT and FallibleStoreElementT does not always store
         // the type tag, so we do the store on the OOL path. We use MIRType::None for the element
         // type so that storeElementTyped will always store the type tag.
         if (ins->isStoreElementHoleT()) {
@@ -9556,22 +9554,21 @@ CodeGenerator::emitArrayPopShift(LInstru
         MOZ_ASSERT(mir->mode() == MArrayPopShift::Shift);
         ool = oolCallVM(ArrayShiftDenseInfo, lir, ArgList(obj), StoreValueTo(out));
     }
 
     // VM call if a write barrier is necessary.
     masm.branchTestNeedsIncrementalBarrier(Assembler::NonZero, ool->entry());
 
     // Load elements and length, and VM call if length != initializedLength.
-    RegisterOrInt32Constant key = RegisterOrInt32Constant(lengthTemp);
     masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), elementsTemp);
     masm.load32(Address(elementsTemp, ObjectElements::offsetOfLength()), lengthTemp);
 
     Address initLength(elementsTemp, ObjectElements::offsetOfInitializedLength());
-    masm.branch32(Assembler::NotEqual, initLength, key, ool->entry());
+    masm.branch32(Assembler::NotEqual, initLength, lengthTemp, ool->entry());
 
     // Test for length != 0. On zero length either take a VM call or generate
     // an undefined value, depending on whether the call is known to produce
     // undefined.
     Label done;
     if (mir->maybeUndefined()) {
         Label notEmpty;
         masm.branchTest32(Assembler::NonZero, lengthTemp, lengthTemp, &notEmpty);
@@ -9585,17 +9582,17 @@ CodeGenerator::emitArrayPopShift(LInstru
 
         masm.moveValue(UndefinedValue(), out.valueReg());
         masm.jump(&done);
         masm.bind(&notEmpty);
     } else {
         masm.branchTest32(Assembler::Zero, lengthTemp, lengthTemp, ool->entry());
     }
 
-    masm.dec32(&key);
+    masm.sub32(Imm32(1), lengthTemp);
 
     if (mir->mode() == MArrayPopShift::Pop) {
         BaseIndex addr(elementsTemp, lengthTemp, TimesEight);
         masm.loadElementTypedOrValue(addr, out, mir->needsHoleCheck(), ool->entry());
     } else {
         MOZ_ASSERT(mir->mode() == MArrayPopShift::Shift);
         Address addr(elementsTemp, 0);
         masm.loadElementTypedOrValue(addr, out, mir->needsHoleCheck(), ool->entry());
@@ -9657,34 +9654,32 @@ static const VMFunction ArrayPushDenseIn
     FunctionInfo<ArrayPushDenseFn>(jit::ArrayPushDense, "ArrayPushDense");
 
 void
 CodeGenerator::emitArrayPush(LInstruction* lir, Register obj,
                              const ConstantOrRegister& value, Register elementsTemp, Register length)
 {
     OutOfLineCode* ool = oolCallVM(ArrayPushDenseInfo, lir, ArgList(obj, value), StoreRegisterTo(length));
 
-    RegisterOrInt32Constant key = RegisterOrInt32Constant(length);
-
     // Load elements and length.
     masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), elementsTemp);
     masm.load32(Address(elementsTemp, ObjectElements::offsetOfLength()), length);
 
     // Guard length == initializedLength.
     Address initLength(elementsTemp, ObjectElements::offsetOfInitializedLength());
-    masm.branch32(Assembler::NotEqual, initLength, key, ool->entry());
+    masm.branch32(Assembler::NotEqual, initLength, length, ool->entry());
 
     // Guard length < capacity.
     Address capacity(elementsTemp, ObjectElements::offsetOfCapacity());
-    masm.branch32(Assembler::BelowOrEqual, capacity, key, ool->entry());
+    masm.branch32(Assembler::BelowOrEqual, capacity, length, ool->entry());
 
     // Do the store.
     masm.storeConstantOrRegister(value, BaseIndex(elementsTemp, length, TimesEight));
 
-    masm.inc32(&key);
+    masm.add32(Imm32(1), length);
 
     // Update length and initialized length.
     masm.store32(length, Address(elementsTemp, ObjectElements::offsetOfLength()));
     masm.store32(length, Address(elementsTemp, ObjectElements::offsetOfInitializedLength()));
 
     masm.bind(ool->rejoin());
 }
 
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -3422,17 +3422,17 @@ LIRGenerator::visitStoreElement(MStoreEl
 void
 LIRGenerator::visitStoreElementHole(MStoreElementHole* ins)
 {
     MOZ_ASSERT(ins->elements()->type() == MIRType::Elements);
     MOZ_ASSERT(ins->index()->type() == MIRType::Int32);
 
     const LUse object = useRegister(ins->object());
     const LUse elements = useRegister(ins->elements());
-    const LAllocation index = useRegisterOrConstant(ins->index());
+    const LAllocation index = useRegister(ins->index());
 
     LInstruction* lir;
     switch (ins->value()->type()) {
       case MIRType::Value:
         lir = new(alloc()) LStoreElementHoleV(object, elements, index, useBox(ins->value()));
         break;
 
       default:
@@ -3450,17 +3450,17 @@ LIRGenerator::visitStoreElementHole(MSto
 void
 LIRGenerator::visitFallibleStoreElement(MFallibleStoreElement* ins)
 {
     MOZ_ASSERT(ins->elements()->type() == MIRType::Elements);
     MOZ_ASSERT(ins->index()->type() == MIRType::Int32);
 
     const LUse object = useRegister(ins->object());
     const LUse elements = useRegister(ins->elements());
-    const LAllocation index = useRegisterOrConstant(ins->index());
+    const LAllocation index = useRegister(ins->index());
 
     LInstruction* lir;
     switch (ins->value()->type()) {
       case MIRType::Value:
         lir = new(alloc()) LFallibleStoreElementV(object, elements, index, useBox(ins->value()));
         break;
       default:
         const LAllocation value = useRegisterOrNonDoubleConstant(ins->value());
--- a/js/src/jit/MacroAssembler-inl.h
+++ b/js/src/jit/MacroAssembler-inl.h
@@ -327,62 +327,19 @@ MacroAssembler::moveValue(const Constant
 // Arithmetic functions
 
 void
 MacroAssembler::addPtr(ImmPtr imm, Register dest)
 {
     addPtr(ImmWord(uintptr_t(imm.value)), dest);
 }
 
-void
-MacroAssembler::inc32(RegisterOrInt32Constant* key)
-{
-    if (key->isRegister())
-        add32(Imm32(1), key->reg());
-    else
-        key->bumpConstant(1);
-}
-
-void
-MacroAssembler::dec32(RegisterOrInt32Constant* key)
-{
-    if (key->isRegister())
-        add32(Imm32(-1), key->reg());
-    else
-        key->bumpConstant(-1);
-}
-
 // ===============================================================
 // Branch functions
 
-void
-MacroAssembler::branch32(Condition cond, Register length, const RegisterOrInt32Constant& key,
-                         Label* label)
-{
-    branch32Impl(cond, length, key, label);
-}
-
-void
-MacroAssembler::branch32(Condition cond, const Address& length, const RegisterOrInt32Constant& key,
-                         Label* label)
-{
-    branch32Impl(cond, length, key, label);
-}
-
-template <typename T>
-void
-MacroAssembler::branch32Impl(Condition cond, const T& length, const RegisterOrInt32Constant& key,
-                             Label* label)
-{
-    if (key.isRegister())
-        branch32(cond, length, key.reg(), label);
-    else
-        branch32(cond, length, Imm32(key.constant()), label);
-}
-
 template <class L>
 void
 MacroAssembler::branchIfFalseBool(Register reg, L label)
 {
     // Note that C++ bool is only 1 byte, so ignore the higher-order bits.
     branchTest32(Assembler::Zero, reg, Imm32(0xFF), label);
 }
 
--- a/js/src/jit/MacroAssembler.h
+++ b/js/src/jit/MacroAssembler.h
@@ -815,21 +815,18 @@ class MacroAssembler : public MacroAssem
     //
     // On x86_shared, srcDest must be eax and edx will be clobbered.
     // On ARM, the chip must have hardware division instructions.
     inline void remainder32(Register rhs, Register srcDest, bool isUnsigned) PER_SHARED_ARCH;
 
     inline void divFloat32(FloatRegister src, FloatRegister dest) PER_SHARED_ARCH;
     inline void divDouble(FloatRegister src, FloatRegister dest) PER_SHARED_ARCH;
 
-    inline void inc32(RegisterOrInt32Constant* key);
     inline void inc64(AbsoluteAddress dest) PER_ARCH;
 
-    inline void dec32(RegisterOrInt32Constant* key);
-
     inline void neg32(Register reg) PER_SHARED_ARCH;
     inline void neg64(Register64 reg) DEFINED_ON(x86, x64, arm, mips32, mips64);
 
     inline void negateFloat(FloatRegister reg) PER_SHARED_ARCH;
 
     inline void negateDouble(FloatRegister reg) PER_SHARED_ARCH;
 
     inline void absFloat32(FloatRegister src, FloatRegister dest) PER_SHARED_ARCH;
@@ -933,23 +930,19 @@ class MacroAssembler : public MacroAssem
 
     // ===============================================================
     // Branch functions
 
     template <class L>
     inline void branch32(Condition cond, Register lhs, Register rhs, L label) PER_SHARED_ARCH;
     template <class L>
     inline void branch32(Condition cond, Register lhs, Imm32 rhs, L label) PER_SHARED_ARCH;
-    inline void branch32(Condition cond, Register length, const RegisterOrInt32Constant& key,
-                         Label* label);
 
     inline void branch32(Condition cond, const Address& lhs, Register rhs, Label* label) PER_SHARED_ARCH;
     inline void branch32(Condition cond, const Address& lhs, Imm32 rhs, Label* label) PER_SHARED_ARCH;
-    inline void branch32(Condition cond, const Address& length, const RegisterOrInt32Constant& key,
-                         Label* label);
 
     inline void branch32(Condition cond, const AbsoluteAddress& lhs, Register rhs, Label* label)
         DEFINED_ON(arm, arm64, mips_shared, x86, x64);
     inline void branch32(Condition cond, const AbsoluteAddress& lhs, Imm32 rhs, Label* label)
         DEFINED_ON(arm, arm64, mips_shared, x86, x64);
 
     inline void branch32(Condition cond, const BaseIndex& lhs, Register rhs, Label* label)
         DEFINED_ON(x86_shared);
@@ -1273,21 +1266,16 @@ class MacroAssembler : public MacroAssem
     inline void branchTestStringTruthy(bool truthy, const ValueOperand& value, Label* label)
         DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
 
     // Create an unconditional branch to the address given as argument.
     inline void branchToComputedAddress(const BaseIndex& address) PER_ARCH;
 
   private:
 
-    // Implementation for branch* methods.
-    template <typename T>
-    inline void branch32Impl(Condition cond, const T& length, const RegisterOrInt32Constant& key,
-                             Label* label);
-
     template <typename T, typename S, typename L>
     inline void branchPtrImpl(Condition cond, const T& lhs, const S& rhs, L label)
         DEFINED_ON(x86_shared);
 
     void branchPtrInNurseryChunkImpl(Condition cond, Register ptr, Label* label)
         DEFINED_ON(x86);
     template <typename T>
     void branchValueIsNurseryCellImpl(Condition cond, const T& value, Register temp, Label* label)
@@ -2116,24 +2104,16 @@ class MacroAssembler : public MacroAssem
             mov(JSReturnReg, dest.valueReg());
 #else
 #error "Bad architecture"
 #endif
     }
 
     inline void storeCallResultValue(TypedOrValueRegister dest);
 
-    using MacroAssemblerSpecific::store32;
-    void store32(const RegisterOrInt32Constant& key, const Address& dest) {
-        if (key.isRegister())
-            store32(key.reg(), dest);
-        else
-            store32(Imm32(key.constant()), dest);
-    }
-
     template <typename T>
     void guardedCallPreBarrier(const T& address, MIRType type) {
         Label done;
 
         branchTestNeedsIncrementalBarrier(Assembler::Zero, &done);
 
         if (type == MIRType::Value)
             branchTestGCThing(Assembler::NotEqual, address, &done);
--- a/js/src/jit/RegisterSets.h
+++ b/js/src/jit/RegisterSets.h
@@ -277,51 +277,16 @@ class ConstantOrRegister
         return dataValue();
     }
 
     const TypedOrValueRegister& reg() const {
         return dataReg();
     }
 };
 
-struct RegisterOrInt32Constant {
-    bool isRegister_;
-    union {
-        Register reg_;
-        int32_t constant_;
-    };
-
-    explicit RegisterOrInt32Constant(Register reg)
-      : isRegister_(true), reg_(reg)
-    { }
-
-    explicit RegisterOrInt32Constant(int32_t index)
-      : isRegister_(false), constant_(index)
-    { }
-
-    inline void bumpConstant(int diff) {
-        MOZ_ASSERT(!isRegister_);
-        constant_ += diff;
-    }
-    inline Register reg() const {
-        MOZ_ASSERT(isRegister_);
-        return reg_;
-    }
-    inline int32_t constant() const {
-        MOZ_ASSERT(!isRegister_);
-        return constant_;
-    }
-    inline bool isRegister() const {
-        return isRegister_;
-    }
-    inline bool isConstant() const {
-        return !isRegister_;
-    }
-};
-
 template <typename T>
 class TypedRegisterSet
 {
   public:
     typedef T RegType;
     typedef typename T::SetType SetType;
 
   private:
--- a/js/src/jit/shared/CodeGenerator-shared-inl.h
+++ b/js/src/jit/shared/CodeGenerator-shared-inl.h
@@ -179,24 +179,16 @@ ToAnyRegister(const LAllocation* a)
 }
 
 static inline AnyRegister
 ToAnyRegister(const LDefinition* def)
 {
     return ToAnyRegister(def->output());
 }
 
-static inline RegisterOrInt32Constant
-ToRegisterOrInt32Constant(const LAllocation* a)
-{
-    if (a->isConstant())
-        return RegisterOrInt32Constant(ToInt32(a));
-    return RegisterOrInt32Constant(ToRegister(a));
-}
-
 static inline ValueOperand
 ToOutValue(LInstruction* ins)
 {
 #if defined(JS_NUNBOX32)
     return ValueOperand(ToRegister(ins->getDef(TYPE_INDEX)),
                         ToRegister(ins->getDef(PAYLOAD_INDEX)));
 #elif defined(JS_PUNBOX64)
     return ValueOperand(ToRegister(ins->getDef(0)));