[maglev] Add CompareObjectType and move IRs to cross-platform
Also adds JumpIf* variants with Label::Distance. Bug: v8:7700 Change-Id: I672f26a0769c5f3231c04605172ccedc0913ed0f Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4200628 Reviewed-by: Darius Mercadier <dmercadier@chromium.org> Auto-Submit: Victor Gomes <victorgomes@chromium.org> Commit-Queue: Darius Mercadier <dmercadier@chromium.org> Cr-Commit-Position: refs/heads/main@{#85535}
This commit is contained in:
parent
0bbbe9b450
commit
2dd722b936
@ -496,6 +496,29 @@ inline void MaglevAssembler::LoadByte(Register dst, MemOperand src) {
|
||||
Ldrb(dst, src);
|
||||
}
|
||||
|
||||
inline void MaglevAssembler::CompareObjectType(Register heap_object,
|
||||
InstanceType type) {
|
||||
ScratchRegisterScope temps(this);
|
||||
Register scratch = temps.Acquire();
|
||||
CompareObjectType(heap_object, type, scratch);
|
||||
}
|
||||
|
||||
inline void MaglevAssembler::CompareObjectType(Register heap_object,
|
||||
InstanceType type,
|
||||
Register scratch) {
|
||||
LoadMap(scratch, heap_object);
|
||||
CompareInstanceType(scratch, scratch, type);
|
||||
}
|
||||
|
||||
inline void MaglevAssembler::CompareObjectTypeRange(Register heap_object,
|
||||
InstanceType lower_limit,
|
||||
InstanceType higher_limit) {
|
||||
ScratchRegisterScope temps(this);
|
||||
Register scratch = temps.Acquire();
|
||||
LoadMap(scratch, heap_object);
|
||||
CompareInstanceTypeRange(scratch, scratch, lower_limit, higher_limit);
|
||||
}
|
||||
|
||||
inline void MaglevAssembler::CompareTagged(Register reg,
|
||||
Handle<HeapObject> obj) {
|
||||
ScratchRegisterScope temps(this);
|
||||
@ -519,6 +542,23 @@ inline void MaglevAssembler::JumpIf(Condition cond, Label* target,
|
||||
b(target, cond);
|
||||
}
|
||||
|
||||
inline void MaglevAssembler::JumpIfRoot(Register with, RootIndex index,
|
||||
Label* if_equal,
|
||||
Label::Distance distance) {
|
||||
MacroAssembler::JumpIfRoot(with, index, if_equal);
|
||||
}
|
||||
|
||||
inline void MaglevAssembler::JumpIfNotRoot(Register with, RootIndex index,
|
||||
Label* if_not_equal,
|
||||
Label::Distance distance) {
|
||||
MacroAssembler::JumpIfNotRoot(with, index, if_not_equal);
|
||||
}
|
||||
|
||||
inline void MaglevAssembler::JumpIfSmi(Register src, Label* on_smi,
|
||||
Label::Distance distance) {
|
||||
MacroAssembler::JumpIfSmi(src, on_smi);
|
||||
}
|
||||
|
||||
inline void MaglevAssembler::CompareInt32AndJumpIf(Register r1, Register r2,
|
||||
Condition cond,
|
||||
Label* target,
|
||||
|
@ -74,116 +74,6 @@ void Int32DecrementWithOverflow::GenerateCode(MaglevAssembler* masm,
|
||||
__ EmitEagerDeoptIf(vs, DeoptimizeReason::kOverflow, this);
|
||||
}
|
||||
|
||||
int ConvertReceiver::MaxCallStackArgs() const {
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kToObject>::type;
|
||||
return D::GetStackParameterCount();
|
||||
}
|
||||
void ConvertReceiver::SetValueLocationConstraints() {
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kToObject>::type;
|
||||
UseFixed(receiver_input(), D::GetRegisterParameter(D::kInput));
|
||||
DefineAsFixed(this, kReturnRegister0);
|
||||
}
|
||||
void ConvertReceiver::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
Label convert_to_object, done;
|
||||
Register receiver = ToRegister(receiver_input());
|
||||
__ JumpIfSmi(receiver, &convert_to_object);
|
||||
static_assert(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
|
||||
{
|
||||
MaglevAssembler::ScratchRegisterScope temps(masm);
|
||||
Register scratch = temps.Acquire();
|
||||
__ JumpIfObjectType(receiver, scratch, scratch, FIRST_JS_RECEIVER_TYPE,
|
||||
&done, hs);
|
||||
}
|
||||
|
||||
if (mode_ != ConvertReceiverMode::kNotNullOrUndefined) {
|
||||
Label convert_global_proxy;
|
||||
__ JumpIfRoot(receiver, RootIndex::kUndefinedValue, &convert_global_proxy);
|
||||
__ JumpIfNotRoot(receiver, RootIndex::kNullValue, &convert_to_object);
|
||||
__ bind(&convert_global_proxy);
|
||||
{
|
||||
// Patch receiver to global proxy.
|
||||
__ Move(ToRegister(result()),
|
||||
target_.native_context().global_proxy_object().object());
|
||||
}
|
||||
__ jmp(&done);
|
||||
}
|
||||
|
||||
__ bind(&convert_to_object);
|
||||
// ToObject needs to be ran with the target context installed.
|
||||
__ Move(kContextRegister, target_.context().object());
|
||||
__ CallBuiltin(Builtin::kToObject);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
int ToObject::MaxCallStackArgs() const {
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kToObject>::type;
|
||||
return D::GetStackParameterCount();
|
||||
}
|
||||
void ToObject::SetValueLocationConstraints() {
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kToObject>::type;
|
||||
UseFixed(context(), kContextRegister);
|
||||
UseFixed(value_input(), D::GetRegisterParameter(D::kInput));
|
||||
DefineAsFixed(this, kReturnRegister0);
|
||||
}
|
||||
void ToObject::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
#ifdef DEBUG
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kToObject>::type;
|
||||
DCHECK_EQ(ToRegister(context()), kContextRegister);
|
||||
DCHECK_EQ(ToRegister(value_input()), D::GetRegisterParameter(D::kInput));
|
||||
#endif // DEBUG
|
||||
Register value = ToRegister(value_input());
|
||||
Label call_builtin, done;
|
||||
// Avoid the builtin call if {value} is a JSReceiver.
|
||||
__ JumpIfSmi(value, &call_builtin);
|
||||
{
|
||||
MaglevAssembler::ScratchRegisterScope temps(masm);
|
||||
Register scratch = temps.Acquire();
|
||||
__ LoadMap(scratch, value);
|
||||
__ CompareInstanceType(scratch, scratch.W(), FIRST_JS_RECEIVER_TYPE);
|
||||
__ B(&done, hs);
|
||||
}
|
||||
__ bind(&call_builtin);
|
||||
__ CallBuiltin(Builtin::kToObject);
|
||||
masm->DefineExceptionHandlerAndLazyDeoptPoint(this);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
int ToString::MaxCallStackArgs() const {
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kToString>::type;
|
||||
return D::GetStackParameterCount();
|
||||
}
|
||||
void ToString::SetValueLocationConstraints() {
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kToString>::type;
|
||||
UseFixed(context(), kContextRegister);
|
||||
UseFixed(value_input(), D::GetRegisterParameter(D::kO));
|
||||
DefineAsFixed(this, kReturnRegister0);
|
||||
}
|
||||
void ToString::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
#ifdef DEBUG
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kToString>::type;
|
||||
DCHECK_EQ(ToRegister(context()), kContextRegister);
|
||||
DCHECK_EQ(ToRegister(value_input()), D::GetRegisterParameter(D::kO));
|
||||
#endif // DEBUG
|
||||
Register value = ToRegister(value_input());
|
||||
Label call_builtin, done;
|
||||
// Avoid the builtin call if {value} is a string.
|
||||
__ JumpIfSmi(value, &call_builtin);
|
||||
{
|
||||
MaglevAssembler::ScratchRegisterScope temps(masm);
|
||||
Register scratch = temps.Acquire();
|
||||
__ LoadMap(scratch, value);
|
||||
__ CompareInstanceType(scratch, scratch.W(), FIRST_NONSTRING_TYPE);
|
||||
__ B(&done, lo);
|
||||
}
|
||||
__ bind(&call_builtin);
|
||||
__ CallBuiltin(Builtin::kToString);
|
||||
masm->DefineExceptionHandlerAndLazyDeoptPoint(this);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
void CheckJSObjectElementsBounds::SetValueLocationConstraints() {
|
||||
UseRegister(receiver_input());
|
||||
set_temporaries_needed(1);
|
||||
@ -199,7 +89,7 @@ void CheckJSObjectElementsBounds::GenerateCode(MaglevAssembler* masm,
|
||||
__ AssertNotSmi(object);
|
||||
|
||||
if (v8_flags.debug_code) {
|
||||
__ CompareObjectType(object, scratch, scratch, FIRST_JS_OBJECT_TYPE);
|
||||
__ CompareObjectType(object, FIRST_JS_OBJECT_TYPE, scratch);
|
||||
__ Assert(ge, AbortReason::kUnexpectedValue);
|
||||
}
|
||||
__ LoadAnyTaggedField(scratch,
|
||||
@ -334,7 +224,7 @@ void CheckJSArrayBounds::GenerateCode(MaglevAssembler* masm,
|
||||
Register scratch = temps.Acquire();
|
||||
|
||||
if (v8_flags.debug_code) {
|
||||
__ CompareObjectType(object, scratch, scratch, JS_ARRAY_TYPE);
|
||||
__ CompareObjectType(object, JS_ARRAY_TYPE, scratch);
|
||||
__ Assert(eq, AbortReason::kUnexpectedValue);
|
||||
}
|
||||
|
||||
@ -686,63 +576,6 @@ void CheckNumber::GenerateCode(MaglevAssembler* masm,
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
void CheckSymbol::SetValueLocationConstraints() {
|
||||
UseRegister(receiver_input());
|
||||
}
|
||||
void CheckSymbol::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
Register object = ToRegister(receiver_input());
|
||||
if (check_type_ == CheckType::kOmitHeapObjectCheck) {
|
||||
__ AssertNotSmi(object);
|
||||
} else {
|
||||
Condition is_smi = __ CheckSmi(object);
|
||||
__ EmitEagerDeoptIf(is_smi, DeoptimizeReason::kNotASymbol, this);
|
||||
}
|
||||
MaglevAssembler::ScratchRegisterScope temps(masm);
|
||||
Register scratch = temps.Acquire();
|
||||
__ CompareObjectType(object, scratch, scratch, SYMBOL_TYPE);
|
||||
__ EmitEagerDeoptIf(ne, DeoptimizeReason::kNotASymbol, this);
|
||||
}
|
||||
|
||||
void CheckInstanceType::SetValueLocationConstraints() {
|
||||
UseRegister(receiver_input());
|
||||
}
|
||||
void CheckInstanceType::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
MaglevAssembler::ScratchRegisterScope temps(masm);
|
||||
Register scratch = temps.Acquire();
|
||||
Register object = ToRegister(receiver_input());
|
||||
if (check_type_ == CheckType::kOmitHeapObjectCheck) {
|
||||
__ AssertNotSmi(object);
|
||||
} else {
|
||||
Condition is_smi = __ CheckSmi(object);
|
||||
__ EmitEagerDeoptIf(is_smi, DeoptimizeReason::kWrongInstanceType, this);
|
||||
}
|
||||
__ LoadMap(scratch, object);
|
||||
__ CompareInstanceType(scratch, scratch, instance_type());
|
||||
__ EmitEagerDeoptIf(ne, DeoptimizeReason::kWrongInstanceType, this);
|
||||
}
|
||||
|
||||
void CheckString::SetValueLocationConstraints() {
|
||||
UseRegister(receiver_input());
|
||||
}
|
||||
void CheckString::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
MaglevAssembler::ScratchRegisterScope temps(masm);
|
||||
Register scratch = temps.Acquire();
|
||||
Register object = ToRegister(receiver_input());
|
||||
if (check_type_ == CheckType::kOmitHeapObjectCheck) {
|
||||
__ AssertNotSmi(object);
|
||||
} else {
|
||||
Condition is_smi = __ CheckSmi(object);
|
||||
__ EmitEagerDeoptIf(is_smi, DeoptimizeReason::kNotAString, this);
|
||||
}
|
||||
__ LoadMap(scratch, object);
|
||||
__ CompareInstanceTypeRange(scratch, scratch, FIRST_STRING_TYPE,
|
||||
LAST_STRING_TYPE);
|
||||
__ EmitEagerDeoptIf(hi, DeoptimizeReason::kNotAString, this);
|
||||
}
|
||||
|
||||
int CheckedObjectToIndex::MaxCallStackArgs() const { return 0; }
|
||||
void CheckedObjectToIndex::SetValueLocationConstraints() {
|
||||
UseRegister(object_input());
|
||||
@ -1373,9 +1206,7 @@ void CheckJSTypedArrayBounds::GenerateCode(MaglevAssembler* masm,
|
||||
|
||||
if (v8_flags.debug_code) {
|
||||
__ AssertNotSmi(object);
|
||||
MaglevAssembler::ScratchRegisterScope temps(masm);
|
||||
Register scratch = temps.Acquire();
|
||||
__ CompareObjectType(object, scratch, scratch, JS_TYPED_ARRAY_TYPE);
|
||||
__ CompareObjectType(object, JS_TYPED_ARRAY_TYPE);
|
||||
__ Assert(eq, AbortReason::kUnexpectedValue);
|
||||
}
|
||||
|
||||
@ -1411,7 +1242,7 @@ void CheckJSDataViewBounds::GenerateCode(MaglevAssembler* masm,
|
||||
Register byte_length = scratch;
|
||||
if (v8_flags.debug_code) {
|
||||
__ AssertNotSmi(object);
|
||||
__ CompareObjectType(object, scratch, scratch, JS_DATA_VIEW_TYPE);
|
||||
__ CompareObjectType(object, JS_DATA_VIEW_TYPE, scratch);
|
||||
__ Assert(eq, AbortReason::kUnexpectedValue);
|
||||
}
|
||||
|
||||
@ -1863,8 +1694,7 @@ void GenerateTypedArrayLoad(MaglevAssembler* masm, NodeT* node, Register object,
|
||||
__ AssertNotSmi(object);
|
||||
if (v8_flags.debug_code) {
|
||||
MaglevAssembler::ScratchRegisterScope temps(masm);
|
||||
Register scratch = temps.Acquire();
|
||||
__ CompareObjectType(object, scratch, scratch, JS_TYPED_ARRAY_TYPE);
|
||||
__ CompareObjectType(object, JS_TYPED_ARRAY_TYPE);
|
||||
__ Assert(eq, AbortReason::kUnexpectedValue);
|
||||
}
|
||||
|
||||
@ -1957,10 +1787,8 @@ void LoadFixedArrayElement::GenerateCode(MaglevAssembler* masm,
|
||||
Register elements = ToRegister(elements_input());
|
||||
Register index = ToRegister(index_input());
|
||||
if (v8_flags.debug_code) {
|
||||
MaglevAssembler::ScratchRegisterScope temps(masm);
|
||||
Register scratch = temps.Acquire();
|
||||
__ AssertNotSmi(elements);
|
||||
__ CompareObjectType(elements, scratch, scratch, FIXED_ARRAY_TYPE);
|
||||
__ CompareObjectType(elements, FIXED_ARRAY_TYPE);
|
||||
__ Assert(eq, AbortReason::kUnexpectedValue);
|
||||
}
|
||||
Register result_reg = ToRegister(result());
|
||||
@ -1979,10 +1807,8 @@ void LoadFixedDoubleArrayElement::GenerateCode(MaglevAssembler* masm,
|
||||
Register elements = ToRegister(elements_input());
|
||||
Register index = ToRegister(index_input());
|
||||
if (v8_flags.debug_code) {
|
||||
MaglevAssembler::ScratchRegisterScope temps(masm);
|
||||
Register scratch = temps.Acquire();
|
||||
__ AssertNotSmi(elements);
|
||||
__ CompareObjectType(elements, scratch, scratch, FIXED_DOUBLE_ARRAY_TYPE);
|
||||
__ CompareObjectType(elements, FIXED_DOUBLE_ARRAY_TYPE);
|
||||
__ Assert(eq, AbortReason::kUnexpectedValue);
|
||||
}
|
||||
__ Add(elements, elements, Operand(index, LSL, kDoubleSizeLog2));
|
||||
@ -2085,9 +1911,7 @@ void LoadSignedIntDataViewElement::GenerateCode(MaglevAssembler* masm,
|
||||
|
||||
__ AssertNotSmi(object);
|
||||
if (v8_flags.debug_code) {
|
||||
MaglevAssembler::ScratchRegisterScope temps(masm);
|
||||
Register scratch = temps.Acquire();
|
||||
__ CompareObjectType(object, scratch, scratch, JS_DATA_VIEW_TYPE);
|
||||
__ CompareObjectType(object, JS_DATA_VIEW_TYPE);
|
||||
__ Assert(hs, AbortReason::kUnexpectedValue);
|
||||
}
|
||||
|
||||
@ -2146,9 +1970,7 @@ void StoreSignedIntDataViewElement::GenerateCode(MaglevAssembler* masm,
|
||||
|
||||
__ AssertNotSmi(object);
|
||||
if (v8_flags.debug_code) {
|
||||
MaglevAssembler::ScratchRegisterScope temps(masm);
|
||||
Register scratch = temps.Acquire();
|
||||
__ CompareObjectType(object, scratch, scratch, JS_DATA_VIEW_TYPE);
|
||||
__ CompareObjectType(object, JS_DATA_VIEW_TYPE);
|
||||
__ Assert(hs, AbortReason::kUnexpectedValue);
|
||||
}
|
||||
|
||||
@ -2200,9 +2022,7 @@ void LoadDoubleDataViewElement::GenerateCode(MaglevAssembler* masm,
|
||||
|
||||
__ AssertNotSmi(object);
|
||||
if (v8_flags.debug_code) {
|
||||
MaglevAssembler::ScratchRegisterScope temps(masm);
|
||||
Register scratch = temps.Acquire();
|
||||
__ CompareObjectType(object, scratch, scratch, JS_DATA_VIEW_TYPE);
|
||||
__ CompareObjectType(object, JS_DATA_VIEW_TYPE);
|
||||
__ Assert(hs, AbortReason::kUnexpectedValue);
|
||||
}
|
||||
|
||||
@ -2265,9 +2085,7 @@ void StoreDoubleDataViewElement::GenerateCode(MaglevAssembler* masm,
|
||||
|
||||
__ AssertNotSmi(object);
|
||||
if (v8_flags.debug_code) {
|
||||
MaglevAssembler::ScratchRegisterScope temps(masm);
|
||||
Register scratch = temps.Acquire();
|
||||
__ CompareObjectType(object, scratch, scratch, JS_DATA_VIEW_TYPE);
|
||||
__ CompareObjectType(object, JS_DATA_VIEW_TYPE);
|
||||
__ Assert(hs, AbortReason::kUnexpectedValue);
|
||||
}
|
||||
|
||||
@ -2509,20 +2327,6 @@ void Return::GenerateCode(MaglevAssembler* masm, const ProcessingState& state) {
|
||||
__ Ret();
|
||||
}
|
||||
|
||||
void BranchIfJSReceiver::SetValueLocationConstraints() {
|
||||
UseRegister(condition_input());
|
||||
}
|
||||
void BranchIfJSReceiver::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
MaglevAssembler::ScratchRegisterScope temps(masm);
|
||||
Register scratch = temps.Acquire();
|
||||
Register value = ToRegister(condition_input());
|
||||
__ JumpIfSmi(value, if_false()->label());
|
||||
__ LoadMap(scratch, value);
|
||||
__ CompareInstanceType(scratch, scratch, FIRST_JS_RECEIVER_TYPE);
|
||||
__ Branch(hs, if_true(), if_false(), state.next_block());
|
||||
}
|
||||
|
||||
void BranchIfFloat64Compare::SetValueLocationConstraints() {
|
||||
UseRegister(left_input());
|
||||
UseRegister(right_input());
|
||||
|
@ -194,6 +194,13 @@ class MaglevAssembler : public MacroAssembler {
|
||||
inline void DeoptIfBufferDetached(Register array, Register scratch,
|
||||
NodeT* node);
|
||||
|
||||
inline void CompareObjectType(Register heap_object, InstanceType type);
|
||||
inline void CompareObjectType(Register heap_object, InstanceType type,
|
||||
Register scratch);
|
||||
inline void CompareObjectTypeRange(Register heap_object,
|
||||
InstanceType lower_limit,
|
||||
InstanceType higher_limit);
|
||||
|
||||
inline void CompareTagged(Register reg, Handle<HeapObject> obj);
|
||||
|
||||
inline void CompareInt32(Register reg, int32_t imm);
|
||||
@ -203,6 +210,13 @@ class MaglevAssembler : public MacroAssembler {
|
||||
inline void JumpIf(Condition cond, Label* target,
|
||||
Label::Distance distance = Label::kFar);
|
||||
|
||||
inline void JumpIfRoot(Register with, RootIndex index, Label* if_equal,
|
||||
Label::Distance distance = Label::kFar);
|
||||
inline void JumpIfNotRoot(Register with, RootIndex index, Label* if_not_equal,
|
||||
Label::Distance distance = Label::kFar);
|
||||
inline void JumpIfSmi(Register src, Label* on_smi,
|
||||
Label::Distance near_jump = Label::kFar);
|
||||
|
||||
inline void CompareInt32AndJumpIf(Register r1, Register r2, Condition cond,
|
||||
Label* target,
|
||||
Label::Distance distance = Label::kFar);
|
||||
|
@ -1201,6 +1201,38 @@ void CheckHeapObject::GenerateCode(MaglevAssembler* masm,
|
||||
__ EmitEagerDeoptIf(is_smi, DeoptimizeReason::kSmi, this);
|
||||
}
|
||||
|
||||
void CheckSymbol::SetValueLocationConstraints() {
|
||||
UseRegister(receiver_input());
|
||||
}
|
||||
void CheckSymbol::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
Register object = ToRegister(receiver_input());
|
||||
if (check_type_ == CheckType::kOmitHeapObjectCheck) {
|
||||
__ AssertNotSmi(object);
|
||||
} else {
|
||||
Condition is_smi = __ CheckSmi(object);
|
||||
__ EmitEagerDeoptIf(is_smi, DeoptimizeReason::kNotASymbol, this);
|
||||
}
|
||||
__ CompareObjectType(object, SYMBOL_TYPE);
|
||||
__ EmitEagerDeoptIf(kNotEqual, DeoptimizeReason::kNotASymbol, this);
|
||||
}
|
||||
|
||||
void CheckInstanceType::SetValueLocationConstraints() {
|
||||
UseRegister(receiver_input());
|
||||
}
|
||||
void CheckInstanceType::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
Register object = ToRegister(receiver_input());
|
||||
if (check_type_ == CheckType::kOmitHeapObjectCheck) {
|
||||
__ AssertNotSmi(object);
|
||||
} else {
|
||||
Condition is_smi = __ CheckSmi(object);
|
||||
__ EmitEagerDeoptIf(is_smi, DeoptimizeReason::kWrongInstanceType, this);
|
||||
}
|
||||
__ CompareObjectType(object, instance_type());
|
||||
__ EmitEagerDeoptIf(kNotEqual, DeoptimizeReason::kWrongInstanceType, this);
|
||||
}
|
||||
|
||||
void CheckInt32Condition::SetValueLocationConstraints() {
|
||||
UseRegister(left_input());
|
||||
UseRegister(right_input());
|
||||
@ -1211,6 +1243,23 @@ void CheckInt32Condition::GenerateCode(MaglevAssembler* masm,
|
||||
__ EmitEagerDeoptIf(NegateCondition(ToCondition(condition_)), reason_, this);
|
||||
}
|
||||
|
||||
void CheckString::SetValueLocationConstraints() {
|
||||
UseRegister(receiver_input());
|
||||
}
|
||||
void CheckString::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
Register object = ToRegister(receiver_input());
|
||||
if (check_type_ == CheckType::kOmitHeapObjectCheck) {
|
||||
__ AssertNotSmi(object);
|
||||
} else {
|
||||
Condition is_smi = __ CheckSmi(object);
|
||||
__ EmitEagerDeoptIf(is_smi, DeoptimizeReason::kNotAString, this);
|
||||
}
|
||||
__ CompareObjectTypeRange(object, FIRST_STRING_TYPE, LAST_STRING_TYPE);
|
||||
__ EmitEagerDeoptIf(kUnsignedGreaterThan, DeoptimizeReason::kNotAString,
|
||||
this);
|
||||
}
|
||||
|
||||
void ConvertHoleToUndefined::SetValueLocationConstraints() {
|
||||
UseRegister(object_input());
|
||||
DefineSameAsFirst(this);
|
||||
@ -1224,6 +1273,44 @@ void ConvertHoleToUndefined::GenerateCode(MaglevAssembler* masm,
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
int ConvertReceiver::MaxCallStackArgs() const {
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kToObject>::type;
|
||||
return D::GetStackParameterCount();
|
||||
}
|
||||
void ConvertReceiver::SetValueLocationConstraints() {
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kToObject>::type;
|
||||
UseFixed(receiver_input(), D::GetRegisterParameter(D::kInput));
|
||||
DefineAsFixed(this, kReturnRegister0);
|
||||
}
|
||||
void ConvertReceiver::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
Label convert_to_object, done;
|
||||
Register receiver = ToRegister(receiver_input());
|
||||
__ JumpIfSmi(receiver, &convert_to_object, Label::Distance::kNear);
|
||||
static_assert(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
|
||||
__ CompareObjectType(receiver, FIRST_JS_RECEIVER_TYPE);
|
||||
__ JumpIf(kUnsignedGreaterThanEqual, &done);
|
||||
|
||||
if (mode_ != ConvertReceiverMode::kNotNullOrUndefined) {
|
||||
Label convert_global_proxy;
|
||||
__ JumpIfRoot(receiver, RootIndex::kUndefinedValue, &convert_global_proxy,
|
||||
Label::Distance::kNear);
|
||||
__ JumpIfNotRoot(receiver, RootIndex::kNullValue, &convert_to_object,
|
||||
Label::Distance::kNear);
|
||||
__ bind(&convert_global_proxy);
|
||||
// Patch receiver to global proxy.
|
||||
__ Move(ToRegister(result()),
|
||||
target_.native_context().global_proxy_object().object());
|
||||
__ Jump(&done);
|
||||
}
|
||||
|
||||
__ bind(&convert_to_object);
|
||||
// ToObject needs to be ran with the target context installed.
|
||||
__ Move(kContextRegister, target_.context().object());
|
||||
__ CallBuiltin(Builtin::kToObject);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
int CreateEmptyArrayLiteral::MaxCallStackArgs() const {
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kCreateEmptyArrayLiteral>::type;
|
||||
return D::GetStackParameterCount();
|
||||
@ -1872,12 +1959,12 @@ void TestTypeOf::GenerateCode(MaglevAssembler* masm,
|
||||
temps.Include(ToRegister(result()));
|
||||
|
||||
Label is_true, is_false, done;
|
||||
__ TestTypeOf(object, literal_, &is_true, Label::kNear, true, &is_false,
|
||||
Label::kNear, false);
|
||||
__ TestTypeOf(object, literal_, &is_true, Label::Distance::kNear, true,
|
||||
&is_false, Label::Distance::kNear, false);
|
||||
// Fallthrough into true.
|
||||
__ bind(&is_true);
|
||||
__ LoadRoot(ToRegister(result()), RootIndex::kTrueValue);
|
||||
__ Jump(&done, Label::kNear);
|
||||
__ Jump(&done, Label::Distance::kNear);
|
||||
__ bind(&is_false);
|
||||
__ LoadRoot(ToRegister(result()), RootIndex::kFalseValue);
|
||||
__ bind(&done);
|
||||
@ -1965,6 +2052,64 @@ void ToNumberOrNumeric::GenerateCode(MaglevAssembler* masm,
|
||||
masm->DefineExceptionHandlerAndLazyDeoptPoint(this);
|
||||
}
|
||||
|
||||
int ToObject::MaxCallStackArgs() const {
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kToObject>::type;
|
||||
return D::GetStackParameterCount();
|
||||
}
|
||||
void ToObject::SetValueLocationConstraints() {
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kToObject>::type;
|
||||
UseFixed(context(), kContextRegister);
|
||||
UseFixed(value_input(), D::GetRegisterParameter(D::kInput));
|
||||
DefineAsFixed(this, kReturnRegister0);
|
||||
}
|
||||
void ToObject::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
#ifdef DEBUG
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kToObject>::type;
|
||||
DCHECK_EQ(ToRegister(context()), kContextRegister);
|
||||
DCHECK_EQ(ToRegister(value_input()), D::GetRegisterParameter(D::kInput));
|
||||
#endif // DEBUG
|
||||
Register value = ToRegister(value_input());
|
||||
Label call_builtin, done;
|
||||
// Avoid the builtin call if {value} is a JSReceiver.
|
||||
__ JumpIfSmi(value, &call_builtin, Label::Distance::kNear);
|
||||
__ CompareObjectType(value, FIRST_JS_RECEIVER_TYPE);
|
||||
__ JumpIf(kUnsignedGreaterThanEqual, &done, Label::Distance::kNear);
|
||||
__ bind(&call_builtin);
|
||||
__ CallBuiltin(Builtin::kToObject);
|
||||
masm->DefineExceptionHandlerAndLazyDeoptPoint(this);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
int ToString::MaxCallStackArgs() const {
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kToString>::type;
|
||||
return D::GetStackParameterCount();
|
||||
}
|
||||
void ToString::SetValueLocationConstraints() {
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kToString>::type;
|
||||
UseFixed(context(), kContextRegister);
|
||||
UseFixed(value_input(), D::GetRegisterParameter(D::kO));
|
||||
DefineAsFixed(this, kReturnRegister0);
|
||||
}
|
||||
void ToString::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
#ifdef DEBUG
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kToString>::type;
|
||||
DCHECK_EQ(ToRegister(context()), kContextRegister);
|
||||
DCHECK_EQ(ToRegister(value_input()), D::GetRegisterParameter(D::kO));
|
||||
#endif // DEBUG
|
||||
Register value = ToRegister(value_input());
|
||||
Label call_builtin, done;
|
||||
// Avoid the builtin call if {value} is a string.
|
||||
__ JumpIfSmi(value, &call_builtin, Label::Distance::kNear);
|
||||
__ CompareObjectType(value, FIRST_NONSTRING_TYPE);
|
||||
__ JumpIf(kUnsignedLessThan, &done, Label::Distance::kNear);
|
||||
__ bind(&call_builtin);
|
||||
__ CallBuiltin(Builtin::kToString);
|
||||
masm->DefineExceptionHandlerAndLazyDeoptPoint(this);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
int ThrowReferenceErrorIfHole::MaxCallStackArgs() const { return 1; }
|
||||
void ThrowReferenceErrorIfHole::SetValueLocationConstraints() {
|
||||
UseAny(value());
|
||||
@ -2543,7 +2688,7 @@ void AttemptOnStackReplacement(MaglevAssembler* masm,
|
||||
FieldMemOperand(scratch0, FeedbackVector::kOsrStateOffset));
|
||||
__ DecodeField<FeedbackVector::OsrUrgencyBits>(scratch0);
|
||||
basm.JumpIfByte(kUnsignedLessThanEqual, scratch0, loop_depth,
|
||||
*no_code_for_osr, Label::kNear);
|
||||
*no_code_for_osr, Label::Distance::kNear);
|
||||
|
||||
// The osr_urgency exceeds the current loop_depth, signaling an OSR
|
||||
// request. Call into runtime to compile.
|
||||
@ -2709,6 +2854,18 @@ void BranchIfTypeOf::GenerateCode(MaglevAssembler* masm,
|
||||
Label::kFar, if_false() == state.next_block());
|
||||
}
|
||||
|
||||
void BranchIfJSReceiver::SetValueLocationConstraints() {
|
||||
UseRegister(condition_input());
|
||||
}
|
||||
void BranchIfJSReceiver::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
Register value = ToRegister(condition_input());
|
||||
__ JumpIfSmi(value, if_false()->label());
|
||||
__ CompareObjectType(value, FIRST_JS_RECEIVER_TYPE);
|
||||
__ Branch(kUnsignedGreaterThanEqual, if_true(), if_false(),
|
||||
state.next_block());
|
||||
}
|
||||
|
||||
void Switch::SetValueLocationConstraints() {
|
||||
UseAndClobberRegister(value());
|
||||
// TODO(victorgomes): Create a arch-agnostic scratch register scope.
|
||||
|
@ -385,6 +385,26 @@ inline void MaglevAssembler::LoadByte(Register dst, MemOperand src) {
|
||||
movzxbl(dst, src);
|
||||
}
|
||||
|
||||
inline void MaglevAssembler::CompareObjectType(Register heap_object,
|
||||
InstanceType type) {
|
||||
LoadMap(kScratchRegister, heap_object);
|
||||
CmpInstanceType(kScratchRegister, type);
|
||||
}
|
||||
|
||||
inline void MaglevAssembler::CompareObjectType(Register heap_object,
|
||||
InstanceType type,
|
||||
Register scratch) {
|
||||
CompareObjectType(heap_object, type);
|
||||
}
|
||||
|
||||
inline void MaglevAssembler::CompareObjectTypeRange(Register heap_object,
|
||||
InstanceType lower_limit,
|
||||
InstanceType higher_limit) {
|
||||
LoadMap(kScratchRegister, heap_object);
|
||||
CmpInstanceTypeRange(kScratchRegister, kScratchRegister, lower_limit,
|
||||
higher_limit);
|
||||
}
|
||||
|
||||
inline void MaglevAssembler::CompareTagged(Register reg,
|
||||
Handle<HeapObject> obj) {
|
||||
Cmp(reg, obj);
|
||||
@ -407,6 +427,23 @@ inline void MaglevAssembler::JumpIf(Condition cond, Label* target,
|
||||
j(cond, target, distance);
|
||||
}
|
||||
|
||||
inline void MaglevAssembler::JumpIfRoot(Register with, RootIndex index,
|
||||
Label* if_equal,
|
||||
Label::Distance distance) {
|
||||
MacroAssembler::JumpIfRoot(with, index, if_equal, distance);
|
||||
}
|
||||
|
||||
inline void MaglevAssembler::JumpIfNotRoot(Register with, RootIndex index,
|
||||
Label* if_not_equal,
|
||||
Label::Distance distance) {
|
||||
MacroAssembler::JumpIfNotRoot(with, index, if_not_equal, distance);
|
||||
}
|
||||
|
||||
inline void MaglevAssembler::JumpIfSmi(Register src, Label* on_smi,
|
||||
Label::Distance distance) {
|
||||
MacroAssembler::JumpIfSmi(src, on_smi, distance);
|
||||
}
|
||||
|
||||
void MaglevAssembler::CompareInt32AndJumpIf(Register r1, Register r2,
|
||||
Condition cond, Label* target,
|
||||
Label::Distance distance) {
|
||||
|
@ -255,58 +255,6 @@ void CheckNumber::GenerateCode(MaglevAssembler* masm,
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
void CheckSymbol::SetValueLocationConstraints() {
|
||||
UseRegister(receiver_input());
|
||||
}
|
||||
void CheckSymbol::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
Register object = ToRegister(receiver_input());
|
||||
if (check_type_ == CheckType::kOmitHeapObjectCheck) {
|
||||
__ AssertNotSmi(object);
|
||||
} else {
|
||||
Condition is_smi = __ CheckSmi(object);
|
||||
__ EmitEagerDeoptIf(is_smi, DeoptimizeReason::kNotASymbol, this);
|
||||
}
|
||||
__ LoadMap(kScratchRegister, object);
|
||||
__ CmpInstanceType(kScratchRegister, SYMBOL_TYPE);
|
||||
__ EmitEagerDeoptIf(not_equal, DeoptimizeReason::kNotASymbol, this);
|
||||
}
|
||||
|
||||
void CheckInstanceType::SetValueLocationConstraints() {
|
||||
UseRegister(receiver_input());
|
||||
}
|
||||
void CheckInstanceType::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
Register object = ToRegister(receiver_input());
|
||||
if (check_type_ == CheckType::kOmitHeapObjectCheck) {
|
||||
__ AssertNotSmi(object);
|
||||
} else {
|
||||
Condition is_smi = __ CheckSmi(object);
|
||||
__ EmitEagerDeoptIf(is_smi, DeoptimizeReason::kWrongInstanceType, this);
|
||||
}
|
||||
__ LoadMap(kScratchRegister, object);
|
||||
__ CmpInstanceType(kScratchRegister, instance_type());
|
||||
__ EmitEagerDeoptIf(not_equal, DeoptimizeReason::kWrongInstanceType, this);
|
||||
}
|
||||
|
||||
void CheckString::SetValueLocationConstraints() {
|
||||
UseRegister(receiver_input());
|
||||
}
|
||||
void CheckString::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
Register object = ToRegister(receiver_input());
|
||||
if (check_type_ == CheckType::kOmitHeapObjectCheck) {
|
||||
__ AssertNotSmi(object);
|
||||
} else {
|
||||
Condition is_smi = __ CheckSmi(object);
|
||||
__ EmitEagerDeoptIf(is_smi, DeoptimizeReason::kNotAString, this);
|
||||
}
|
||||
__ LoadMap(kScratchRegister, object);
|
||||
__ CmpInstanceTypeRange(kScratchRegister, kScratchRegister, FIRST_STRING_TYPE,
|
||||
LAST_STRING_TYPE);
|
||||
__ EmitEagerDeoptIf(above, DeoptimizeReason::kNotAString, this);
|
||||
}
|
||||
|
||||
int CheckMapsWithMigration::MaxCallStackArgs() const {
|
||||
DCHECK_EQ(Runtime::FunctionForId(Runtime::kTryMigrateInstance)->nargs, 1);
|
||||
return 1;
|
||||
@ -2114,68 +2062,6 @@ void TestUndetectable::GenerateCode(MaglevAssembler* masm,
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
int ToObject::MaxCallStackArgs() const {
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kToObject>::type;
|
||||
return D::GetStackParameterCount();
|
||||
}
|
||||
void ToObject::SetValueLocationConstraints() {
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kToObject>::type;
|
||||
UseFixed(context(), kContextRegister);
|
||||
UseFixed(value_input(), D::GetRegisterParameter(D::kInput));
|
||||
DefineAsFixed(this, kReturnRegister0);
|
||||
}
|
||||
void ToObject::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
#ifdef DEBUG
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kToObject>::type;
|
||||
DCHECK_EQ(ToRegister(context()), kContextRegister);
|
||||
DCHECK_EQ(ToRegister(value_input()), D::GetRegisterParameter(D::kInput));
|
||||
#endif // DEBUG
|
||||
Register value = ToRegister(value_input());
|
||||
Label call_builtin, done;
|
||||
// Avoid the builtin call if {value} is a JSReceiver.
|
||||
__ JumpIfSmi(value, &call_builtin);
|
||||
__ LoadMap(kScratchRegister, value);
|
||||
__ cmpw(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset),
|
||||
Immediate(FIRST_JS_RECEIVER_TYPE));
|
||||
__ j(greater_equal, &done);
|
||||
__ bind(&call_builtin);
|
||||
__ CallBuiltin(Builtin::kToObject);
|
||||
masm->DefineExceptionHandlerAndLazyDeoptPoint(this);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
int ToString::MaxCallStackArgs() const {
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kToString>::type;
|
||||
return D::GetStackParameterCount();
|
||||
}
|
||||
void ToString::SetValueLocationConstraints() {
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kToString>::type;
|
||||
UseFixed(context(), kContextRegister);
|
||||
UseFixed(value_input(), D::GetRegisterParameter(D::kO));
|
||||
DefineAsFixed(this, kReturnRegister0);
|
||||
}
|
||||
void ToString::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
#ifdef DEBUG
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kToString>::type;
|
||||
DCHECK_EQ(ToRegister(context()), kContextRegister);
|
||||
DCHECK_EQ(ToRegister(value_input()), D::GetRegisterParameter(D::kO));
|
||||
#endif // DEBUG
|
||||
Register value = ToRegister(value_input());
|
||||
Label call_builtin, done;
|
||||
// Avoid the builtin call if {value} is a string.
|
||||
__ JumpIfSmi(value, &call_builtin);
|
||||
__ LoadMap(kScratchRegister, value);
|
||||
__ cmpw(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset),
|
||||
Immediate(FIRST_NONSTRING_TYPE));
|
||||
__ j(less, &done);
|
||||
__ bind(&call_builtin);
|
||||
__ CallBuiltin(Builtin::kToString);
|
||||
masm->DefineExceptionHandlerAndLazyDeoptPoint(this);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
void CheckedInt32ToUint32::SetValueLocationConstraints() {
|
||||
UseRegister(input());
|
||||
DefineSameAsFirst(this);
|
||||
@ -2290,49 +2176,6 @@ void CheckedTruncateFloat64ToUint32::GenerateCode(
|
||||
__ bind(&check_done);
|
||||
}
|
||||
|
||||
int ConvertReceiver::MaxCallStackArgs() const {
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kToObject>::type;
|
||||
return D::GetStackParameterCount();
|
||||
}
|
||||
void ConvertReceiver::SetValueLocationConstraints() {
|
||||
using D = CallInterfaceDescriptorFor<Builtin::kToObject>::type;
|
||||
UseFixed(receiver_input(), D::GetRegisterParameter(D::kInput));
|
||||
set_temporaries_needed(1);
|
||||
DefineAsFixed(this, kReturnRegister0);
|
||||
}
|
||||
void ConvertReceiver::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
Label convert_to_object, done;
|
||||
MaglevAssembler::ScratchRegisterScope temps(masm);
|
||||
Register scratch = temps.Acquire();
|
||||
Register receiver = ToRegister(receiver_input());
|
||||
__ JumpIfSmi(receiver, &convert_to_object, Label::kNear);
|
||||
static_assert(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
|
||||
__ CmpObjectType(receiver, FIRST_JS_RECEIVER_TYPE, scratch);
|
||||
__ j(above_equal, &done);
|
||||
|
||||
if (mode_ != ConvertReceiverMode::kNotNullOrUndefined) {
|
||||
Label convert_global_proxy;
|
||||
__ JumpIfRoot(receiver, RootIndex::kUndefinedValue, &convert_global_proxy,
|
||||
Label::kNear);
|
||||
__ JumpIfNotRoot(receiver, RootIndex::kNullValue, &convert_to_object,
|
||||
Label::kNear);
|
||||
__ bind(&convert_global_proxy);
|
||||
{
|
||||
// Patch receiver to global proxy.
|
||||
__ Move(ToRegister(result()),
|
||||
target_.native_context().global_proxy_object().object());
|
||||
}
|
||||
__ jmp(&done);
|
||||
}
|
||||
|
||||
__ bind(&convert_to_object);
|
||||
// ToObject needs to be ran with the target context installed.
|
||||
__ Move(kContextRegister, target_.context().object());
|
||||
__ CallBuiltin(Builtin::kToObject);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
void IncreaseInterruptBudget::SetValueLocationConstraints() {
|
||||
set_temporaries_needed(1);
|
||||
}
|
||||
@ -2526,18 +2369,6 @@ void Return::GenerateCode(MaglevAssembler* masm, const ProcessingState& state) {
|
||||
__ Ret();
|
||||
}
|
||||
|
||||
void BranchIfJSReceiver::SetValueLocationConstraints() {
|
||||
UseRegister(condition_input());
|
||||
}
|
||||
void BranchIfJSReceiver::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
Register value = ToRegister(condition_input());
|
||||
__ JumpIfSmi(value, if_false()->label());
|
||||
__ LoadMap(kScratchRegister, value);
|
||||
__ CmpInstanceType(kScratchRegister, FIRST_JS_RECEIVER_TYPE);
|
||||
__ Branch(above_equal, if_true(), if_false(), state.next_block());
|
||||
}
|
||||
|
||||
void BranchIfFloat64Compare::SetValueLocationConstraints() {
|
||||
UseRegister(left_input());
|
||||
UseRegister(right_input());
|
||||
|
Loading…
Reference in New Issue
Block a user