44 if (input.operand().IsConstant()) {
45 input.node()->LoadToRegister(
this, scratch);
64 LoadRoot(table, RootIndex::kSingleCharacterStringTable);
74 if (access_info.
holder().has_value()) {
75 load_source = scratch;
76 Move(load_source, access_info.
holder().value().object());
80 Register load_source_object = load_source;
81 if (load_source ==
object) {
82 load_source = scratch;
87 JSReceiver::kPropertiesOrHashOffset);
104 Map::Bits1::IsUndetectableBit::kMask, target,
120 Map::Bits1::IsUndetectableBit::kMask, target,
134 static_assert(Map::kBitFieldOffsetEnd + 1 - Map::kBitFieldOffset == 1);
136 Map::Bits1::IsCallableBit::kMask, target,
150 snapshot.live_registers.clear(result_reg);
151 snapshot.live_tagged_registers.clear(result_reg);
159 done, object, elements, register_snapshot);
165 bool fallthrough_when_true) {
179 value, is_true, is_false);
184#if V8_STATIC_ROOTS_BOOL
189 static_assert(StaticReadOnlyRoot::kFirstAllocatedRoot ==
190 StaticReadOnlyRoot::kUndefinedValue);
191 static_assert(StaticReadOnlyRoot::kUndefinedValue +
sizeof(
Undefined) ==
192 StaticReadOnlyRoot::kNullValue);
193 static_assert(StaticReadOnlyRoot::kNullValue +
sizeof(
Null) ==
194 StaticReadOnlyRoot::kempty_string);
195 static_assert(StaticReadOnlyRoot::kempty_string +
197 StaticReadOnlyRoot::kFalseValue);
198 static_assert(StaticReadOnlyRoot::kFalseValue +
sizeof(
False) ==
199 StaticReadOnlyRoot::kTrueValue);
207 JumpIfRoot(value, RootIndex::kFalseValue, *is_false);
210 JumpIfRoot(value, RootIndex::kTrueValue, *is_true);
213 JumpIfRoot(value, RootIndex::kempty_string, *is_false);
220 ->DependOnNoUndetectableObjectsProtector()) {
222 JumpIfRoot(value, RootIndex::kUndefinedValue, *is_false);
225 JumpIfRoot(value, RootIndex::kNullValue, *is_false);
234 ->DependOnNoUndetectableObjectsProtector()) {
237 Map::Bits1::IsUndetectableBit::kMask, *is_false);
250 value, is_true, is_false));
268 if (!fallthrough_when_true) {
274 switch (value->opcode()) {
275 case Opcode::kInt32Constant: {
284 case Opcode::kUint32Constant: {
293 case Opcode::kFloat64Constant: {
294 double double_value =
307 DCHECK(!value->allocation().IsConstant());
308 DCHECK(value->allocation().IsAnyStackSlot());
310 DoubleRegister builtin_input_value = D::GetDoubleRegisterParameter(D::kValue);
312 switch (value->properties().value_representation()) {
349 LoadRoot(dst, RootIndex::kUndefinedValue);
381 bool fallthrough_when_false) {
383 if (fallthrough_when_true && fallthrough_when_false)
return;
390 case LiteralFlag::kNumber: {
393 JumpIfSmi(
object, is_true, true_distance);
395 Branch(
kEqual, is_true, true_distance, fallthrough_when_true, is_false,
396 false_distance, fallthrough_when_false);
399 case LiteralFlag::kString: {
400 JumpIfSmi(
object, is_false, false_distance);
402 fallthrough_when_true, is_false,
403 false_distance, fallthrough_when_false);
406 case LiteralFlag::kSymbol: {
407 JumpIfSmi(
object, is_false, false_distance);
409 fallthrough_when_true, is_false, false_distance,
410 fallthrough_when_false);
413 case LiteralFlag::kBoolean:
414 JumpIfRoot(
object, RootIndex::kTrueValue, is_true, true_distance);
416 Branch(
kEqual, is_true, true_distance, fallthrough_when_true, is_false,
417 false_distance, fallthrough_when_false);
419 case LiteralFlag::kBigInt: {
420 JumpIfSmi(
object, is_false, false_distance);
422 fallthrough_when_true, is_false, false_distance,
423 fallthrough_when_false);
426 case LiteralFlag::kUndefined: {
431 JumpIfSmi(
object, is_false, false_distance);
435 Map::Bits1::IsUndetectableBit::kMask, is_false,
438 Branch(
kNotEqual, is_true, true_distance, fallthrough_when_true, is_false,
439 false_distance, fallthrough_when_false);
442 case LiteralFlag::kFunction: {
445 JumpIfSmi(
object, is_false, false_distance);
449 true_distance, fallthrough_when_true, is_false, false_distance,
450 fallthrough_when_false);
453 case LiteralFlag::kObject: {
456 JumpIfSmi(
object, is_false, false_distance);
458 JumpIfRoot(
object, RootIndex::kNullValue, is_true, true_distance);
462 is_false, false_distance);
465 true_distance, fallthrough_when_true, is_false, false_distance,
466 fallthrough_when_false);
469 case LiteralFlag::kOther:
470 if (!fallthrough_when_false) {
471 Jump(is_false, false_distance);
478template <MaglevAssembler::StoreMode store_mode>
515 if (
object != stub_object_reg &&
517 saved.
set(stub_object_reg);
525 if (
object != stub_object_reg) {
526 __ Move(stub_object_reg,
object);
527 object = stub_object_reg;
530 if constexpr (store_mode ==
kElement) {
533 static_assert(store_mode ==
kField);
547 done, object,
offset,
value, register_snapshot, value_is_compressed);
549 if (!value_can_be_smi) {
553#if V8_STATIC_ROOTS_BOOL
559 if (value_can_be_smi) {
568 deferred_write_barrier);
572#ifdef V8_ENABLE_SANDBOX
592 if (
object != stub_object_reg &&
594 saved.
set(stub_object_reg);
605 if (
object != stub_object_reg) {
606 __ Move(stub_object_reg,
object);
607 object = stub_object_reg;
622 done, object,
offset,
value, register_snapshot, tag);
639 object,
offset, value, register_snapshot, value_is_compressed,
643#ifdef V8_ENABLE_SANDBOX
645void MaglevAssembler::StoreTrustedPointerFieldWithWriteBarrier(
649 StoreTrustedPointerFieldNoWriteBarrier(
object,
offset, value);
651 register_snapshot, tag);
662 AbortReason::kUnexpectedNegativeValue);
674 Label smi_data, deopt;
687 JumpIfRoot(data, RootIndex::kUndefinedValue, &deopt);
690 AbortReason::kUnexpectedValue);
693 ContextSidePropertyCell::kPropertyDetailsRawOffset);
721 Move(scratch, return_val);
722 return_val = scratch;
735 CallRuntime(Runtime::kTryMigrateInstanceAndMarkMapAsMigrationTarget);
constexpr int kRegularPageSize
static constexpr Builtin IndirectPointerBarrier(SaveFPRegsMode fp_mode)
static Tagged< Smi > Const()
static V8_INLINE constexpr int OffsetOfElementAt(int index)
@ MIN_CONTEXT_EXTENDED_SLOTS
@ CONTEXT_SIDE_TABLE_PROPERTY_INDEX
static constexpr Register IndirectPointerTagRegister()
static constexpr Register ObjectRegister()
static constexpr Register SlotAddressRegister()
void PushAll(RegList registers)
void AssertNotSmi(Register object, AbortReason reason=AbortReason::kOperandIsASmi) NOOP_UNLESS_DEBUG_CODE
void CompareRoot(Register obj, RootIndex index)
void JumpIfUnsignedLessThan(Register x, int32_t y, Label *dest)
void JumpIfMarking(Label *is_marking, Label::Distance condition_met_distance=Label::kFar)
void LoadRoot(Register destination, RootIndex index) final
void CheckPageFlag(Register object, int mask, Condition cc, Label *condition_met)
void CallRecordWriteStub(Register object, Register slot_address, SaveFPRegsMode fp_mode, StubCallMode mode=StubCallMode::kCallBuiltinPointer)
void PopAll(RegList registers)
void DecompressTagged(const Register &destination, const MemOperand &field_operand)
Condition CheckSmi(Register src)
void LoadMap(Register destination, Register object)
static constexpr MainThreadFlags kPointersToHereAreInterestingMask
static constexpr MainThreadFlags kPointersFromHereAreInterestingMask
static constexpr int kEmptyHashField
constexpr void set(RegisterT reg)
constexpr bool is_empty() const
constexpr bool has(RegisterT reg) const
static constexpr Register no_reg()
static V8_INLINE constexpr int32_t SizeFor(int32_t length)
static V8_INLINE constexpr int32_t SizeFor(int32_t length)
static constexpr Tagged< Smi > FromInt(int value)
static bool constexpr IsValid(T value)
static constexpr Tagged< Smi > zero()
static const int32_t kMaxOneByteCharCode
static constexpr int OffsetOfElementAt(int index)
static constexpr Register ObjectRegister()
static constexpr Register SlotAddressRegister()
static constexpr bool kUninterestingPagesCanBeSkipped
static LocationOperand * cast(InstructionOperand *op)
Register AcquireScratch()
void IncludeScratch(Register reg)
void CompareMapWithRoot(Register object, RootIndex index, Register scratch)
Register FromAnyToRegister(const Input &input, Register scratch)
Condition IsNotCallableNorUndetactable(Register map, Register scratch)
void JumpIfRoot(Register with, RootIndex index, Label *if_equal, Label::Distance distance=Label::kFar)
Condition IsCallableAndNotUndetectable(Register map, Register scratch)
compiler::NativeContextRef native_context() const
void IntPtrToDouble(DoubleRegister result, Register src)
void Branch(Condition condition, BasicBlock *if_true, BasicBlock *if_false, BasicBlock *next_block)
void LoadSingleCharacterString(Register result, int char_code)
void JumpIfSmi(Register src, Label *on_smi, Label::Distance near_jump=Label::kFar)
void TestUint8AndJumpIfAllClear(MemOperand operand, uint8_t mask, Label *target, Label::Distance distance=Label::kFar)
void CompareInt32AndAssert(Register r1, Register r2, Condition cond, AbortReason reason)
void CompareDoubleAndJumpIfZeroOrNaN(DoubleRegister reg, Label *target, Label::Distance distance=Label::kFar)
void Jump(Label *target, Label::Distance distance=Label::kFar)
void StoreTaggedSignedField(Register object, int offset, Register value)
void CompareSmiAndJumpIf(Register r1, Tagged< Smi > value, Condition cond, Label *target, Label::Distance distance=Label::kFar)
void TestUint8AndJumpIfAnySet(MemOperand operand, uint8_t mask, Label *target, Label::Distance distance=Label::kFar)
void CallRuntime(Runtime::FunctionId fid)
void StoreFixedArrayElementNoWriteBarrier(Register array, Register index, Register value)
void Allocate(RegisterSnapshot register_snapshot, Register result, int size_in_bytes, AllocationType alloc_type=AllocationType::kYoung, AllocationAlignment alignment=kTaggedAligned)
void SetSlotAddressForTaggedField(Register slot_reg, Register object, int offset)
void CompareTaggedAndJumpIf(Register reg, Tagged< Smi > smi, Condition cond, Label *target, Label::Distance distance=Label::kFar)
void StoreInt32Field(Register object, int offset, int32_t value)
void ToBoolean(Register value, CheckType check_type, ZoneLabelRef is_true, ZoneLabelRef is_false, bool fallthrough_when_true)
void MaterialiseValueNode(Register dst, ValueNode *value)
void BranchOnObjectType(Register heap_object, InstanceType type, Label *if_true, Label::Distance true_distance, bool fallthrough_when_true, Label *if_false, Label::Distance false_distance, bool fallthrough_when_false)
void AllocateTwoByteString(RegisterSnapshot register_snapshot, Register result, int length)
void Move(StackSlot dst, Register src)
void SetMapAsRoot(Register object, RootIndex map)
void CallBuiltin(Builtin builtin)
Label * MakeDeferredCode(Function &&deferred_code_gen, Args &&... args)
void JumpToDeferredIf(Condition cond, Function &&deferred_code_gen, Args &&... args)
void GenerateCheckConstTrackingLetCellFooter(Register context, Register data, int index, Label *done)
MaglevCompilationInfo * compilation_info() const
void TestInt32AndJumpIfAllClear(Register r1, int32_t mask, Label *target, Label::Distance distance=Label::kFar)
void JumpIfNotCallable(Register object, Register scratch, CheckType check_type, Label *target, Label::Distance distance=Label::kFar)
void CompareInt32AndJumpIf(Register r1, Register r2, Condition cond, Label *target, Label::Distance distance=Label::kFar)
void StoreTaggedFieldWithWriteBarrier(Register object, int offset, Register value, RegisterSnapshot register_snapshot, ValueIsCompressed value_is_compressed, ValueCanBeSmi value_can_be_smi)
void SmiTagIntPtrAndJumpIfSuccess(Register dst, Register src, Label *success, Label::Distance distance=Label::kFar)
void SetSlotAddressForFixedArrayElement(Register slot_reg, Register object, Register index)
void LoadDataField(const PolymorphicAccessInfo &access_info, Register result, Register object, Register scratch)
void JumpIf(Condition cond, Label *target, Label::Distance distance=Label::kFar)
void CheckJSAnyIsStringAndBranch(Register heap_object, Label *if_true, Label::Distance true_distance, bool fallthrough_when_true, Label *if_false, Label::Distance false_distance, bool fallthrough_when_false)
void LoadFloat64(DoubleRegister dst, MemOperand src)
void TryMigrateInstanceAndMarkMapAsMigrationTarget(Register object, RegisterSnapshot ®ister_snapshot)
void StoreFixedArrayElementWithWriteBarrier(Register array, Register index, Register value, RegisterSnapshot register_snapshot)
void StoreFloat64(MemOperand dst, DoubleRegister src)
void CheckAndEmitDeferredWriteBarrier(Register object, OffsetTypeFor< store_mode > offset, Register value, RegisterSnapshot register_snapshot, ValueIsCompressed value_is_compressed, ValueCanBeSmi value_can_be_smi)
void StoreTaggedFieldNoWriteBarrier(Register object, int offset, Register value)
MemOperand ToMemOperand(const compiler::InstructionOperand &operand)
void MoveHeapNumber(Register dst, double value)
void LoadTaggedField(Register result, MemOperand operand)
void JumpIfUndetectable(Register object, Register scratch, CheckType check_type, Label *target, Label::Distance distance=Label::kFar)
void SmiTagInt32AndJumpIfSuccess(Register dst, Register src, Label *success, Label::Distance distance=Label::kFar)
void JumpIfNotHoleNan(DoubleRegister value, Register scratch, Label *target, Label::Distance distance=Label::kFar)
void TryMigrateInstance(Register object, RegisterSnapshot ®ister_snapshot, Label *fail)
void EnsureWritableFastElements(RegisterSnapshot register_snapshot, Register elements, Register object, Register scratch)
void Uint32ToDouble(DoubleRegister result, Register src)
void Int32ToDouble(DoubleRegister result, Register src)
void JumpIfNotUndetectable(Register object, Register scratch, CheckType, Label *target, Label::Distance distance=Label::kFar)
void AssertObjectType(Register heap_object, InstanceType type, AbortReason reason)
void CheckAndEmitDeferredIndirectPointerWriteBarrier(Register object, int offset, Register value, RegisterSnapshot register_snapshot, IndirectPointerTag tag)
void AllocateHeapNumber(RegisterSnapshot register_snapshot, Register result, DoubleRegister value)
void CompareInstanceTypeAndJumpIf(Register map, InstanceType type, Condition cond, Label *target, Label::Distance distance)
void SmiTagUint32AndJumpIfSuccess(Register dst, Register src, Label *success, Label::Distance distance=Label::kFar)
std::conditional_t< store_mode==kField, int, Register > OffsetTypeFor
void TestTypeOf(Register object, interpreter::TestTypeOfFlags::LiteralFlag literal, Label *if_true, Label::Distance true_distance, bool fallthrough_when_true, Label *if_false, Label::Distance false_distance, bool fallthrough_when_false)
FieldIndex field_index() const
compiler::OptionalJSObjectRef holder() const
#define ASM_CODE_COMMENT_STRING(asm,...)
ZoneVector< RpoNumber > & result
FunctionLiteral * literal
Register ToRegister(const compiler::InstructionOperand &operand)
constexpr int kTaggedSize
constexpr intptr_t kObjectAlignment
bool DoubleToSmiInteger(double value, int *smi_int_value)
static constexpr RegList kAllocatableGeneralRegisters
MemOperand FieldMemOperand(Register object, int offset)
constexpr Register kReturnRegister0
constexpr Register kContextRegister
V8_EXPORT_PRIVATE FlagValues v8_flags
constexpr bool PointerCompressionIsEnabled()
V8_INLINE Local< Primitive > Null(Isolate *isolate)
V8_INLINE Local< Boolean > False(Isolate *isolate)
V8_INLINE Local< Primitive > Undefined(Isolate *isolate)
#define DCHECK_GE(v1, v2)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
DoubleRegList live_double_registers
#define OFFSET_OF_DATA_START(Type)