29int TaggedOffset(FieldAccess access) {
30 DCHECK(access.base_is_tagged);
37 bool disable_trap_handler,
44 gasm_(mcgraph, mcgraph->zone()),
46 dead_(mcgraph->Dead()),
51 switch (node->opcode()) {
52 case IrOpcode::kWasmTypeCheck:
54 case IrOpcode::kWasmTypeCheckAbstract:
56 case IrOpcode::kWasmTypeCast:
58 case IrOpcode::kWasmTypeCastAbstract:
60 case IrOpcode::kAssertNotNull:
64 case IrOpcode::kIsNull:
66 case IrOpcode::kIsNotNull:
68 case IrOpcode::kRttCanon:
70 case IrOpcode::kTypeGuard:
72 case IrOpcode::kWasmAnyConvertExtern:
74 case IrOpcode::kWasmExternConvertAny:
76 case IrOpcode::kWasmStructGet:
78 case IrOpcode::kWasmStructSet:
80 case IrOpcode::kWasmArrayGet:
82 case IrOpcode::kWasmArraySet:
84 case IrOpcode::kWasmArrayLength:
86 case IrOpcode::kWasmArrayInitializeLength:
88 case IrOpcode::kStringAsWtf16:
90 case IrOpcode::kStringPrepareForGetCodeunit:
99 type.use_wasm_null() ? RootIndex::kWasmNull : RootIndex::kNullValue;
105#if V8_STATIC_ROOTS_BOOL
107 type.use_wasm_null() ? StaticReadOnlyRoot::kWasmNull
108 : StaticReadOnlyRoot::kNullValue);
119 DCHECK_EQ(node->opcode(), IrOpcode::kWasmTypeCheck);
127 bool object_can_be_null = config.from.is_nullable();
128 bool object_can_be_i31 =
139 if (object_can_be_null && (!is_cast_from_any || config.to.is_nullable())) {
140 const int kResult = config.to.is_nullable() ? 1 : 0;
145 if (object_can_be_i31) {
163 if (is_cast_from_any) {
175 Node* supertypes_length =
179 WasmTypeInfo::kSupertypesLengthOffset)));
197 return Replace(end_label.PhiAt(0));
201 DCHECK_EQ(node->opcode(), IrOpcode::kWasmTypeCheckAbstract);
209 const bool object_can_be_i31 =
243 if (object_can_be_i31) {
251 if (object_can_be_i31) {
274 if (end_label.IsUsed()) {
277 result = end_label.PhiAt(0);
286 DCHECK_EQ(node->opcode(), IrOpcode::kWasmTypeCast);
294 bool object_can_be_null = config.from.is_nullable();
295 bool object_can_be_i31 =
306 if (object_can_be_null && (!is_cast_from_any || config.to.is_nullable())) {
308 if (config.to.is_nullable()) {
310 }
else if (!
v8_flags.experimental_wasm_skip_null_checks) {
316 if (object_can_be_i31) {
336 if (is_cast_from_any) {
348 Node* supertypes_length =
352 WasmTypeInfo::kSupertypesLengthOffset)));
355 TrapId::kTrapIllegalCast);
365 TrapId::kTrapIllegalCast);
378 DCHECK_EQ(node->opcode(), IrOpcode::kWasmTypeCastAbstract);
386 const bool object_can_be_i31 =
409 !
v8_flags.experimental_wasm_skip_null_checks) {
422 if (object_can_be_i31) {
426 TrapId::kTrapIllegalCast);
431 if (object_can_be_i31) {
437 TrapId::kTrapIllegalCast);
443 TrapId::kTrapIllegalCast);
451 gasm_.Uint32LessThan(instance_type,
453 TrapId::kTrapIllegalCast);
460 if (end_label.IsUsed()) {
471 DCHECK_EQ(node->opcode(), IrOpcode::kAssertNotNull);
480 if (op_parameter.trap_id == TrapId::kTrapNullDereference) {
481 if (!
v8_flags.experimental_wasm_skip_null_checks) {
490 !op_parameter.type.use_wasm_null()) {
494 static_assert(WasmStruct::kHeaderSize >
kTaggedSize);
495 static_assert(WasmArray::kHeaderSize >
kTaggedSize);
496 static_assert(WasmInternalFunction::kHeaderSize >
kTaggedSize);
514 DCHECK_EQ(node->opcode(), IrOpcode::kNull);
520 DCHECK_EQ(node->opcode(), IrOpcode::kIsNull);
527 DCHECK_EQ(node->opcode(), IrOpcode::kIsNotNull);
535 DCHECK_EQ(node->opcode(), IrOpcode::kRttCanon);
540 WasmTrustedInstanceData::kManagedObjectMapsOffset -
kHeapObjectTag);
547 DCHECK_EQ(node->opcode(), IrOpcode::kTypeGuard);
555constexpr int32_t kInt31MaxValue = 0x3fffffff;
556constexpr int32_t kInt31MinValue = -kInt31MaxValue - 1;
560 DCHECK_EQ(node->opcode(), IrOpcode::kWasmAnyConvertExtern);
593 &to_heap_number_label);
596 &to_heap_number_label);
618 Node* is_minus_zero =
nullptr;
621 Node* float_bits =
gasm_.BitcastFloat64ToInt64(float_value);
622 is_minus_zero =
gasm_.Word64Equal(float_bits, minus_zero);
628 Node* value_lo =
gasm_.Float64ExtractLowWord32(float_value);
632 Node* value_hi =
gasm_.Float64ExtractHighWord32(float_value);
636 is_minus_zero = done.PhiAt(0);
640 Node* int_value =
gasm_.ChangeFloat64ToInt32(float_value);
642 gasm_.Float64Equal(float_value,
gasm_.ChangeInt32ToFloat64(int_value)),
652 return Replace(end_label.PhiAt(0));
656 DCHECK_EQ(node->opcode(), IrOpcode::kWasmExternConvertAny);
670 DCHECK_EQ(node->opcode(), IrOpcode::kWasmStructGet);
679 info.type->field(info.field_index).machine_representation(),
684 bool explicit_null_check =
688 bool implicit_null_check =
691 if (explicit_null_check) {
693 TrapId::kTrapNullDereference);
698 : info.
type->mutability(info.field_index)
701 if (implicit_null_check) {
711 DCHECK_EQ(node->opcode(), IrOpcode::kWasmStructSet);
720 bool explicit_null_check =
724 bool implicit_null_check =
727 if (explicit_null_check) {
729 TrapId::kTrapNullDereference);
742 : info.type->mutability(info.field_index)
747 if (implicit_null_check) {
757 DCHECK_EQ(node->opcode(), IrOpcode::kWasmArrayGet);
769 info.type->element_type().machine_representation(), info.is_signed);
771 Node* value = info.
type->mutability()
779 DCHECK_EQ(node->opcode(), IrOpcode::kWasmArraySet);
802 DCHECK_EQ(node->opcode(), IrOpcode::kWasmArrayLength);
813 TrapId::kTrapNullDereference);
839 DCHECK_EQ(node->opcode(), IrOpcode::kWasmArrayInitializeLength);
854 DCHECK_EQ(node->opcode(), IrOpcode::kStringAsWtf16);
863 Node* string_representation =
gasm_.Word32And(
877 DCHECK_EQ(node->opcode(), IrOpcode::kStringPrepareForGetCodeunit);
919 Node*
string = dispatch.PhiAt(0);
920 Node* instance_type = dispatch.PhiAt(1);
923 static constexpr int kIsDirectStringTag = 0;
928 &direct_string,
string, instance_type,
offset);
931 Node* string_representation =
gasm_.Word32And(
949 gasm_.
Goto(&next, parent, parent_type, new_offset);
970 gasm_.
Goto(&dispatch, next.PhiAt(0), next.PhiAt(1), next.PhiAt(2));
975 Node*
string = direct_string.PhiAt(0);
976 Node* instance_type = direct_string.PhiAt(1);
983 Node* charwidth_shift =
988 Node* string_representation =
gasm_.Word32And(
997 const int chars_start_offset =
1008 gasm_.Word32And(instance_type,
1023 Node* final_offset = done.PhiAt(1);
1024 Node* charwidth_shift = done.PhiAt(2);
1036 offset_proj->
Kill();
1038 if (charwidth_proj) {
1041 charwidth_proj->
Kill();
static constexpr int root_slot_offset(RootIndex root_index)
static MachineType TypeForRepresentation(const MachineRepresentation &rep, bool isSigned=true)
static constexpr MachineType Float64()
static constexpr MachineType Pointer()
static constexpr MachineType Int32()
static constexpr MachineType Uint32()
static constexpr MachineType TaggedSigned()
static constexpr MachineType TaggedPointer()
static constexpr MachineRepresentation PointerRepresentation()
static ElementAccess ForSeqTwoByteStringCharacter()
static FieldAccess ForHeapNumberValue()
static ElementAccess ForSeqOneByteStringCharacter()
static FieldAccess ForThinStringActual()
static FieldAccess ForExternalStringResourceData()
static FieldAccess ForSlicedStringParent()
static FieldAccess ForSlicedStringOffset()
static FieldAccess ForConsStringFirst()
void ReplaceWithValue(Node *node, Node *value, Node *effect=nullptr, Node *control=nullptr)
static Reduction Replace(Node *node)
detail::GraphAssemblerLabelForReps< Reps... > MakeLabel(Reps... reps)
TNode< Uint32T > Uint32Constant(uint32_t value)
Node * IntPtrConstant(intptr_t value)
Node * TaggedEqual(Node *left, Node *right)
TNode< UintPtrT > UintPtrConstant(uintptr_t value)
Node * LoadTrapOnNull(MachineType type, Node *object, Node *offset)
Node * Int64Constant(int64_t value)
detail::GraphAssemblerLabelForReps< Reps... > MakeLoopLabel(Reps... reps)
void InitializeEffectControl(Node *effect, Node *control)
Node * LoadRootRegister()
void GotoIf(Node *condition, detail::GraphAssemblerLabelForVars< Vars... > *label, BranchHint hint, Vars...)
Node * StoreTrapOnNull(StoreRepresentation rep, Node *object, Node *offset, Node *value)
Node * Float64Constant(double value)
Node * IntPtrAdd(Node *a, Node *b)
void Bind(GraphAssemblerLabel< VarCount > *label)
void GotoIfNot(Node *condition, detail::GraphAssemblerLabelForVars< Vars... > *label, BranchHint hint, Vars...)
void Goto(detail::GraphAssemblerLabelForVars< Vars... > *label, Vars...)
Node * Int32Constant(int32_t value)
static Node * GetEffectInput(Node *node, int index=0)
static Node * GetValueInput(Node *node, int index)
static Node * FindProjection(Node *node, size_t projection_index)
static Node * GetControlInput(Node *node, int index=0)
Node * InputAt(int index) const
static Reduction NoChange()
void SetSourcePosition(Node *node, SourcePosition position)
SourcePosition GetSourcePosition(Node *node) const
Reduction ReduceWasmStructSet(Node *node)
Reduction ReduceIsNull(Node *node)
Reduction ReduceWasmArrayLength(Node *node)
Node * Null(wasm::ValueType type)
Reduction ReduceWasmStructGet(Node *node)
Reduction ReduceWasmArrayGet(Node *node)
WasmGCLowering(Editor *editor, MachineGraph *mcgraph, const wasm::WasmModule *module, bool disable_trap_handler, SourcePositionTable *source_position_table)
Reduction ReduceRttCanon(Node *node)
void UpdateSourcePosition(Node *new_node, Node *old_node)
SourcePositionTable * source_position_table_
Reduction ReduceWasmTypeCheckAbstract(Node *node)
Reduction ReduceWasmTypeCastAbstract(Node *node)
Reduction ReduceTypeGuard(Node *node)
Reduction ReduceWasmAnyConvertExtern(Node *node)
const wasm::WasmModule * module_
NullCheckStrategy null_check_strategy_
Reduction ReduceAssertNotNull(Node *node)
Reduction ReduceStringPrepareForGetCodeunit(Node *node)
Node * IsNull(Node *object, wasm::ValueType type)
Reduction ReduceWasmExternConvertAny(Node *node)
const MachineGraph * mcgraph_
Reduction ReduceWasmArrayInitializeLength(Node *node)
Reduction ReduceWasmArraySet(Node *node)
Reduction ReduceNull(Node *node)
Reduction ReduceWasmTypeCheck(Node *node)
Reduction ReduceWasmTypeCast(Node *node)
Reduction ReduceStringAsWtf16(Node *node)
Reduction ReduceIsNotNull(Node *node)
Reduction Reduce(Node *node) final
Node * BuildChangeSmiToInt32(Node *value)
Node * SmiConstant(Tagged_t value)
Node * BuildChangeInt32ToSmi(Node *value)
Node * LoadImmutableFromObject(MachineType type, Node *base, Node *offset)
Node * IsSmi(Node *object)
Node * FieldOffset(const wasm::StructType *type, uint32_t field_index)
Node * BuildLoadExternalPointerFromObject(Node *object, int offset, ExternalPointerTagRange tag_range, Node *isolate_root)
Node * CallBuiltin(Builtin name, Operator::Properties properties, Args... args)
void TrapIf(Node *condition, TrapId reason)
void TrapUnless(Node *condition, TrapId reason)
Node * LoadFromObject(MachineType type, Node *base, Node *offset)
Node * StoreToObject(ObjectAccess access, Node *base, Node *offset, Node *value)
Node * LoadImmutable(LoadRepresentation rep, Node *base, Node *offset)
Node * LoadInstanceType(Node *map)
Node * IsDataRefMap(Node *map)
Node * BuildChangeInt32ToIntPtr(Node *value)
Node * BuildChangeSmiToIntPtr(Node *value)
Node * LoadMap(Node *object)
Node * InitializeImmutableInObject(ObjectAccess access, Node *base, Node *offset, Node *value)
Node * LoadWasmTypeInfo(Node *map)
Node * HasInstanceType(Node *heap_object, InstanceType type)
Node * WasmArrayElementOffset(Node *index, wasm::ValueType element_type)
static constexpr int ElementOffsetInTaggedFixedArray(int index)
static constexpr int ToTagged(int offset)
constexpr bool is_reference() const
constexpr MachineRepresentation machine_representation() const
constexpr bool is_nullable() const
constexpr HeapType::Representation heap_representation() const
constexpr int32_t kMinusZeroLoBits
constexpr int32_t kMinusZeroHiBits
ZoneVector< RpoNumber > & result
const compiler::NullCheckStrategy null_check_strategy_
V8_INLINE Dest bit_cast(Source const &source)
ObjectAccess ObjectAccessForGCStores(wasm::ValueType type)
T const & OpParameter(const Operator *op)
static constexpr int kCharWidthBailoutSentinel
int GetSubtypingDepth(const WasmModule *module, ModuleTypeIndex type_index)
constexpr IndependentHeapType kWasmNullRef
constexpr uint32_t kMinimumSupertypeArraySize
constexpr IndependentHeapType kWasmAnyRef
constexpr IndependentHeapType kWasmExternRef
constexpr IndependentHeapType kWasmI31Ref
constexpr int kMaxStructFieldIndexForImplicitNullCheck
V8_INLINE bool IsSubtypeOf(ValueType subtype, ValueType supertype, const WasmModule *sub_module, const WasmModule *super_module)
const uint32_t kStringEncodingMask
constexpr int kTaggedSize
constexpr int kNoSourcePosition
const uint32_t kUncachedExternalStringMask
constexpr bool SmiValuesAre31Bits()
const uint32_t kStringRepresentationMask
@ kExternalStringResourceDataTag
const uint32_t kIsIndirectStringTag
V8_EXPORT_PRIVATE FlagValues v8_flags
const uint32_t kIsIndirectStringMask
#define DCHECK_NOT_NULL(val)
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK_GE(v1, v2)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define V8_STATIC_ROOTS_BOOL
SourcePositionTable * source_position_table_
const wasm::WasmModule * module_