Flutter Engine
The Flutter Engine
Public Types | Public Member Functions | Static Public Member Functions | Friends | List of all members
dart::Slot Class Reference

#include <slot.h>

Inheritance diagram for dart::Slot:
dart::ZoneAllocated

Public Types

enum class  Kind : uint8_t {
  DECLARE_KIND , kTypeArguments , kTypeArgumentsIndex , kArrayElement ,
  kRecordField , kCapturedVariable , kDartField
}
 

Public Member Functions

Kind kind () const
 
bool IsDartField () const
 
bool IsLocalVariable () const
 
bool IsTypeArguments () const
 
bool IsArgumentOfType () const
 
bool IsArrayElement () const
 
bool IsRecordField () const
 
bool IsImmutableLengthSlot () const
 
const char * Name () const
 
intptr_t offset_in_bytes () const
 
Representation representation () const
 
bool is_immutable () const
 
bool is_weak () const
 
bool is_guarded_field () const
 
bool is_compressed () const
 
bool may_contain_inner_pointer () const
 
CompileType type () const
 
const Fieldfield () const
 
bool Equals (const Slot &other) const
 
uword Hash () const
 
bool IsIdentical (const Slot &other) const
 
bool IsContextSlot () const
 
bool is_tagged () const
 
bool has_untagged_instance () const
 
void Write (FlowGraphSerializer *s) const
 
- Public Member Functions inherited from dart::ZoneAllocated
 ZoneAllocated ()
 
void * operator new (size_t size)
 
void * operator new (size_t size, Zone *zone)
 
void operator delete (void *pointer)
 

Static Public Member Functions

static const SlotGetLengthFieldForArrayCid (intptr_t array_cid)
 
static const SlotGetTypeArgumentsSlotFor (Thread *thread, const Class &cls)
 
static const SlotGetTypeArgumentsIndexSlot (Thread *thread, intptr_t index)
 
static const SlotGetArrayElementSlot (Thread *thread, intptr_t offset_in_bytes)
 
static const SlotGetRecordFieldSlot (Thread *thread, intptr_t offset_in_bytes)
 
static const SlotGetContextVariableSlotFor (Thread *thread, const LocalVariable &var)
 
static const SlotGet (const Field &field, const ParsedFunction *parsed_function)
 
static const SlotRead (FlowGraphDeserializer *d)
 

Friends

class SlotCache
 

Detailed Description

Definition at line 431 of file slot.h.

Member Enumeration Documentation

◆ Kind

enum class dart::Slot::Kind : uint8_t
strong
Enumerator
DECLARE_KIND 
kTypeArguments 
kTypeArgumentsIndex 
kArrayElement 
kRecordField 
kCapturedVariable 
kDartField 

Definition at line 434 of file slot.h.

434 : uint8_t {
435 // Native slots are identified by their kind - each native slot has its own.
436#define DECLARE_KIND(ClassName, __, FieldName, ___, ____) \
437 k##ClassName##_##FieldName,
438 NATIVE_SLOTS_LIST(DECLARE_KIND)
439#undef DECLARE_KIND
440
441 // A slot used to store type arguments.
442 kTypeArguments,
443
444 // A slot at a specific [index] in a [UntaggedTypeArgument] vector.
445 kTypeArgumentsIndex,
446
447 // A slot corresponding to an array element at given offset.
448 // Only used during allocation sinking and in MaterializeObjectInstr.
449 kArrayElement,
450
451 // A slot corresponding to a record field at the given offset.
452 kRecordField,
453
454 // A slot within a Context object that contains a value of a captured
455 // local variable.
456 kCapturedVariable,
457
458 // A slot that corresponds to a Dart field (has corresponding Field object).
459 kDartField,
460 };
#define NATIVE_SLOTS_LIST(V)
Definition: slot.h:366

Member Function Documentation

◆ Equals()

bool dart::Slot::Equals ( const Slot other) const

Definition at line 481 of file slot.cc.

