Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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 =
281 compiler::target::Class::TypeArgumentsFieldOffset(cls);
283 return GetCanonicalSlot(
284 thread, Kind::kTypeArguments,
287 compiler::target::Class::HasCompressedPointers(cls)),
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()) |
299 compiler::target::Context::variable_offset(variable.index().value()),
300 &variable.name(), *(variable.inferred_type()), kTagged);
301}
302
303const Slot& Slot::GetTypeArgumentsIndexSlot(Thread* thread, intptr_t index) {
304 const intptr_t offset =
305 compiler::target::TypeArguments::type_at_offset(index);
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())) {
347 ASSERT(compiler::target::UntaggedObject::kClassIdTagSize <=
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;
365 is_nullable = false;
366 }
367 }
368
369 AbstractType& field_type = AbstractType::ZoneHandle(zone, field.type());
370 if (field_type.IsStrictlyNonNullable()) {
371 is_nullable = false;
372 }
373
374 FieldGuardState field_guard_state(field);
375
376 bool used_guarded_state = false;
377 if (field_guard_state.guarded_cid() != kIllegalCid &&
378 field_guard_state.guarded_cid() != kDynamicCid) {
379 // Use guarded state if it is more precise then what we already have.
380 if (nullable_cid == kDynamicCid) {
381 nullable_cid = field_guard_state.guarded_cid();
382 used_guarded_state = true;
383 }
384
385 if (is_nullable && !field_guard_state.is_nullable()) {
386 is_nullable = false;
387 used_guarded_state = true;
388 }
389 }
390
391 const bool needs_load_guard = field.needs_load_guard();
392 const bool is_unboxed = field.is_unboxed();
393 ASSERT(!(needs_load_guard && is_unboxed));
394
395 if (needs_load_guard) {
396 // Should be kept in sync with LoadStaticFieldInstr::ComputeType.
397 field_type = Type::DynamicType();
398 nullable_cid = kDynamicCid;
399 is_nullable = true;
400 used_guarded_state = false;
401 }
402
403 if (is_unboxed) {
404 // The decision to unbox is made based on static types (or TFA annotations).
405 // It is therefore not part of the dynamically initialized & updated guarded
406 // state.
407 used_guarded_state = false;
408 is_nullable = false;
409 nullable_cid = field_guard_state.guarded_cid();
410 switch (nullable_cid) {
411 case kDoubleCid:
412 rep = kUnboxedDouble;
413 break;
414 case kFloat32x4Cid:
415 rep = kUnboxedFloat32x4;
416 break;
417 case kFloat64x2Cid:
418 rep = kUnboxedFloat64x2;
419 break;
420 default:
421 rep = kUnboxedInt64;
422 break;
423 }
424 }
425
426 const bool is_sentinel_visible =
428
429 CompileType type = (rep != kTagged)
431 : CompileType(is_nullable, is_sentinel_visible,
432 nullable_cid, &field_type);
433
434 Class& owner = Class::Handle(zone, field.Owner());
435 const Slot& slot = GetCanonicalSlot(
436 thread, Kind::kDartField,
438 field.is_const()) |
439 IsGuardedBit::encode(used_guarded_state) |
441 compiler::target::Class::HasCompressedPointers(owner)) |
442 IsNonTaggedBit::encode(is_unboxed),
443 compiler::target::Field::OffsetOf(field), &field, type, rep,
444 field_guard_state);
445
446 // If properties of this slot were based on the guarded state make sure
447 // to add the field to the list of guarded fields. Note that during background
448 // compilation we might have two field clones that have incompatible guarded
449 // state - however both of these clones would correspond to the same slot.
450 // That is why we check the is_guarded_field() property of the slot rather
451 // than look at the current guarded state of the field, because current
452 // guarded state of the field might be set to kDynamicCid, while it was
453 // set to something more concrete when the slot was created.
454 // Note that we could have created this slot during an unsuccessful inlining
455 // attempt where we built and discarded the graph, in this case guarded
456 // fields associated with that graph are also discarded. However the slot
457 // itself stays behind in the compilation global cache. Thus we must always
458 // try to add it to the list of guarded fields of the current function.
459 if (slot.is_guarded_field()) {
460 if (thread->isolate_group()->use_field_guards()) {
461 ASSERT(parsed_function != nullptr);
462 parsed_function->AddToGuardedFields(&slot.field());
463 } else {
464 // In precompiled mode we use guarded_cid field for type information
465 // inferred by TFA.
466 ASSERT(CompilerState::Current().is_aot());
467 }
468 }
469
470 return slot;
471}
472
473const char* Slot::Name() const {
474 if (IsLocalVariable()) {
475 return DataAs<const String>()->ToCString();
476 } else if (IsDartField()) {
477 return String::Handle(field().name()).ToCString();
478 } else {
479 return DataAs<const char>();
480 }
481}
482
483bool Slot::Equals(const Slot& other) const {
484 if (kind_ != other.kind_ || offset_in_bytes_ != other.offset_in_bytes_) {
485 return false;
486 }
487
488 switch (kind_) {
493 return true;
494
496 auto other_type = other.type();
497 return (flags_ == other.flags_) &&
498 (DataAs<const String>()->ptr() ==
499 other.DataAs<const String>()->ptr()) &&
500 type().IsEqualTo(&other_type);
501 }
502
503 case Kind::kDartField:
504 return other.DataAs<const Field>()->Original() ==
505 DataAs<const Field>()->Original();
506
507 default:
508 UNREACHABLE();
509 return false;
510 }
511}
512
514 uword result = (static_cast<int8_t>(kind_) * 63 + offset_in_bytes_) * 31;
515 if (IsDartField()) {
516 result += String::Handle(DataAs<const Field>()->name()).Hash();
517 } else if (IsLocalVariable()) {
518 result += DataAs<const String>()->Hash();
519 }
520 return result;
521}
522
523} // namespace dart
static void encode(uint8_t output[16], const uint32_t input[4])
Definition SkMD5.cpp:240
#define UNREACHABLE()
Definition assert.h:248
bool IsStrictlyNonNullable() const
Definition object.cc:21101
static constexpr int bitsize()
Definition bitfield.h:164
static constexpr S encode(T value)
Definition bitfield.h:167
intptr_t id() const
Definition object.h:1235
static constexpr intptr_t kNoTypeArguments
Definition object.h:1376
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
bool is_nullable() const
Definition slot.h:415
intptr_t guarded_cid() const
Definition slot.h:414
bool is_final() const
Definition object.h:4420
bool has_initializer() const
Definition object.h:4586
ClassPtr Owner() const
Definition object.cc:11911
bool is_unboxed() const
Definition object.h:4685
bool has_pragma() const
Definition object.h:4448
FieldPtr Original() const
Definition object.cc:11790
bool is_late() const
Definition object.h:4422
bool needs_load_guard() const
Definition object.h:4429
AbstractTypePtr type() const
Definition object.h:4523
bool is_const() const
Definition object.h:4421
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)
static bool HasNonNullableResultTypeFromPragma(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:483
const Field & field() const
Definition slot.h:540
Representation representation() const
Definition slot.h:519
uword Hash() const
Definition slot.cc:513
intptr_t offset_in_bytes() const
Definition slot.h:513
const char * Name() const
Definition slot.cc:473
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
static Thread * Current()
Definition thread.h:361
CompilerState & compiler_state()
Definition thread.h:583
IsolateGroup * isolate_group() const
Definition thread.h:540
static TypePtr DynamicType()
Definition object.cc:21866
int value() const
Definition scopes.h:69
#define ASSERT(E)
FlutterSemanticsFlag flags
uint8_t value
GAsyncResult * result
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
Point offset