Bug 1699271 - Part 10: Auto generate more MIR instructions. r=iain

Differential Revision: https://phabricator.services.mozilla.com/D112685
This commit is contained in:
Caroline Cullen 2021-05-27 22:55:34 +00:00
parent 08b92c3498
commit f3a7647605
6 changed files with 161 additions and 353 deletions

View File

@ -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));

View File

@ -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) {

View File

@ -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_;

View File

@ -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

View File

@ -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 {

View File

@ -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;
} }