Flutter Engine
The Flutter Engine
Public Member Functions | Static Public Attributes | List of all members
dart::HierarchyInfo Class Reference

#include <il.h>

Inheritance diagram for dart::HierarchyInfo:
dart::ThreadStackResource dart::StackResource

Public Member Functions

 HierarchyInfo (Thread *thread)
 
 ~HierarchyInfo ()
 
const CidRangeVectorSubtypeRangesForClass (const Class &klass, bool include_abstract, bool exclude_null)
 
bool InstanceOfHasClassRange (const AbstractType &type, intptr_t *lower_limit, intptr_t *upper_limit)
 
bool CanUseSubtypeRangeCheckFor (const AbstractType &type)
 
bool CanUseGenericSubtypeRangeCheckFor (const AbstractType &type)
 
bool CanUseRecordSubtypeRangeCheckFor (const AbstractType &type)
 
- Public Member Functions inherited from dart::ThreadStackResource
 ThreadStackResource (Thread *T)
 
 ~ThreadStackResource ()
 
Threadthread () const
 
Isolateisolate () const
 
IsolateGroupisolate_group () const
 
- Public Member Functions inherited from dart::StackResource
 StackResource (ThreadState *thread)
 
virtual ~StackResource ()
 
ThreadStatethread () const
 

Static Public Attributes

static constexpr intptr_t kNoCompatibleTAVOffset = 0
 

Additional Inherited Members

- Static Public Member Functions inherited from dart::StackResource
static void Unwind (ThreadState *thread)
 
static void UnwindAbove (ThreadState *thread, StackResource *new_top)
 

Detailed Description

Definition at line 267 of file il.h.

Constructor & Destructor Documentation

◆ HierarchyInfo()

dart::HierarchyInfo::HierarchyInfo ( Thread thread)
inlineexplicit

Definition at line 269 of file il.h.

271 cid_subtype_ranges_nullable_(),
272 cid_subtype_ranges_abstract_nullable_(),
273 cid_subtype_ranges_nonnullable_(),
274 cid_subtype_ranges_abstract_nonnullable_() {
276 }
void set_hierarchy_info(HierarchyInfo *value)
Definition: thread.h:598

◆ ~HierarchyInfo()

dart::HierarchyInfo::~HierarchyInfo ( )
inline

Definition at line 278 of file il.h.

278{ thread()->set_hierarchy_info(nullptr); }

Member Function Documentation

◆ CanUseGenericSubtypeRangeCheckFor()

bool dart::HierarchyInfo::CanUseGenericSubtypeRangeCheckFor ( const AbstractType type)

Definition at line 343 of file il.cc.

344 {
345 ASSERT(type.IsFinalized());
346
347 if (!type.IsType() || type.IsDartFunctionType()) {
348 return false;
349 }
350
351 // The FutureOr<T> type cannot be handled by checking whether the instance is
352 // a subtype of FutureOr and then checking whether the type argument `T`
353 // matches.
354 //
355 // Instead we would need to perform multiple checks:
356 //
357 // instance is Null || instance is T || instance is Future<T>
358 //
359 if (type.IsFutureOrType()) {
360 return false;
361 }
362
363 // NOTE: We do allow non-instantiated types here (in comparison to
364 // [CanUseSubtypeRangeCheckFor], since we handle type parameters in the type
365 // expression in some cases (see below).
366
367 Zone* zone = thread()->zone();
368 const Class& type_class = Class::Handle(zone, type.type_class());
369 const intptr_t num_type_parameters = type_class.NumTypeParameters();
370 if (type_class.has_dynamically_extendable_subtypes()) {
371 return false;
372 }
373
374 // This function should only be called for generic classes.
375 ASSERT(type_class.NumTypeParameters() > 0 &&
376 Type::Cast(type).arguments() != TypeArguments::null());
377
378 const TypeArguments& ta =
379 TypeArguments::Handle(zone, Type::Cast(type).arguments());
380 ASSERT(ta.Length() == num_type_parameters);
381
382 // Ensure we can handle all type arguments
383 // via [CidRange]-based checks or that it is a type parameter.
384 AbstractType& type_arg = AbstractType::Handle(zone);
385 for (intptr_t i = 0; i < num_type_parameters; ++i) {
386 type_arg = ta.TypeAt(i);
387 if (!CanUseSubtypeRangeCheckFor(type_arg) && !type_arg.IsTypeParameter()) {
388 return false;
389 }
390 }
391
392 return true;
393}
GLenum type
bool CanUseSubtypeRangeCheckFor(const AbstractType &type)
Definition: il.cc:301
static ObjectPtr null()
Definition: object.h:433
static Object & Handle()
Definition: object.h:407
Zone * zone() const
Definition: thread_state.h:37
#define ASSERT(E)

◆ CanUseRecordSubtypeRangeCheckFor()

bool dart::HierarchyInfo::CanUseRecordSubtypeRangeCheckFor ( const AbstractType type)

Definition at line 395 of file il.cc.

