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

#include <object.h>

Inheritance diagram for dart::ICData:
dart::CallSiteData dart::Object

Public Types

enum  DeoptReasonId
 
enum  DeoptFlags { kHoisted = 1 << 0 , kGeneralized = 1 << 1 }
 
enum  RebindRule { kNumRebindRules }
 
enum  { kCachedICDataZeroArgTestedWithoutExactnessTrackingIdx = 0 , kCachedICDataMaxArgsTestedWithoutExactnessTracking = 2 , kCachedICDataOneArgWithExactnessTrackingIdx , kCachedICDataArrayCount = kCachedICDataOneArgWithExactnessTrackingIdx + 1 }
 
- Public Types inherited from dart::Object
enum  NameVisibility { kInternalName = 0 , kScrubbedName , kUserVisibleName }
 
enum class  NameDisambiguation { kYes , kNo }
 
using UntaggedObjectType = UntaggedObject
 
using ObjectPtrType = ObjectPtr
 

Public Member Functions

FunctionPtr Owner () const
 
ICDataPtr Original () const
 
void SetOriginal (const ICData &value) const
 
bool IsOriginal () const
 
intptr_t NumArgsTested () const
 
intptr_t deopt_id () const
 
bool IsImmutable () const
 
AbstractTypePtr receivers_static_type () const
 
bool is_tracking_exactness () const
 
bool HasDeoptReasons () const
 
uint32_t DeoptReasons () const
 
void SetDeoptReasons (uint32_t reasons) const
 
bool HasDeoptReason (ICData::DeoptReasonId reason) const
 
void AddDeoptReason (ICData::DeoptReasonId reason) const
 
RebindRule rebind_rule () const
 
void set_is_megamorphic (bool value) const
 
intptr_t Length () const
 
intptr_t NumberOfChecks () const
 
intptr_t NumberOfUsedChecks () const
 
bool NumberOfChecksIs (intptr_t n) const
 
bool IsValidEntryIndex (intptr_t index) const
 
void Clear (const CallSiteResetter &proof_of_reload) const
 
void TruncateTo (intptr_t num_checks, const CallSiteResetter &proof_of_reload) const
 
void ClearCountAt (intptr_t index, const CallSiteResetter &proof_of_reload) const
 
void ClearAndSetStaticTarget (const Function &func, const CallSiteResetter &proof_of_reload) const
 
void DebugDump () const
 
void EnsureHasCheck (const GrowableArray< intptr_t > &class_ids, const Function &target, intptr_t count=1) const
 
void AddCheck (const GrowableArray< intptr_t > &class_ids, const Function &target, intptr_t count=1) const
 
StaticTypeExactnessState GetExactnessAt (intptr_t count) const
 
void EnsureHasReceiverCheck (intptr_t receiver_class_id, const Function &target, intptr_t count=1, StaticTypeExactnessState exactness=StaticTypeExactnessState::NotTracking()) const
 
void AddReceiverCheck (intptr_t receiver_class_id, const Function &target, intptr_t count=1, StaticTypeExactnessState exactness=StaticTypeExactnessState::NotTracking()) const
 
void GetCheckAt (intptr_t index, GrowableArray< intptr_t > *class_ids, Function *target) const
 
void GetClassIdsAt (intptr_t index, GrowableArray< intptr_t > *class_ids) const
 
void GetOneClassCheckAt (intptr_t index, intptr_t *class_id, Function *target) const
 
intptr_t GetCidAt (intptr_t index) const
 
intptr_t GetReceiverClassIdAt (intptr_t index) const
 
intptr_t GetClassIdAt (intptr_t index, intptr_t arg_nr) const
 
FunctionPtr GetTargetAt (intptr_t index) const
 
void IncrementCountAt (intptr_t index, intptr_t value) const
 
void SetCountAt (intptr_t index, intptr_t value) const
 
intptr_t GetCountAt (intptr_t index) const
 
intptr_t AggregateCount () const
 
ICDataPtr AsUnaryClassChecksForArgNr (intptr_t arg_nr) const
 
ICDataPtr AsUnaryClassChecks () const
 
ICDataPtr AsUnaryClassChecksSortedByCount () const
 
UnlinkedCallPtr AsUnlinkedCall () const
 
bool HasReceiverClassId (intptr_t class_id) const
 
bool IsUsedAt (intptr_t i) const
 
void PrintToJSONArray (const JSONArray &jsarray, TokenPosition token_pos) const
 
bool is_static_call () const
 
intptr_t FindCheck (const GrowableArray< intptr_t > &cids) const
 
ArrayPtr entries () const
 
bool receiver_cannot_be_smi () const
 
void set_receiver_cannot_be_smi (bool value) const
 
uword Hash () const
 
- Public Member Functions inherited from dart::CallSiteData
StringPtr target_name () const
 
ArrayPtr arguments_descriptor () const
 
intptr_t TypeArgsLen () const
 
intptr_t CountWithTypeArgs () const
 
intptr_t CountWithoutTypeArgs () const
 
intptr_t SizeWithoutTypeArgs () const
 
intptr_t SizeWithTypeArgs () const
 
- Public Member Functions inherited from dart::Object
virtual ~Object ()
 
ObjectPtr ptr () const
 
void operator= (ObjectPtr value)
 
bool IsCanonical () const
 
void SetCanonical () const
 
void ClearCanonical () const
 
bool IsImmutable () const
 
void SetImmutable () const
 
void ClearImmutable () const
 
intptr_t GetClassId () const
 
ClassPtr clazz () const
 
 CLASS_LIST_FOR_HANDLES (DEFINE_CLASS_TESTER)
 
bool IsNull () const
 
virtual const char * ToCString () const
 
void PrintJSON (JSONStream *stream, bool ref=true) const
 
virtual void PrintJSONImpl (JSONStream *stream, bool ref) const
 
void PrintImplementationFields (JSONStream *stream) const
 
virtual void PrintImplementationFieldsImpl (const JSONArray &jsarr_fields) const
 
virtual const char * JSONType () const
 
virtual StringPtr DictionaryName () const
 
bool IsNew () const
 
bool IsOld () const
 
bool InVMIsolateHeap () const
 
void Print () const
 

Static Public Member Functions

static const char * RebindRuleToCString (RebindRule r)
 
static bool ParseRebindRule (const char *str, RebindRule *out)
 
static intptr_t InstanceSize ()
 
static intptr_t state_bits_offset ()
 
static intptr_t NumArgsTestedShift ()
 
static intptr_t NumArgsTestedMask ()
 
static intptr_t entries_offset ()
 
static intptr_t owner_offset ()
 
static intptr_t receivers_static_type_offset ()
 
static ICDataPtr New (const Function &owner, const String &target_name, const Array &arguments_descriptor, intptr_t deopt_id, intptr_t num_args_tested, RebindRule rebind_rule, const AbstractType &receiver_type=Object::null_abstract_type())
 
static ICDataPtr NewWithCheck (const Function &owner, const String &target_name, const Array &arguments_descriptor, intptr_t deopt_id, intptr_t num_args_tested, RebindRule rebind_rule, GrowableArray< intptr_t > *cids, const Function &target, const AbstractType &receiver_type=Object::null_abstract_type())
 
static ICDataPtr NewForStaticCall (const Function &owner, const Function &target, const Array &arguments_descriptor, intptr_t deopt_id, intptr_t num_args_tested, RebindRule rebind_rule)
 
static ICDataPtr NewFrom (const ICData &from, intptr_t num_args_tested)
 
static ICDataPtr Clone (const ICData &from)
 
static ICDataPtr ICDataOfEntriesArray (const Array &array)
 
static intptr_t TestEntryLengthFor (intptr_t num_args, bool tracking_exactness)
 
static intptr_t CountIndexFor (intptr_t num_args)
 
static intptr_t EntryPointIndexFor (intptr_t num_args)
 
static intptr_t TargetIndexFor (intptr_t num_args)
 
static intptr_t CodeIndexFor (intptr_t num_args)
 
static intptr_t ExactnessIndexFor (intptr_t num_args)
 
static void Init ()
 
static void Cleanup ()
 
- Static Public Member Functions inherited from dart::CallSiteData
static intptr_t target_name_offset ()
 
