mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-18 07:45:30 +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) {
|
||||
MDefinition* argsObj = ins->getArgsObject();
|
||||
MDefinition* argsObj = ins->argsObject();
|
||||
MOZ_ASSERT(argsObj->type() == MIRType::Object);
|
||||
|
||||
auto* lir = new (alloc()) LArgumentsObjectLength(useRegister(argsObj));
|
||||
|
@ -3109,6 +3109,11 @@ AliasSet MLoadArgumentsObjectArg::getAliasSet() const {
|
||||
return AliasSet::Load(AliasSet::Any);
|
||||
}
|
||||
|
||||
AliasSet MArgumentsObjectLength::getAliasSet() const {
|
||||
return AliasSet::Load(AliasSet::ObjectFields | AliasSet::FixedSlot |
|
||||
AliasSet::DynamicSlot);
|
||||
}
|
||||
|
||||
MDefinition* MReturnFromCtor::foldsTo(TempAllocator& alloc) {
|
||||
MDefinition* rval = value();
|
||||
if (rval->isBox()) {
|
||||
@ -5090,6 +5095,22 @@ AliasSet MElements::getAliasSet() const {
|
||||
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 {
|
||||
return AliasSet::Load(AliasSet::ObjectFields | AliasSet::FixedSlot |
|
||||
AliasSet::DynamicSlot);
|
||||
@ -5108,6 +5129,10 @@ AliasSet MArrayBufferViewLength::getAliasSet() const {
|
||||
return AliasSet::Load(AliasSet::ArrayBufferViewLengthOrOffset);
|
||||
}
|
||||
|
||||
AliasSet MArrayBufferViewByteOffset::getAliasSet() const {
|
||||
return AliasSet::Load(AliasSet::ArrayBufferViewLengthOrOffset);
|
||||
}
|
||||
|
||||
AliasSet MArrayBufferViewElements::getAliasSet() const {
|
||||
return AliasSet::Load(AliasSet::ObjectFields);
|
||||
}
|
||||
@ -5365,6 +5390,13 @@ MDefinition* MGuardSpecificSymbol::foldsTo(TempAllocator& alloc) {
|
||||
return this;
|
||||
}
|
||||
|
||||
bool MCallBindVar::congruentTo(const MDefinition* ins) const {
|
||||
if (!ins->isCallBindVar()) {
|
||||
return false;
|
||||
}
|
||||
return congruentIfOperandsEqual(ins);
|
||||
}
|
||||
|
||||
MDefinition* MGuardIsNotProxy::foldsTo(TempAllocator& alloc) {
|
||||
KnownClass known = GetObjectKnownClass(object());
|
||||
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;
|
||||
};
|
||||
|
||||
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 {
|
||||
protected:
|
||||
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.
|
||||
class MGuardArgumentsObjectFlags : public MUnaryInstruction,
|
||||
public SingleObjectPolicy::Data {
|
||||
@ -3341,26 +3295,6 @@ class MToFloat32 : public MToFPInstruction {
|
||||
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).
|
||||
class MWasmUnsignedToFloat32 : public MUnaryInstruction,
|
||||
public NoTypePolicy::Data {
|
||||
@ -4853,32 +4787,6 @@ class MPowHalf : public MUnaryInstruction, public DoublePolicy<0>::Data {
|
||||
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 {
|
||||
private:
|
||||
MSign(MDefinition* input, MIRType resultType)
|
||||
@ -5939,29 +5847,6 @@ class MStringConvertCase : public MUnaryInstruction,
|
||||
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
|
||||
// BoxNonStrictThis in Interpreter.h.
|
||||
class MBoxNonStrictThis : public MUnaryInstruction, public BoxPolicy<0>::Data {
|
||||
@ -6322,17 +6207,6 @@ class MBinaryCache : public MBinaryInstruction,
|
||||
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).
|
||||
class MWasmInterruptCheck : public MUnaryInstruction,
|
||||
public NoTypePolicy::Data {
|
||||
@ -6674,96 +6548,6 @@ class MSetFunName : public MBinaryInstruction,
|
||||
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
|
||||
: public MBinaryInstruction,
|
||||
public MixPolicy<ObjectPolicy<0>, ObjectPolicy<1>>::Data {
|
||||
@ -6787,56 +6571,6 @@ class MGetNextEntryForIterator
|
||||
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
|
||||
// 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
|
||||
@ -7904,28 +7638,6 @@ class MGetPropSuperCache
|
||||
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.
|
||||
class MGuardShape : public MUnaryInstruction, public SingleObjectPolicy::Data {
|
||||
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.
|
||||
class MFloor : public MUnaryInstruction, public FloatingPointPolicy<0>::Data {
|
||||
explicit MFloor(MDefinition* num) : MUnaryInstruction(classOpcode, num) {
|
||||
@ -9506,22 +9186,6 @@ class MInstanceOf : public MBinaryInstruction,
|
||||
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 {
|
||||
unsigned numFormals_;
|
||||
CompilerGCPointer<Shape*> shape_;
|
||||
|
@ -161,7 +161,10 @@
|
||||
gen_boilerplate: false
|
||||
|
||||
- name: Callee
|
||||
gen_boilerplate: false
|
||||
result_type: Object
|
||||
movable: true
|
||||
congruent_to: if_operands_equal
|
||||
alias_set: none
|
||||
|
||||
- name: IsConstructing
|
||||
result_type: Boolean
|
||||
@ -353,8 +356,18 @@
|
||||
congruent_to: if_operands_equal
|
||||
alias_set: custom
|
||||
|
||||
# Load |arguments.length|. Bails out if the length has been overriden.
|
||||
- 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
|
||||
gen_boilerplate: false
|
||||
@ -378,8 +391,16 @@
|
||||
- name: ToFloat32
|
||||
gen_boilerplate: false
|
||||
|
||||
# Converts a uint32 to a double (coming from wasm).
|
||||
- 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
|
||||
gen_boilerplate: false
|
||||
@ -550,7 +571,12 @@
|
||||
gen_boilerplate: false
|
||||
|
||||
- name: Random
|
||||
gen_boilerplate: false
|
||||
result_type: Double
|
||||
alias_set: none
|
||||
possibly_calls: true
|
||||
compute_range: custom
|
||||
can_recover: custom
|
||||
clone: true
|
||||
|
||||
- name: Sign
|
||||
gen_boilerplate: false
|
||||
@ -668,7 +694,16 @@
|
||||
gen_boilerplate: false
|
||||
|
||||
- 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
|
||||
gen_boilerplate: false
|
||||
@ -720,8 +755,11 @@
|
||||
guard: true
|
||||
alias_set: none
|
||||
|
||||
|
||||
# Check whether we need to fire the interrupt handler.
|
||||
- name: InterruptCheck
|
||||
gen_boilerplate: false
|
||||
guard: true
|
||||
alias_set: none
|
||||
|
||||
- name: WasmInterruptCheck
|
||||
gen_boilerplate: false
|
||||
@ -841,17 +879,50 @@
|
||||
alias_set: custom
|
||||
clone: true
|
||||
|
||||
# Load the initialized length from an elements header.
|
||||
- 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
|
||||
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
|
||||
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
|
||||
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
|
||||
# resolved "length" property.
|
||||
@ -902,7 +973,13 @@
|
||||
compute_range: custom
|
||||
|
||||
- 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.
|
||||
- name: ArrayBufferViewElements
|
||||
@ -914,8 +991,16 @@
|
||||
alias_set: custom
|
||||
clone: true
|
||||
|
||||
# Return the element size of a typed array.
|
||||
- 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.
|
||||
- name: GuardHasAttachedArrayBuffer
|
||||
@ -1052,7 +1137,12 @@
|
||||
result_type: Object
|
||||
|
||||
- name: CallBindVar
|
||||
gen_boilerplate: false
|
||||
operands:
|
||||
environmentChain: Object
|
||||
result_type: Object
|
||||
movable: true
|
||||
congruent_to: custom
|
||||
alias_set: none
|
||||
|
||||
- name: GuardShape
|
||||
gen_boilerplate: false
|
||||
@ -1352,7 +1442,18 @@
|
||||
gen_boilerplate: false
|
||||
|
||||
- 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
|
||||
gen_boilerplate: false
|
||||
@ -1440,7 +1541,10 @@
|
||||
alias_set: none
|
||||
|
||||
- name: NewTarget
|
||||
gen_boilerplate: false
|
||||
result_type: Value
|
||||
movable: true
|
||||
congruent_to: if_operands_equal
|
||||
alias_set: none
|
||||
|
||||
- name: Rest
|
||||
gen_boilerplate: false
|
||||
|
@ -1282,6 +1282,10 @@ bool MRandom::writeRecoverData(CompactBufferWriter& writer) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MRandom::canRecoverOnBailout() const {
|
||||
return !js::SupportDifferentialTesting();
|
||||
}
|
||||
|
||||
RRandom::RRandom(CompactBufferReader& reader) {}
|
||||
|
||||
bool RRandom::recover(JSContext* cx, SnapshotIterator& iter) const {
|
||||
@ -1875,6 +1879,10 @@ bool MSetArrayLength::writeRecoverData(CompactBufferWriter& writer) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MSetArrayLength::canRecoverOnBailout() const {
|
||||
return isRecoveredOnBailout();
|
||||
}
|
||||
|
||||
RSetArrayLength::RSetArrayLength(CompactBufferReader& reader) {}
|
||||
|
||||
bool RSetArrayLength::recover(JSContext* cx, SnapshotIterator& iter) const {
|
||||
|
@ -1702,7 +1702,7 @@ void ArgumentsReplacer::visitLoadArgumentsObjectArg(
|
||||
void ArgumentsReplacer::visitArgumentsObjectLength(
|
||||
MArgumentsObjectLength* ins) {
|
||||
// Skip other arguments objects.
|
||||
if (ins->getArgsObject() != args_) {
|
||||
if (ins->argsObject() != args_) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user