481 {
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}
#define UNREACHABLE()
Definition: assert.h:248
bool IsEqualTo(CompileType *other)
Definition: compile_type.h:214
CompileType type() const
Definition: slot.h:538

◆ field()

const Field & dart::Slot::field ( ) const
inline

Definition at line 540 of file slot.h.

540 {
542 ASSERT(data_ != nullptr);
543 return *DataAs<const Field>();
544 }
bool IsDartField() const
Definition: slot.h:503
#define ASSERT(E)

◆ Get()

const Slot & dart::Slot::Get ( const Field field,
const ParsedFunction parsed_function 
)
static

Definition at line 351 of file slot.cc.

352 {
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}
static constexpr S encode(T value)
Definition: bitfield.h:165
static CompileType FromUnboxedRepresentation(Representation rep)
static CompilerState & Current()
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
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
static intptr_t ResultCidFromPragma(const Object &function_or_field)
static Object & Handle()
Definition: object.h:407
static Object & ZoneHandle()
Definition: object.h:419
const Field & field() const
Definition: slot.h:540
static Thread * Current()
Definition: thread.h:362
static TypePtr DynamicType()
static bool HasCompressedPointers(const dart::Class &handle)
Definition: runtime_api.cc:526
static word OffsetOf(const dart::Field &field)
@ kIllegalCid
Definition: class_id.h:214
@ kDynamicCid
Definition: class_id.h:253
Representation
Definition: locations.h:66
const intptr_t cid

◆ GetArrayElementSlot()

const Slot & dart::Slot::GetArrayElementSlot ( Thread thread,
intptr_t  offset_in_bytes 
)
static

Definition at line 316 of file slot.cc.

317 {
318 return GetCanonicalSlot(
319 thread, Kind::kArrayElement,
321 offset_in_bytes, ":array_element", CompileType::Dynamic(), kTagged);
322}
static CompileType Dynamic()
static constexpr bool ContainsCompressedPointers()
Definition: object.h:329
intptr_t offset_in_bytes() const
Definition: slot.h:513

◆ GetContextVariableSlotFor()

const Slot & dart::Slot::GetContextVariableSlotFor ( Thread thread,
const LocalVariable var 
)
static

Definition at line 292 of file slot.cc.

293 {
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}
static word variable_offset(intptr_t index)

◆ GetLengthFieldForArrayCid()

const Slot & dart::Slot::GetLengthFieldForArrayCid ( intptr_t  array_cid)
static

Definition at line 249 of file slot.cc.

249 {
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}
bool IsTypedDataViewClassId(intptr_t index)
Definition: class_id.h:439
bool IsTypedDataClassId(intptr_t index)
Definition: class_id.h:433
bool IsUnmodifiableTypedDataViewClassId(intptr_t index)
Definition: class_id.h:453
bool IsExternalTypedDataClassId(intptr_t index)
Definition: class_id.h:447

◆ GetRecordFieldSlot()

const Slot & dart::Slot::GetRecordFieldSlot ( Thread thread,
intptr_t  offset_in_bytes 
)
static

Definition at line 324 of file slot.cc.

324 {
325 return GetCanonicalSlot(
326 thread, Kind::kRecordField,
328 offset_in_bytes, ":record_field", CompileType::Dynamic(), kTagged);
329}

◆ GetTypeArgumentsIndexSlot()

const Slot & dart::Slot::GetTypeArgumentsIndexSlot ( Thread thread,
intptr_t  index 
)
static

Definition at line 303 of file slot.cc.

303 {
304 const intptr_t offset =
306 return GetCanonicalSlot(
310 offset, ":argument",
312 kDynamicCid, nullptr),
313 kTagged);
314}
static constexpr bool kCannotBeSentinel
Definition: compile_type.h:49
static constexpr bool kCannotBeNull
Definition: compile_type.h:46
static word type_at_offset(intptr_t i)
SeparatedVector2 offset

◆ GetTypeArgumentsSlotFor()

const Slot & dart::Slot::GetTypeArgumentsSlotFor ( Thread thread,
const Class cls 
)
static