static intptr_t arguments_descriptor_offset ()
 
- Static Public Member Functions inherited from dart::Object
static ObjectPtr RawCast (ObjectPtr obj)
 
static constexpr bool ContainsCompressedPointers ()
 
static intptr_t tags_offset ()
 
static ObjectHandle ()
 
static ObjectHandle (Zone *zone)
 
static ObjectHandle (ObjectPtr ptr)
 
static ObjectHandle (Zone *zone, ObjectPtr ptr)
 
static ObjectZoneHandle ()
 
static ObjectZoneHandle (Zone *zone)
 
static ObjectZoneHandle (ObjectPtr ptr)
 
static ObjectZoneHandle (Zone *zone, ObjectPtr ptr)
 
static ObjectReadOnlyHandle ()
 
static ObjectPtr null ()
 
static void set_vm_isolate_snapshot_object_table (const Array &table)
 
static ClassPtr class_class ()
 
static ClassPtr dynamic_class ()
 
static ClassPtr void_class ()
 
static ClassPtr type_parameters_class ()
 
static ClassPtr type_arguments_class ()
 
static ClassPtr patch_class_class ()
 
static ClassPtr function_class ()
 
static ClassPtr closure_data_class ()
 
static ClassPtr ffi_trampoline_data_class ()
 
static ClassPtr field_class ()
 
static ClassPtr script_class ()
 
static ClassPtr library_class ()
 
static ClassPtr namespace_class ()
 
static ClassPtr kernel_program_info_class ()
 
static ClassPtr code_class ()
 
static ClassPtr instructions_class ()
 
static ClassPtr instructions_section_class ()
 
static ClassPtr instructions_table_class ()
 
static ClassPtr object_pool_class ()
 
static ClassPtr pc_descriptors_class ()
 
static ClassPtr code_source_map_class ()
 
static ClassPtr compressed_stackmaps_class ()
 
static ClassPtr var_descriptors_class ()
 
static ClassPtr exception_handlers_class ()
 
static ClassPtr context_class ()
 
static ClassPtr context_scope_class ()
 
static ClassPtr sentinel_class ()
 
static ClassPtr api_error_class ()
 
static ClassPtr language_error_class ()
 
static ClassPtr unhandled_exception_class ()
 
static ClassPtr unwind_error_class ()
 
static ClassPtr singletargetcache_class ()
 
static ClassPtr unlinkedcall_class ()
 
static ClassPtr monomorphicsmiablecall_class ()
 
static ClassPtr icdata_class ()
 
static ClassPtr megamorphic_cache_class ()
 
static ClassPtr subtypetestcache_class ()
 
static ClassPtr loadingunit_class ()
 
static ClassPtr weak_serialization_reference_class ()
 
static ClassPtr weak_array_class ()
 
static void InitNullAndBool (IsolateGroup *isolate_group)
 
static void Init (IsolateGroup *isolate_group)
 
static void InitVtables ()
 
static void FinishInit (IsolateGroup *isolate_group)
 
static void FinalizeVMIsolate (IsolateGroup *isolate_group)
 
static void FinalizeReadOnlyObject (ObjectPtr object)
 
static void Cleanup ()
 
static ErrorPtr Init (IsolateGroup *isolate_group, const uint8_t *kernel_buffer, intptr_t kernel_buffer_size)
 
static void MakeUnusedSpaceTraversable (const Object &obj, intptr_t original_size, intptr_t used_size)
 
static intptr_t InstanceSize ()
 
template<class FakeObject >
static void VerifyBuiltinVtable (intptr_t cid)
 
static void VerifyBuiltinVtables ()
 
static bool ShouldHaveImmutabilityBitSet (classid_t class_id)
 

Static Public Attributes

static constexpr intptr_t kLastRecordedDeoptReason = kDeoptUnknown - 1
 
- Static Public Attributes inherited from dart::Object
static constexpr intptr_t kHashBits = 30
 
static const ClassId kClassId = kObjectCid
 

Friends

class CallSiteResetter
 
class CallTargets
 
class Class
 
class VMDeserializationRoots
 
class ICDataTestTask
 
class VMSerializationRoots
 

Additional Inherited Members

- Protected Member Functions inherited from dart::Object
 Object ()
 
uword raw_value () const
 
void setPtr (ObjectPtr value, intptr_t default_cid)
 
void CheckHandle () const
 
cpp_vtable vtable () const
 
void set_vtable (cpp_vtable value)
 
bool Contains (uword addr) const
 
template<typename type , std::memory_order order = std::memory_order_relaxed>
type LoadPointer (type const *addr) const
 
template<typename type , std::memory_order order = std::memory_order_relaxed>
void StorePointer (type const *addr, type value) const
 
template<typename type , typename compressed_type , std::memory_order order = std::memory_order_relaxed>
void StoreCompressedPointer (compressed_type const *addr, type value) const
 
template<typename type >
void StorePointerUnaligned (type const *addr, type value, Thread *thread) const
 
void StoreSmi (SmiPtr const *addr, SmiPtr value) const
 
template<typename FieldType >
void StoreSimd128 (const FieldType *addr, simd128_value_t value) const
 
template<typename FieldType >
FieldType LoadNonPointer (const FieldType *addr) const
 
template<typename FieldType , std::memory_order order>
FieldType LoadNonPointer (const FieldType *addr) const
 
template<typename FieldType , typename ValueType >
void StoreNonPointer (const FieldType *addr, ValueType value) const
 
template<typename FieldType , typename ValueType , std::memory_order order>
void StoreNonPointer (const FieldType *addr, ValueType value) const
 
template<typename FieldType >
FieldType * UnsafeMutableNonPointer (const FieldType *addr) const
 
 CLASS_LIST (STORE_NON_POINTER_ILLEGAL_TYPE)
 
void UnimplementedMethod () const
 
void AddCommonObjectProperties (JSONObject *jsobj, const char *protocol_type, bool ref) const
 
- Static Protected Member Functions inherited from dart::Object
static DART_NOINLINE ObjectHandleImpl (Zone *zone, ObjectPtr ptr, intptr_t default_cid)
 
static DART_NOINLINE ObjectZoneHandleImpl (Zone *zone, ObjectPtr ptr, intptr_t default_cid)
 
static DART_NOINLINE ObjectReadOnlyHandleImpl (intptr_t cid)
 
static ObjectPtr Allocate (intptr_t cls_id, intptr_t size, Heap::Space space, bool compressed, uword ptr_field_start_offset, uword ptr_field_end_offset)
 
template<typename T >
static DART_FORCE_INLINE T::ObjectPtrType Allocate (Heap::Space space)
 
template<typename T >
static DART_FORCE_INLINE T::ObjectPtrType Allocate (Heap::Space space, intptr_t elements)
 
template<typename T >
static DART_FORCE_INLINE T::ObjectPtrType AllocateVariant (intptr_t class_id, Heap::Space space)
 
template<typename T >
static DART_FORCE_INLINE T::ObjectPtrType AllocateVariant (intptr_t class_id, Heap::Space space, intptr_t elements)
 
static constexpr intptr_t RoundedAllocationSize (intptr_t size)
 
static ObjectPtr Clone (const Object &orig, Heap::Space space, bool load_with_relaxed_atomics=false)
 
template<typename T >
static DART_FORCE_INLINE uword from_offset ()
 
template<typename T >
static DART_FORCE_INLINE uword to_offset (intptr_t length=0)
 
- Protected Attributes inherited from dart::Object
ObjectPtr ptr_
 

Detailed Description

Definition at line 2456 of file object.h.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
Enumerator
kCachedICDataZeroArgTestedWithoutExactnessTrackingIdx 
kCachedICDataMaxArgsTestedWithoutExactnessTracking 
kCachedICDataOneArgWithExactnessTrackingIdx 
kCachedICDataArrayCount 

Definition at line 2770 of file object.h.

◆ DeoptFlags

Enumerator
kHoisted 
kGeneralized 

Definition at line 2520 of file object.h.

2520 {
2521 // Deoptimization is caused by an optimistically hoisted instruction.
2522 kHoisted = 1 << 0,
2523
2524 // Deoptimization is caused by an optimistically generalized bounds check.
2525 kGeneralized = 1 << 1
2526 };
@ kGeneralized
Definition: object.h:2525

