Flutter Engine
The Flutter Engine
slot.cc
Go to the documentation of this file.
1// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
6
10#include "vm/hash_map.h"
11#include "vm/parser.h"
12#include "vm/scopes.h"
13
14namespace dart {
15
17#define DECLARE_KIND(CN, __, FN, ___, ____) k##CN##_##FN,
19#undef DECLARE_KIND
21};
22
23// Canonicalization cache for Slot objects.
24//
25// This cache is attached to the CompilerState to ensure that we preserve
26// identity of Slot objects during each individual compilation.
27class SlotCache : public ZoneAllocated {
28 public:
29 // Returns an instance of SlotCache for the current compilation.
30 static SlotCache& Instance(Thread* thread) {
31 auto result = thread->compiler_state().slot_cache();
32 if (result == nullptr) {
33 result = new (thread->zone()) SlotCache(thread);
35 }
36 return *result;
37 }
38
39 const Slot& Canonicalize(const Slot& value) {
40 auto result = fields_.LookupValue(&value);
41 if (result == nullptr) {
42 result = new (zone_) Slot(value);
43 fields_.Insert(result);
44 }
45 return *result;
46 }
47
49 const intptr_t index = static_cast<intptr_t>(kind);
50 ASSERT((index >= 0) && (index < kNativeSlotsCount));
51 const Slot* slot = native_fields_[index];
52 if (slot == nullptr) {
53 native_fields_[index] = slot = CreateNativeSlot(kind);
54 }
55 return *slot;
56 }
57
58 private:
59 explicit SlotCache(Thread* thread)
60 : zone_(thread->zone()), fields_(thread->zone()) {}
61
62 Slot* CreateNativeSlot(Slot::Kind kind);
63
64 Zone* const zone_;
65 PointerSet<const Slot> fields_;
66 const Slot* native_fields_[kNativeSlotsCount] = {nullptr};
67};
68
69Slot* SlotCache::CreateNativeSlot(Slot::Kind kind) {
70 switch (kind) {
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), \
89 kTagged);
90
93
94#undef DEFINE_NULLABLE_TAGGED_NATIVE_DART_FIELD
95
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), \
108 kTagged);
109
114
115#undef DEFINE_NONNULLABLE_TAGGED_NATIVE_DART_FIELD
116
117#define DEFINE_UNBOXED_NATIVE_DART_FIELD(ClassName, UnderlyingType, FieldName, \
118 representation, mutability) \
119 case Slot::Kind::k##ClassName##_##FieldName: \
120 return new (zone_) \
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);
127
129
130#undef DEFINE_UNBOXED_NATIVE_DART_FIELD
131
132#define DEFINE_UNTAGGED_NATIVE_DART_FIELD(ClassName, UnderlyingType, \
133 FieldName, GcMayMove, mutability) \
134 case Slot::Kind::k##ClassName##_##FieldName: \
135 return new (zone_) \
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);
142
144
145#undef DEFINE_UNTAGGED_NATIVE_DART_FIELD
146
147#define DEFINE_NULLABLE_TAGGED_NATIVE_NONDART_FIELD(ClassName, __, FieldName, \
148 cid, mutability) \
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), \
157 kTagged);
158
161
162#undef DEFINE_NULLABLE_TAGGED_NONDART_FIELD
163
164#define DEFINE_UNBOXED_NATIVE_NONDART_FIELD(ClassName, __, FieldName, \
165 representation, mutability) \
166 case Slot::Kind::k##ClassName##_##FieldName: \
167 return new (zone_) \
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);
175
177
178#undef DEFINE_UNBOXED_NATIVE_NONDART_FIELD
179
180#define DEFINE_UNTAGGED_NATIVE_NONDART_FIELD(ClassName, __, FieldName, \
181 gc_may_move, mutability) \
182 case Slot::Kind::k##ClassName##_##FieldName: \
183 return new (zone_) \
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);
191
193
194#undef DEFINE_UNTAGGED_NATIVE_NONDART_FIELD
195
196#undef FIELD_FLAGS_FINAL
197#undef FIELD_FLAGS_VAR
198#undef FIELD_FLAGS_WEAK
199 default:
200 UNREACHABLE();
201 }
202}
203
204const Slot& Slot::GetNativeSlot(Kind kind) {
206}
207
209 switch (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:
214 return true;
215 case Slot::Kind::kGrowableObjectArray_length:
216 return false;
217
218 // Not length loads.
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:
242 return false;
243 }
244 UNREACHABLE();
245 return false;
246}
247
248// Note: should only be called with cids of array-like classes.
249const Slot& Slot::GetLengthFieldForArrayCid(intptr_t array_cid) {
250 if (IsExternalTypedDataClassId(array_cid) || IsTypedDataClassId(array_cid) ||
251 IsTypedDataViewClassId(array_cid) ||
253 return GetNativeSlot(Kind::kTypedDataBase_length);
254 }
255 switch (array_cid) {
256 case kGrowableObjectArrayCid:
257 return GetNativeSlot(Kind::kGrowableObjectArray_length);
258
259 case kOneByteStringCid:
260 case kTwoByteStringCid:
261 return GetNativeSlot(Kind::kString_length);
262
263 case kArrayCid:
264 case kImmutableArrayCid:
265 return GetNativeSlot(Kind::kArray_length);
266
267 case kTypeArgumentsCid:
268 return GetNativeSlot(Kind::kTypeArguments_length);
269
270 default:
271 UNREACHABLE();
272 return GetNativeSlot(Kind::kArray_length);
273 }
274}
275
276const Slot& Slot::GetTypeArgumentsSlotFor(Thread* thread, const Class& cls) {
277 if (cls.id() == kArrayCid || cls.id() == kImmutableArrayCid) {
278 return Slot::Array_type_arguments();
279 }
280 const intptr_t offset =
283 return GetCanonicalSlot(
284 thread, Kind::kTypeArguments,
288 offset, ":type_arguments", CompileType::FromCid(kTypeArgumentsCid),
289 kTagged);
290}
291
293 const LocalVariable& variable) {
294 ASSERT(variable.is_captured());
295 return GetCanonicalSlot(
297 IsImmutableBit::encode(variable.is_final() && !variable.is_late()) |
300 &variable.name(), *(variable.inferred_type()), kTagged);
301}
302
303const Slot& Slot::GetTypeArgumentsIndexSlot(Thread* thread, intptr_t index) {
304 const intptr_t offset =
306 return GetCanonicalSlot(
310 offset, ":argument",
312 kDynamicCid, nullptr),
313 kTagged);
314}
315
317 intptr_t offset_in_bytes) {
318 return GetCanonicalSlot(
319 thread, Kind::kArrayElement,
321 offset_in_bytes, ":array_element", CompileType::Dynamic(), kTagged);
322}
323
324const Slot& Slot::GetRecordFieldSlot(Thread* thread, intptr_t offset_in_bytes) {
325 return GetCanonicalSlot(
326 thread, Kind::kRecordField,
328 offset_in_bytes, ":record_field", CompileType::Dynamic(), kTagged);
329}
330
331const Slot& Slot::GetCanonicalSlot(Thread* thread,
332 Slot::Kind kind,
333 int8_t flags,
334 intptr_t offset_in_bytes,
335 const void* data,
337 Representation representation,
338 const FieldGuardState& field_guard_state) {
339 const Slot& slot = Slot(kind, flags, offset_in_bytes, data, type,
340 representation, field_guard_state);
341 return SlotCache::Instance(thread).Canonicalize(slot);
342}
343
345 : state_(GuardedCidBits::encode(field.guarded_cid()) |
346 IsNullableBit::encode(field.is_nullable())) {
349}
350
351const Slot& Slot::Get(const Field& field,
352 const ParsedFunction* parsed_function) {
353 Thread* thread = Thread::Current();
354 Zone* zone = thread->zone();
355 Representation rep = kTagged;
356 intptr_t nullable_cid = kDynamicCid;
357 bool is_nullable = true;
358
359 if (field.has_pragma()) {
361 if (cid != kDynamicCid) {
362 nullable_cid = cid;
363 is_nullable = false;
364 }
365 }
366
367 AbstractType& field_type = AbstractType::ZoneHandle(zone, field.type());
368 if (field_type.IsStrictlyNonNullable()) {
369 is_nullable = false;
370 }
371
372 FieldGuardState field_guard_state(field);
373
374 bool used_guarded_state = false;
375 if (field_guard_state.guarded_cid() != kIllegalCid &&
376 field_guard_state.guarded_cid() != kDynamicCid) {
377 // Use guarded state if it is more precise then what we already have.
378 if (nullable_cid == kDynamicCid) {
379 nullable_cid = field_guard_state.guarded_cid();
380 used_guarded_state = true;
381 }
382
383 if (is_nullable && !field_guard_state.is_nullable()) {
384 is_nullable = false;
385 used_guarded_state = true;
386 }
387 }
388
389 const bool needs_load_guard = field.needs_load_guard();
390 const bool is_unboxed = field.is_unboxed();
391 ASSERT(!(needs_load_guard && is_unboxed));
392
393 if (needs_load_guard) {
394 // Should be kept in sync with LoadStaticFieldInstr::ComputeType.
395 field_type = Type::DynamicType();
396 nullable_cid = kDynamicCid;
397 is_nullable = true;
398 used_guarded_state = false;
399 }
400
401 if (is_unboxed) {
402 // The decision to unbox is made based on static types (or TFA annotations).
403 // It is therefore not part of the dynamically initialized & updated guarded
404 // state.
405 used_guarded_state = false;
406 is_nullable = false;
407 nullable_cid = field_guard_state.guarded_cid();
408 switch (nullable_cid) {
409 case kDoubleCid:
410 rep = kUnboxedDouble;
411 break;
412 case kFloat32x4Cid:
413 rep = kUnboxedFloat32x4;
414 break;
415 case kFloat64x2Cid:
416 rep = kUnboxedFloat64x2;
417 break;
418 default:
419 rep = kUnboxedInt64;
420 break;
421 }
422 }
423
424 const bool is_sentinel_visible =
426
427 CompileType type = (rep != kTagged)
429 : CompileType(is_nullable, is_sentinel_visible,
430 nullable_cid, &field_type);
431
432 Class& owner = Class::Handle(zone, field.Owner());
433 const Slot& slot = GetCanonicalSlot(
434 thread, Kind::kDartField,
436 field.is_const()) |
437 IsGuardedBit::encode(used_guarded_state) |
440 IsNonTaggedBit::encode(is_unboxed),
442 field_guard_state);
443
444 // If properties of this slot were based on the guarded state make sure
445 // to add the field to the list of guarded fields. Note that during background
446 // compilation we might have two field clones that have incompatible guarded
447 // state - however both of these clones would correspond to the same slot.
448 // That is why we check the is_guarded_field() property of the slot rather
449 // than look at the current guarded state of the field, because current
450 // guarded state of the field might be set to kDynamicCid, while it was
451 // set to something more concrete when the slot was created.
452 // Note that we could have created this slot during an unsuccessful inlining
453 // attempt where we built and discarded the graph, in this case guarded
454 // fields associated with that graph are also discarded. However the slot
455 // itself stays behind in the compilation global cache. Thus we must always
456 // try to add it to the list of guarded fields of the current function.
457 if (slot.is_guarded_field()) {
458 if (thread->isolate_group()->use_field_guards()) {
459 ASSERT(parsed_function != nullptr);
460 parsed_function->AddToGuardedFields(&slot.field());
461 } else {
462 // In precompiled mode we use guarded_cid field for type information
463 // inferred by TFA.
464 ASSERT(CompilerState::Current().is_aot());
465 }
466 }
467
468 return slot;
469}
470
471const char* Slot::Name() const {
472 if (IsLocalVariable()) {
473 return DataAs<const String>()->ToCString();
474 } else if (IsDartField()) {
475 return String::Handle(field().name()).ToCString();
476 } else {
477 return DataAs<const char>();
478 }
479}
480
481bool Slot::Equals(const Slot& other) const {
482 if (kind_ != other.kind_ || offset_in_bytes_ != other.offset_in_bytes_) {
483 return false;
484 }
485
486 switch (kind_) {
491 return true;
492
494 auto other_type = other.type();
495 return (flags_ == other.flags_) &&
496 (DataAs<const String>()->ptr() ==
497 other.DataAs<const String>()->ptr()) &&
498 type().IsEqualTo(&other_type);
499 }
500
501 case Kind::kDartField:
502 return other.DataAs<const Field>()->Original() ==
503 DataAs<const Field>()->Original();
504
505 default:
506 UNREACHABLE();
507 return false;
508 }
509}
510
512 uword result = (static_cast<int8_t>(kind_) * 63 + offset_in_bytes_) * 31;
513 if (IsDartField()) {
514 result += String::Handle(DataAs<const Field>()->name()).Hash();
515 } else if (IsLocalVariable()) {
516 result += DataAs<const String>()->Hash();
517 }
518 return result;
519}
520
521} // namespace dart
static void encode(uint8_t output[16], const uint32_t input[4])
Definition: SkMD5.cpp:240
#define UNREACHABLE()
Definition: assert.h:248
GLenum type
bool IsStrictlyNonNullable() const
Definition: object.cc:21060
static constexpr int bitsize()
Definition: bitfield.h:162
static constexpr S encode(T value)
Definition: bitfield.h:165
intptr_t id() const
Definition: object.h:1233
static constexpr intptr_t kNoTypeArguments
Definition: object.h:1374
static CompileType FromCid(intptr_t cid)
static constexpr bool kCannotBeSentinel
Definition: compile_type.h:49
static constexpr bool kCannotBeNull
Definition: compile_type.h:46
static CompileType Dynamic()
bool IsEqualTo(CompileType *other)
Definition: compile_type.h:214
static CompileType FromUnboxedRepresentation(Representation rep)
void set_slot_cache(SlotCache *cache)
static CompilerState & Current()
SlotCache * slot_cache() const
bool is_nullable() const
Definition: slot.h:415
intptr_t guarded_cid() const
Definition: slot.h:414
bool is_final() const
Definition: object.h:4442
bool has_initializer() const
Definition: object.h:4613
ClassPtr Owner() const
Definition: object.cc:11860
bool is_unboxed() const
Definition: object.h:4712
bool has_pragma() const
Definition: object.h:4470
FieldPtr Original() const
Definition: object.cc:11739
bool is_late() const
Definition: object.h:4444
bool needs_load_guard() const
Definition: object.h:4451
AbstractTypePtr type() const
Definition: object.h:4550
bool is_const() const
Definition: object.h:4443
bool is_late() const
Definition: scopes.h:160
CompileType * inferred_type() const
Definition: scopes.h:136
VariableIndex index() const
Definition: scopes.h:202
bool is_captured() const
Definition: scopes.h:143
const String & name() const
Definition: scopes.h:119
bool is_final() const
Definition: scopes.h:140
static intptr_t ResultCidFromPragma(const Object &function_or_field)
virtual const char * ToCString() const
Definition: object.h:366
static constexpr bool ContainsCompressedPointers()
Definition: object.h:329
static Object & Handle()
Definition: object.h:407
static Object & ZoneHandle()
Definition: object.h:419
void AddToGuardedFields(const Field *field) const
Definition: parser.cc:88
const Slot & Canonicalize(const Slot &value)
Definition: slot.cc:39
static SlotCache & Instance(Thread *thread)
Definition: slot.cc:30
const Slot & GetNativeSlot(Slot::Kind kind)
Definition: slot.cc:48
bool is_guarded_field() const
Definition: slot.h:527
static const Slot & GetContextVariableSlotFor(Thread *thread, const LocalVariable &var)
Definition: slot.cc:292
bool IsImmutableLengthSlot() const
Definition: slot.cc:208
static const Slot & GetRecordFieldSlot(Thread *thread, intptr_t offset_in_bytes)
Definition: slot.cc:324
bool IsLocalVariable() const
Definition: slot.h:504
static const Slot & GetArrayElementSlot(Thread *thread, intptr_t offset_in_bytes)
Definition: slot.cc:316
Kind kind() const
Definition: slot.h:502
bool IsDartField() const
Definition: slot.h:503
static const Slot & Get(const Field &field, const ParsedFunction *parsed_function)
Definition: slot.cc:351
static const Slot & GetLengthFieldForArrayCid(intptr_t array_cid)
Definition: slot.cc:249
bool Equals(const Slot &other) const
Definition: slot.cc:481
const Field & field() const
Definition: slot.h:540
Representation representation() const
Definition: slot.h:519
uword Hash() const
Definition: slot.cc:511
intptr_t offset_in_bytes() const
Definition: slot.h:513
const char * Name() const
Definition: slot.cc:471
static const Slot & GetTypeArgumentsIndexSlot(Thread *thread, intptr_t index)
Definition: slot.cc:303
CompileType type() const
Definition: slot.h:538
static const Slot & GetTypeArgumentsSlotFor(Thread *thread, const Class &cls)
Definition: slot.cc:276
Zone * zone() const
Definition: thread_state.h:37
static Thread * Current()
Definition: thread.h:362
CompilerState & compiler_state()
Definition: thread.h:588
IsolateGroup * isolate_group() const
Definition: thread.h:541
static TypePtr DynamicType()
int value() const
Definition: scopes.h:69
static bool HasCompressedPointers(const dart::Class &handle)
Definition: runtime_api.cc:526
static intptr_t TypeArgumentsFieldOffset(const dart::Class &klass)
Definition: runtime_api.cc:539
static word variable_offset(intptr_t index)
static word OffsetOf(const dart::Field &field)
static word type_at_offset(intptr_t i)
#define ASSERT(E)
FlutterSemanticsFlag flags
uint8_t value
GAsyncResult * result
Definition: dart_vm.cc:33
bool IsTypedDataViewClassId(intptr_t index)
Definition: class_id.h:439
bool IsTypedDataClassId(intptr_t index)
Definition: class_id.h:433
const char *const name
bool IsUnmodifiableTypedDataViewClassId(intptr_t index)
Definition: class_id.h:453
@ kIllegalCid
Definition: class_id.h:214
@ kDynamicCid
Definition: class_id.h:253
Representation
Definition: locations.h:66
uintptr_t uword
Definition: globals.h:501
const intptr_t cid
static int8_t data[kExtLength]
bool IsExternalTypedDataClassId(intptr_t index)
Definition: class_id.h:447
NativeSlotsEnumeration
Definition: slot.cc:16
@ kNativeSlotsCount
Definition: slot.cc:20
#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, ___, ____)
Definition: slot.cc:17
#define NULLABLE_TAGGED_NATIVE_DART_SLOTS_LIST(V)
Definition: slot.h:54
#define NONNULLABLE_INT_TAGGED_NATIVE_DART_SLOTS_LIST(V)
Definition: slot.h:102
#define UNBOXED_NATIVE_DART_SLOTS_LIST(V)
Definition: slot.h:170
#define NULLABLE_TAGGED_NATIVE_NONDART_SLOTS_LIST(V)
Definition: slot.h:230
#define UNBOXED_NATIVE_SLOTS_LIST(V)
Definition: slot.h:297
#define NATIVE_SLOTS_LIST(V)
Definition: slot.h:366
#define NOT_INT_NATIVE_SLOTS_LIST(V)
Definition: slot.h:335
#define UNBOXED_NATIVE_NONDART_SLOTS_LIST(V)
Definition: slot.h:253
#define NONNULLABLE_NONINT_TAGGED_NATIVE_DART_SLOTS_LIST(V)
Definition: slot.h:134
#define UNTAGGED_NATIVE_DART_SLOTS_LIST(V)
Definition: slot.h:209
#define UNTAGGED_NATIVE_NONDART_SLOTS_LIST(V)
Definition: slot.h:279
SeparatedVector2 offset