[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:
Victor Gomes 2023-01-27 16:24:10 +01:00 committed by V8 LUCI CQ
parent 0bbbe9b450
commit 2dd722b936
6 changed files with 263 additions and 380 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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