◆ DeoptReasonId

Definition at line 2512 of file object.h.

2512 {
2513#define DEFINE_ENUM_LIST(name) kDeopt##name,
2515#undef DEFINE_ENUM_LIST
2516 };
#define DEOPT_REASONS(V)
Definition: object.h:2493
#define DEFINE_ENUM_LIST(name)
Definition: object.h:2513

◆ RebindRule

Enumerator
kNumRebindRules 

Definition at line 2545 of file object.h.

2545 {
2546#define REBIND_ENUM_DEF(name) k##name,
2548#undef REBIND_ENUM_DEF
2550 };
@ kNumRebindRules
Definition: object.h:2549
#define FOR_EACH_REBIND_RULE(V)
Definition: object.h:2537
#define REBIND_ENUM_DEF(name)
Definition: object.h:2546

Member Function Documentation

◆ AddCheck()

void dart::ICData::AddCheck ( const GrowableArray< intptr_t > &  class_ids,
const Function target,
intptr_t  count = 1 
) const

Definition at line 16784 of file object.cc.

16786 {
16787 SafepointMutexLocker ml(IsolateGroup::Current()->type_feedback_mutex());
16788 AddCheckInternal(class_ids, target, count);
16789}
int count
Definition: FontMgrTest.cpp:50
static IsolateGroup * Current()
Definition: isolate.h:539
uint32_t * target

◆ AddDeoptReason()

void dart::ICData::AddDeoptReason ( ICData::DeoptReasonId  reason) const

Definition at line 16518 of file object.cc.

16518 {
16519 if (reason <= kLastRecordedDeoptReason) {
16520 untag()->state_bits_.FetchOr<DeoptReasonBits>(1 << reason);
16521 }
16522}
static constexpr intptr_t kLastRecordedDeoptReason
Definition: object.h:2518
raw_obj untag() -> num_entries()) VARIABLE_COMPRESSED_VISITOR(Array, Smi::Value(raw_obj->untag() ->length())) VARIABLE_COMPRESSED_VISITOR(TypedData, TypedData::ElementSizeInBytes(raw_obj->GetClassId()) *Smi::Value(raw_obj->untag() ->length())) VARIABLE_COMPRESSED_VISITOR(Record, RecordShape(raw_obj->untag() ->shape()).num_fields()) VARIABLE_NULL_VISITOR(CompressedStackMaps, CompressedStackMaps::PayloadSizeOf(raw_obj)) VARIABLE_NULL_VISITOR(OneByteString, Smi::Value(raw_obj->untag() ->length())) VARIABLE_NULL_VISITOR(TwoByteString, Smi::Value(raw_obj->untag() ->length())) intptr_t UntaggedField::VisitFieldPointers(FieldPtr raw_obj, ObjectPointerVisitor *visitor)
Definition: raw_object.cc:558

◆ AddReceiverCheck()

void dart::ICData::AddReceiverCheck ( intptr_t  receiver_class_id,
const Function target,
intptr_t  count = 1,
StaticTypeExactnessState  exactness = StaticTypeExactnessState::NotTracking() 
) const

Definition at line 16889 of file object.cc.

16892 {
16893 SafepointMutexLocker ml(IsolateGroup::Current()->type_feedback_mutex());
16894 AddReceiverCheckInternal(receiver_class_id, target, count, exactness);
16895}

◆ AggregateCount()

intptr_t dart::ICData::AggregateCount ( ) const

Definition at line 17084 of file object.cc.

17084 {
17085 if (IsNull()) return 0;
17086 const intptr_t len = NumberOfChecks();
17087 intptr_t count = 0;
17088 for (intptr_t i = 0; i < len; i++) {
17089 count += GetCountAt(i);
17090 }
17091 return count;
17092}
intptr_t GetCountAt(intptr_t index) const
Definition: object.cc:17063
intptr_t NumberOfChecks() const
Definition: object.cc:16577
bool IsNull() const
Definition: object.h:363

◆ AsUnaryClassChecks()

ICDataPtr dart::ICData::AsUnaryClassChecks ( ) const
inline

Definition at line 2691 of file object.h.

2691{ return AsUnaryClassChecksForArgNr(0); }
ICDataPtr AsUnaryClassChecksForArgNr(intptr_t arg_nr) const
Definition: object.cc:17095

◆ AsUnaryClassChecksForArgNr()

ICDataPtr dart::ICData::AsUnaryClassChecksForArgNr ( intptr_t  arg_nr) const

Definition at line 17095 of file object.cc.

