Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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,
439#undef DECLARE_KIND
440
441 // A slot used to store type arguments.
443
444 // A slot at a specific [index] in a [UntaggedTypeArgument] vector.
446
447 // A slot corresponding to an array element at given offset.
448 // Only used during allocation sinking and in MaterializeObjectInstr.
450
451 // A slot corresponding to a record field at the given offset.
453
454 // A slot within a Context object that contains a value of a captured
455 // local variable.
457
458 // A slot that corresponds to a Dart field (has corresponding Field object).
460 };
DECLARE_KIND(ClassName, __, FieldName, ___, ____)
#define NATIVE_SLOTS_LIST(V)
Definition slot.h:366

Member Function Documentation

◆ Equals()

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

Definition at line 483 of file slot.cc.

483 {
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}
#define UNREACHABLE()
Definition assert.h:248
bool IsEqualTo(CompileType *other)
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;
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}
static constexpr S encode(T value)
Definition bitfield.h:167
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: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
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
static intptr_t ResultCidFromPragma(const Object &function_or_field)
static bool HasNonNullableResultTypeFromPragma(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:361
static TypePtr DynamicType()
Definition object.cc:21866
@ 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}

◆ 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 =
305 compiler::target::TypeArguments::type_at_offset(index);
306 return GetCanonicalSlot(
310 offset, ":argument",
312 kDynamicCid, nullptr),
313 kTagged);
314}
static constexpr bool kCannotBeSentinel
static constexpr bool kCannotBeNull
Point 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 =
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}
static constexpr intptr_t kNoTypeArguments
Definition object.h:1376
static CompileType FromCid(intptr_t cid)

◆ 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:173

◆ Hash()

uword dart::Slot::Hash ( ) const

Definition at line 513 of file slot.cc.

513 {
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}
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 473 of file slot.cc.

473 {
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}
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()
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 Symbol 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: