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

#include <il.h>

Inheritance diagram for dart::CallTargets:
dart::Cids dart::ZoneAllocated

Public Member Functions

 CallTargets (Zone *zone)
 
TargetInfoTargetAt (int i) const
 
intptr_t AggregateCallCount () const
 
StaticTypeExactnessState MonomorphicExactness () const
 
bool HasSingleTarget () const
 
bool HasSingleRecognizedTarget () const
 
const FunctionFirstTarget () const
 
const FunctionMostPopularTarget () const
 
void Print () const
 
bool ReceiverIs (intptr_t cid) const
 
bool ReceiverIsSmiOrMint () const
 
void Write (FlowGraphSerializer *s) const
 
 CallTargets (FlowGraphDeserializer *d)
 
- Public Member Functions inherited from dart::Cids
 Cids (Zone *zone)
 
bool Equals (const Cids &other) const
 
bool HasClassId (intptr_t cid) const
 
void Add (CidRange *target)
 
CidRangeoperator[] (intptr_t index) const
 
CidRangeAt (int index) const
 
intptr_t length () const
 
void SetLength (intptr_t len)
 
bool is_empty () const
 
void Sort (int compare(CidRange *const *a, CidRange *const *b))
 
bool IsMonomorphic () const
 
intptr_t MonomorphicReceiverCid () const
 
intptr_t ComputeLowestCid () const
 
intptr_t ComputeHighestCid () 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 CallTargetsCreateMonomorphic (Zone *zone, intptr_t receiver_cid, const Function &target)
 
static const CallTargetsCreate (Zone *zone, const ICData &ic_data)
 
static const CallTargetsCreateAndExpand (Zone *zone, const ICData &ic_data)
 
- Static Public Member Functions inherited from dart::Cids
static CidsCreateForArgument (Zone *zone, const BinaryFeedback &binary_feedback, int argument_number)
 
static CidsCreateMonomorphic (Zone *zone, intptr_t cid)
 

Additional Inherited Members

- Protected Attributes inherited from dart::Cids
GrowableArray< CidRange * > cid_ranges_
 

Detailed Description

Definition at line 780 of file il.h.

Constructor & Destructor Documentation

◆ CallTargets() [1/2]

dart::CallTargets::CallTargets ( Zone zone)
inlineexplicit

Definition at line 782 of file il.h.

782: Cids(zone) {}
Cids(Zone *zone)
Definition: il.h:738

◆ CallTargets() [2/2]

dart::CallTargets::CallTargets ( FlowGraphDeserializer d)
explicit

Definition at line 305 of file il_serializer.cc.

305 : Cids(d->zone()) {
306 const intptr_t len = d->Read<intptr_t>();
307 cid_ranges_.EnsureLength(len, nullptr);
308 for (intptr_t i = 0; i < len; ++i) {
309 const intptr_t cid_start = d->Read<intptr_t>();
310 const intptr_t cid_end = d->Read<intptr_t>();
311 const Function& target = d->Read<const Function&>();
312 const intptr_t count = d->Read<intptr_t>();
313 const StaticTypeExactnessState exactness =
314 StaticTypeExactnessState::Decode(d->Read<int8_t>());
315 TargetInfo* t = new (d->zone())
316 TargetInfo(cid_start, cid_end, &target, count, exactness);
317 cid_ranges_[i] = t;
318 }
319}
int count
Definition: FontMgrTest.cpp:50
GrowableArray< CidRange * > cid_ranges_
Definition: il.h:774
static StaticTypeExactnessState Decode(int8_t value)
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition: main.cc:19
uint32_t * target

Member Function Documentation

◆ AggregateCallCount()

intptr_t dart::CallTargets::AggregateCallCount ( ) const

Definition at line 5528 of file il.cc.

5528 {
5529 intptr_t sum = 0;
5530 for (int i = 0; i < length(); i++) {
5531 sum += TargetAt(i)->count;
5532 }
5533 return sum;
5534}
TargetInfo * TargetAt(int i) const
Definition: il.h:796
intptr_t length() const
Definition: il.h:758
intptr_t count
Definition: il.h:728

◆ Create()

const CallTargets * dart::CallTargets::Create ( Zone zone,
const ICData ic_data 
)
static

Definition at line 4129 of file il.cc.

4129 {
4130 CallTargets* targets = new (zone) CallTargets(zone);
4131 targets->CreateHelper(zone, ic_data);
4132 targets->Sort(OrderById);
4133 targets->MergeIntoRanges();
4134 return targets;
4135}
CallTargets(Zone *zone)
Definition: il.h:782
static int OrderById(CidRange *const *a, CidRange *const *b)
Definition: il.cc:637

◆ CreateAndExpand()

const CallTargets * dart::CallTargets::CreateAndExpand ( Zone zone,
const ICData ic_data 
)
static