17095 {
17096 ASSERT(!IsNull());
17097 ASSERT(NumArgsTested() > arg_nr);
17098 if ((arg_nr == 0) && (NumArgsTested() == 1)) {
17099 // Frequent case.
17100 return ptr();
17101 }
17102 const intptr_t kNumArgsTested = 1;
17103 ICData& result = ICData::Handle(ICData::NewFrom(*this, kNumArgsTested));
17104 const intptr_t len = NumberOfChecks();
17105 for (intptr_t i = 0; i < len; i++) {
17106 const intptr_t class_id = GetClassIdAt(i, arg_nr);
17107 const intptr_t count = GetCountAt(i);
17108 if (count == 0) {
17109 continue;
17110 }
17111 intptr_t duplicate_class_id = -1;
17112 const intptr_t result_len = result.NumberOfChecks();
17113 for (intptr_t k = 0; k < result_len; k++) {
17114 if (class_id == result.GetReceiverClassIdAt(k)) {
17115 duplicate_class_id = k;
17116 break;
17117 }
17118 }
17119 if (duplicate_class_id >= 0) {
17120 // This check is valid only when checking the receiver.
17121 ASSERT((arg_nr != 0) ||
17122 (result.GetTargetAt(duplicate_class_id) == GetTargetAt(i)));
17123 result.IncrementCountAt(duplicate_class_id, count);
17124 } else {
17125 // This will make sure that Smi is first if it exists.
17126 result.AddReceiverCheckInternal(class_id,
17129 }
17130 }
17131
17132 return result.ptr();
17133}
friend class ICData
Definition: object.h:2399
intptr_t NumArgsTested() const
Definition: object.cc:16471
FunctionPtr GetTargetAt(intptr_t index) const
Definition: object.cc:17029
static ICDataPtr NewFrom(const ICData &from, intptr_t num_args_tested)
Definition: object.cc:17424
intptr_t GetClassIdAt(intptr_t index, intptr_t arg_nr) const
Definition: object.cc:17014
ObjectPtr ptr() const
Definition: object.h:332
static Object & Handle()
Definition: object.h:407
static StaticTypeExactnessState NotTracking()
#define ASSERT(E)
GAsyncResult * result

◆ AsUnaryClassChecksSortedByCount()

ICDataPtr dart::ICData::AsUnaryClassChecksSortedByCount ( ) const

Definition at line 17154 of file object.cc.

17154 {
17155 ASSERT(!IsNull());
17156 const intptr_t kNumArgsTested = 1;
17157 const intptr_t len = NumberOfChecks();
17158 if (len <= 1) {
17159 // No sorting needed.
17160 return AsUnaryClassChecks();
17161 }
17162 GrowableArray<CidCount> aggregate;
17163 for (intptr_t i = 0; i < len; i++) {
17164 const intptr_t class_id = GetClassIdAt(i, 0);
17165 const intptr_t count = GetCountAt(i);
17166 if (count == 0) {
17167 continue;
17168 }
17169 bool found = false;
17170 for (intptr_t r = 0; r < aggregate.length(); r++) {
17171 if (aggregate[r].cid == class_id) {
17172 aggregate[r].count += count;
17173 found = true;
17174 break;
17175 }
17176 }
17177 if (!found) {
17178 aggregate.Add(
17179 CidCount(class_id, count, &Function::ZoneHandle(GetTargetAt(i))));
17180 }
17181 }
17182 aggregate.Sort(CidCount::HighestCountFirst);
17183
17184 ICData& result = ICData::Handle(ICData::NewFrom(*this, kNumArgsTested));
17185 ASSERT(result.NumberOfChecksIs(0));
17186 // Room for all entries and the sentinel.
17187 const intptr_t data_len = result.TestEntryLength() * (aggregate.length() + 1);
17188 // Allocate the array but do not assign it to result until we have populated
17189 // it with the aggregate data and the terminating sentinel.
17190 const Array& data = Array::Handle(Array::New(data_len, Heap::kOld));
17191 intptr_t pos = 0;
17192 for (intptr_t i = 0; i < aggregate.length(); i++) {
17193 data.SetAt(pos + 0, Smi::Handle(Smi::New(aggregate[i].cid)));
17194 data.SetAt(pos + TargetIndexFor(1), *aggregate[i].function);
17195 data.SetAt(pos + CountIndexFor(1),
17196 Smi::Handle(Smi::New(aggregate[i].count)));
17197
17198 pos += result.TestEntryLength();
17199 }
17200 WriteSentinel(data, result.TestEntryLength(), result);
17201 result.set_entries(data);
17202 ASSERT(result.NumberOfChecksIs(aggregate.length()));
17203 return result.ptr();
17204}
SkPoint pos
static ArrayPtr New(intptr_t len, Heap::Space space=Heap::kNew)
Definition: object.h:10959
@ kOld
Definition: heap.h:39
static intptr_t TargetIndexFor(intptr_t num_args)
Definition: object.h:2752
ICDataPtr AsUnaryClassChecks() const
Definition: object.h:2691
static intptr_t CountIndexFor(intptr_t num_args)
Definition: object.h:2749
static Object & ZoneHandle()
Definition: object.h:419
static SmiPtr New(intptr_t value)
Definition: object.h:10006
Dart_NativeFunction function
Definition: fuchsia.cc:51
const intptr_t cid
static int8_t data[kExtLength]
static int HighestCountFirst(const CidCount *a, const CidCount *b)
Definition: object.cc:17147

◆ AsUnlinkedCall()

UnlinkedCallPtr dart::ICData::AsUnlinkedCall ( ) const

Definition at line 17206 of file object.cc.

17206 {
17207 ASSERT(NumArgsTested() == 1);
17209 const UnlinkedCall& result = UnlinkedCall::Handle(UnlinkedCall::New());
17210 result.set_target_name(String::Handle(target_name()));
17211 result.set_arguments_descriptor(Array::Handle(arguments_descriptor()));
17212 result.set_can_patch_to_monomorphic(!FLAG_precompiled_mode ||
17214 return result.ptr();
17215}
StringPtr target_name() const
Definition: object.h:2372
ArrayPtr arguments_descriptor() const
Definition: object.h:2373
bool receiver_cannot_be_smi() const
Definition: object.h:2787
bool is_tracking_exactness() const
Definition: object.h:2483
static UnlinkedCallPtr New()
Definition: object.cc:16343

◆ Cleanup()

void dart::ICData::Cleanup ( )
static

Definition at line 17259 of file object.cc.

17259 {
17260 for (int i = 0; i < kCachedICDataArrayCount; ++i) {
17261 cached_icdata_arrays_[i] = nullptr;
17262 }
17263}

◆ Clear()

void dart::ICData::Clear ( const CallSiteResetter proof_of_reload) const
inline

Definition at line 2603 of file object.h.

2603 {
2604 TruncateTo(0, proof_of_reload);
2605 }
void TruncateTo(intptr_t num_checks, const CallSiteResetter &proof_of_reload) const
Definition: object.cc:16690

◆ ClearAndSetStaticTarget()

void dart::ICData::ClearAndSetStaticTarget ( const Function func,
const CallSiteResetter proof_of_reload 
) const

Definition at line 16730 of file object.cc.

16732 {
16733 USE(proof_of_reload); // This method can only be called during reload.
16734
16735 // The final entry is always the sentinel.
16736 DEBUG_ONLY(AssertInvariantsAreSatisfied());
16737
16738 if (IsImmutable()) return;
16739 if (NumberOfChecks() == 0) return;
16740
16741 // Leave one entry.
16742 TruncateTo(/*num_checks=*/1, proof_of_reload);
16743
16744 // Reinitialize the one and only entry.
16745 const intptr_t num_args = NumArgsTested();
16746 Thread* thread = Thread::Current();
16748 Array& data = thread->ArrayHandle();
16749 data = entries();
16750 const Smi& object_cid = Smi::Handle(Smi::New(kObjectCid));
16751 for (intptr_t i = 0; i < num_args; i++) {
16752 data.SetAt(i, object_cid);
16753 }
16754 data.SetAt(TargetIndexFor(num_args), func);
16755 data.SetAt(CountIndexFor(num_args), Object::smi_zero());
16756}
ArrayPtr entries() const
Definition: object.h:2783
bool IsImmutable() const
Definition: object.cc:17330
friend class Thread
Definition: object.h:1025
static Thread * Current()
Definition: thread.h:362
static void USE(T &&)
Definition: globals.h:618
#define DEBUG_ONLY(code)
Definition: globals.h:141
#define REUSABLE_ARRAY_HANDLESCOPE(thread)

◆ ClearCountAt()

void dart::ICData::ClearCountAt ( intptr_t  index,
const CallSiteResetter proof_of_reload 
) const

Definition at line 16721 of file object.cc.

16722 {
16723 USE(proof_of_reload); // This method can only be called during reload.
16724
16725 ASSERT(index >= 0);
16726 ASSERT(index < NumberOfChecks());
16727 SetCountAt(index, 0);
16728}
void SetCountAt(intptr_t index, intptr_t value) const
Definition: object.cc:17050

◆ Clone()

ICDataPtr dart::ICData::Clone ( const ICData from)
static

Definition at line 17439 of file object.cc.

17439 {
17440 Zone* zone = Thread::Current()->zone();
17441
17442 // We have to check the megamorphic bit before accessing the entries of the
17443 // ICData to ensure all writes to the entries have been flushed and are
17444 // visible at this point.
17445 //
17446 // This will allow us to maintain the invariant that if the megamorphic bit is
17447 // set, the number of entries in the ICData have reached the limit.
17448 const bool is_megamorphic = from.is_megamorphic();
17449
17450 const ICData& result = ICData::Handle(
17451 zone, ICData::NewDescriptor(
17452 zone, Function::Handle(zone, from.Owner()),
17453 String::Handle(zone, from.target_name()),
17454 Array::Handle(zone, from.arguments_descriptor()),
17455 from.deopt_id(), from.NumArgsTested(), from.rebind_rule(),
17456 AbstractType::Handle(zone, from.receivers_static_type())));
17457 // Clone entry array.
17458 const Array& from_array = Array::Handle(zone, from.entries());
17459 if (ICData::IsCachedEmptyEntry(from_array)) {
17460 result.set_entries(from_array);
17461 } else {
17462 const intptr_t len = from_array.Length();
17463 const Array& cloned_array =
17465 Object& obj = Object::Handle(zone);
17466 for (intptr_t i = 0; i < len; i++) {
17467 obj = from_array.At(i);
17468 cloned_array.SetAt(i, obj);
17469 }
17470 // Update backref in our clone.
17471 cloned_array.SetAt(cloned_array.Length() - 1, result);
17472 result.set_entries(cloned_array);
17473 }
17474 // Copy deoptimization reasons.
17475 result.SetDeoptReasons(from.DeoptReasons());
17476 result.set_is_megamorphic(is_megamorphic);
17477
17478 DEBUG_ONLY(result.AssertInvariantsAreSatisfied());
17479
17480 return result.ptr();
17481}
Zone * zone() const
Definition: thread_state.h:37

◆ CodeIndexFor()

static intptr_t dart::ICData::CodeIndexFor ( intptr_t  num_args)
inlinestatic

Definition at line 2753 of file object.h.

2753{ return num_args + 1; }

◆ CountIndexFor()

static intptr_t dart::ICData::CountIndexFor ( intptr_t  num_args)
inlinestatic

Definition at line 2749 of file object.h.

2749{ return num_args; }

◆ DebugDump()

void dart::ICData::DebugDump ( ) const

Definition at line 16857 of file object.cc.

16857 {
16858 const Function& owner = Function::Handle(Owner());
16859 THR_Print("ICData::DebugDump\n");
16860 THR_Print("Owner = %s [deopt=%" Pd "]\n", owner.ToCString(), deopt_id());
16861 THR_Print("NumArgsTested = %" Pd "\n", NumArgsTested());
16862 THR_Print("Length = %" Pd "\n", Length());
16863 THR_Print("NumberOfChecks = %" Pd "\n", NumberOfChecks());
16864
16865 GrowableArray<intptr_t> class_ids;
16866 for (intptr_t i = 0; i < NumberOfChecks(); i++) {
16867 THR_Print("Check[%" Pd "]:", i);
16868 GetClassIdsAt(i, &class_ids);
16869 for (intptr_t c = 0; c < class_ids.length(); c++) {
16870 THR_Print(" %" Pd "", class_ids[c]);
16871 }
16872 THR_Print("--- %" Pd " hits\n", GetCountAt(i));
16873 }
16874}
intptr_t deopt_id() const
Definition: object.h:2468
void GetClassIdsAt(intptr_t index, GrowableArray< intptr_t > *class_ids) const
Definition: object.cc:16973
intptr_t Length() const
Definition: object.cc:16573
FunctionPtr Owner() const
Definition: object.cc:16423
#define THR_Print(format,...)
Definition: log.h:20
#define Pd
Definition: globals.h:408

◆ deopt_id()

intptr_t dart::ICData::deopt_id ( ) const
inline

Definition at line 2468 of file object.h.

2468 {
2469#if defined(DART_PRECOMPILED_RUNTIME)
2470 UNREACHABLE();
2471 return -1;
2472#else
2473 return untag()->deopt_id_;
2474#endif
2475 }
#define UNREACHABLE()
Definition: assert.h:248

◆ DeoptReasons()

uint32_t dart::ICData::DeoptReasons ( ) const

Definition at line 16505 of file object.cc.

16505 {
16506 return untag()->state_bits_.Read<DeoptReasonBits>();
16507}

◆ EnsureHasCheck()

void dart::ICData::EnsureHasCheck ( const GrowableArray< intptr_t > &  class_ids,
const Function target,
intptr_t  count = 1 
) const

Definition at line 16775 of file object.cc.

16777 {
16778 SafepointMutexLocker ml(IsolateGroup::Current()->type_feedback_mutex());
16779
16780 if (FindCheck(class_ids) != -1) return;
16781 AddCheckInternal(class_ids, target, count);
16782}
intptr_t FindCheck(const GrowableArray< intptr_t > &cids) const
Definition: object.cc:16670

◆ EnsureHasReceiverCheck()

void dart::ICData::EnsureHasReceiverCheck ( intptr_t  receiver_class_id,
const Function target,
intptr_t  count = 1,
StaticTypeExactnessState  exactness = StaticTypeExactnessState::NotTracking() 
) const

Definition at line 16876 of file object.cc.

16879 {
16880 SafepointMutexLocker ml(IsolateGroup::Current()->type_feedback_mutex());
16881
16882 GrowableArray<intptr_t> class_ids(1);
16883 class_ids.Add(receiver_class_id);
16884 if (FindCheck(class_ids) != -1) return;
16885
16886 AddReceiverCheckInternal(receiver_class_id, target, count, exactness);
16887}

◆ entries()

ArrayPtr dart::ICData::entries ( ) const
inline

Definition at line 2783 of file object.h.

2783 {
2784 return untag()->entries<std::memory_order_acquire>();
2785 }

◆ entries_offset()

static intptr_t dart::ICData::entries_offset ( )
inlinestatic

Definition at line 2590 of file object.h.

2590 {
2591 return OFFSET_OF(UntaggedICData, entries_);
2592 }
#define OFFSET_OF(type, field)
Definition: globals.h:138

◆ EntryPointIndexFor()

static intptr_t dart::ICData::EntryPointIndexFor ( intptr_t  num_args)
inlinestatic

Definition at line 2750 of file object.h.

2750{ return num_args; }

◆ ExactnessIndexFor()

static intptr_t dart::ICData::ExactnessIndexFor ( intptr_t  num_args)
inlinestatic

Definition at line 2755 of file object.h.

2755{ return num_args + 2; }

◆ FindCheck()

intptr_t dart::ICData::FindCheck ( const GrowableArray< intptr_t > &  cids) const

Definition at line 16670 of file object.cc.

16670 {
16671 const intptr_t len = NumberOfChecks();
16672 GrowableArray<intptr_t> class_ids;
16673 for (intptr_t i = 0; i < len; i++) {
16674 GetClassIdsAt(i, &class_ids);
16675 bool matches = true;
16676 for (intptr_t k = 0; k < class_ids.length(); k++) {
16677 ASSERT(class_ids[k] != kIllegalCid);
16678 if (class_ids[k] != cids[k]) {
16679 matches = false;
16680 break;
16681 }
16682 }
16683 if (matches) {
16684 return i;
16685 }
16686 }
16687 return -1;
16688}
@ kIllegalCid
Definition: class_id.h:214
def matches(file)
Definition: gen_manifest.py:38

◆ GetCheckAt()

void dart::ICData::GetCheckAt ( intptr_t  index,
GrowableArray< intptr_t > *  class_ids,
Function target 
) const

Definition at line 16955 of file object.cc.

16957 {
16958 ASSERT(index < NumberOfChecks());
16959 ASSERT(class_ids != nullptr);
16960 ASSERT(target != nullptr);
16961 class_ids->Clear();
16962 Thread* thread = Thread::Current();
16964 Array& data = thread->ArrayHandle();
16965 data = entries();
16966 intptr_t data_pos = index * TestEntryLength();
16967 for (intptr_t i = 0; i < NumArgsTested(); i++) {
16968 class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos + i))));
16969 }
16970 (*target) ^= data.At(data_pos + TargetIndexFor(NumArgsTested()));
16971}
void Add(const T &value)
static ObjectPtr RawCast(ObjectPtr obj)
Definition: object.h:325
intptr_t Value() const
Definition: object.h:9990

