17#define DECLARE_KIND(CN, __, FN, ___, ____) k##CN##_##FN,
49 const intptr_t index =
static_cast<intptr_t
>(kind);
51 const Slot* slot = native_fields_[index];
52 if (slot ==
nullptr) {
53 native_fields_[index] = slot = CreateNativeSlot(kind);
60 : zone_(thread->zone()), fields_(thread->zone()) {}
65 PointerSet<const Slot> fields_;
71#define FIELD_FLAGS_FINAL \
72 (Slot::IsImmutableBit::encode(true) | Slot::IsWeakBit::encode(false))
73#define FIELD_FLAGS_VAR \
74 (Slot::IsImmutableBit::encode(false) | Slot::IsWeakBit::encode(false))
75#define FIELD_FLAGS_WEAK \
76 (Slot::IsImmutableBit::encode(false) | Slot::IsWeakBit::encode(true))
77#define DEFINE_NULLABLE_TAGGED_NATIVE_DART_FIELD(ClassName, UnderlyingType, \
78 FieldName, cid, mutability) \
79 case Slot::Kind::k##ClassName##_##FieldName: \
80 return new (zone_) Slot( \
81 Slot::Kind::k##ClassName##_##FieldName, \
82 (FIELD_FLAGS_##mutability | \
83 Slot::IsCompressedBit::encode( \
84 ClassName::ContainsCompressedPointers())), \
85 compiler::target::ClassName::FieldName##_offset(), \
86 #ClassName "." #FieldName, \
87 CompileType(CompileType::kCanBeNull, CompileType::kCannotBeSentinel, \
88 k##cid##Cid, nullptr), \
94#undef DEFINE_NULLABLE_TAGGED_NATIVE_DART_FIELD
96#define DEFINE_NONNULLABLE_TAGGED_NATIVE_DART_FIELD( \
97 ClassName, UnderlyingType, FieldName, cid, mutability) \
98 case Slot::Kind::k##ClassName##_##FieldName: \
99 return new (zone_) Slot( \
100 Slot::Kind::k##ClassName##_##FieldName, \
101 (FIELD_FLAGS_##mutability | \
102 Slot::IsCompressedBit::encode( \
103 ClassName::ContainsCompressedPointers())), \
104 compiler::target::ClassName::FieldName##_offset(), \
105 #ClassName "." #FieldName, \
106 CompileType(CompileType::kCannotBeNull, \
107 CompileType::kCannotBeSentinel, k##cid##Cid, nullptr), \
115#undef DEFINE_NONNULLABLE_TAGGED_NATIVE_DART_FIELD
117#define DEFINE_UNBOXED_NATIVE_DART_FIELD(ClassName, UnderlyingType, FieldName, \
118 representation, mutability) \
119 case Slot::Kind::k##ClassName##_##FieldName: \
121 Slot(Slot::Kind::k##ClassName##_##FieldName, \
122 FIELD_FLAGS_##mutability | Slot::IsNonTaggedBit::encode(true), \
123 compiler::target::ClassName::FieldName##_offset(), \
124 #ClassName "." #FieldName, \
125 CompileType::FromUnboxedRepresentation(kUnboxed##representation), \
126 kUnboxed##representation);
130#undef DEFINE_UNBOXED_NATIVE_DART_FIELD
132#define DEFINE_UNTAGGED_NATIVE_DART_FIELD(ClassName, UnderlyingType, \
133 FieldName, GcMayMove, mutability) \
134 case Slot::Kind::k##ClassName##_##FieldName: \
136 Slot(Slot::Kind::k##ClassName##_##FieldName, \
137 FIELD_FLAGS_##mutability | \
138 Slot::MayContainInnerPointerBit::encode(GcMayMove) | \
139 Slot::IsNonTaggedBit::encode(true), \
140 compiler::target::ClassName::FieldName##_offset(), \
141 #ClassName "." #FieldName, CompileType::Object(), kUntagged);
145#undef DEFINE_UNTAGGED_NATIVE_DART_FIELD
147#define DEFINE_NULLABLE_TAGGED_NATIVE_NONDART_FIELD(ClassName, __, FieldName, \
149 case Slot::Kind::k##ClassName##_##FieldName: \
150 return new (zone_) Slot( \
151 Slot::Kind::k##ClassName##_##FieldName, \
152 FIELD_FLAGS_##mutability | Slot::HasUntaggedInstanceBit::encode(true), \
153 compiler::target::ClassName::FieldName##_offset(), \
154 #ClassName "." #FieldName, \
155 CompileType(CompileType::kCanBeNull, CompileType::kCannotBeSentinel, \
156 k##cid##Cid, nullptr), \
162#undef DEFINE_NULLABLE_TAGGED_NONDART_FIELD
164#define DEFINE_UNBOXED_NATIVE_NONDART_FIELD(ClassName, __, FieldName, \
165 representation, mutability) \
166 case Slot::Kind::k##ClassName##_##FieldName: \
168 Slot(Slot::Kind::k##ClassName##_##FieldName, \
169 FIELD_FLAGS_##mutability | Slot::IsNonTaggedBit::encode(true) | \
170 Slot::HasUntaggedInstanceBit::encode(true), \
171 compiler::target::ClassName::FieldName##_offset(), \
172 #ClassName "." #FieldName, \
173 CompileType::FromUnboxedRepresentation(kUnboxed##representation), \
174 kUnboxed##representation);
178#undef DEFINE_UNBOXED_NATIVE_NONDART_FIELD
180#define DEFINE_UNTAGGED_NATIVE_NONDART_FIELD(ClassName, __, FieldName, \
181 gc_may_move, mutability) \
182 case Slot::Kind::k##ClassName##_##FieldName: \
184 Slot(Slot::Kind::k##ClassName##_##FieldName, \
185 FIELD_FLAGS_##mutability | \
186 Slot::MayContainInnerPointerBit::encode(gc_may_move) | \
187 Slot::IsNonTaggedBit::encode(true) | \
188 Slot::HasUntaggedInstanceBit::encode(true), \
189 compiler::target::ClassName::FieldName##_offset(), \
190 #ClassName "." #FieldName, CompileType::Object(), kUntagged);
194#undef DEFINE_UNTAGGED_NATIVE_NONDART_FIELD
196#undef FIELD_FLAGS_FINAL
197#undef FIELD_FLAGS_VAR
198#undef FIELD_FLAGS_WEAK
204const Slot& Slot::GetNativeSlot(
Kind kind) {
210 case Slot::Kind::kArray_length:
211 case Slot::Kind::kTypedDataBase_length:
212 case Slot::Kind::kString_length:
213 case Slot::Kind::kTypeArguments_length:
215 case Slot::Kind::kGrowableObjectArray_length:
225#define NOT_TAGGED_INT_NATIVE_SLOT_CASE(Class, __, Field, ___, ____) \
226 case Slot::Kind::k##Class##_##Field:
229#undef NONTAGGED_NATIVE_DART_SLOT_CASE
230 case Slot::Kind::kLinkedHashBase_hash_mask:
231 case Slot::Kind::kLinkedHashBase_used_data:
232 case Slot::Kind::kLinkedHashBase_deleted_keys:
233 case Slot::Kind::kArgumentsDescriptor_type_args_len:
234 case Slot::Kind::kArgumentsDescriptor_positional_count:
235 case Slot::Kind::kArgumentsDescriptor_count:
236 case Slot::Kind::kArgumentsDescriptor_size:
237 case Slot::Kind::kTypeArguments_hash:
238 case Slot::Kind::kTypedDataView_offset_in_bytes:
239 case Slot::Kind::kClosure_hash:
240 case Slot::Kind::kRecord_shape:
241 case Slot::Kind::kAbstractType_hash:
253 return GetNativeSlot(Kind::kTypedDataBase_length);
256 case kGrowableObjectArrayCid:
257 return GetNativeSlot(Kind::kGrowableObjectArray_length);
259 case kOneByteStringCid:
260 case kTwoByteStringCid:
261 return GetNativeSlot(Kind::kString_length);
264 case kImmutableArrayCid:
265 return GetNativeSlot(Kind::kArray_length);
267 case kTypeArgumentsCid:
268 return GetNativeSlot(Kind::kTypeArguments_length);
272 return GetNativeSlot(Kind::kArray_length);
277 if (cls.
id() == kArrayCid || cls.
id() == kImmutableArrayCid) {
278 return Slot::Array_type_arguments();
283 return GetCanonicalSlot(
295 return GetCanonicalSlot(
306 return GetCanonicalSlot(
317 intptr_t offset_in_bytes) {
318 return GetCanonicalSlot(
325 return GetCanonicalSlot(
331const Slot& Slot::GetCanonicalSlot(
Thread* thread,
334 intptr_t offset_in_bytes,
357 bool is_nullable =
true;
374 bool used_guarded_state =
false;
380 used_guarded_state =
true;
383 if (is_nullable && !field_guard_state.
is_nullable()) {
385 used_guarded_state =
true;
391 ASSERT(!(needs_load_guard && is_unboxed));
393 if (needs_load_guard) {
398 used_guarded_state =
false;
405 used_guarded_state =
false;
408 switch (nullable_cid) {
410 rep = kUnboxedDouble;
413 rep = kUnboxedFloat32x4;
416 rep = kUnboxedFloat64x2;
424 const bool is_sentinel_visible =
430 nullable_cid, &field_type);
433 const Slot& slot = GetCanonicalSlot(
459 ASSERT(parsed_function !=
nullptr);
473 return DataAs<const String>()->ToCString();
477 return DataAs<const char>();
482 if (kind_ != other.kind_ || offset_in_bytes_ != other.offset_in_bytes_) {
494 auto other_type = other.
type();
495 return (flags_ == other.flags_) &&
496 (DataAs<const String>()->ptr() ==
497 other.DataAs<
const String>()->ptr()) &&
502 return other.DataAs<
const Field>()->Original() ==
512 uword result = (
static_cast<int8_t
>(kind_) * 63 + offset_in_bytes_) * 31;
516 result += DataAs<const String>()->Hash();
static void encode(uint8_t output[16], const uint32_t input[4])
bool IsStrictlyNonNullable() const
static constexpr int bitsize()
static constexpr S encode(T value)
static constexpr intptr_t kNoTypeArguments
static CompileType FromCid(intptr_t cid)
static constexpr bool kCannotBeSentinel
static constexpr bool kCannotBeNull
static CompileType Dynamic()
bool IsEqualTo(CompileType *other)
static CompileType FromUnboxedRepresentation(Representation rep)
void set_slot_cache(SlotCache *cache)
static CompilerState & Current()
SlotCache * slot_cache() const
intptr_t guarded_cid() const
bool has_initializer() const
FieldPtr Original() const
bool needs_load_guard() const
AbstractTypePtr type() const
CompileType * inferred_type() const
VariableIndex index() const
const String & name() const
static intptr_t ResultCidFromPragma(const Object &function_or_field)
virtual const char * ToCString() const
static constexpr bool ContainsCompressedPointers()
static Object & ZoneHandle()
void AddToGuardedFields(const Field *field) const
const Slot & Canonicalize(const Slot &value)
static SlotCache & Instance(Thread *thread)
const Slot & GetNativeSlot(Slot::Kind kind)
bool is_guarded_field() const
static const Slot & GetContextVariableSlotFor(Thread *thread, const LocalVariable &var)
bool IsImmutableLengthSlot() const
static const Slot & GetRecordFieldSlot(Thread *thread, intptr_t offset_in_bytes)
bool IsLocalVariable() const
static const Slot & GetArrayElementSlot(Thread *thread, intptr_t offset_in_bytes)
static const Slot & Get(const Field &field, const ParsedFunction *parsed_function)
static const Slot & GetLengthFieldForArrayCid(intptr_t array_cid)
bool Equals(const Slot &other) const
const Field & field() const
Representation representation() const
intptr_t offset_in_bytes() const
const char * Name() const
static const Slot & GetTypeArgumentsIndexSlot(Thread *thread, intptr_t index)
static const Slot & GetTypeArgumentsSlotFor(Thread *thread, const Class &cls)
static Thread * Current()
CompilerState & compiler_state()
IsolateGroup * isolate_group() const
static TypePtr DynamicType()
static bool HasCompressedPointers(const dart::Class &handle)
static intptr_t TypeArgumentsFieldOffset(const dart::Class &klass)
static word variable_offset(intptr_t index)
static word OffsetOf(const dart::Field &field)
static word type_at_offset(intptr_t i)
static const word kClassIdTagSize
FlutterSemanticsFlag flags
bool IsTypedDataViewClassId(intptr_t index)
bool IsTypedDataClassId(intptr_t index)
bool IsUnmodifiableTypedDataViewClassId(intptr_t index)
static int8_t data[kExtLength]
bool IsExternalTypedDataClassId(intptr_t index)
#define DEFINE_UNBOXED_NATIVE_NONDART_FIELD(ClassName, __, FieldName, representation, mutability)
#define DEFINE_UNBOXED_NATIVE_DART_FIELD(ClassName, UnderlyingType, FieldName, representation, mutability)
#define DEFINE_NULLABLE_TAGGED_NATIVE_DART_FIELD(ClassName, UnderlyingType, FieldName, cid, mutability)
#define NOT_TAGGED_INT_NATIVE_SLOT_CASE(Class, __, Field, ___, ____)
#define DEFINE_UNTAGGED_NATIVE_NONDART_FIELD(ClassName, __, FieldName, gc_may_move, mutability)
#define DEFINE_UNTAGGED_NATIVE_DART_FIELD(ClassName, UnderlyingType, FieldName, GcMayMove, mutability)
#define DEFINE_NULLABLE_TAGGED_NATIVE_NONDART_FIELD(ClassName, __, FieldName, cid, mutability)
#define DEFINE_NONNULLABLE_TAGGED_NATIVE_DART_FIELD( ClassName, UnderlyingType, FieldName, cid, mutability)
#define DECLARE_KIND(CN, __, FN, ___, ____)
#define NULLABLE_TAGGED_NATIVE_DART_SLOTS_LIST(V)
#define NONNULLABLE_INT_TAGGED_NATIVE_DART_SLOTS_LIST(V)
#define UNBOXED_NATIVE_DART_SLOTS_LIST(V)
#define NULLABLE_TAGGED_NATIVE_NONDART_SLOTS_LIST(V)
#define UNBOXED_NATIVE_SLOTS_LIST(V)
#define NATIVE_SLOTS_LIST(V)
#define NOT_INT_NATIVE_SLOTS_LIST(V)
#define UNBOXED_NATIVE_NONDART_SLOTS_LIST(V)
#define NONNULLABLE_NONINT_TAGGED_NATIVE_DART_SLOTS_LIST(V)
#define UNTAGGED_NATIVE_DART_SLOTS_LIST(V)
#define UNTAGGED_NATIVE_NONDART_SLOTS_LIST(V)