diff --git a/js/src/ion/CodeGenerator.cpp b/js/src/ion/CodeGenerator.cpp index 67bc9ef15ac..5106493af10 100644 --- a/js/src/ion/CodeGenerator.cpp +++ b/js/src/ion/CodeGenerator.cpp @@ -2648,6 +2648,11 @@ CodeGenerator::visitNewStringObject(LNewStringObject *lir) return true; } +typedef bool(*InitPropFn)(JSContext *cx, HandleObject obj, + HandlePropertyName name, HandleValue value); +static const VMFunction InitPropInfo = + FunctionInfo(InitProp); + bool CodeGenerator::visitParNew(LParNew *lir) { @@ -2742,28 +2747,6 @@ CodeGenerator::visitParBailout(LParBailout *lir) return true; } -typedef bool(*InitElemFn)(JSContext *cx, HandleObject obj, - HandleValue id, HandleValue value); -static const VMFunction InitElemInfo = - FunctionInfo(InitElemOperation); - -bool -CodeGenerator::visitInitElem(LInitElem *lir) -{ - Register objReg = ToRegister(lir->getObject()); - - pushArg(ToValue(lir, LInitElem::ValueIndex)); - pushArg(ToValue(lir, LInitElem::IdIndex)); - pushArg(objReg); - - return callVM(InitElemInfo, lir); -} - -typedef bool(*InitPropFn)(JSContext *cx, HandleObject obj, - HandlePropertyName name, HandleValue value); -static const VMFunction InitPropInfo = - FunctionInfo(InitProp); - bool CodeGenerator::visitInitProp(LInitProp *lir) { @@ -5578,76 +5561,35 @@ CodeGenerator::visitIn(LIn *ins) return callVM(OperatorInInfo, ins); } -typedef bool (*OperatorInIFn)(JSContext *, uint32_t, HandleObject, JSBool *); -static const VMFunction OperatorInIInfo = FunctionInfo(OperatorInI); - bool CodeGenerator::visitInArray(LInArray *lir) { - const MInArray *mir = lir->mir(); Register elements = ToRegister(lir->elements()); Register initLength = ToRegister(lir->initLength()); Register output = ToRegister(lir->output()); // When the array is not packed we need to do a hole check in addition to the bounds check. - Label falseBranch, done, trueBranch; - - OutOfLineCode *ool = NULL; - Label* failedInitLength = &falseBranch; - + Label falseBranch, done; if (lir->index()->isConstant()) { - int32_t index = ToInt32(lir->index()); - - JS_ASSERT_IF(index < 0, mir->needsNegativeIntCheck()); - if (mir->needsNegativeIntCheck()) { - ool = oolCallVM(OperatorInIInfo, lir, - (ArgList(), Imm32(index), ToRegister(lir->object())), - StoreRegisterTo(output)); - failedInitLength = ool->entry(); - } - - masm.branch32(Assembler::BelowOrEqual, initLength, Imm32(index), failedInitLength); - if (mir->needsHoleCheck()) { - Address address = Address(elements, index * sizeof(Value)); - masm.branchTestMagic(Assembler::Equal, address, &falseBranch); + masm.branch32(Assembler::BelowOrEqual, initLength, Imm32(ToInt32(lir->index())), &falseBranch); + if (lir->mir()->needsHoleCheck()) { + masm.branchTestMagic(Assembler::Equal, Address(elements, ToInt32(lir->index()) * sizeof(Value)), + &falseBranch); } } else { - Label negativeIntCheck; - Register index = ToRegister(lir->index()); - - if (mir->needsNegativeIntCheck()) - failedInitLength = &negativeIntCheck; - - masm.branch32(Assembler::BelowOrEqual, initLength, index, failedInitLength); - if (mir->needsHoleCheck()) { - BaseIndex address = BaseIndex(elements, ToRegister(lir->index()), TimesEight); - masm.branchTestMagic(Assembler::Equal, address, &falseBranch); - } - masm.jump(&trueBranch); - - if (mir->needsNegativeIntCheck()) { - masm.bind(&negativeIntCheck); - ool = oolCallVM(OperatorInIInfo, lir, - (ArgList(), index, ToRegister(lir->object())), - StoreRegisterTo(output)); - - masm.testl(index, index); - masm.j(Assembler::Signed, ool->entry()); - masm.jump(&falseBranch); + masm.branch32(Assembler::BelowOrEqual, initLength, ToRegister(lir->index()), &falseBranch); + if (lir->mir()->needsHoleCheck()) { + masm.branchTestMagic(Assembler::Equal, BaseIndex(elements, ToRegister(lir->index()), TimesEight), + &falseBranch); } } - masm.bind(&trueBranch); masm.move32(Imm32(1), output); masm.jump(&done); masm.bind(&falseBranch); masm.move32(Imm32(0), output); masm.bind(&done); - - if (ool) - masm.bind(ool->rejoin()); - return true; } diff --git a/js/src/ion/CodeGenerator.h b/js/src/ion/CodeGenerator.h index b48e613a949..4130a3611eb 100644 --- a/js/src/ion/CodeGenerator.h +++ b/js/src/ion/CodeGenerator.h @@ -116,7 +116,6 @@ class CodeGenerator : public CodeGeneratorSpecific bool visitParNew(LParNew *lir); bool visitParNewDenseArray(LParNewDenseArray *lir); bool visitParBailout(LParBailout *lir); - bool visitInitElem(LInitElem *lir); bool visitInitProp(LInitProp *lir); bool visitCreateThis(LCreateThis *lir); bool visitCreateThisWithProto(LCreateThisWithProto *lir); diff --git a/js/src/ion/IonBuilder.cpp b/js/src/ion/IonBuilder.cpp index f4e080bdd36..0aa2d376f40 100644 --- a/js/src/ion/IonBuilder.cpp +++ b/js/src/ion/IonBuilder.cpp @@ -952,9 +952,6 @@ IonBuilder::inspectOpcode(JSOp op) return jsop_newobject(baseObj); } - case JSOP_INITELEM: - return jsop_initelem(); - case JSOP_INITELEM_ARRAY: return jsop_initelem_array(); @@ -4782,19 +4779,6 @@ IonBuilder::jsop_newobject(HandleObject baseObj) return resumeAfter(ins); } -bool -IonBuilder::jsop_initelem() -{ - MDefinition *value = current->pop(); - MDefinition *id = current->pop(); - MDefinition *obj = current->peek(-1); - - MInitElem *initElem = MInitElem::New(obj, id, value); - current->add(initElem); - - return resumeAfter(initElem); -} - bool IonBuilder::jsop_initelem_array() { @@ -7410,7 +7394,7 @@ IonBuilder::jsop_in_dense() current->add(initLength); // Check if id < initLength and elem[id] not a hole. - MInArray *ins = MInArray::New(elements, id, initLength, obj, needsHoleCheck); + MInArray *ins = MInArray::New(elements, id, initLength, needsHoleCheck); current->add(ins); current->push(ins); diff --git a/js/src/ion/IonBuilder.h b/js/src/ion/IonBuilder.h index 91fdee67303..8f8f2a48673 100644 --- a/js/src/ion/IonBuilder.h +++ b/js/src/ion/IonBuilder.h @@ -375,7 +375,6 @@ class IonBuilder : public MIRGenerator bool jsop_delprop(HandlePropertyName name); bool jsop_newarray(uint32_t count); bool jsop_newobject(HandleObject baseObj); - bool jsop_initelem(); bool jsop_initelem_array(); bool jsop_initprop(HandlePropertyName name); bool jsop_regexp(RegExpObject *reobj); diff --git a/js/src/ion/LIR-Common.h b/js/src/ion/LIR-Common.h index 56eaa8d0d19..5d6ef835e6b 100644 --- a/js/src/ion/LIR-Common.h +++ b/js/src/ion/LIR-Common.h @@ -478,26 +478,6 @@ class LParBailout : public LInstructionHelper<0, 0, 0> LIR_HEADER(ParBailout); }; -class LInitElem : public LCallInstructionHelper<0, 1 + 2*BOX_PIECES, 0> -{ - public: - LIR_HEADER(InitElem) - - LInitElem(const LAllocation &object) { - setOperand(0, object); - } - - static const size_t IdIndex = 1; - static const size_t ValueIndex = 1 + BOX_PIECES; - - const LAllocation *getObject() { - return getOperand(0); - } - MInitElem *mir() const { - return mir_->toInitElem(); - } -}; - // Takes in an Object and a Value. class LInitProp : public LCallInstructionHelper<0, 1 + BOX_PIECES, 0> { @@ -2738,18 +2718,15 @@ class LLoadElementV : public LInstructionHelper } }; -class LInArray : public LInstructionHelper<1, 4, 0> +class LInArray : public LInstructionHelper<1, 3, 0> { public: LIR_HEADER(InArray) - LInArray(const LAllocation &elements, const LAllocation &index, - const LAllocation &initLength, const LAllocation &object) - { + LInArray(const LAllocation &elements, const LAllocation &index, const LAllocation &initLength) { setOperand(0, elements); setOperand(1, index); setOperand(2, initLength); - setOperand(3, object); } const MInArray *mir() const { return mir_->toInArray(); @@ -2763,9 +2740,6 @@ class LInArray : public LInstructionHelper<1, 4, 0> const LAllocation *initLength() { return getOperand(2); } - const LAllocation *object() { - return getOperand(3); - } }; diff --git a/js/src/ion/LOpcodes.h b/js/src/ion/LOpcodes.h index 88142926f1c..b7bf009b266 100644 --- a/js/src/ion/LOpcodes.h +++ b/js/src/ion/LOpcodes.h @@ -32,7 +32,6 @@ _(ParNewDenseArray) \ _(ParNewCallObject) \ _(ParBailout) \ - _(InitElem) \ _(InitProp) \ _(CheckOverRecursed) \ _(ParCheckOverRecursed) \ diff --git a/js/src/ion/Lowering.cpp b/js/src/ion/Lowering.cpp index f36d0984a4d..75de254f657 100644 --- a/js/src/ion/Lowering.cpp +++ b/js/src/ion/Lowering.cpp @@ -237,18 +237,6 @@ LIRGenerator::visitParBailout(MParBailout *ins) return add(lir, ins); } -bool -LIRGenerator::visitInitElem(MInitElem *ins) -{ - LInitElem *lir = new LInitElem(useRegisterAtStart(ins->getObject())); - if (!useBoxAtStart(lir, LInitElem::IdIndex, ins->getId())) - return false; - if (!useBoxAtStart(lir, LInitElem::ValueIndex, ins->getValue())) - return false; - - return add(lir, ins) && assignSafepoint(lir, ins); -} - bool LIRGenerator::visitInitProp(MInitProp *ins) { @@ -1831,19 +1819,11 @@ LIRGenerator::visitInArray(MInArray *ins) JS_ASSERT(ins->elements()->type() == MIRType_Elements); JS_ASSERT(ins->index()->type() == MIRType_Int32); JS_ASSERT(ins->initLength()->type() == MIRType_Int32); - JS_ASSERT(ins->object()->type() == MIRType_Object); JS_ASSERT(ins->type() == MIRType_Boolean); - LAllocation object; - if (ins->needsNegativeIntCheck()) - object = useRegister(ins->object()); - else - object = LConstantIndex::Bogus(); - LInArray *lir = new LInArray(useRegister(ins->elements()), useRegisterOrConstant(ins->index()), - useRegister(ins->initLength()), - object); + useRegister(ins->initLength())); return define(lir, ins) && assignSafepoint(lir, ins); } diff --git a/js/src/ion/Lowering.h b/js/src/ion/Lowering.h index 6e11bcdbf05..cc8cd249df8 100644 --- a/js/src/ion/Lowering.h +++ b/js/src/ion/Lowering.h @@ -94,7 +94,6 @@ class LIRGenerator : public LIRGeneratorSpecific bool visitParNewCallObject(MParNewCallObject *ins); bool visitParNewDenseArray(MParNewDenseArray *ins); bool visitParBailout(MParBailout *ins); - bool visitInitElem(MInitElem *ins); bool visitInitProp(MInitProp *ins); bool visitCheckOverRecursed(MCheckOverRecursed *ins); bool visitParCheckOverRecursed(MParCheckOverRecursed *ins); diff --git a/js/src/ion/MIR.cpp b/js/src/ion/MIR.cpp index 2914423b66b..7b94d6c7419 100644 --- a/js/src/ion/MIR.cpp +++ b/js/src/ion/MIR.cpp @@ -2007,12 +2007,6 @@ InlinePropertyTable::hasFunction(JSFunction *func) const return false; } -bool -MInArray::needsNegativeIntCheck() const -{ - return !index()->range() || index()->range()->lower() < 0; -} - MDefinition * MAsmJSUnsignedToDouble::foldsTo(bool useValueNumbers) { diff --git a/js/src/ion/MIR.h b/js/src/ion/MIR.h index 58437d641a5..faa0d1ed38f 100644 --- a/js/src/ion/MIR.h +++ b/js/src/ion/MIR.h @@ -1243,39 +1243,6 @@ class MInitProp } }; -class MInitElem - : public MAryInstruction<3>, - public Mix3Policy, BoxPolicy<1>, BoxPolicy<2> > -{ - MInitElem(MDefinition *obj, MDefinition *id, MDefinition *value) - { - setOperand(0, obj); - setOperand(1, id); - setOperand(2, value); - setResultType(MIRType_None); - } - - public: - INSTRUCTION_HEADER(InitElem) - - static MInitElem *New(MDefinition *obj, MDefinition *id, MDefinition *value) { - return new MInitElem(obj, id, value); - } - - MDefinition *getObject() const { - return getOperand(0); - } - MDefinition *getId() const { - return getOperand(1); - } - MDefinition *getValue() const { - return getOperand(2); - } - TypePolicy *typePolicy() { - return this; - } -}; - // Designates the start of call frame construction. // Generates code to adjust the stack pointer for the argument vector. // Argc is inferred by checking the use chain during lowering. @@ -1687,57 +1654,6 @@ class MTernaryInstruction : public MAryInstruction<3> } }; -class MQuaternaryInstruction : public MAryInstruction<4> -{ - protected: - MQuaternaryInstruction(MDefinition *first, MDefinition *second, - MDefinition *third, MDefinition *fourth) - { - setOperand(0, first); - setOperand(1, second); - setOperand(2, third); - setOperand(3, fourth); - } - - protected: - HashNumber valueHash() const - { - MDefinition *first = getOperand(0); - MDefinition *second = getOperand(1); - MDefinition *third = getOperand(2); - MDefinition *fourth = getOperand(3); - - return op() ^ first->valueNumber() ^ second->valueNumber() ^ - third->valueNumber() ^ fourth->valueNumber(); - } - - bool congruentTo(MDefinition *const &ins) const - { - if (op() != ins->op()) - return false; - - if (type() != ins->type()) - return false; - - if (isEffectful() || ins->isEffectful()) - return false; - - MDefinition *first = getOperand(0); - MDefinition *second = getOperand(1); - MDefinition *third = getOperand(2); - MDefinition *fourth = getOperand(3); - MDefinition *insFirst = ins->getOperand(0); - MDefinition *insSecond = ins->getOperand(1); - MDefinition *insThird = ins->getOperand(2); - MDefinition *insFourth = ins->getOperand(3); - - return first->valueNumber() == insFirst->valueNumber() && - second->valueNumber() == insSecond->valueNumber() && - third->valueNumber() == insThird->valueNumber() && - fourth->valueNumber() == insFourth->valueNumber(); - } -}; - class MCompare : public MBinaryInstruction, public ComparePolicy @@ -6379,15 +6295,12 @@ class MIn // Test whether the index is in the array bounds or a hole. class MInArray - : public MQuaternaryInstruction, - public ObjectPolicy<3> + : public MTernaryInstruction { bool needsHoleCheck_; - MInArray(MDefinition *elements, MDefinition *index, - MDefinition *initLength, MDefinition *object, - bool needsHoleCheck) - : MQuaternaryInstruction(elements, index, initLength, object), + MInArray(MDefinition *elements, MDefinition *index, MDefinition *initLength, bool needsHoleCheck) + : MTernaryInstruction(elements, index, initLength), needsHoleCheck_(needsHoleCheck) { setResultType(MIRType_Boolean); @@ -6401,10 +6314,8 @@ class MInArray INSTRUCTION_HEADER(InArray) static MInArray *New(MDefinition *elements, MDefinition *index, - MDefinition *initLength, MDefinition *object, - bool needsHoleCheck) - { - return new MInArray(elements, index, initLength, object, needsHoleCheck); + MDefinition *initLength, bool needsHoleCheck) { + return new MInArray(elements, index, initLength, needsHoleCheck); } MDefinition *elements() const { @@ -6416,19 +6327,12 @@ class MInArray MDefinition *initLength() const { return getOperand(2); } - MDefinition *object() const { - return getOperand(3); - } bool needsHoleCheck() const { return needsHoleCheck_; } - bool needsNegativeIntCheck() const; AliasSet getAliasSet() const { return AliasSet::Load(AliasSet::Element); } - TypePolicy *typePolicy() { - return this; - } }; // Implementation for instanceof operator with specific rhs. diff --git a/js/src/ion/MOpcodes.h b/js/src/ion/MOpcodes.h index 06630fd7ae2..a5123a627cc 100644 --- a/js/src/ion/MOpcodes.h +++ b/js/src/ion/MOpcodes.h @@ -81,7 +81,6 @@ namespace ion { _(NewDeclEnvObject) \ _(NewCallObject) \ _(NewStringObject) \ - _(InitElem) \ _(InitProp) \ _(Start) \ _(OsrEntry) \ diff --git a/js/src/ion/ParallelArrayAnalysis.cpp b/js/src/ion/ParallelArrayAnalysis.cpp index 3fe70a52343..364df7b0902 100644 --- a/js/src/ion/ParallelArrayAnalysis.cpp +++ b/js/src/ion/ParallelArrayAnalysis.cpp @@ -172,7 +172,6 @@ class ParallelArrayVisitor : public MInstructionVisitor CUSTOM_OP(NewObject) CUSTOM_OP(NewCallObject) CUSTOM_OP(NewParallelArray) - UNSAFE_OP(InitElem) UNSAFE_OP(InitProp) SAFE_OP(Start) UNSAFE_OP(OsrEntry) diff --git a/js/src/ion/TypePolicy.cpp b/js/src/ion/TypePolicy.cpp index f26e28caecd..9cec5d4a8f5 100644 --- a/js/src/ion/TypePolicy.cpp +++ b/js/src/ion/TypePolicy.cpp @@ -399,8 +399,6 @@ ObjectPolicy::staticAdjustInputs(MInstruction *ins) template bool ObjectPolicy<0>::staticAdjustInputs(MInstruction *ins); template bool ObjectPolicy<1>::staticAdjustInputs(MInstruction *ins); -template bool ObjectPolicy<2>::staticAdjustInputs(MInstruction *ins); -template bool ObjectPolicy<3>::staticAdjustInputs(MInstruction *ins); bool CallPolicy::adjustInputs(MInstruction *ins) diff --git a/js/src/ion/TypePolicy.h b/js/src/ion/TypePolicy.h index 3dd5812581b..3f209e53c85 100644 --- a/js/src/ion/TypePolicy.h +++ b/js/src/ion/TypePolicy.h @@ -186,20 +186,6 @@ class MixPolicy : public TypePolicy } }; -// Combine three policies. -template -class Mix3Policy : public TypePolicy -{ - public: - static bool staticAdjustInputs(MInstruction *ins) { - return Policy1::staticAdjustInputs(ins) && Policy2::staticAdjustInputs(ins) && - Policy3::staticAdjustInputs(ins); - } - virtual bool adjustInputs(MInstruction *ins) { - return staticAdjustInputs(ins); - } -}; - class CallSetElementPolicy : public SingleObjectPolicy { public: diff --git a/js/src/ion/VMFunctions.cpp b/js/src/ion/VMFunctions.cpp index b1dd826206a..c9f2f8dda26 100644 --- a/js/src/ion/VMFunctions.cpp +++ b/js/src/ion/VMFunctions.cpp @@ -507,13 +507,6 @@ OperatorIn(JSContext *cx, HandleValue key, HandleObject obj, JSBool *out) return true; } -bool -OperatorInI(JSContext *cx, uint32_t index, HandleObject obj, JSBool *out) -{ - RootedValue key(cx, Int32Value(index)); - return OperatorIn(cx, key, obj, out); -} - bool GetIntrinsicValue(JSContext *cx, HandlePropertyName name, MutableHandleValue rval) { diff --git a/js/src/ion/VMFunctions.h b/js/src/ion/VMFunctions.h index 13be91aea58..c7477ddd2b0 100644 --- a/js/src/ion/VMFunctions.h +++ b/js/src/ion/VMFunctions.h @@ -521,7 +521,6 @@ bool SPSEnter(JSContext *cx, HandleScript script); bool SPSExit(JSContext *cx, HandleScript script); bool OperatorIn(JSContext *cx, HandleValue key, HandleObject obj, JSBool *out); -bool OperatorInI(JSContext *cx, uint32_t index, HandleObject obj, JSBool *out); bool GetIntrinsicValue(JSContext *cx, HandlePropertyName name, MutableHandleValue rval); diff --git a/js/src/jit-test/tests/ion/bug861165.js b/js/src/jit-test/tests/ion/bug861165.js deleted file mode 100644 index 924dcbaaef8..00000000000 --- a/js/src/jit-test/tests/ion/bug861165.js +++ /dev/null @@ -1,85 +0,0 @@ -// |jit-test| no-jm - -// IM has the following fastpaths: -// - constant index (constant) -// - need negative int check (neg) -// - needs hole check (hole) -// So to test everything we have to do: -// constant | neg | hole -// test 1: 0 0 0 -// test 2: 1 0 0 -// test 3: 0 1 0 -// test 4: 1 1 0 -// test 5: 0 0 1 -// test 6: 1 0 1 -// test 7: 0 1 1 -// test 8: 1 1 1 - -function test1(index, a) { - if (index < 0) - index = -index - return index in a; -} -assertEq(test1(1, [1,2]), true); - -function test2(a) { - return 0 in a; -} -assertEq(test2([1,2]), true); - -function test3(index, a) { - return index in a; -} - -var arr3 = []; -arr3["-1073741828"] = 17; -assertEq(test3(-1073741828, arr3), true); - -function test4(a) { - return -1073741828 in a; -} -assertEq(test4(arr3), true); - - -function test5(index, a) { - if (index < 0) - index = -index - return index in a; -} -var arr5 = []; -arr5[0] = 1 -arr5[1] = 1 -arr5[2] = 1 -arr5[4] = 1 -assertEq(test5(1, arr5), true); -assertEq(test5(3, arr5), false); - -function test7a(a) { - return 3 in a; -} -function test7b(a) { - return 4 in a; -} -assertEq(test7a(arr5), false); -assertEq(test7b(arr5), true); - -function test8(index, a) { - return index in a; -} -arr5["-1073741828"] = 17; -assertEq(test8(-1073741828, arr5), true); -assertEq(test8(3, arr5), false); -assertEq(test8(0, arr5), true); - -function test9a(a) { - return 0 in a; -} -function test9b(a) { - return 3 in a; -} -function test9c(a) { - return -1073741828 in a; -} -assertEq(test9a(arr5), true); -assertEq(test9b(arr5), false); -assertEq(test9c(arr5), true);