◆ GetCidAt()

intptr_t dart::ICData::GetCidAt ( intptr_t  index) const

Definition at line 17004 of file object.cc.

17004 {
17005 ASSERT(NumArgsTested() == 1);
17006 Thread* thread = Thread::Current();
17008 Array& data = thread->ArrayHandle();
17009 data = entries();
17010 const intptr_t data_pos = index * TestEntryLength();
17011 return Smi::Value(Smi::RawCast(data.At(data_pos)));
17012}

◆ GetClassIdAt()

intptr_t dart::ICData::GetClassIdAt ( intptr_t  index,
intptr_t  arg_nr 
) const

Definition at line 17014 of file object.cc.

17014 {
17015 GrowableArray<intptr_t> class_ids;
17016 GetClassIdsAt(index, &class_ids);
17017 return class_ids[arg_nr];
17018}

◆ GetClassIdsAt()

void dart::ICData::GetClassIdsAt ( intptr_t  index,
GrowableArray< intptr_t > *  class_ids 
) const

Definition at line 16973 of file object.cc.

16974 {
16975 ASSERT(index < Length());
16976 ASSERT(class_ids != nullptr);
16977 ASSERT(IsValidEntryIndex(index));
16978 class_ids->Clear();
16979 Thread* thread = Thread::Current();
16981 Array& data = thread->ArrayHandle();
16982 data = entries();
16983 intptr_t data_pos = index * TestEntryLength();
16984 for (intptr_t i = 0; i < NumArgsTested(); i++) {
16985 class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++))));
16986 }
16987}
bool IsValidEntryIndex(intptr_t index) const
Definition: object.h:2572

◆ GetCountAt()

intptr_t dart::ICData::GetCountAt ( intptr_t  index) const

Definition at line 17063 of file object.cc.

17063 {
17064#if defined(DART_PRECOMPILED_RUNTIME)
17065 UNREACHABLE();
17066 return 0;
17067#else
17068 Thread* thread = Thread::Current();
17070 Array& data = thread->ArrayHandle();
17071 data = entries();
17072 const intptr_t data_pos =
17073 index * TestEntryLength() + CountIndexFor(NumArgsTested());
17074 intptr_t value = Smi::Value(Smi::RawCast(data.At(data_pos)));
17075 if (value >= 0) return value;
17076
17077 // The counter very rarely overflows to a negative value, but if it does, we
17078 // would rather just reset it to zero.
17079 SetCountAt(index, 0);
17080 return 0;
17081#endif
17082}
uint8_t value

