author | Hannes Verschore <hv1989@gmail.com> |
Tue, 18 Jun 2013 11:43:34 +0200 | |
changeset 135451 | e9e7d8066cb940fd97acd95a494f1d043c1bab57 |
parent 135450 | db02f2b140d22ca39b64c69b509e400c0c600723 |
child 135452 | b2d1e90f21a2cd5108e511e82cf6232891d2d7af |
push id | 24841 |
push user | ryanvm@gmail.com |
push date | Tue, 18 Jun 2013 23:04:53 +0000 |
treeherder | mozilla-central@d2a7cfa34154 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jandem |
bugs | 880471 |
milestone | 24.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
|
--- a/js/src/ion/CodeGenerator.cpp +++ b/js/src/ion/CodeGenerator.cpp @@ -1134,32 +1134,32 @@ CodeGenerator::visitParDump(LParDump *li masm.freeStack(sizeof(Value)); return true; } bool CodeGenerator::visitTypeBarrier(LTypeBarrier *lir) { ValueOperand operand = ToValue(lir, LTypeBarrier::Input); - Register scratch = ToRegister(lir->temp()); + Register scratch = ToTempUnboxRegister(lir->temp()); Label matched, miss; masm.guardTypeSet(operand, lir->mir()->resultTypeSet(), scratch, &matched, &miss); masm.jump(&miss); if (!bailoutFrom(&miss, lir->snapshot())) return false; masm.bind(&matched); return true; } bool CodeGenerator::visitMonitorTypes(LMonitorTypes *lir) { ValueOperand operand = ToValue(lir, LMonitorTypes::Input); - Register scratch = ToRegister(lir->temp()); + Register scratch = ToTempUnboxRegister(lir->temp()); Label matched, miss; masm.guardTypeSet(operand, lir->mir()->typeSet(), scratch, &matched, &miss); masm.jump(&miss); if (!bailoutFrom(&miss, lir->snapshot())) return false; masm.bind(&matched); return true; @@ -1283,17 +1283,17 @@ CodeGenerator::visitPostWriteBarrierV(LP } else { Label tenured; Register objreg = ToRegister(lir->object()); masm.branchPtr(Assembler::Below, objreg, ImmWord(nursery.start()), &tenured); masm.branchPtr(Assembler::Below, objreg, ImmWord(nursery.heapEnd()), ool->rejoin()); masm.bind(&tenured); } - Register valuereg = masm.extractObject(value, ToRegister(lir->temp())); + Register valuereg = masm.extractObject(value, ToTempUnboxRegister(lir->temp())); masm.branchPtr(Assembler::Below, valuereg, ImmWord(nursery.start()), ool->rejoin()); masm.branchPtr(Assembler::Below, valuereg, ImmWord(nursery.heapEnd()), ool->entry()); masm.bind(ool->rejoin()); #endif return true; } @@ -3539,26 +3539,27 @@ bool CodeGenerator::visitCompareStrictS(LCompareStrictS *lir) { JSOp op = lir->mir()->jsop(); JS_ASSERT(op == JSOP_STRICTEQ || op == JSOP_STRICTNE); const ValueOperand leftV = ToValue(lir, LCompareStrictS::Lhs); Register right = ToRegister(lir->right()); Register output = ToRegister(lir->output()); - Register temp = ToRegister(lir->temp0()); + Register temp = ToRegister(lir->temp()); + Register tempToUnbox = ToTempUnboxRegister(lir->tempToUnbox()); Label string, done; masm.branchTestString(Assembler::Equal, leftV, &string); masm.move32(Imm32(op == JSOP_STRICTNE), output); masm.jump(&done); masm.bind(&string); - Register left = masm.extractString(leftV, ToRegister(lir->temp1())); + Register left = masm.extractString(leftV, tempToUnbox); if (!emitCompareS(lir, op, left, right, output, temp)) return false; masm.bind(&done); return true; } @@ -3705,19 +3706,19 @@ CodeGenerator::visitIsNullOrLikeUndefine masm.branchTestNull(Assembler::Equal, tag, nullOrLikeUndefined); masm.branchTestUndefined(Assembler::Equal, tag, nullOrLikeUndefined); if (ool) { // Check whether it's a truthy object or a falsy object that emulates // undefined. masm.branchTestObject(Assembler::NotEqual, tag, notNullOrLikeUndefined); - Register objreg = masm.extractObject(value, ToRegister(lir->temp0())); + Register objreg = masm.extractObject(value, ToTempUnboxRegister(lir->tempToUnbox())); testObjectTruthy(objreg, notNullOrLikeUndefined, nullOrLikeUndefined, - ToRegister(lir->temp1()), ool); + ToRegister(lir->temp()), ool); } Label done; // It's not null or undefined, and if it's an object it doesn't // emulate undefined, so it's not like undefined. masm.bind(notNullOrLikeUndefined); masm.move32(Imm32(op == JSOP_NE), output); @@ -3784,18 +3785,18 @@ CodeGenerator::visitIsNullOrLikeUndefine masm.branchTestNull(Assembler::Equal, tag, ifTrueLabel); masm.branchTestUndefined(Assembler::Equal, tag, ifTrueLabel); if (ool) { masm.branchTestObject(Assembler::NotEqual, tag, ifFalseLabel); // Objects that emulate undefined are loosely equal to null/undefined. - Register objreg = masm.extractObject(value, ToRegister(lir->temp0())); - testObjectTruthy(objreg, ifFalseLabel, ifTrueLabel, ToRegister(lir->temp1()), ool); + Register objreg = masm.extractObject(value, ToTempUnboxRegister(lir->tempToUnbox())); + testObjectTruthy(objreg, ifFalseLabel, ifTrueLabel, ToRegister(lir->temp()), ool); } else { masm.jump(ifFalseLabel); } return true; } JS_ASSERT(op == JSOP_STRICTEQ || op == JSOP_STRICTNE);
--- a/js/src/ion/IonMacroAssembler.cpp +++ b/js/src/ion/IonMacroAssembler.cpp @@ -78,16 +78,17 @@ MacroAssembler::guardTypeSet(const Sourc if (types->hasType(types::Type::NullType())) branchTestNull(Equal, tag, matched); if (types->hasType(types::Type::MagicArgType())) branchTestMagic(Equal, tag, matched); if (types->hasType(types::Type::AnyObjectType())) { branchTestObject(Equal, tag, matched); } else if (types->getObjectCount()) { + JS_ASSERT(scratch != InvalidReg); branchTestObject(NotEqual, tag, miss); Register obj = extractObject(address, scratch); unsigned count = types->getObjectCount(); for (unsigned i = 0; i < count; i++) { if (JSObject *object = types->getSingleObject(i)) branchPtr(Equal, obj, ImmGCPtr(object), matched); }
--- a/js/src/ion/LIR-Common.h +++ b/js/src/ion/LIR-Common.h @@ -1556,20 +1556,20 @@ class LCompareStrictS : public LInstruct setTemp(1, temp1); } static const size_t Lhs = 0; const LAllocation *right() { return getOperand(BOX_PIECES); } - const LDefinition *temp0() { + const LDefinition *temp() { return getTemp(0); } - const LDefinition *temp1() { + const LDefinition *tempToUnbox() { return getTemp(1); } MCompare *mir() { return mir_->toCompare(); } }; // Used for strict-equality comparisons where one side is a boolean @@ -1675,65 +1675,65 @@ class LCompareVM : public LCallInstructi } }; class LIsNullOrLikeUndefined : public LInstructionHelper<1, BOX_PIECES, 2> { public: LIR_HEADER(IsNullOrLikeUndefined) - LIsNullOrLikeUndefined(const LDefinition &temp0, const LDefinition &temp1) + LIsNullOrLikeUndefined(const LDefinition &temp, const LDefinition &tempToUnbox) { - setTemp(0, temp0); - setTemp(1, temp1); + setTemp(0, temp); + setTemp(1, tempToUnbox); } static const size_t Value = 0; MCompare *mir() { return mir_->toCompare(); } - const LDefinition *temp0() { + const LDefinition *temp() { return getTemp(0); } - const LDefinition *temp1() { + const LDefinition *tempToUnbox() { return getTemp(1); } }; class LIsNullOrLikeUndefinedAndBranch : public LControlInstructionHelper<2, BOX_PIECES, 2> { public: LIR_HEADER(IsNullOrLikeUndefinedAndBranch) - LIsNullOrLikeUndefinedAndBranch(MBasicBlock *ifTrue, MBasicBlock *ifFalse, const LDefinition &temp0, const LDefinition &temp1) + LIsNullOrLikeUndefinedAndBranch(MBasicBlock *ifTrue, MBasicBlock *ifFalse, const LDefinition &temp, const LDefinition &tempToUnbox) { setSuccessor(0, ifTrue); setSuccessor(1, ifFalse); - setTemp(0, temp0); - setTemp(1, temp1); + setTemp(0, temp); + setTemp(1, tempToUnbox); } static const size_t Value = 0; MBasicBlock *ifTrue() const { return getSuccessor(0); } MBasicBlock *ifFalse() const { return getSuccessor(1); } MCompare *mir() { return mir_->toCompare(); } - const LDefinition *temp0() { + const LDefinition *temp() { return getTemp(0); } - const LDefinition *temp1() { + const LDefinition *tempToUnbox() { return getTemp(1); } }; // Takes an object and tests whether it emulates |undefined|, as determined by // the JSCLASS_EMULATES_UNDEFINED class flag on unwrapped objects. See also // js::EmulatesUndefined. class LEmulatesUndefined : public LInstructionHelper<1, 1, 0>
--- a/js/src/ion/Lowering.cpp +++ b/js/src/ion/Lowering.cpp @@ -601,27 +601,27 @@ LIRGenerator::visitTest(MTest *test) MOZ_ASSERT(comp->operandMightEmulateUndefined(), "MCompare::tryFold should handle the never-emulates-undefined case"); LEmulatesUndefinedAndBranch *lir = new LEmulatesUndefinedAndBranch(useRegister(left), ifTrue, ifFalse, temp()); return add(lir, comp); } - LDefinition temp0, temp1; + LDefinition tmp, tmpToUnbox; if (comp->operandMightEmulateUndefined()) { - temp0 = temp(); - temp1 = temp(); + tmp = temp(); + tmpToUnbox = tempToUnbox(); } else { - temp0 = LDefinition::BogusTemp(); - temp1 = LDefinition::BogusTemp(); + tmp = LDefinition::BogusTemp(); + tmpToUnbox = LDefinition::BogusTemp(); } LIsNullOrLikeUndefinedAndBranch *lir = - new LIsNullOrLikeUndefinedAndBranch(ifTrue, ifFalse, temp0, temp1); + new LIsNullOrLikeUndefinedAndBranch(ifTrue, ifFalse, tmp, tmpToUnbox); if (!useBox(lir, LIsNullOrLikeUndefinedAndBranch::Value, left)) return false; return add(lir, comp); } // Compare and branch booleans. if (comp->compareType() == MCompare::Compare_Boolean) { JS_ASSERT(left->type() == MIRType_Value); @@ -744,17 +744,17 @@ LIRGenerator::visitCompare(MCompare *com return assignSafepoint(lir, comp); } // Strict compare between value and string if (comp->compareType() == MCompare::Compare_StrictString) { JS_ASSERT(left->type() == MIRType_Value); JS_ASSERT(right->type() == MIRType_String); - LCompareStrictS *lir = new LCompareStrictS(useRegister(right), temp(), temp()); + LCompareStrictS *lir = new LCompareStrictS(useRegister(right), temp(), tempToUnbox()); if (!useBox(lir, LCompareStrictS::Lhs, left)) return false; if (!define(lir, comp)) return false; return assignSafepoint(lir, comp); } // Unknown/unspecialized compare use a VM call. @@ -780,26 +780,26 @@ LIRGenerator::visitCompare(MCompare *com { if (left->type() == MIRType_Object) { MOZ_ASSERT(comp->operandMightEmulateUndefined(), "MCompare::tryFold should have folded this away"); return define(new LEmulatesUndefined(useRegister(left)), comp); } - LDefinition temp0, temp1; + LDefinition tmp, tmpToUnbox; if (comp->operandMightEmulateUndefined()) { - temp0 = temp(); - temp1 = temp(); + tmp = temp(); + tmpToUnbox = tempToUnbox(); } else { - temp0 = LDefinition::BogusTemp(); - temp1 = LDefinition::BogusTemp(); + tmp = LDefinition::BogusTemp(); + tmpToUnbox = LDefinition::BogusTemp(); } - LIsNullOrLikeUndefined *lir = new LIsNullOrLikeUndefined(temp0, temp1); + LIsNullOrLikeUndefined *lir = new LIsNullOrLikeUndefined(tmp, tmpToUnbox); if (!useBox(lir, LIsNullOrLikeUndefined::Value, left)) return false; return define(lir, comp); } // Compare booleans. if (comp->compareType() == MCompare::Compare_Boolean) { JS_ASSERT(left->type() == MIRType_Value); @@ -1727,30 +1727,40 @@ LIRGenerator::visitStoreSlot(MStoreSlot return true; } bool LIRGenerator::visitTypeBarrier(MTypeBarrier *ins) { // Requesting a non-GC pointer is safe here since we never re-enter C++ // from inside a type barrier test. - LTypeBarrier *barrier = new LTypeBarrier(temp()); + + const types::StackTypeSet *types = ins->resultTypeSet(); + bool needTemp = !types->unknownObject() && types->getObjectCount() > 0; + LDefinition tmp = needTemp ? temp() : tempToUnbox(); + + LTypeBarrier *barrier = new LTypeBarrier(tmp); if (!useBox(barrier, LTypeBarrier::Input, ins->input())) return false; if (!assignSnapshot(barrier, ins->bailoutKind())) return false; return redefine(ins, ins->input()) && add(barrier, ins); } bool LIRGenerator::visitMonitorTypes(MMonitorTypes *ins) { // Requesting a non-GC pointer is safe here since we never re-enter C++ // from inside a type check. - LMonitorTypes *lir = new LMonitorTypes(temp()); + + const types::StackTypeSet *types = ins->typeSet(); + bool needTemp = !types->unknownObject() && types->getObjectCount() > 0; + LDefinition tmp = needTemp ? temp() : tempToUnbox(); + + LMonitorTypes *lir = new LMonitorTypes(tmp); if (!useBox(lir, LMonitorTypes::Input, ins->input())) return false; return assignSnapshot(lir, Bailout_Normal) && add(lir, ins); } bool LIRGenerator::visitPostWriteBarrier(MPostWriteBarrier *ins) { @@ -1758,17 +1768,17 @@ LIRGenerator::visitPostWriteBarrier(MPos switch (ins->value()->type()) { case MIRType_Object: { LPostWriteBarrierO *lir = new LPostWriteBarrierO(useRegisterOrConstant(ins->object()), useRegister(ins->value())); return add(lir, ins) && assignSafepoint(lir, ins); } case MIRType_Value: { LPostWriteBarrierV *lir = - new LPostWriteBarrierV(useRegisterOrConstant(ins->object()), temp()); + new LPostWriteBarrierV(useRegisterOrConstant(ins->object()), tempToUnbox()); if (!useBox(lir, LPostWriteBarrierV::Input, ins->value())) return false; return add(lir, ins) && assignSafepoint(lir, ins); } default: // Currently, only objects can be in the nursery. Other instruction // types cannot hold nursery pointers. return true;
--- a/js/src/ion/arm/Lowering-arm.h +++ b/js/src/ion/arm/Lowering-arm.h @@ -21,16 +21,20 @@ class LIRGeneratorARM : public LIRGenera protected: // Adds a box input to an instruction, setting operand |n| to the type and // |n+1| to the payload. bool useBox(LInstruction *lir, size_t n, MDefinition *mir, LUse::Policy policy = LUse::REGISTER, bool useAtStart = false); bool useBoxFixed(LInstruction *lir, size_t n, MDefinition *mir, Register reg1, Register reg2); + inline LDefinition tempToUnbox() { + return LDefinition::BogusTemp(); + } + void lowerUntypedPhiInput(MPhi *phi, uint32_t inputPosition, LBlock *block, size_t lirIndex); bool defineUntypedPhi(MPhi *phi, size_t lirIndex); bool lowerForShift(LInstructionHelper<1, 2, 0> *ins, MDefinition *mir, MDefinition *lhs, MDefinition *rhs); bool lowerUrshD(MUrsh *mir); bool lowerForALU(LInstructionHelper<1, 1, 0> *ins, MDefinition *mir, MDefinition *input);
--- a/js/src/ion/shared/CodeGenerator-shared-inl.h +++ b/js/src/ion/shared/CodeGenerator-shared-inl.h @@ -41,16 +41,24 @@ ToRegister(const LAllocation *a) static inline Register ToRegister(const LDefinition *def) { return ToRegister(*def->output()); } static inline Register +ToTempUnboxRegister(const LDefinition *def) +{ + if (def->isBogusTemp()) + return InvalidReg; + return ToRegister(def); +} + +static inline Register ToRegisterOrInvalid(const LAllocation *a) { return a ? ToRegister(*a) : InvalidReg; } static inline FloatRegister ToFloatRegister(const LAllocation &a) {
--- a/js/src/ion/x64/Lowering-x64.h +++ b/js/src/ion/x64/Lowering-x64.h @@ -23,16 +23,20 @@ class LIRGeneratorX64 : public LIRGenera void lowerUntypedPhiInput(MPhi *phi, uint32_t inputPosition, LBlock *block, size_t lirIndex); bool defineUntypedPhi(MPhi *phi, size_t lirIndex); // Adds a use at operand |n| of a value-typed insturction. bool useBox(LInstruction *lir, size_t n, MDefinition *mir, LUse::Policy policy = LUse::REGISTER, bool useAtStart = false); bool useBoxFixed(LInstruction *lir, size_t n, MDefinition *mir, Register reg1, Register); + inline LDefinition tempToUnbox() { + return temp(); + } + LGetPropertyCacheT *newLGetPropertyCacheT(MGetPropertyCache *ins); public: bool visitBox(MBox *box); bool visitUnbox(MUnbox *unbox); bool visitReturn(MReturn *ret); bool visitStoreTypedArrayElement(MStoreTypedArrayElement *ins); bool visitStoreTypedArrayElementHole(MStoreTypedArrayElementHole *ins);
--- a/js/src/ion/x86/Lowering-x86.h +++ b/js/src/ion/x86/Lowering-x86.h @@ -21,16 +21,20 @@ class LIRGeneratorX86 : public LIRGenera protected: // Adds a box input to an instruction, setting operand |n| to the type and // |n+1| to the payload. bool useBox(LInstruction *lir, size_t n, MDefinition *mir, LUse::Policy policy = LUse::REGISTER, bool useAtStart = false); bool useBoxFixed(LInstruction *lir, size_t n, MDefinition *mir, Register reg1, Register reg2); + inline LDefinition tempToUnbox() { + return LDefinition::BogusTemp(); + } + void lowerUntypedPhiInput(MPhi *phi, uint32_t inputPosition, LBlock *block, size_t lirIndex); bool defineUntypedPhi(MPhi *phi, size_t lirIndex); LGetPropertyCacheT *newLGetPropertyCacheT(MGetPropertyCache *ins); public: bool visitBox(MBox *box); bool visitUnbox(MUnbox *unbox);