Definition at line 276 of file slot.cc.

276 {
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}
static constexpr intptr_t kNoTypeArguments
Definition: object.h:1374
static CompileType FromCid(intptr_t cid)
static intptr_t TypeArgumentsFieldOffset(const dart::Class &klass)
Definition: runtime_api.cc:539

◆ has_untagged_instance()

bool dart::Slot::has_untagged_instance ( ) const
inline

Definition at line 556 of file slot.h.

556 {
557 return HasUntaggedInstanceBit::decode(flags_);
558 }
static constexpr T decode(S value)
Definition: bitfield.h:171

◆ Hash()

uword dart::Slot::Hash ( ) const

Definition at line 511 of file slot.cc.

511 {
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}
bool IsLocalVariable() const
Definition: slot.h:504
GAsyncResult * result
const char *const name
uintptr_t uword
Definition: globals.h:501

◆ is_compressed()

bool dart::Slot::is_compressed ( ) const
inline

Definition at line 529 of file slot.h.

529{ return IsCompressedBit::decode(flags_); }

◆ is_guarded_field()

bool dart::Slot::is_guarded_field ( ) const
inline

Definition at line 527 of file slot.h.

527{ return IsGuardedBit::decode(flags_); }

◆ is_immutable()

bool dart::Slot::is_immutable ( ) const
inline

Definition at line 521 of file slot.h.

521{ return IsImmutableBit::decode(flags_); }

◆ is_tagged()

bool dart::Slot::is_tagged ( ) const
inline

Definition at line 555 of file slot.h.

555{ return !IsNonTaggedBit::decode(flags_); }

◆ is_weak()

bool dart::Slot::is_weak ( ) const
inline

Definition at line 523 of file slot.h.

523{ return IsWeakBit::decode(flags_); }

◆ IsArgumentOfType()

bool dart::Slot::IsArgumentOfType ( ) const
inline

Definition at line 506 of file slot.h.

506{ return kind() == Kind::kTypeArgumentsIndex; }
Kind kind() const
Definition: slot.h:502

◆ IsArrayElement()

bool dart::Slot::IsArrayElement ( ) const
inline

Definition at line 507 of file slot.h.

507{ return kind() == Kind::kArrayElement; }

◆ IsContextSlot()

bool dart::Slot::IsContextSlot ( ) const
inline

Definition at line 551 of file slot.h.

551 {
552 return kind() == Kind::kCapturedVariable || kind() == Kind::kContext_parent;
553 }

◆ IsDartField()

bool dart::Slot::IsDartField ( ) const
inline

Definition at line 503 of file slot.h.

503{ return kind() == Kind::kDartField; }

◆ IsIdentical()

bool dart::Slot::IsIdentical ( const Slot other) const
inline

Definition at line 549 of file slot.h.

549{ return this == &other; }

◆ IsImmutableLengthSlot()

bool dart::Slot::IsImmutableLengthSlot ( ) const

Definition at line 208 of file slot.cc.

208 {
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}
#define NOT_TAGGED_INT_NATIVE_SLOT_CASE(Class, __, Field, ___, ____)
#define UNBOXED_NATIVE_SLOTS_LIST(V)
Definition: slot.h:297
#define NOT_INT_NATIVE_SLOTS_LIST(V)
Definition: slot.h:335

◆ IsLocalVariable()

bool dart::Slot::IsLocalVariable ( ) const
inline

Definition at line 504 of file slot.h.

504{ return kind() == Kind::kCapturedVariable; }

◆ IsRecordField()

bool dart::Slot::IsRecordField ( ) const
inline

Definition at line 508 of file slot.h.

508{ return kind() == Kind::kRecordField; }

◆ IsTypeArguments()

bool dart::Slot::IsTypeArguments ( ) const
inline

Definition at line 505 of file slot.h.

505{ return kind() == Kind::kTypeArguments; }

◆ kind()

Kind dart::Slot::kind ( ) const
inline

Definition at line 502 of file slot.h.

502{ return kind_; }

◆ may_contain_inner_pointer()