Definition at line 4137 of file il.cc.

4138 {
4139 CallTargets& targets = *new (zone) CallTargets(zone);
4140 targets.CreateHelper(zone, ic_data);
4141
4142 if (targets.is_empty() || targets.IsMonomorphic()) {
4143 return &targets;
4144 }
4145
4146 targets.Sort(OrderById);
4147
4148 Array& args_desc_array = Array::Handle(zone, ic_data.arguments_descriptor());
4149 ArgumentsDescriptor args_desc(args_desc_array);
4150 String& name = String::Handle(zone, ic_data.target_name());
4151
4152 Function& fn = Function::Handle(zone);
4153
4154 intptr_t length = targets.length();
4155
4156 // Merging/extending cid ranges is also done in Cids::CreateAndExpand.
4157 // If changing this code, consider also adjusting Cids code.
4158
4159 // Spread class-ids to preceding classes where a lookup yields the same
4160 // method. A polymorphic target is not really the same method since its
4161 // behaviour depends on the receiver class-id, so we don't spread the
4162 // class-ids in that case.
4163 for (int idx = 0; idx < length; idx++) {
4164 int lower_limit_cid = (idx == 0) ? -1 : targets[idx - 1].cid_end;
4165 auto target_info = targets.TargetAt(idx);
4166 const Function& target = *target_info->target;
4167 if (target.is_polymorphic_target()) continue;
4168 for (int i = target_info->cid_start - 1; i > lower_limit_cid; i--) {
4169 bool class_is_abstract = false;
4170 if (FlowGraphCompiler::LookupMethodFor(i, name, args_desc, &fn,
4171 &class_is_abstract) &&
4172 fn.ptr() == target.ptr()) {
4173 if (!class_is_abstract) {
4174 target_info->cid_start = i;
4175 target_info->exactness = StaticTypeExactnessState::NotTracking();
4176 }
4177 } else {
4178 break;
4179 }
4180 }
4181 }
4182
4183 // Spread class-ids to following classes where a lookup yields the same
4184 // method.
4185 const intptr_t max_cid = IsolateGroup::Current()->class_table()->NumCids();
4186 for (int idx = 0; idx < length; idx++) {
4187 int upper_limit_cid =
4188 (idx == length - 1) ? max_cid : targets[idx + 1].cid_start;
4189 auto target_info = targets.TargetAt(idx);
4190 const Function& target = *target_info->target;
4191 if (target.is_polymorphic_target()) continue;
4192 // The code below makes attempt to avoid spreading class-id range
4193 // into a suffix that consists purely of abstract classes to
4194 // shorten the range.
4195 // However such spreading is beneficial when it allows to
4196 // merge to consecutive ranges.
4197 intptr_t cid_end_including_abstract = target_info->cid_end;
4198 for (int i = target_info->cid_end + 1; i < upper_limit_cid; i++) {
4199 bool class_is_abstract = false;
4200 if (FlowGraphCompiler::LookupMethodFor(i, name, args_desc, &fn,
4201 &class_is_abstract) &&
4202 fn.ptr() == target.ptr()) {
4203 cid_end_including_abstract = i;
4204 if (!class_is_abstract) {
4205 target_info->cid_end = i;
4206 target_info->exactness = StaticTypeExactnessState::NotTracking();
4207 }
4208 } else {
4209 break;
4210 }
4211 }
4212
4213 // Check if we have a suffix that consists of abstract classes
4214 // and expand into it if that would allow us to merge this
4215 // range with subsequent range.
4216 if ((cid_end_including_abstract > target_info->cid_end) &&
4217 (idx < length - 1) &&
4218 ((cid_end_including_abstract + 1) == targets[idx + 1].cid_start) &&
4219 (target.ptr() == targets.TargetAt(idx + 1)->target->ptr())) {
4220 target_info->cid_end = cid_end_including_abstract;
4221 target_info->exactness = StaticTypeExactnessState::NotTracking();
4222 }
4223 }
4224 targets.MergeIntoRanges();
4225 return &targets;
4226}
intptr_t NumCids() const
Definition: class_table.h:447
static bool LookupMethodFor(int class_id, const String &name, const ArgumentsDescriptor &args_desc, Function *fn_return, bool *class_is_abstract_return=nullptr)
static IsolateGroup * Current()
Definition: isolate.h:539
ClassTable * class_table() const
Definition: isolate.h:496
static Object & Handle()
Definition: object.h:407
static StaticTypeExactnessState NotTracking()
const char *const name

◆ CreateMonomorphic()

const CallTargets * dart::CallTargets::CreateMonomorphic ( Zone zone,
intptr_t  receiver_cid,
const Function target 
)
static

Definition at line 4118 of file il.cc.

