mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-18 15:55:36 +00:00
Bug 1699271 - Part 10: Auto generate more MIR instructions. r=iain
Differential Revision: https://phabricator.services.mozilla.com/D112685
This commit is contained in:
parent
08b92c3498
commit
f3a7647605
@ -370,7 +370,7 @@ void LIRGenerator::visitLoadArgumentsObjectArg(MLoadArgumentsObjectArg* ins) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LIRGenerator::visitArgumentsObjectLength(MArgumentsObjectLength* ins) {
|
void LIRGenerator::visitArgumentsObjectLength(MArgumentsObjectLength* ins) {
|
||||||
MDefinition* argsObj = ins->getArgsObject();
|
MDefinition* argsObj = ins->argsObject();
|
||||||
MOZ_ASSERT(argsObj->type() == MIRType::Object);
|
MOZ_ASSERT(argsObj->type() == MIRType::Object);
|
||||||
|
|
||||||
auto* lir = new (alloc()) LArgumentsObjectLength(useRegister(argsObj));
|
auto* lir = new (alloc()) LArgumentsObjectLength(useRegister(argsObj));
|
||||||
|
@ -3109,6 +3109,11 @@ AliasSet MLoadArgumentsObjectArg::getAliasSet() const {
|
|||||||
return AliasSet::Load(AliasSet::Any);
|
return AliasSet::Load(AliasSet::Any);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AliasSet MArgumentsObjectLength::getAliasSet() const {
|
||||||
|
return AliasSet::Load(AliasSet::ObjectFields | AliasSet::FixedSlot |
|
||||||
|
AliasSet::DynamicSlot);
|
||||||
|
}
|
||||||
|
|
||||||
MDefinition* MReturnFromCtor::foldsTo(TempAllocator& alloc) {
|
MDefinition* MReturnFromCtor::foldsTo(TempAllocator& alloc) {
|
||||||
MDefinition* rval = value();
|
MDefinition* rval = value();
|
||||||
if (rval->isBox()) {
|
if (rval->isBox()) {
|
||||||
@ -5090,6 +5095,22 @@ AliasSet MElements::getAliasSet() const {
|
|||||||
return AliasSet::Load(AliasSet::ObjectFields);
|
return AliasSet::Load(AliasSet::ObjectFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AliasSet MInitializedLength::getAliasSet() const {
|
||||||
|
return AliasSet::Load(AliasSet::ObjectFields);
|
||||||
|
}
|
||||||
|
|
||||||
|
AliasSet MSetInitializedLength::getAliasSet() const {
|
||||||
|
return AliasSet::Store(AliasSet::ObjectFields);
|
||||||
|
}
|
||||||
|
|
||||||
|
AliasSet MArrayLength::getAliasSet() const {
|
||||||
|
return AliasSet::Load(AliasSet::ObjectFields);
|
||||||
|
}
|
||||||
|
|
||||||
|
AliasSet MSetArrayLength::getAliasSet() const {
|
||||||
|
return AliasSet::Store(AliasSet::ObjectFields);
|
||||||
|
}
|
||||||
|
|
||||||
AliasSet MFunctionLength::getAliasSet() const {
|
AliasSet MFunctionLength::getAliasSet() const {
|
||||||
return AliasSet::Load(AliasSet::ObjectFields | AliasSet::FixedSlot |
|
return AliasSet::Load(AliasSet::ObjectFields | AliasSet::FixedSlot |
|
||||||
AliasSet::DynamicSlot);
|
AliasSet::DynamicSlot);
|
||||||
@ -5108,6 +5129,10 @@ AliasSet MArrayBufferViewLength::getAliasSet() const {
|
|||||||
return AliasSet::Load(AliasSet::ArrayBufferViewLengthOrOffset);
|
return AliasSet::Load(AliasSet::ArrayBufferViewLengthOrOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AliasSet MArrayBufferViewByteOffset::getAliasSet() const {
|
||||||
|
return AliasSet::Load(AliasSet::ArrayBufferViewLengthOrOffset);
|
||||||
|
}
|
||||||
|
|
||||||
AliasSet MArrayBufferViewElements::getAliasSet() const {
|
AliasSet MArrayBufferViewElements::getAliasSet() const {
|
||||||
return AliasSet::Load(AliasSet::ObjectFields);
|
return AliasSet::Load(AliasSet::ObjectFields);
|
||||||
}
|
}
|
||||||
@ -5365,6 +5390,13 @@ MDefinition* MGuardSpecificSymbol::foldsTo(TempAllocator& alloc) {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MCallBindVar::congruentTo(const MDefinition* ins) const {
|
||||||
|
if (!ins->isCallBindVar()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return congruentIfOperandsEqual(ins);
|
||||||
|
}
|
||||||
|
|
||||||
MDefinition* MGuardIsNotProxy::foldsTo(TempAllocator& alloc) {
|
MDefinition* MGuardIsNotProxy::foldsTo(TempAllocator& alloc) {
|
||||||
KnownClass known = GetObjectKnownClass(object());
|
KnownClass known = GetObjectKnownClass(object());
|
||||||
if (known == KnownClass::None) {
|
if (known == KnownClass::None) {
|
||||||
|
336
js/src/jit/MIR.h
336
js/src/jit/MIR.h
@ -1535,24 +1535,6 @@ class MParameter : public MNullaryInstruction {
|
|||||||
bool congruentTo(const MDefinition* ins) const override;
|
bool congruentTo(const MDefinition* ins) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MCallee : public MNullaryInstruction {
|
|
||||||
public:
|
|
||||||
MCallee() : MNullaryInstruction(classOpcode) {
|
|
||||||
setResultType(MIRType::Object);
|
|
||||||
setMovable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
INSTRUCTION_HEADER(Callee)
|
|
||||||
TRIVIAL_NEW_WRAPPERS
|
|
||||||
|
|
||||||
bool congruentTo(const MDefinition* ins) const override {
|
|
||||||
return congruentIfOperandsEqual(ins);
|
|
||||||
}
|
|
||||||
|
|
||||||
AliasSet getAliasSet() const override { return AliasSet::None(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class MControlInstruction : public MInstruction {
|
class MControlInstruction : public MInstruction {
|
||||||
protected:
|
protected:
|
||||||
explicit MControlInstruction(Opcode op) : MInstruction(op) {}
|
explicit MControlInstruction(Opcode op) : MInstruction(op) {}
|
||||||
@ -3144,34 +3126,6 @@ class MSetArgumentsObjectArg
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Load |arguments.length|. Bails out if the length has been overriden.
|
|
||||||
class MArgumentsObjectLength : public MUnaryInstruction,
|
|
||||||
public SingleObjectPolicy::Data {
|
|
||||||
explicit MArgumentsObjectLength(MDefinition* argsObj)
|
|
||||||
: MUnaryInstruction(classOpcode, argsObj) {
|
|
||||||
setResultType(MIRType::Int32);
|
|
||||||
setMovable();
|
|
||||||
setGuard();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
INSTRUCTION_HEADER(ArgumentsObjectLength)
|
|
||||||
TRIVIAL_NEW_WRAPPERS
|
|
||||||
NAMED_OPERANDS((0, getArgsObject))
|
|
||||||
|
|
||||||
bool congruentTo(const MDefinition* ins) const override {
|
|
||||||
return congruentIfOperandsEqual(ins);
|
|
||||||
}
|
|
||||||
|
|
||||||
AliasSet getAliasSet() const override {
|
|
||||||
// Even though the "length" property is lazily resolved, it acts similar to
|
|
||||||
// a normal property load, so we can treat this operation like any other
|
|
||||||
// property read.
|
|
||||||
return AliasSet::Load(AliasSet::ObjectFields | AliasSet::FixedSlot |
|
|
||||||
AliasSet::DynamicSlot);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Guard that the given flags are not set on the arguments object.
|
// Guard that the given flags are not set on the arguments object.
|
||||||
class MGuardArgumentsObjectFlags : public MUnaryInstruction,
|
class MGuardArgumentsObjectFlags : public MUnaryInstruction,
|
||||||
public SingleObjectPolicy::Data {
|
public SingleObjectPolicy::Data {
|
||||||
@ -3341,26 +3295,6 @@ class MToFloat32 : public MToFPInstruction {
|
|||||||
ALLOW_CLONE(MToFloat32)
|
ALLOW_CLONE(MToFloat32)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Converts a uint32 to a double (coming from wasm).
|
|
||||||
class MWasmUnsignedToDouble : public MUnaryInstruction,
|
|
||||||
public NoTypePolicy::Data {
|
|
||||||
explicit MWasmUnsignedToDouble(MDefinition* def)
|
|
||||||
: MUnaryInstruction(classOpcode, def) {
|
|
||||||
setResultType(MIRType::Double);
|
|
||||||
setMovable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
INSTRUCTION_HEADER(WasmUnsignedToDouble)
|
|
||||||
TRIVIAL_NEW_WRAPPERS
|
|
||||||
|
|
||||||
MDefinition* foldsTo(TempAllocator& alloc) override;
|
|
||||||
bool congruentTo(const MDefinition* ins) const override {
|
|
||||||
return congruentIfOperandsEqual(ins);
|
|
||||||
}
|
|
||||||
AliasSet getAliasSet() const override { return AliasSet::None(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
// Converts a uint32 to a float32 (coming from wasm).
|
// Converts a uint32 to a float32 (coming from wasm).
|
||||||
class MWasmUnsignedToFloat32 : public MUnaryInstruction,
|
class MWasmUnsignedToFloat32 : public MUnaryInstruction,
|
||||||
public NoTypePolicy::Data {
|
public NoTypePolicy::Data {
|
||||||
@ -4853,32 +4787,6 @@ class MPowHalf : public MUnaryInstruction, public DoublePolicy<0>::Data {
|
|||||||
ALLOW_CLONE(MPowHalf)
|
ALLOW_CLONE(MPowHalf)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Inline implementation of Math.random().
|
|
||||||
class MRandom : public MNullaryInstruction {
|
|
||||||
MRandom() : MNullaryInstruction(classOpcode) {
|
|
||||||
setResultType(MIRType::Double);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
INSTRUCTION_HEADER(Random)
|
|
||||||
TRIVIAL_NEW_WRAPPERS
|
|
||||||
|
|
||||||
AliasSet getAliasSet() const override { return AliasSet::None(); }
|
|
||||||
|
|
||||||
bool possiblyCalls() const override { return true; }
|
|
||||||
|
|
||||||
void computeRange(TempAllocator& alloc) override;
|
|
||||||
|
|
||||||
[[nodiscard]] bool writeRecoverData(
|
|
||||||
CompactBufferWriter& writer) const override;
|
|
||||||
|
|
||||||
bool canRecoverOnBailout() const override {
|
|
||||||
return !js::SupportDifferentialTesting();
|
|
||||||
}
|
|
||||||
|
|
||||||
ALLOW_CLONE(MRandom)
|
|
||||||
};
|
|
||||||
|
|
||||||
class MSign : public MUnaryInstruction, public SignPolicy::Data {
|
class MSign : public MUnaryInstruction, public SignPolicy::Data {
|
||||||
private:
|
private:
|
||||||
MSign(MDefinition* input, MIRType resultType)
|
MSign(MDefinition* input, MIRType resultType)
|
||||||
@ -5939,29 +5847,6 @@ class MStringConvertCase : public MUnaryInstruction,
|
|||||||
Mode mode() const { return mode_; }
|
Mode mode() const { return mode_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class MStringSplit : public MBinaryInstruction,
|
|
||||||
public MixPolicy<StringPolicy<0>, StringPolicy<1>>::Data {
|
|
||||||
MStringSplit(TempAllocator& alloc, MDefinition* string, MDefinition* sep)
|
|
||||||
: MBinaryInstruction(classOpcode, string, sep) {
|
|
||||||
setResultType(MIRType::Object);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
INSTRUCTION_HEADER(StringSplit)
|
|
||||||
TRIVIAL_NEW_WRAPPERS_WITH_ALLOC
|
|
||||||
NAMED_OPERANDS((0, string), (1, separator))
|
|
||||||
|
|
||||||
bool possiblyCalls() const override { return true; }
|
|
||||||
virtual AliasSet getAliasSet() const override {
|
|
||||||
// Although this instruction returns a new array, we don't have to mark
|
|
||||||
// it as store instruction, see also MNewArray.
|
|
||||||
return AliasSet::None();
|
|
||||||
}
|
|
||||||
[[nodiscard]] bool writeRecoverData(
|
|
||||||
CompactBufferWriter& writer) const override;
|
|
||||||
bool canRecoverOnBailout() const override { return true; }
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns the object to use as |this| value in a non-strict function. See also
|
// Returns the object to use as |this| value in a non-strict function. See also
|
||||||
// BoxNonStrictThis in Interpreter.h.
|
// BoxNonStrictThis in Interpreter.h.
|
||||||
class MBoxNonStrictThis : public MUnaryInstruction, public BoxPolicy<0>::Data {
|
class MBoxNonStrictThis : public MUnaryInstruction, public BoxPolicy<0>::Data {
|
||||||
@ -6322,17 +6207,6 @@ class MBinaryCache : public MBinaryInstruction,
|
|||||||
TRIVIAL_NEW_WRAPPERS
|
TRIVIAL_NEW_WRAPPERS
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check whether we need to fire the interrupt handler.
|
|
||||||
class MInterruptCheck : public MNullaryInstruction {
|
|
||||||
MInterruptCheck() : MNullaryInstruction(classOpcode) { setGuard(); }
|
|
||||||
|
|
||||||
public:
|
|
||||||
INSTRUCTION_HEADER(InterruptCheck)
|
|
||||||
TRIVIAL_NEW_WRAPPERS
|
|
||||||
|
|
||||||
AliasSet getAliasSet() const override { return AliasSet::None(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
// Check whether we need to fire the interrupt handler (in wasm code).
|
// Check whether we need to fire the interrupt handler (in wasm code).
|
||||||
class MWasmInterruptCheck : public MUnaryInstruction,
|
class MWasmInterruptCheck : public MUnaryInstruction,
|
||||||
public NoTypePolicy::Data {
|
public NoTypePolicy::Data {
|
||||||
@ -6674,96 +6548,6 @@ class MSetFunName : public MBinaryInstruction,
|
|||||||
bool possiblyCalls() const override { return true; }
|
bool possiblyCalls() const override { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Load the initialized length from an elements header.
|
|
||||||
class MInitializedLength : public MUnaryInstruction, public NoTypePolicy::Data {
|
|
||||||
explicit MInitializedLength(MDefinition* elements)
|
|
||||||
: MUnaryInstruction(classOpcode, elements) {
|
|
||||||
setResultType(MIRType::Int32);
|
|
||||||
setMovable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
INSTRUCTION_HEADER(InitializedLength)
|
|
||||||
TRIVIAL_NEW_WRAPPERS
|
|
||||||
NAMED_OPERANDS((0, elements))
|
|
||||||
|
|
||||||
bool congruentTo(const MDefinition* ins) const override {
|
|
||||||
return congruentIfOperandsEqual(ins);
|
|
||||||
}
|
|
||||||
AliasSet getAliasSet() const override {
|
|
||||||
return AliasSet::Load(AliasSet::ObjectFields);
|
|
||||||
}
|
|
||||||
|
|
||||||
void computeRange(TempAllocator& alloc) override;
|
|
||||||
|
|
||||||
ALLOW_CLONE(MInitializedLength)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Store to the initialized length in an elements header. Note the input is an
|
|
||||||
// *index*, one less than the desired length.
|
|
||||||
class MSetInitializedLength : public MBinaryInstruction,
|
|
||||||
public NoTypePolicy::Data {
|
|
||||||
MSetInitializedLength(MDefinition* elements, MDefinition* index)
|
|
||||||
: MBinaryInstruction(classOpcode, elements, index) {}
|
|
||||||
|
|
||||||
public:
|
|
||||||
INSTRUCTION_HEADER(SetInitializedLength)
|
|
||||||
TRIVIAL_NEW_WRAPPERS
|
|
||||||
NAMED_OPERANDS((0, elements), (1, index))
|
|
||||||
|
|
||||||
AliasSet getAliasSet() const override {
|
|
||||||
return AliasSet::Store(AliasSet::ObjectFields);
|
|
||||||
}
|
|
||||||
|
|
||||||
ALLOW_CLONE(MSetInitializedLength)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Load the array length from an elements header.
|
|
||||||
class MArrayLength : public MUnaryInstruction, public NoTypePolicy::Data {
|
|
||||||
explicit MArrayLength(MDefinition* elements)
|
|
||||||
: MUnaryInstruction(classOpcode, elements) {
|
|
||||||
setResultType(MIRType::Int32);
|
|
||||||
setMovable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
INSTRUCTION_HEADER(ArrayLength)
|
|
||||||
TRIVIAL_NEW_WRAPPERS
|
|
||||||
NAMED_OPERANDS((0, elements))
|
|
||||||
|
|
||||||
bool congruentTo(const MDefinition* ins) const override {
|
|
||||||
return congruentIfOperandsEqual(ins);
|
|
||||||
}
|
|
||||||
AliasSet getAliasSet() const override {
|
|
||||||
return AliasSet::Load(AliasSet::ObjectFields);
|
|
||||||
}
|
|
||||||
|
|
||||||
void computeRange(TempAllocator& alloc) override;
|
|
||||||
|
|
||||||
ALLOW_CLONE(MArrayLength)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Store to the length in an elements header. Note the input is an *index*, one
|
|
||||||
// less than the desired length.
|
|
||||||
class MSetArrayLength : public MBinaryInstruction, public NoTypePolicy::Data {
|
|
||||||
MSetArrayLength(MDefinition* elements, MDefinition* index)
|
|
||||||
: MBinaryInstruction(classOpcode, elements, index) {}
|
|
||||||
|
|
||||||
public:
|
|
||||||
INSTRUCTION_HEADER(SetArrayLength)
|
|
||||||
TRIVIAL_NEW_WRAPPERS
|
|
||||||
NAMED_OPERANDS((0, elements), (1, index))
|
|
||||||
|
|
||||||
AliasSet getAliasSet() const override {
|
|
||||||
return AliasSet::Store(AliasSet::ObjectFields);
|
|
||||||
}
|
|
||||||
|
|
||||||
// By default no, unless built as a recovered instruction.
|
|
||||||
[[nodiscard]] bool writeRecoverData(
|
|
||||||
CompactBufferWriter& writer) const override;
|
|
||||||
bool canRecoverOnBailout() const override { return isRecoveredOnBailout(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class MGetNextEntryForIterator
|
class MGetNextEntryForIterator
|
||||||
: public MBinaryInstruction,
|
: public MBinaryInstruction,
|
||||||
public MixPolicy<ObjectPolicy<0>, ObjectPolicy<1>>::Data {
|
public MixPolicy<ObjectPolicy<0>, ObjectPolicy<1>>::Data {
|
||||||
@ -6787,56 +6571,6 @@ class MGetNextEntryForIterator
|
|||||||
Mode mode() const { return mode_; }
|
Mode mode() const { return mode_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Read the byteOffset of an array buffer view.
|
|
||||||
class MArrayBufferViewByteOffset : public MUnaryInstruction,
|
|
||||||
public SingleObjectPolicy::Data {
|
|
||||||
explicit MArrayBufferViewByteOffset(MDefinition* obj)
|
|
||||||
: MUnaryInstruction(classOpcode, obj) {
|
|
||||||
setResultType(MIRType::IntPtr);
|
|
||||||
setMovable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
INSTRUCTION_HEADER(ArrayBufferViewByteOffset)
|
|
||||||
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::ArrayBufferViewLengthOrOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void computeRange(TempAllocator& alloc) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return the element size of a typed array.
|
|
||||||
class MTypedArrayElementSize : public MUnaryInstruction,
|
|
||||||
public SingleObjectPolicy::Data {
|
|
||||||
explicit MTypedArrayElementSize(MDefinition* obj)
|
|
||||||
: MUnaryInstruction(classOpcode, obj) {
|
|
||||||
setResultType(MIRType::Int32);
|
|
||||||
setMovable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
INSTRUCTION_HEADER(TypedArrayElementSize)
|
|
||||||
TRIVIAL_NEW_WRAPPERS
|
|
||||||
NAMED_OPERANDS((0, object))
|
|
||||||
|
|
||||||
bool congruentTo(const MDefinition* ins) const override {
|
|
||||||
return congruentIfOperandsEqual(ins);
|
|
||||||
}
|
|
||||||
|
|
||||||
AliasSet getAliasSet() const override {
|
|
||||||
// Class is immutable. See also MHasClass.
|
|
||||||
return AliasSet::None();
|
|
||||||
}
|
|
||||||
|
|
||||||
void computeRange(TempAllocator& alloc) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Convert a Double into an IntPtr value for accessing a TypedArray or DataView
|
// Convert a Double into an IntPtr value for accessing a TypedArray or DataView
|
||||||
// element. If the input is non-finite, not an integer, negative, or outside the
|
// element. If the input is non-finite, not an integer, negative, or outside the
|
||||||
// IntPtr range, either bails out or produces a value which is known to trigger
|
// IntPtr range, either bails out or produces a value which is known to trigger
|
||||||
@ -7904,28 +7638,6 @@ class MGetPropSuperCache
|
|||||||
NAMED_OPERANDS((0, object), (1, receiver), (2, idval))
|
NAMED_OPERANDS((0, object), (1, receiver), (2, idval))
|
||||||
};
|
};
|
||||||
|
|
||||||
class MCallBindVar : public MUnaryInstruction, public SingleObjectPolicy::Data {
|
|
||||||
explicit MCallBindVar(MDefinition* envChain)
|
|
||||||
: MUnaryInstruction(classOpcode, envChain) {
|
|
||||||
setResultType(MIRType::Object);
|
|
||||||
setMovable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
INSTRUCTION_HEADER(CallBindVar)
|
|
||||||
TRIVIAL_NEW_WRAPPERS
|
|
||||||
NAMED_OPERANDS((0, environmentChain))
|
|
||||||
|
|
||||||
bool congruentTo(const MDefinition* ins) const override {
|
|
||||||
if (!ins->isCallBindVar()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return congruentIfOperandsEqual(ins);
|
|
||||||
}
|
|
||||||
|
|
||||||
AliasSet getAliasSet() const override { return AliasSet::None(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
// Guard on an object's shape.
|
// Guard on an object's shape.
|
||||||
class MGuardShape : public MUnaryInstruction, public SingleObjectPolicy::Data {
|
class MGuardShape : public MUnaryInstruction, public SingleObjectPolicy::Data {
|
||||||
CompilerShape shape_;
|
CompilerShape shape_;
|
||||||
@ -9156,38 +8868,6 @@ class MGuardDOMExpandoMissingOrGuardShape : public MUnaryInstruction,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class MStringLength : public MUnaryInstruction, public StringPolicy<0>::Data {
|
|
||||||
explicit MStringLength(MDefinition* string)
|
|
||||||
: MUnaryInstruction(classOpcode, string) {
|
|
||||||
setResultType(MIRType::Int32);
|
|
||||||
setMovable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
INSTRUCTION_HEADER(StringLength)
|
|
||||||
TRIVIAL_NEW_WRAPPERS
|
|
||||||
NAMED_OPERANDS((0, string))
|
|
||||||
|
|
||||||
MDefinition* foldsTo(TempAllocator& alloc) override;
|
|
||||||
|
|
||||||
bool congruentTo(const MDefinition* ins) const override {
|
|
||||||
return congruentIfOperandsEqual(ins);
|
|
||||||
}
|
|
||||||
AliasSet getAliasSet() const override {
|
|
||||||
// The string |length| property is immutable, so there is no
|
|
||||||
// implicit dependency.
|
|
||||||
return AliasSet::None();
|
|
||||||
}
|
|
||||||
|
|
||||||
void computeRange(TempAllocator& alloc) override;
|
|
||||||
|
|
||||||
[[nodiscard]] bool writeRecoverData(
|
|
||||||
CompactBufferWriter& writer) const override;
|
|
||||||
bool canRecoverOnBailout() const override { return true; }
|
|
||||||
|
|
||||||
ALLOW_CLONE(MStringLength)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Inlined assembly for Math.floor(double | float32) -> int32.
|
// Inlined assembly for Math.floor(double | float32) -> int32.
|
||||||
class MFloor : public MUnaryInstruction, public FloatingPointPolicy<0>::Data {
|
class MFloor : public MUnaryInstruction, public FloatingPointPolicy<0>::Data {
|
||||||
explicit MFloor(MDefinition* num) : MUnaryInstruction(classOpcode, num) {
|
explicit MFloor(MDefinition* num) : MUnaryInstruction(classOpcode, num) {
|
||||||
@ -9506,22 +9186,6 @@ class MInstanceOf : public MBinaryInstruction,
|
|||||||
TRIVIAL_NEW_WRAPPERS
|
TRIVIAL_NEW_WRAPPERS
|
||||||
};
|
};
|
||||||
|
|
||||||
class MNewTarget : public MNullaryInstruction {
|
|
||||||
MNewTarget() : MNullaryInstruction(classOpcode) {
|
|
||||||
setResultType(MIRType::Value);
|
|
||||||
setMovable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
INSTRUCTION_HEADER(NewTarget)
|
|
||||||
TRIVIAL_NEW_WRAPPERS
|
|
||||||
|
|
||||||
bool congruentTo(const MDefinition* ins) const override {
|
|
||||||
return congruentIfOperandsEqual(ins);
|
|
||||||
}
|
|
||||||
AliasSet getAliasSet() const override { return AliasSet::None(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class MRest : public MUnaryInstruction, public UnboxedInt32Policy<0>::Data {
|
class MRest : public MUnaryInstruction, public UnboxedInt32Policy<0>::Data {
|
||||||
unsigned numFormals_;
|
unsigned numFormals_;
|
||||||
CompilerGCPointer<Shape*> shape_;
|
CompilerGCPointer<Shape*> shape_;
|
||||||
|
@ -161,7 +161,10 @@
|
|||||||
gen_boilerplate: false
|
gen_boilerplate: false
|
||||||
|
|
||||||
- name: Callee
|
- name: Callee
|
||||||
gen_boilerplate: false
|
result_type: Object
|
||||||
|
movable: true
|
||||||
|
congruent_to: if_operands_equal
|
||||||
|
alias_set: none
|
||||||
|
|
||||||
- name: IsConstructing
|
- name: IsConstructing
|
||||||
result_type: Boolean
|
result_type: Boolean
|
||||||
@ -353,8 +356,18 @@
|
|||||||
congruent_to: if_operands_equal
|
congruent_to: if_operands_equal
|
||||||
alias_set: custom
|
alias_set: custom
|
||||||
|
|
||||||
|
# Load |arguments.length|. Bails out if the length has been overriden.
|
||||||
- name: ArgumentsObjectLength
|
- name: ArgumentsObjectLength
|
||||||
gen_boilerplate: false
|
operands:
|
||||||
|
argsObject: Object
|
||||||
|
result_type: Int32
|
||||||
|
guard: true
|
||||||
|
movable: true
|
||||||
|
congruent_to: if_operands_equal
|
||||||
|
# Even though the "length" property is lazily resolved, it acts similar to
|
||||||
|
# a normal property load, so we can treat this operation like any other
|
||||||
|
# property read.
|
||||||
|
alias_set: custom
|
||||||
|
|
||||||
- name: GuardArgumentsObjectFlags
|
- name: GuardArgumentsObjectFlags
|
||||||
gen_boilerplate: false
|
gen_boilerplate: false
|
||||||
@ -378,8 +391,16 @@
|
|||||||
- name: ToFloat32
|
- name: ToFloat32
|
||||||
gen_boilerplate: false
|
gen_boilerplate: false
|
||||||
|
|
||||||
|
# Converts a uint32 to a double (coming from wasm).
|
||||||
- name: WasmUnsignedToDouble
|
- name: WasmUnsignedToDouble
|
||||||
gen_boilerplate: false
|
operands:
|
||||||
|
def: Int32
|
||||||
|
type_policy: none
|
||||||
|
result_type: Double
|
||||||
|
movable: true
|
||||||
|
folds_to: custom
|
||||||
|
congruent_to: if_operands_equal
|
||||||
|
alias_set: none
|
||||||
|
|
||||||
- name: WasmUnsignedToFloat32
|
- name: WasmUnsignedToFloat32
|
||||||
gen_boilerplate: false
|
gen_boilerplate: false
|
||||||
@ -550,7 +571,12 @@
|
|||||||
gen_boilerplate: false
|
gen_boilerplate: false
|
||||||
|
|
||||||
- name: Random
|
- name: Random
|
||||||
gen_boilerplate: false
|
result_type: Double
|
||||||
|
alias_set: none
|
||||||
|
possibly_calls: true
|
||||||
|
compute_range: custom
|
||||||
|
can_recover: custom
|
||||||
|
clone: true
|
||||||
|
|
||||||
- name: Sign
|
- name: Sign
|
||||||
gen_boilerplate: false
|
gen_boilerplate: false
|
||||||
@ -668,7 +694,16 @@
|
|||||||
gen_boilerplate: false
|
gen_boilerplate: false
|
||||||
|
|
||||||
- name: StringSplit
|
- name: StringSplit
|
||||||
gen_boilerplate: false
|
operands:
|
||||||
|
string: String
|
||||||
|
separator: String
|
||||||
|
result_type: Object
|
||||||
|
possibly_calls: true
|
||||||
|
congruent_to: if_operands_equal
|
||||||
|
# Although this instruction returns a new array, we don't have to mark
|
||||||
|
# it as store instruction, see also MNewArray.
|
||||||
|
alias_set: none
|
||||||
|
can_recover: true
|
||||||
|
|
||||||
- name: BoxNonStrictThis
|
- name: BoxNonStrictThis
|
||||||
gen_boilerplate: false
|
gen_boilerplate: false
|
||||||
@ -720,8 +755,11 @@
|
|||||||
guard: true
|
guard: true
|
||||||
alias_set: none
|
alias_set: none
|
||||||
|
|
||||||
|
|
||||||
|
# Check whether we need to fire the interrupt handler.
|
||||||
- name: InterruptCheck
|
- name: InterruptCheck
|
||||||
gen_boilerplate: false
|
guard: true
|
||||||
|
alias_set: none
|
||||||
|
|
||||||
- name: WasmInterruptCheck
|
- name: WasmInterruptCheck
|
||||||
gen_boilerplate: false
|
gen_boilerplate: false
|
||||||
@ -841,17 +879,50 @@
|
|||||||
alias_set: custom
|
alias_set: custom
|
||||||
clone: true
|
clone: true
|
||||||
|
|
||||||
|
# Load the initialized length from an elements header.
|
||||||
- name: InitializedLength
|
- name: InitializedLength
|
||||||
gen_boilerplate: false
|
operands:
|
||||||
|
elements: Elements
|
||||||
|
type_policy: none
|
||||||
|
result_type: Int32
|
||||||
|
movable: true
|
||||||
|
congruent_to: if_operands_equal
|
||||||
|
alias_set: custom
|
||||||
|
compute_range: custom
|
||||||
|
clone: true
|
||||||
|
|
||||||
- name: SetInitializedLength
|
- name: SetInitializedLength
|
||||||
gen_boilerplate: false
|
operands:
|
||||||
|
elements: Elements
|
||||||
|
index: Int32
|
||||||
|
type_policy: none
|
||||||
|
alias_set: custom
|
||||||
|
clone: true
|
||||||
|
|
||||||
|
|
||||||
|
# Load the array length from an elements header.
|
||||||
- name: ArrayLength
|
- name: ArrayLength
|
||||||
gen_boilerplate: false
|
operands:
|
||||||
|
elements: Elements
|
||||||
|
type_policy: none
|
||||||
|
result_type: Int32
|
||||||
|
movable: true
|
||||||
|
congruent_to: if_operands_equal
|
||||||
|
alias_set: custom
|
||||||
|
compute_range: custom
|
||||||
|
clone: true
|
||||||
|
|
||||||
|
|
||||||
|
# Store to the length in an elements header. Note the input is an *index*, one
|
||||||
|
# less than the desired length.
|
||||||
- name: SetArrayLength
|
- name: SetArrayLength
|
||||||
gen_boilerplate: false
|
operands:
|
||||||
|
elements: Elements
|
||||||
|
index: Int32
|
||||||
|
type_policy: none
|
||||||
|
alias_set: custom
|
||||||
|
# By default no, unless built as a recovered instruction.
|
||||||
|
can_recover: custom
|
||||||
|
|
||||||
# Load the function length. Bails for functions with lazy scripts or a
|
# Load the function length. Bails for functions with lazy scripts or a
|
||||||
# resolved "length" property.
|
# resolved "length" property.
|
||||||
@ -902,7 +973,13 @@
|
|||||||
compute_range: custom
|
compute_range: custom
|
||||||
|
|
||||||
- name: ArrayBufferViewByteOffset
|
- name: ArrayBufferViewByteOffset
|
||||||
gen_boilerplate: false
|
operands:
|
||||||
|
object: Object
|
||||||
|
result_type: IntPtr
|
||||||
|
movable: true
|
||||||
|
congruent_to: if_operands_equal
|
||||||
|
alias_set: custom
|
||||||
|
compute_range: custom
|
||||||
|
|
||||||
# Read the length of an array buffer view.
|
# Read the length of an array buffer view.
|
||||||
- name: ArrayBufferViewElements
|
- name: ArrayBufferViewElements
|
||||||
@ -914,8 +991,16 @@
|
|||||||
alias_set: custom
|
alias_set: custom
|
||||||
clone: true
|
clone: true
|
||||||
|
|
||||||
|
# Return the element size of a typed array.
|
||||||
- name: TypedArrayElementSize
|
- name: TypedArrayElementSize
|
||||||
gen_boilerplate: false
|
operands:
|
||||||
|
object: Object
|
||||||
|
result_type: Int32
|
||||||
|
movable: true
|
||||||
|
congruent_to: if_operands_equal
|
||||||
|
# Class is immutable. See also MHasClass.
|
||||||
|
alias_set: none
|
||||||
|
compute_range: custom
|
||||||
|
|
||||||
# Guard an ArrayBufferView has an attached ArrayBuffer.
|
# Guard an ArrayBufferView has an attached ArrayBuffer.
|
||||||
- name: GuardHasAttachedArrayBuffer
|
- name: GuardHasAttachedArrayBuffer
|
||||||
@ -1052,7 +1137,12 @@
|
|||||||
result_type: Object
|
result_type: Object
|
||||||
|
|
||||||
- name: CallBindVar
|
- name: CallBindVar
|
||||||
gen_boilerplate: false
|
operands:
|
||||||
|
environmentChain: Object
|
||||||
|
result_type: Object
|
||||||
|
movable: true
|
||||||
|
congruent_to: custom
|
||||||
|
alias_set: none
|
||||||
|
|
||||||
- name: GuardShape
|
- name: GuardShape
|
||||||
gen_boilerplate: false
|
gen_boilerplate: false
|
||||||
@ -1352,7 +1442,18 @@
|
|||||||
gen_boilerplate: false
|
gen_boilerplate: false
|
||||||
|
|
||||||
- name: StringLength
|
- name: StringLength
|
||||||
gen_boilerplate: false
|
operands:
|
||||||
|
string: String
|
||||||
|
result_type: Int32
|
||||||
|
movable: true
|
||||||
|
folds_to: custom
|
||||||
|
congruent_to: if_operands_equal
|
||||||
|
# The string |length| property is immutable, so there is no
|
||||||
|
# implicit dependency.
|
||||||
|
alias_set: none
|
||||||
|
compute_range: custom
|
||||||
|
can_recover: true
|
||||||
|
clone: true
|
||||||
|
|
||||||
- name: Floor
|
- name: Floor
|
||||||
gen_boilerplate: false
|
gen_boilerplate: false
|
||||||
@ -1440,7 +1541,10 @@
|
|||||||
alias_set: none
|
alias_set: none
|
||||||
|
|
||||||
- name: NewTarget
|
- name: NewTarget
|
||||||
gen_boilerplate: false
|
result_type: Value
|
||||||
|
movable: true
|
||||||
|
congruent_to: if_operands_equal
|
||||||
|
alias_set: none
|
||||||
|
|
||||||
- name: Rest
|
- name: Rest
|
||||||
gen_boilerplate: false
|
gen_boilerplate: false
|
||||||
|
@ -1282,6 +1282,10 @@ bool MRandom::writeRecoverData(CompactBufferWriter& writer) const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MRandom::canRecoverOnBailout() const {
|
||||||
|
return !js::SupportDifferentialTesting();
|
||||||
|
}
|
||||||
|
|
||||||
RRandom::RRandom(CompactBufferReader& reader) {}
|
RRandom::RRandom(CompactBufferReader& reader) {}
|
||||||
|
|
||||||
bool RRandom::recover(JSContext* cx, SnapshotIterator& iter) const {
|
bool RRandom::recover(JSContext* cx, SnapshotIterator& iter) const {
|
||||||
@ -1875,6 +1879,10 @@ bool MSetArrayLength::writeRecoverData(CompactBufferWriter& writer) const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MSetArrayLength::canRecoverOnBailout() const {
|
||||||
|
return isRecoveredOnBailout();
|
||||||
|
}
|
||||||
|
|
||||||
RSetArrayLength::RSetArrayLength(CompactBufferReader& reader) {}
|
RSetArrayLength::RSetArrayLength(CompactBufferReader& reader) {}
|
||||||
|
|
||||||
bool RSetArrayLength::recover(JSContext* cx, SnapshotIterator& iter) const {
|
bool RSetArrayLength::recover(JSContext* cx, SnapshotIterator& iter) const {
|
||||||
|
@ -1702,7 +1702,7 @@ void ArgumentsReplacer::visitLoadArgumentsObjectArg(
|
|||||||
void ArgumentsReplacer::visitArgumentsObjectLength(
|
void ArgumentsReplacer::visitArgumentsObjectLength(
|
||||||
MArgumentsObjectLength* ins) {
|
MArgumentsObjectLength* ins) {
|
||||||
// Skip other arguments objects.
|
// Skip other arguments objects.
|
||||||
if (ins->getArgsObject() != args_) {
|
if (ins->argsObject() != args_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user