◆ GetExactnessAt()

StaticTypeExactnessState dart::ICData::GetExactnessAt ( intptr_t  count) const

Definition at line 16941 of file object.cc.

16941 {
16942 if (!is_tracking_exactness()) {
16944 }
16945 Thread* thread = Thread::Current();
16947 Array& data = thread->ArrayHandle();
16948 data = entries();
16949 intptr_t data_pos =
16950 index * TestEntryLength() + ExactnessIndexFor(NumArgsTested());
16952 Smi::Value(Smi::RawCast(data.At(data_pos))));
16953}
static intptr_t ExactnessIndexFor(intptr_t num_args)
Definition: object.h:2755
static StaticTypeExactnessState Decode(int8_t value)

◆ GetOneClassCheckAt()

void dart::ICData::GetOneClassCheckAt ( intptr_t  index,
intptr_t *  class_id,
Function target 
) const

Definition at line 16989 of file object.cc.

16991 {
16992 ASSERT(class_id != nullptr);
16993 ASSERT(target != nullptr);
16994 ASSERT(NumArgsTested() == 1);
16995 Thread* thread = Thread::Current();
16997 Array& data = thread->ArrayHandle();
16998 data = entries();
16999 const intptr_t data_pos = index * TestEntryLength();
17000 *class_id = Smi::Value(Smi::RawCast(data.At(data_pos)));
17001 *target ^= data.At(data_pos + TargetIndexFor(NumArgsTested()));
17002}

◆ GetReceiverClassIdAt()

intptr_t dart::ICData::GetReceiverClassIdAt ( intptr_t  index) const

Definition at line 17020 of file object.cc.

17020 {
17021 ASSERT(index < Length());
17022 ASSERT(IsValidEntryIndex(index));
17023 const intptr_t data_pos = index * TestEntryLength();
17024 NoSafepointScope no_safepoint;
17025 ArrayPtr raw_data = entries();
17026 return Smi::Value(Smi::RawCast(raw_data->untag()->element(data_pos)));
17027}

◆ GetTargetAt()

FunctionPtr dart::ICData::GetTargetAt ( intptr_t  index) const

Definition at line 17029 of file object.cc.

17029 {
17030#if defined(DART_PRECOMPILED_RUNTIME)
17031 UNREACHABLE();
17032 return nullptr;
17033#else
17034 const intptr_t data_pos =
17035 index * TestEntryLength() + TargetIndexFor(NumArgsTested());
17036 ASSERT(Object::Handle(Array::Handle(entries()).At(data_pos)).IsFunction());
17037
17038 NoSafepointScope no_safepoint;
17039 ArrayPtr raw_data = entries();
17040 return static_cast<FunctionPtr>(raw_data->untag()->element(data_pos));
17041#endif
17042}

◆ HasDeoptReason()

bool dart::ICData::HasDeoptReason ( ICData::DeoptReasonId  reason) const

Definition at line 16513 of file object.cc.

16513 {
16515 return (DeoptReasons() & (1 << reason)) != 0;
16516}
uint32_t DeoptReasons() const
Definition: object.cc:16505

◆ HasDeoptReasons()

bool dart::ICData::HasDeoptReasons ( ) const
inline

Definition at line 2528 of file object.h.

2528{ return DeoptReasons() != 0; }

◆ Hash()

uword dart::ICData::Hash ( ) const

Definition at line 16410 of file object.cc.

16410 {
16412}
static uword HashRawSymbol(const StringPtr symbol)
Definition: object.h:10247

◆ HasReceiverClassId()

bool dart::ICData::HasReceiverClassId ( intptr_t  class_id) const

Definition at line 17217 of file object.cc.

17217 {
17218 ASSERT(NumArgsTested() > 0);
17219 const intptr_t len = NumberOfChecks();
17220 for (intptr_t i = 0; i < len; i++) {
17221 if (IsUsedAt(i)) {
17222 const intptr_t test_class_id = GetReceiverClassIdAt(i);
17223 if (test_class_id == class_id) {
17224 return true;
17225 }
17226 }
17227 }
17228 return false;
17229}
intptr_t GetReceiverClassIdAt(intptr_t index) const
Definition: object.cc:17020
bool IsUsedAt(intptr_t i) const
Definition: object.cc:17232

◆ ICDataOfEntriesArray()

ICDataPtr dart::ICData::ICDataOfEntriesArray ( const Array array)
static

Definition at line 17484 of file object.cc.

17484 {
17485 const auto& back_ref = Object::Handle(array.At(array.Length() - 1));
17486 if (back_ref.ptr() == smi_illegal_cid().ptr()) {
17487 ASSERT(IsCachedEmptyEntry(array));
17488 return ICData::null();
17489 }
17490
17491 const auto& ic_data = ICData::Cast(back_ref);
17492 DEBUG_ONLY(ic_data.AssertInvariantsAreSatisfied());
17493 return ic_data.ptr();
17494}
static ObjectPtr null()
Definition: object.h:433

◆ IncrementCountAt()

void dart::ICData::IncrementCountAt ( intptr_t  index,
intptr_t  value 
) const

Definition at line 17044 of file object.cc.

17044 {
17045 ASSERT(0 <= value);
17048}
static constexpr intptr_t kMaxValue
Definition: object.h:9987
static T Minimum(T x, T y)
Definition: utils.h:36

◆ Init()

void dart::ICData::Init ( )
static

Definition at line 17248 of file object.cc.

17248 {
17250 i++) {
17251 cached_icdata_arrays_
17253 ICData::NewNonCachedEmptyICDataArray(i, false);
17254 }
17255 cached_icdata_arrays_[kCachedICDataOneArgWithExactnessTrackingIdx] =
17256 ICData::NewNonCachedEmptyICDataArray(1, true);
17257}

◆ InstanceSize()

static intptr_t dart::ICData::InstanceSize ( )
inlinestatic

Definition at line 2576 of file object.h.

2576 {
2577 return RoundedAllocationSize(sizeof(UntaggedICData));
2578 }
static constexpr intptr_t RoundedAllocationSize(intptr_t size)
Definition: object.h:758

◆ is_static_call()

bool dart::ICData::is_static_call ( ) const

Definition at line 16555 of file object.cc.

16555 {
16556 return rebind_rule() != kInstance;
16557}
RebindRule rebind_rule() const
Definition: object.cc:16547

◆ is_tracking_exactness()

bool dart::ICData::is_tracking_exactness ( ) const
inline

Definition at line 2483 of file object.h.

2483 {
2484 return untag()->state_bits_.Read<TrackingExactnessBit>();
2485 }

◆ IsImmutable()

bool dart::ICData::IsImmutable ( ) const

Definition at line 17330 of file object.cc.

17330 {
17331 return entries()->IsImmutableArray();
17332}

◆ IsOriginal()

bool dart::ICData::IsOriginal ( ) const
inline

Definition at line 2464 of file object.h.

2464{ return Original() == this->ptr(); }
ICDataPtr Original() const
Definition: object.cc:16437

◆ IsUsedAt()

bool dart::ICData::IsUsedAt ( intptr_t  i) const

Definition at line 17232 of file object.cc.

17232 {
17233 if (GetCountAt(i) <= 0) {
17234 // Do not mistake unoptimized static call ICData for unused.
17235 // See ICData::AddTarget.
17236 // TODO(srdjan): Make this test more robust.
17237 if (NumArgsTested() > 0) {
17238 const intptr_t cid = GetReceiverClassIdAt(i);
17239 if (cid == kObjectCid) {
17240 return true;
17241 }
17242 }
17243 return false;
17244 }
17245 return true;
17246}

◆ IsValidEntryIndex()

bool dart::ICData::IsValidEntryIndex ( intptr_t  index) const
inline

Definition at line 2572 of file object.h.

2572 {
2573 return 0 <= index && index < NumberOfChecks();
2574 }