395 {
396 ASSERT(type.IsFinalized());
397 if (!type.IsRecordType()) {
398 return false;
399 }
400 const RecordType& rec = RecordType::Cast(type);
401 Zone* zone = thread()->zone();
402 auto& field_type = AbstractType::Handle(zone);
403 for (intptr_t i = 0, n = rec.NumFields(); i < n; ++i) {
404 field_type = rec.FieldTypeAt(i);
405 if (!CanUseSubtypeRangeCheckFor(field_type)) {
406 return false;
407 }
408 }
409 return true;
410}

◆ CanUseSubtypeRangeCheckFor()

bool dart::HierarchyInfo::CanUseSubtypeRangeCheckFor ( const AbstractType type)

Definition at line 301 of file il.cc.

301 {
302 ASSERT(type.IsFinalized());
303
304 if (!type.IsInstantiated() || !type.IsType()) {
305 return false;
306 }
307
308 // The FutureOr<T> type cannot be handled by checking whether the instance is
309 // a subtype of FutureOr and then checking whether the type argument `T`
310 // matches.
311 //
312 // Instead we would need to perform multiple checks:
313 //
314 // instance is Null || instance is T || instance is Future<T>
315 //
316 if (type.IsFutureOrType()) {
317 return false;
318 }
319
320 Zone* zone = thread()->zone();
321 const Class& type_class = Class::Handle(zone, type.type_class());
322 if (type_class.has_dynamically_extendable_subtypes()) {
323 return false;
324 }
325
326 // We can use class id range checks only if we don't have to test type
327 // arguments.
328 //
329 // This is e.g. true for "String" but also for "List<dynamic>". (A type for
330 // which the type arguments vector is instantiated to bounds is known as a
331 // rare type.)
332 if (type_class.IsGeneric()) {
333 const Type& rare_type = Type::Handle(zone, type_class.RareType());
334 if (!rare_type.IsSubtypeOf(type, Heap::kNew)) {
335 ASSERT(Type::Cast(type).arguments() != TypeArguments::null());
336 return false;
337 }
338 }
339
340 return true;
341}
@ kNew
Definition: heap.h:38

◆ InstanceOfHasClassRange()

bool dart::HierarchyInfo::InstanceOfHasClassRange ( const AbstractType type,
intptr_t *  lower_limit,
intptr_t *  upper_limit 
)

Definition at line 412 of file il.cc.

414 {
415 ASSERT(CompilerState::Current().is_aot());
416 if (type.IsNullable()) {
417 // 'is' test for nullable types should accept null cid in addition to the
418 // class range. In most cases it is not possible to extend class range to
419 // include kNullCid.
420 return false;
421 }
423 const Class& type_class =
424 Class::Handle(thread()->zone(), type.type_class());
425 const CidRangeVector& ranges =
426 SubtypeRangesForClass(type_class,
427 /*include_abstract=*/false,
428 /*exclude_null=*/true);
429 if (ranges.length() == 1) {
430 const CidRangeValue& range = ranges[0];
431 ASSERT(!range.IsIllegalRange());
432 *lower_limit = range.cid_start;
433 *upper_limit = range.cid_end;
434 return true;
435 }
436 }
437 return false;
438}
static CompilerState & Current()
const CidRangeVector & SubtypeRangesForClass(const Class &klass, bool include_abstract, bool exclude_null)
Definition: il.cc:110
MallocGrowableArray< CidRangeValue > CidRangeVector
Definition: il.h:253

◆ SubtypeRangesForClass()

const CidRangeVector & dart::HierarchyInfo::SubtypeRangesForClass ( const Class klass,
bool  include_abstract,
bool  exclude_null 
)

Definition at line 110 of file il.cc.

113 {
114 ClassTable* table = thread()->isolate_group()->class_table();
115 const intptr_t cid_count = table->NumCids();
116 std::unique_ptr<CidRangeVector[]>* cid_ranges = nullptr;
117 if (include_abstract) {
118 cid_ranges = exclude_null ? &cid_subtype_ranges_abstract_nonnullable_
119 : &cid_subtype_ranges_abstract_nullable_;
120 } else {
121 cid_ranges = exclude_null ? &cid_subtype_ranges_nonnullable_
122 : &cid_subtype_ranges_nullable_;
123 }
124 if (*cid_ranges == nullptr) {
125 cid_ranges->reset(new CidRangeVector[cid_count]);
126 }
127 CidRangeVector& ranges = (*cid_ranges)[klass.id()];
128 if (ranges.length() == 0) {
129 BuildRangesFor(table, &ranges, klass, include_abstract, exclude_null);
130 }
131 return ranges;
132}
SI F table(const skcms_Curve *curve, F v)
ClassTable * class_table() const
Definition: isolate.h:496
IsolateGroup * isolate_group() const
Definition: thread.h:541

Member Data Documentation

◆ kNoCompatibleTAVOffset

constexpr intptr_t dart::HierarchyInfo::kNoCompatibleTAVOffset = 0
staticconstexpr

Definition at line 282 of file il.h.


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