bool dart::Slot::may_contain_inner_pointer ( ) const
inline

Definition at line 533 of file slot.h.

533 {
535 }

◆ Name()

const char * dart::Slot::Name ( ) const

Definition at line 471 of file slot.cc.

471 {
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}
virtual const char * ToCString() const
Definition: object.h:366

◆ offset_in_bytes()

intptr_t dart::Slot::offset_in_bytes ( ) const
inline

Definition at line 513 of file slot.h.

513{ return offset_in_bytes_; }

◆ Read()

const Slot & dart::Slot::Read ( FlowGraphDeserializer d)
static

Definition at line 2329 of file il_serializer.cc.

2329 {
2330 const Kind kind = static_cast<Kind>(d->Read<serializable_type_t<Kind>>());
2331 int8_t flags = 0;
2332 intptr_t offset = -1;
2333 const void* data = nullptr;
2334 CompileType type = CompileType::None();
2336
2337 switch (kind) {
2339 flags = d->Read<int8_t>();
2340 offset = d->Read<intptr_t>();
2341 data = ":type_arguments";
2342 type = CompileType::FromCid(kTypeArgumentsCid);
2343 break;
2345 flags =
2348 offset = d->Read<intptr_t>();
2349 data = ":argument";
2350 type = CompileType(CompileType::kCannotBeNull,
2352 break;
2355 offset = d->Read<intptr_t>();
2356 data = ":array_element";
2358 break;
2359 case Kind::kRecordField:
2361 offset = d->Read<intptr_t>();
2362 data = ":record_field";
2364 break;
2366 flags = d->Read<int8_t>();
2367 offset = d->Read<intptr_t>();
2368 data = &d->Read<const String&>();
2369 type = CompileType(d);
2370 break;
2371 case Kind::kDartField: {
2372 const Field& field = d->Read<const Field&>();
2373 return Slot::Get(field, &d->parsed_function());
2374 }
2375 default:
2376 return Slot::GetNativeSlot(kind);
2377 }
2378
2379 return GetCanonicalSlot(d->thread(), kind, flags, offset, data, type,
2381}
static CompileType None()
Definition: compile_type.h:155
static const Slot & Get(const Field &field, const ParsedFunction *parsed_function)
Definition: slot.cc:351
Representation representation() const
Definition: slot.h:519
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition: main.cc:19
FlutterSemanticsFlag flags
static int8_t data[kExtLength]

◆ representation()

Representation dart::Slot::representation ( ) const
inline

Definition at line 519 of file slot.h.

519{ return representation_; }

◆ type()

CompileType dart::Slot::type ( ) const
inline

Definition at line 538 of file slot.h.

538{ return type_; }

◆ Write()

void dart::Slot::Write ( FlowGraphSerializer s) const

Definition at line 2297 of file il_serializer.cc.

2297 {
2298 s->Write<serializable_type_t<Kind>>(
2299 static_cast<serializable_type_t<Kind>>(kind_));
2300
2301 switch (kind_) {
2303 s->Write<int8_t>(flags_);
2304 s->Write<intptr_t>(offset_in_bytes_);
2305 break;
2307 s->Write<intptr_t>(offset_in_bytes_);
2308 break;
2310 s->Write<intptr_t>(offset_in_bytes_);
2311 break;
2312 case Kind::kRecordField:
2313 s->Write<intptr_t>(offset_in_bytes_);
2314 break;
2316 s->Write<int8_t>(flags_);
2317 s->Write<intptr_t>(offset_in_bytes_);
2318 s->Write<const String&>(*DataAs<const String>());
2319 type_.Write(s);
2320 break;
2321 case Kind::kDartField:
2322 s->Write<const Field&>(field());
2323 break;
2324 default:
2325 break;
2326 }
2327}
void Write(FlowGraphSerializer *s) const
struct MyStruct s

Friends And Related Function Documentation

◆ SlotCache

friend class SlotCache
friend

Definition at line 638 of file slot.h.


The documentation for this class was generated from the following files: