diff --git a/js/src/ion/CodeGenerator.cpp b/js/src/ion/CodeGenerator.cpp index 4343bae792cc..ccb6f29cd238 100644 --- a/js/src/ion/CodeGenerator.cpp +++ b/js/src/ion/CodeGenerator.cpp @@ -957,20 +957,6 @@ CodeGenerator::visitMonitorTypes(LMonitorTypes *lir) return true; } -bool -CodeGenerator::visitExcludeType(LExcludeType *lir) -{ - ValueOperand operand = ToValue(lir, LExcludeType::Input); - Register scratch = ToRegister(lir->temp()); - - Label matched, miss; - masm.guardType(operand, lir->mir()->type(), scratch, &matched, &miss); - if (matched.used() && !bailoutFrom(&matched, lir->snapshot())) - return false; - masm.bind(&miss); - return true; -} - bool CodeGenerator::visitCallNative(LCallNative *call) { diff --git a/js/src/ion/CodeGenerator.h b/js/src/ion/CodeGenerator.h index 74c555db8ffc..0070f119c85a 100644 --- a/js/src/ion/CodeGenerator.h +++ b/js/src/ion/CodeGenerator.h @@ -84,7 +84,6 @@ class CodeGenerator : public CodeGeneratorSpecific bool visitConvertElementsToDoubles(LConvertElementsToDoubles *lir); bool visitTypeBarrier(LTypeBarrier *lir); bool visitMonitorTypes(LMonitorTypes *lir); - bool visitExcludeType(LExcludeType *lir); bool visitCallNative(LCallNative *call); bool emitCallInvokeFunction(LInstruction *call, Register callereg, uint32_t argc, uint32_t unusedStack); diff --git a/js/src/ion/IonBuilder.cpp b/js/src/ion/IonBuilder.cpp index 28cc96de7aa1..bb2a8f33eee4 100644 --- a/js/src/ion/IonBuilder.cpp +++ b/js/src/ion/IonBuilder.cpp @@ -3027,10 +3027,13 @@ IonBuilder::addTypeBarrier(uint32_t i, CallInfo &callinfo, types::StackTypeSet * callerObs = callinfo.getArgType(i - 1); } + bool needsBarrier = false; + while (excluded) { if (excluded->target == calleeObs && callerObs->hasType(excluded->type)) { if (excluded->type == types::Type::DoubleType() && - calleeObs->hasType(types::Type::Int32Type())) { + calleeObs->hasType(types::Type::Int32Type())) + { // The double type also implies int32, so this implies that // double should be coerced into int if possible, and other // types should remain. @@ -3040,7 +3043,6 @@ IonBuilder::addTypeBarrier(uint32_t i, CallInfo &callinfo, types::StackTypeSet * MInstruction *bailType = MToInt32::New(ins); current->add(bailType); ins = bailType; - break; } else { // We expect either an Int or a Value, this variant is not // optimized and favor the int variant by filtering out all @@ -3054,18 +3056,21 @@ IonBuilder::addTypeBarrier(uint32_t i, CallInfo &callinfo, types::StackTypeSet * current->add(toInt); ins = toInt; } - } else { - JS_ASSERT(!calleeObs->hasType(excluded->type)); - // Filter out unexpected type which are not yet added to the set - // observed type but which are infered by type inference. - MInstruction *bailType = MExcludeType::New(ins, excluded->type); - current->add(bailType); + needsBarrier = false; + break; } + + needsBarrier = true; } excluded = excluded->next; } + if (needsBarrier) { + MTypeBarrier *barrier = MTypeBarrier::New(ins, cloneTypeSet(calleeObs), Bailout_Normal); + current->add(barrier); + } + if (i == 0) callinfo.setThis(ins); else diff --git a/js/src/ion/LIR-Common.h b/js/src/ion/LIR-Common.h index db023f9fbeee..56bfaffc62bf 100644 --- a/js/src/ion/LIR-Common.h +++ b/js/src/ion/LIR-Common.h @@ -3735,11 +3735,10 @@ class LParDump : public LCallInstructionHelper<0, BOX_PIECES, 0> }; // Guard that a value is in a TypeSet. -class LTypeBarrier : public LInstructionHelper +class LTypeBarrier : public LInstructionHelper<0, BOX_PIECES, 1> { public: LIR_HEADER(TypeBarrier) - BOX_OUTPUT_ACCESSORS() LTypeBarrier(const LDefinition &temp) { setTemp(0, temp); @@ -3775,27 +3774,6 @@ class LMonitorTypes : public LInstructionHelper<0, BOX_PIECES, 1> } }; -// Guard that a value is in a TypeSet. -class LExcludeType : public LInstructionHelper<0, BOX_PIECES, 1> -{ - public: - LIR_HEADER(ExcludeType); - BOX_OUTPUT_ACCESSORS(); - - LExcludeType(const LDefinition &temp) { - setTemp(0, temp); - } - - static const size_t Input = 0; - - const MExcludeType *mir() const { - return mir_->toExcludeType(); - } - const LDefinition *temp() { - return getTemp(0); - } -}; - // Guard against an object's class. class LGuardClass : public LInstructionHelper<0, 1, 1> { diff --git a/js/src/ion/LOpcodes.h b/js/src/ion/LOpcodes.h index 54b834c6dcf9..38d67821d5c1 100644 --- a/js/src/ion/LOpcodes.h +++ b/js/src/ion/LOpcodes.h @@ -134,7 +134,6 @@ _(ParDump) \ _(TypeBarrier) \ _(MonitorTypes) \ - _(ExcludeType) \ _(InitializedLength) \ _(SetInitializedLength) \ _(BoundsCheck) \ diff --git a/js/src/ion/Lowering.cpp b/js/src/ion/Lowering.cpp index 729d2524f44a..7f83f6be7083 100644 --- a/js/src/ion/Lowering.cpp +++ b/js/src/ion/Lowering.cpp @@ -1650,7 +1650,7 @@ LIRGenerator::visitTypeBarrier(MTypeBarrier *ins) return false; if (!assignSnapshot(barrier, ins->bailoutKind())) return false; - return defineAs(barrier, ins, ins->input()) && add(barrier); + return redefine(ins, ins->input()) && add(barrier, ins); } bool @@ -1664,18 +1664,6 @@ LIRGenerator::visitMonitorTypes(MMonitorTypes *ins) return assignSnapshot(lir, Bailout_Monitor) && add(lir, ins); } -bool -LIRGenerator::visitExcludeType(MExcludeType *ins) -{ - LExcludeType *filter = new LExcludeType(temp()); - if (!useBox(filter, LExcludeType::Input, ins->input())) - return false; - if (!assignSnapshot(filter, ins->bailoutKind())) - return false; - filter->setMir(ins); - return add(filter); -} - bool LIRGenerator::visitArrayLength(MArrayLength *ins) { diff --git a/js/src/ion/Lowering.h b/js/src/ion/Lowering.h index 56281155a1e0..a5e02ebaeb9a 100644 --- a/js/src/ion/Lowering.h +++ b/js/src/ion/Lowering.h @@ -160,7 +160,6 @@ class LIRGenerator : public LIRGeneratorSpecific bool visitStoreSlot(MStoreSlot *ins); bool visitTypeBarrier(MTypeBarrier *ins); bool visitMonitorTypes(MMonitorTypes *ins); - bool visitExcludeType(MExcludeType *ins); bool visitArrayLength(MArrayLength *ins); bool visitTypedArrayLength(MTypedArrayLength *ins); bool visitTypedArrayElements(MTypedArrayElements *ins); diff --git a/js/src/ion/MIR.h b/js/src/ion/MIR.h index 53371a525e03..437699e20309 100644 --- a/js/src/ion/MIR.h +++ b/js/src/ion/MIR.h @@ -6162,28 +6162,39 @@ class MParDump // Given a value, guard that the value is in a particular TypeSet, then returns // that value. -class MTypeBarrier : public MUnaryInstruction +class MTypeBarrier + : public MUnaryInstruction, + public BoxInputsPolicy { BailoutKind bailoutKind_; const types::StackTypeSet *typeSet_; - MTypeBarrier(MDefinition *def, const types::StackTypeSet *types) + MTypeBarrier(MDefinition *def, const types::StackTypeSet *types, BailoutKind bailoutKind) : MUnaryInstruction(def), typeSet_(types) { setResultType(MIRType_Value); setGuard(); setMovable(); - bailoutKind_ = def->isEffectful() - ? Bailout_TypeBarrier - : Bailout_Normal; + bailoutKind_ = bailoutKind; } public: INSTRUCTION_HEADER(TypeBarrier) static MTypeBarrier *New(MDefinition *def, const types::StackTypeSet *types) { - return new MTypeBarrier(def, types); + BailoutKind bailoutKind = def->isEffectful() + ? Bailout_TypeBarrier + : Bailout_Normal; + return new MTypeBarrier(def, types, bailoutKind); + } + static MTypeBarrier *New(MDefinition *def, const types::StackTypeSet *types, + BailoutKind bailoutKind) { + return new MTypeBarrier(def, types, bailoutKind); + } + + TypePolicy *typePolicy() { + return this; } bool congruentTo(MDefinition * const &def) const { @@ -6204,7 +6215,6 @@ class MTypeBarrier : public MUnaryInstruction virtual bool neverHoist() const { return typeSet()->empty(); } - }; // Like MTypeBarrier, guard that the value is in the given type set. This is @@ -6240,46 +6250,6 @@ class MMonitorTypes : public MUnaryInstruction } }; -// Guards that the incoming value does not have the specified Type. -class MExcludeType - : public MUnaryInstruction, - public BoxInputsPolicy -{ - types::Type type_; - - MExcludeType(MDefinition *def, types::Type type) - : MUnaryInstruction(def), - type_(type) - { - setGuard(); - setMovable(); - } - - public: - INSTRUCTION_HEADER(ExcludeType); - - static MExcludeType *New(MDefinition *def, types::Type type) { - return new MExcludeType(def, type); - } - - MDefinition *input() const { - return getOperand(0); - } - BailoutKind bailoutKind() const { - return Bailout_Normal; - } - types::Type type() const { - return type_; - } - - TypePolicy *typePolicy() { - return this; - } - AliasSet getAliasSet() const { - return AliasSet::None(); - } -}; - class MNewSlots : public MNullaryInstruction { unsigned nslots_; diff --git a/js/src/ion/MOpcodes.h b/js/src/ion/MOpcodes.h index 2d36ecc924fa..9c2133b3acd5 100644 --- a/js/src/ion/MOpcodes.h +++ b/js/src/ion/MOpcodes.h @@ -98,7 +98,6 @@ namespace ion { _(FunctionEnvironment) \ _(TypeBarrier) \ _(MonitorTypes) \ - _(ExcludeType) \ _(GetPropertyCache) \ _(GetElementCache) \ _(BindNameCache) \ diff --git a/js/src/ion/ParallelArrayAnalysis.cpp b/js/src/ion/ParallelArrayAnalysis.cpp index cebf8c8e65e0..735695faa4d4 100644 --- a/js/src/ion/ParallelArrayAnalysis.cpp +++ b/js/src/ion/ParallelArrayAnalysis.cpp @@ -194,7 +194,6 @@ class ParallelArrayVisitor : public MInstructionVisitor SAFE_OP(FunctionEnvironment) // just a load of func env ptr SAFE_OP(TypeBarrier) // causes a bailout if the type is not found: a-ok with us SAFE_OP(MonitorTypes) // causes a bailout if the type is not found: a-ok with us - SAFE_OP(ExcludeType) // causes a bailout if the type is not found: a-ok with us UNSAFE_OP(GetPropertyCache) UNSAFE_OP(GetElementCache) UNSAFE_OP(BindNameCache)