◆ Length()

intptr_t dart::ICData::Length ( ) const

Definition at line 16573 of file object.cc.

16573 {
16574 return (Smi::Value(entries()->untag()->length()) / TestEntryLength());
16575}
size_t length

◆ New()

ICDataPtr dart::ICData::New ( const Function owner,
const String target_name,
const Array arguments_descriptor,
intptr_t  deopt_id,
intptr_t  num_args_tested,
RebindRule  rebind_rule,
const AbstractType receiver_type = Object::null_abstract_type() 
)
static

Definition at line 17342 of file object.cc.

17348 {
17349 Zone* zone = Thread::Current()->zone();
17350 const ICData& result = ICData::Handle(
17351 zone,
17352 NewDescriptor(zone, owner, target_name, arguments_descriptor, deopt_id,
17353 num_args_tested, rebind_rule, receivers_static_type));
17354 result.set_entries(Array::Handle(
17355 zone,
17356 CachedEmptyICDataArray(num_args_tested, result.is_tracking_exactness())));
17357 return result.ptr();
17358}
AbstractTypePtr receivers_static_type() const
Definition: object.h:2480

◆ NewForStaticCall()

ICDataPtr dart::ICData::NewForStaticCall ( const Function owner,
const Function target,
const Array arguments_descriptor,
intptr_t  deopt_id,
intptr_t  num_args_tested,
RebindRule  rebind_rule 
)
static

Definition at line 17401 of file object.cc.

17406 {
17407 // See `MethodRecognizer::NumArgsCheckedForStaticCall`.
17408 ASSERT(num_args_tested == 0 || num_args_tested == 2);
17409 ASSERT(!target.IsNull());
17410
17411 Zone* zone = Thread::Current()->zone();
17412 const auto& target_name = String::Handle(zone, target.name());
17413 GrowableArray<intptr_t> cids(num_args_tested);
17414 if (num_args_tested == 2) {
17415 cids.Add(kObjectCid);
17416 cids.Add(kObjectCid);
17417 }
17419 deopt_id, num_args_tested, rebind_rule, &cids,
17420 target, Object::null_abstract_type());
17421}
static ICDataPtr NewWithCheck(const Function &owner, const String &target_name, const Array &arguments_descriptor, intptr_t deopt_id, intptr_t num_args_tested, RebindRule rebind_rule, GrowableArray< intptr_t > *cids, const Function &target, const AbstractType &receiver_type=Object::null_abstract_type())
Definition: object.cc:17360

◆ NewFrom()

ICDataPtr dart::ICData::NewFrom ( const ICData from,
intptr_t  num_args_tested 
)
static

Definition at line 17424 of file object.cc.

17424 {
17425 // See comment in [ICData::Clone] why we access the megamorphic bit first.
17426 const bool is_megamorphic = from.is_megamorphic();
17427
17428 const ICData& result = ICData::Handle(ICData::New(
17429 Function::Handle(from.Owner()), String::Handle(from.target_name()),
17430 Array::Handle(from.arguments_descriptor()), from.deopt_id(),
17431 num_args_tested, from.rebind_rule(),
17432 AbstractType::Handle(from.receivers_static_type())));
17433 // Copy deoptimization reasons.
17434 result.SetDeoptReasons(from.DeoptReasons());
17435 result.set_is_megamorphic(is_megamorphic);
17436 return result.ptr();
17437}

◆ NewWithCheck()

ICDataPtr dart::ICData::NewWithCheck ( const Function owner,
const String target_name,
const Array arguments_descriptor,
intptr_t  deopt_id,
intptr_t  num_args_tested,
RebindRule  rebind_rule,
GrowableArray< intptr_t > *  cids,
const Function target,
const AbstractType receiver_type = Object::null_abstract_type() 
)
static

Definition at line 17360 of file object.cc.

17368 {
17369 ASSERT((cids != nullptr) && !target.IsNull());
17370 ASSERT(cids->length() == num_args_tested);
17371
17372 Zone* zone = Thread::Current()->zone();
17373 const auto& result = ICData::Handle(
17374 zone,
17375 NewDescriptor(zone, owner, target_name, arguments_descriptor, deopt_id,
17376 num_args_tested, rebind_rule, receiver_type));
17377
17378 const intptr_t kNumEntries = 2; // 1 entry and a sentinel.
17379 const intptr_t entry_len =
17380 TestEntryLengthFor(num_args_tested, result.is_tracking_exactness());
17381 const auto& array =
17382 Array::Handle(zone, Array::New(kNumEntries * entry_len, Heap::kOld));
17383
17384 auto& cid = Smi::Handle(zone);
17385 for (intptr_t i = 0; i < num_args_tested; ++i) {
17386 cid = Smi::New((*cids)[i]);
17387 array.SetAt(i, cid);
17388 }
17389
17390 SetTargetAtPos(array, 0, num_args_tested, target);
17391#if !defined(DART_PRECOMPILED_RUNTIME)
17392 array.SetAt(CountIndexFor(num_args_tested), Object::smi_zero());
17393#endif
17394 WriteSentinel(array, entry_len, result);
17395
17396 result.set_entries(array);
17397
17398 return result.ptr();
17399}
intptr_t length() const
static intptr_t TestEntryLengthFor(intptr_t num_args, bool tracking_exactness)
Definition: object.cc:16563

◆ NumArgsTested()

intptr_t dart::ICData::NumArgsTested ( ) const

Definition at line 16471 of file object.cc.

16471 {
16472 return untag()->state_bits_.Read<NumArgsTestedBits>();
16473}

◆ NumArgsTestedMask()

static intptr_t dart::ICData::NumArgsTestedMask ( )
inlinestatic

Definition at line 2586 of file object.h.

2586 {
2587 return ((1 << kNumArgsTestedSize) - 1) << kNumArgsTestedPos;
2588 }

◆ NumArgsTestedShift()

static intptr_t dart::ICData::NumArgsTestedShift ( )
inlinestatic

Definition at line 2584 of file object.h.

2584{ return kNumArgsTestedPos; }

◆ NumberOfChecks()

intptr_t dart::ICData::NumberOfChecks ( ) const

Definition at line 16577 of file object.cc.

16577 {
16578 DEBUG_ONLY(AssertInvariantsAreSatisfied());
16579 return Length() - 1;
16580}

◆ NumberOfChecksIs()

bool dart::ICData::NumberOfChecksIs ( intptr_t  n) const

Definition at line 16582 of file object.cc.

16582 {
16583 DEBUG_ONLY(AssertInvariantsAreSatisfied());
16584 return NumberOfChecks() == n;
16585}

◆ NumberOfUsedChecks()

intptr_t dart::ICData::NumberOfUsedChecks ( ) const

Definition at line 16640 of file object.cc.

16640 {
16641 const intptr_t n = NumberOfChecks();
16642 intptr_t count = 0;
16643 for (intptr_t i = 0; i < n; i++) {
16644 if (GetCountAt(i) > 0) {
16645 count++;
16646 }
16647 }
16648 return count;
16649}

◆ Original()

ICDataPtr dart::ICData::Original ( ) const

Definition at line 16437 of file object.cc.

16437 {
16438 if (IsNull()) {
16439 return ICData::null();
16440 }
16441 if (untag()->owner()->IsICData()) {
16442 return static_cast<ICDataPtr>(untag()->owner());
16443 }
16444 return this->ptr();
16445}

◆ Owner()

FunctionPtr dart::ICData::Owner ( ) const

Definition at line 16423 of file object.cc.

16423 {
16424 Object& obj = Object::Handle(untag()->owner());
16425 if (obj.IsNull()) {
16427 return Function::null();
16428 } else if (obj.IsFunction()) {
16429 return Function::Cast(obj).ptr();
16430 } else {
16431 ICData& original = ICData::Handle();
16432 original ^= obj.ptr();
16433 return original.Owner();
16434 }
16435}
static Snapshot::Kind vm_snapshot_kind()
Definition: dart.h:95

◆ owner_offset()

static intptr_t dart::ICData::owner_offset ( )
inlinestatic

Definition at line 2594 of file object.h.

2594{ return OFFSET_OF(UntaggedICData, owner_); }

