diff options
Diffstat (limited to 'js/src/jit/MIR.h')
-rw-r--r-- | js/src/jit/MIR.h | 188 |
1 files changed, 168 insertions, 20 deletions
diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index cafdbab71..ebc98a4f8 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -375,7 +375,8 @@ class AliasSet { Element = 1 << 1, // A Value member of obj->elements or // a typed object. UnboxedElement = 1 << 2, // An unboxed scalar or reference member of - // typed object or unboxed object. + // a typed array, typed object, or unboxed + // object. DynamicSlot = 1 << 3, // A Value member of obj->slots. FixedSlot = 1 << 4, // A Value member of obj->fixedSlots(). DOMProperty = 1 << 5, // A DOM property @@ -432,6 +433,9 @@ class AliasSet { MOZ_ASSERT(flags && !(flags & Store_)); return AliasSet(flags | Store_); } + static uint32_t BoxedOrUnboxedElements(JSValueType type) { + return (type == JSVAL_TYPE_MAGIC) ? Element : UnboxedElement; + } }; typedef Vector<MDefinition*, 6, JitAllocPolicy> MDefinitionVector; @@ -8758,6 +8762,102 @@ class MSetInitializedLength ALLOW_CLONE(MSetInitializedLength) }; +// Load the length from an unboxed array. +class MUnboxedArrayLength + : public MUnaryInstruction, + public SingleObjectPolicy::Data +{ + explicit MUnboxedArrayLength(MDefinition* object) + : MUnaryInstruction(object) + { + setResultType(MIRType::Int32); + setMovable(); + } + + public: + INSTRUCTION_HEADER(UnboxedArrayLength) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, object)) + + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } + AliasSet getAliasSet() const override { + return AliasSet::Load(AliasSet::ObjectFields); + } + + ALLOW_CLONE(MUnboxedArrayLength) +}; + +// Load the initialized length from an unboxed array. +class MUnboxedArrayInitializedLength + : public MUnaryInstruction, + public SingleObjectPolicy::Data +{ + explicit MUnboxedArrayInitializedLength(MDefinition* object) + : MUnaryInstruction(object) + { + setResultType(MIRType::Int32); + setMovable(); + } + + public: + INSTRUCTION_HEADER(UnboxedArrayInitializedLength) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, object)) + + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } + AliasSet getAliasSet() const override { + return AliasSet::Load(AliasSet::ObjectFields); + } + + ALLOW_CLONE(MUnboxedArrayInitializedLength) +}; + +// Increment the initialized length of an unboxed array object. +class MIncrementUnboxedArrayInitializedLength + : public MUnaryInstruction, + public SingleObjectPolicy::Data +{ + explicit MIncrementUnboxedArrayInitializedLength(MDefinition* obj) + : MUnaryInstruction(obj) + {} + + public: + INSTRUCTION_HEADER(IncrementUnboxedArrayInitializedLength) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, object)) + + AliasSet getAliasSet() const override { + return AliasSet::Store(AliasSet::ObjectFields); + } + + ALLOW_CLONE(MIncrementUnboxedArrayInitializedLength) +}; + +// Set the initialized length of an unboxed array object. +class MSetUnboxedArrayInitializedLength + : public MBinaryInstruction, + public SingleObjectPolicy::Data +{ + explicit MSetUnboxedArrayInitializedLength(MDefinition* obj, MDefinition* length) + : MBinaryInstruction(obj, length) + {} + + public: + INSTRUCTION_HEADER(SetUnboxedArrayInitializedLength) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, object), (1, length)) + + AliasSet getAliasSet() const override { + return AliasSet::Store(AliasSet::ObjectFields); + } + + ALLOW_CLONE(MSetUnboxedArrayInitializedLength) +}; + // Load the array length from an elements header. class MArrayLength : public MUnaryInstruction, @@ -9251,19 +9351,23 @@ class MLoadElement ALLOW_CLONE(MLoadElement) }; -// Load a value from the elements vector of a native object. +// Load a value from the elements vector for a dense native or unboxed array. // If the index is out-of-bounds, or the indexed slot has a hole, undefined is // returned instead. class MLoadElementHole : public MTernaryInstruction, public SingleObjectPolicy::Data { + // Unboxed element type, JSVAL_TYPE_MAGIC for dense native elements. + JSValueType unboxedType_; + bool needsNegativeIntCheck_; bool needsHoleCheck_; MLoadElementHole(MDefinition* elements, MDefinition* index, MDefinition* initLength, - bool needsHoleCheck) + JSValueType unboxedType, bool needsHoleCheck) : MTernaryInstruction(elements, index, initLength), + unboxedType_(unboxedType), needsNegativeIntCheck_(true), needsHoleCheck_(needsHoleCheck) { @@ -9285,6 +9389,9 @@ class MLoadElementHole TRIVIAL_NEW_WRAPPERS NAMED_OPERANDS((0, elements), (1, index), (2, initLength)) + JSValueType unboxedType() const { + return unboxedType_; + } bool needsNegativeIntCheck() const { return needsNegativeIntCheck_; } @@ -9295,6 +9402,8 @@ class MLoadElementHole if (!ins->isLoadElementHole()) return false; const MLoadElementHole* other = ins->toLoadElementHole(); + if (unboxedType() != other->unboxedType()) + return false; if (needsHoleCheck() != other->needsHoleCheck()) return false; if (needsNegativeIntCheck() != other->needsNegativeIntCheck()) @@ -9302,7 +9411,7 @@ class MLoadElementHole return congruentIfOperandsEqual(other); } AliasSet getAliasSet() const override { - return AliasSet::Load(AliasSet::Element); + return AliasSet::Load(AliasSet::BoxedOrUnboxedElements(unboxedType())); } void collectRangeInfoPreTrunc() override; @@ -9482,17 +9591,20 @@ class MStoreElement ALLOW_CLONE(MStoreElement) }; -// Like MStoreElement, but supports indexes >= initialized length. The downside -// is that we cannot hoist the elements vector and bounds check, since this -// instruction may update the (initialized) length and reallocate the elements -// vector. +// Like MStoreElement, but supports indexes >= initialized length, and can +// handle unboxed arrays. The downside is that we cannot hoist the elements +// vector and bounds check, since this instruction may update the (initialized) +// length and reallocate the elements vector. class MStoreElementHole : public MAryInstruction<4>, public MStoreElementCommon, public MixPolicy<SingleObjectPolicy, NoFloatPolicy<3> >::Data { + JSValueType unboxedType_; + MStoreElementHole(MDefinition* object, MDefinition* elements, - MDefinition* index, MDefinition* value) + MDefinition* index, MDefinition* value, JSValueType unboxedType) + : unboxedType_(unboxedType) { initOperand(0, object); initOperand(1, elements); @@ -9507,6 +9619,10 @@ class MStoreElementHole TRIVIAL_NEW_WRAPPERS NAMED_OPERANDS((0, object), (1, elements), (2, index), (3, value)) + JSValueType unboxedType() const { + return unboxedType_; + } + ALLOW_CLONE(MStoreElementHole) }; @@ -9517,11 +9633,13 @@ class MFallibleStoreElement public MStoreElementCommon, public MixPolicy<SingleObjectPolicy, NoFloatPolicy<3> >::Data { + JSValueType unboxedType_; bool strict_; MFallibleStoreElement(MDefinition* object, MDefinition* elements, MDefinition* index, MDefinition* value, - bool strict) + JSValueType unboxedType, bool strict) + : unboxedType_(unboxedType) { initOperand(0, object); initOperand(1, elements); @@ -9537,6 +9655,10 @@ class MFallibleStoreElement TRIVIAL_NEW_WRAPPERS NAMED_OPERANDS((0, object), (1, elements), (2, index), (3, value)) + JSValueType unboxedType() const { + return unboxedType_; + } + bool strict() const { return strict_; } @@ -9640,12 +9762,13 @@ class MArrayPopShift private: Mode mode_; + JSValueType unboxedType_; bool needsHoleCheck_; bool maybeUndefined_; - MArrayPopShift(MDefinition* object, Mode mode, + MArrayPopShift(MDefinition* object, Mode mode, JSValueType unboxedType, bool needsHoleCheck, bool maybeUndefined) - : MUnaryInstruction(object), mode_(mode), + : MUnaryInstruction(object), mode_(mode), unboxedType_(unboxedType), needsHoleCheck_(needsHoleCheck), maybeUndefined_(maybeUndefined) { } @@ -9663,8 +9786,12 @@ class MArrayPopShift bool mode() const { return mode_; } + JSValueType unboxedType() const { + return unboxedType_; + } AliasSet getAliasSet() const override { - return AliasSet::Store(AliasSet::ObjectFields | AliasSet::Element); + return AliasSet::Store(AliasSet::ObjectFields | + AliasSet::BoxedOrUnboxedElements(unboxedType())); } ALLOW_CLONE(MArrayPopShift) @@ -9675,8 +9802,10 @@ class MArrayPush : public MBinaryInstruction, public MixPolicy<SingleObjectPolicy, NoFloatPolicy<1> >::Data { - MArrayPush(MDefinition* object, MDefinition* value) - : MBinaryInstruction(object, value) + JSValueType unboxedType_; + + MArrayPush(MDefinition* object, MDefinition* value, JSValueType unboxedType) + : MBinaryInstruction(object, value), unboxedType_(unboxedType) { setResultType(MIRType::Int32); } @@ -9686,8 +9815,12 @@ class MArrayPush TRIVIAL_NEW_WRAPPERS NAMED_OPERANDS((0, object), (1, value)) + JSValueType unboxedType() const { + return unboxedType_; + } AliasSet getAliasSet() const override { - return AliasSet::Store(AliasSet::ObjectFields | AliasSet::Element); + return AliasSet::Store(AliasSet::ObjectFields | + AliasSet::BoxedOrUnboxedElements(unboxedType())); } void computeRange(TempAllocator& alloc) override; @@ -9701,13 +9834,15 @@ class MArraySlice { CompilerObject templateObj_; gc::InitialHeap initialHeap_; + JSValueType unboxedType_; MArraySlice(CompilerConstraintList* constraints, MDefinition* obj, MDefinition* begin, MDefinition* end, - JSObject* templateObj, gc::InitialHeap initialHeap) + JSObject* templateObj, gc::InitialHeap initialHeap, JSValueType unboxedType) : MTernaryInstruction(obj, begin, end), templateObj_(templateObj), - initialHeap_(initialHeap) + initialHeap_(initialHeap), + unboxedType_(unboxedType) { setResultType(MIRType::Object); } @@ -9725,6 +9860,10 @@ class MArraySlice return initialHeap_; } + JSValueType unboxedType() const { + return unboxedType_; + } + bool possiblyCalls() const override { return true; } @@ -12093,13 +12232,15 @@ class MInArray { bool needsHoleCheck_; bool needsNegativeIntCheck_; + JSValueType unboxedType_; MInArray(MDefinition* elements, MDefinition* index, MDefinition* initLength, MDefinition* object, - bool needsHoleCheck) + bool needsHoleCheck, JSValueType unboxedType) : MQuaternaryInstruction(elements, index, initLength, object), needsHoleCheck_(needsHoleCheck), - needsNegativeIntCheck_(true) + needsNegativeIntCheck_(true), + unboxedType_(unboxedType) { setResultType(MIRType::Boolean); setMovable(); @@ -12119,6 +12260,9 @@ class MInArray bool needsNegativeIntCheck() const { return needsNegativeIntCheck_; } + JSValueType unboxedType() const { + return unboxedType_; + } void collectRangeInfoPreTrunc() override; AliasSet getAliasSet() const override { return AliasSet::Load(AliasSet::Element); @@ -12131,6 +12275,8 @@ class MInArray return false; if (needsNegativeIntCheck() != other->needsNegativeIntCheck()) return false; + if (unboxedType() != other->unboxedType()) + return false; return congruentIfOperandsEqual(other); } }; @@ -14031,6 +14177,8 @@ MDefinition::maybeConstantValue() bool ElementAccessIsDenseNative(CompilerConstraintList* constraints, MDefinition* obj, MDefinition* id); +JSValueType UnboxedArrayElementType(CompilerConstraintList* constraints, MDefinition* obj, + MDefinition* id); bool ElementAccessIsTypedArray(CompilerConstraintList* constraints, MDefinition* obj, MDefinition* id, Scalar::Type* arrayType); |