4120 {
4121 CallTargets* targets = new (zone) CallTargets(zone);
4122 const intptr_t count = 1;
4123 targets->cid_ranges_.Add(new (zone) TargetInfo(
4124 receiver_cid, receiver_cid, &Function::ZoneHandle(zone, target.ptr()),
4126 return targets;
4127}
static Object & ZoneHandle()
Definition: object.h:419

◆ FirstTarget()

const Function & dart::CallTargets::FirstTarget ( ) const

Definition at line 5513 of file il.cc.

5513 {
5514 ASSERT(length() != 0);
5515 DEBUG_ASSERT(TargetAt(0)->target->IsNotTemporaryScopedHandle());
5516 return *TargetAt(0)->target;
5517}
#define DEBUG_ASSERT(cond)
Definition: assert.h:321
#define ASSERT(E)
const Function * target
Definition: il.h:727

◆ HasSingleRecognizedTarget()

bool dart::CallTargets::HasSingleRecognizedTarget ( ) const

Definition at line 5500 of file il.cc.

5500 {
5501 if (!HasSingleTarget()) return false;
5503}
bool HasSingleTarget() const
Definition: il.cc:5505
const Function & FirstTarget() const
Definition: il.cc:5513
MethodRecognizer::Kind recognized_kind() const
Definition: object.h:3619

◆ HasSingleTarget()

bool dart::CallTargets::HasSingleTarget ( ) const

Definition at line 5505 of file il.cc.

5505 {
5506 if (length() == 0) return false;
5507 for (int i = 0; i < length(); i++) {
5508 if (TargetAt(i)->target->ptr() != TargetAt(0)->target->ptr()) return false;
5509 }
5510 return true;
5511}
ObjectPtr ptr() const
Definition: object.h:332

◆ MonomorphicExactness()

StaticTypeExactnessState dart::CallTargets::MonomorphicExactness ( ) const

Definition at line 811 of file il.cc.

811 {
813 return TargetAt(0)->exactness;
814}
bool IsMonomorphic() const
Definition: il.cc:801
StaticTypeExactnessState exactness
Definition: il.h:729

◆ MostPopularTarget()

const Function & dart::CallTargets::MostPopularTarget ( ) const

Definition at line 5519 of file il.cc.

5519 {
5520 ASSERT(length() != 0);
5521 DEBUG_ASSERT(TargetAt(0)->target->IsNotTemporaryScopedHandle());
5522 for (int i = 1; i < length(); i++) {
5523 ASSERT(TargetAt(i)->count <= TargetAt(0)->count);
5524 }
5525 return *TargetAt(0)->target;
5526}

◆ Print()

void dart::CallTargets::Print ( ) const

Definition at line 4258 of file il.cc.

4258 {
4259 for (intptr_t i = 0; i < length(); i++) {
4260 THR_Print("cid = [%" Pd ", %" Pd "], count = %" Pd ", target = %s\n",
4261 TargetAt(i)->cid_start, TargetAt(i)->cid_end, TargetAt(i)->count,
4262 TargetAt(i)->target->ToQualifiedCString());
4263 }
4264}
#define THR_Print(format,...)
Definition: log.h:20
#define Pd
Definition: globals.h:408

◆ ReceiverIs()

bool dart::CallTargets::ReceiverIs ( intptr_t  cid) const
inline

Definition at line 808 of file il.h.

808 {
810 }
intptr_t MonomorphicReceiverCid() const
Definition: il.cc:806
const intptr_t cid

◆ ReceiverIsSmiOrMint()

bool dart::CallTargets::ReceiverIsSmiOrMint ( ) const
inline

Definition at line 811 of file il.h.

811 {
812 if (cid_ranges_.is_empty()) {
813 return false;
814 }
815 for (intptr_t i = 0, n = cid_ranges_.length(); i < n; i++) {
816 for (intptr_t j = cid_ranges_[i]->cid_start; j <= cid_ranges_[i]->cid_end;
817 j++) {
818 if (j != kSmiCid && j != kMintCid) {
819 return false;
820 }
821 }
822 }
823 return true;
824 }

◆ TargetAt()

TargetInfo * dart::CallTargets::TargetAt ( int  i) const
inline

Definition at line 796 of file il.h.

796{ return static_cast<TargetInfo*>(At(i)); }
CidRange * At(int index) const
Definition: il.h:756

◆ Write()

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

Definition at line 292 of file il_serializer.cc.

292 {
293 const intptr_t len = cid_ranges_.length();
294 s->Write<intptr_t>(len);
295 for (intptr_t i = 0; i < len; ++i) {
296 TargetInfo* t = TargetAt(i);
297 s->Write<intptr_t>(t->cid_start);
298 s->Write<intptr_t>(t->cid_end);
299 s->Write<const Function&>(*(t->target));
300 s->Write<intptr_t>(t->count);
301 s->Write<int8_t>(t->exactness.Encode());
302 }
303}
struct MyStruct s

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