◆ ParseRebindRule()

bool dart::ICData::ParseRebindRule ( const char *  str,
RebindRule out 
)
static

Definition at line 16536 of file object.cc.

16536 {
16537#define RULE_CASE(Name) \
16538 if (strcmp(str, #Name) == 0) { \
16539 *out = RebindRule::k##Name; \
16540 return true; \
16541 }
16543#undef RULE_CASE
16544 return false;
16545}
#define RULE_CASE(Name)

◆ PrintToJSONArray()

void dart::ICData::PrintToJSONArray ( const JSONArray jsarray,
TokenPosition  token_pos 
) const

Definition at line 993 of file object_service.cc.

994 {
995 auto class_table = IsolateGroup::Current()->class_table();
996 Class& cls = Class::Handle();
997 Function& func = Function::Handle();
998
999 JSONObject jsobj(&jsarray);
1000 jsobj.AddProperty("name", String::Handle(target_name()).ToCString());
1001 jsobj.AddProperty("tokenPos", static_cast<intptr_t>(token_pos.Serialize()));
1002 // TODO(rmacnak): Figure out how to stringify DeoptReasons().
1003 // jsobj.AddProperty("deoptReasons", ...);
1004
1005 JSONArray cache_entries(&jsobj, "cacheEntries");
1006 for (intptr_t i = 0; i < NumberOfChecks(); i++) {
1007 JSONObject cache_entry(&cache_entries);
1008 func = GetTargetAt(i);
1009 intptr_t count = GetCountAt(i);
1010 if (!is_static_call()) {
1011 intptr_t cid = GetReceiverClassIdAt(i);
1012 cls = class_table->At(cid);
1013 cache_entry.AddProperty("receiver", cls);
1014 }
1015 cache_entry.AddProperty("target", func);
1016 cache_entry.AddProperty("count", count);
1017 }
1018}
bool is_static_call() const
Definition: object.cc:16555
friend class Class
Definition: object.h:2918
ClassTable * class_table() const
Definition: isolate.h:496
virtual const char * ToCString() const
Definition: object.h:366

◆ rebind_rule()

ICData::RebindRule dart::ICData::rebind_rule ( ) const

Definition at line 16547 of file object.cc.

16547 {
16548 return RebindRule(untag()->state_bits_.Read<RebindRuleBits>());
16549}

◆ RebindRuleToCString()

const char * dart::ICData::RebindRuleToCString ( RebindRule  r)
static

Definition at line 16524 of file object.cc.

16524 {
16525 switch (r) {
16526#define RULE_CASE(Name) \
16527 case RebindRule::k##Name: \
16528 return #Name;
16530#undef RULE_CASE
16531 default:
16532 return nullptr;
16533 }
16534}

◆ receiver_cannot_be_smi()

bool dart::ICData::receiver_cannot_be_smi ( ) const
inline

Definition at line 2787 of file object.h.

2787 {
2788 return untag()->state_bits_.Read<ReceiverCannotBeSmiBit>();
2789 }

◆ receivers_static_type()

AbstractTypePtr dart::ICData::receivers_static_type ( ) const
inline

Definition at line 2480 of file object.h.

2480 {
2481 return untag()->receivers_static_type();
2482 }

◆ receivers_static_type_offset()

static intptr_t dart::ICData::receivers_static_type_offset ( )
inlinestatic

Definition at line 2597 of file object.h.

2597 {
2598 return OFFSET_OF(UntaggedICData, receivers_static_type_);
2599 }

◆ set_is_megamorphic()

void dart::ICData::set_is_megamorphic ( bool  value) const
inline

Definition at line 2555 of file object.h.

2555 {
2556 untag()->state_bits_.UpdateBool<MegamorphicBit, std::memory_order_release>(
2557 value);
2558 }

◆ set_receiver_cannot_be_smi()

void dart::ICData::set_receiver_cannot_be_smi ( bool  value) const
inline

Definition at line 2791 of file object.h.

2791 {
2792 untag()->state_bits_.UpdateBool<ReceiverCannotBeSmiBit>(value);
2793 }

◆ SetCountAt()

void dart::ICData::SetCountAt ( intptr_t  index,
intptr_t  value 
) const

Definition at line 17050 of file object.cc.

17050 {
17051 ASSERT(0 <= value);
17053
17054 Thread* thread = Thread::Current();
17056 Array& data = thread->ArrayHandle();
17057 data = entries();
17058 const intptr_t data_pos =
17059 index * TestEntryLength() + CountIndexFor(NumArgsTested());
17060 data.SetAt(data_pos, Smi::Handle(Smi::New(value)));
17061}

◆ SetDeoptReasons()

void dart::ICData::SetDeoptReasons ( uint32_t  reasons) const

Definition at line 16509 of file object.cc.

16509 {
16510 untag()->state_bits_.Update<DeoptReasonBits>(reasons);
16511}

◆ SetOriginal()

void dart::ICData::SetOriginal ( const ICData value) const

Definition at line 16447 of file object.cc.

16447 {
16448 ASSERT(value.IsOriginal());
16449 ASSERT(!value.IsNull());
16450 untag()->set_owner(static_cast<ObjectPtr>(value.ptr()));
16451}

◆ state_bits_offset()

static intptr_t dart::ICData::state_bits_offset ( )
inlinestatic

Definition at line 2580 of file object.h.

2580 {
2581 return OFFSET_OF(UntaggedICData, state_bits_);
2582 }

◆ TargetIndexFor()

static intptr_t dart::ICData::TargetIndexFor ( intptr_t  num_args)
inlinestatic

Definition at line 2752 of file object.h.

2752{ return num_args + 1; }

◆ TestEntryLengthFor()

intptr_t dart::ICData::TestEntryLengthFor ( intptr_t  num_args,
bool  tracking_exactness 
)
static

Definition at line 16563 of file object.cc.

16564 {
16565 return num_args + 1 /* target function*/ + 1 /* frequency */ +
16566 (tracking_exactness ? 1 : 0) /* exactness state */;
16567}

◆ TruncateTo()

void dart::ICData::TruncateTo ( intptr_t  num_checks,
const CallSiteResetter proof_of_reload 
) const

Definition at line 16690 of file object.cc.

16691 {
16692 USE(proof_of_reload); // This method can only be called during reload.
16693
16694 DEBUG_ONLY(AssertInvariantsAreSatisfied());
16695 ASSERT(num_checks <= NumberOfChecks());
16696
16697 // Nothing to do.
16698 if (NumberOfChecks() == num_checks) return;
16699
16700 auto thread = Thread::Current();
16702 auto& array = thread->ArrayHandle();
16703
16704 // If we make the ICData empty, use the pre-allocated shared backing stores.
16705 const intptr_t num_args = NumArgsTested();
16706 if (num_checks == 0) {
16707 array = ICData::CachedEmptyICDataArray(num_args, is_tracking_exactness());
16708 set_entries(array);
16709 return;
16710 }
16711
16712 // Otherwise truncate array and initialize sentinel.
16713 // Use kSmiCid for all slots in the entry except the last, which is a backref
16714 // to ICData.
16715 const intptr_t entry_length = TestEntryLength();
16716 array = entries();
16717 array.Truncate((num_checks + 1) * entry_length);
16718 WriteSentinel(array, entry_length, *this);
16719}

Friends And Related Function Documentation

◆ CallSiteResetter

friend class CallSiteResetter
friend

Definition at line 2916 of file object.h.

◆ CallTargets

friend class CallTargets
friend

Definition at line 2917 of file object.h.

◆ Class

friend class Class
friend

Definition at line 2918 of file object.h.

◆ ICDataTestTask

friend class ICDataTestTask
friend

Definition at line 2920 of file object.h.

◆ VMDeserializationRoots

friend class VMDeserializationRoots
friend

Definition at line 2919 of file object.h.

◆ VMSerializationRoots

friend class VMSerializationRoots
friend

Definition at line 2921 of file object.h.

Member Data Documentation

◆ kLastRecordedDeoptReason

constexpr intptr_t dart::ICData::kLastRecordedDeoptReason = kDeoptUnknown - 1
staticconstexpr

Definition at line 2518 of file object.h.


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