Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Public Member Functions | Static Public Member Functions | List of all members
dart::CHA Class Reference

#include <cha.h>

Inheritance diagram for dart::CHA:
dart::ValueObject

Public Member Functions

 CHA (Thread *thread)
 
bool HasSubclasses (intptr_t cid) const
 
bool HasOverride (const Class &cls, const String &function_name, intptr_t *subclass_count)
 
void AddToGuardedClassesForSubclassCount (const Class &cls, intptr_t subclass_count)
 
void AddToGuardedClassesForImplementorCid (const Class &cls, intptr_t implementor_cid)
 
void AddToGuardedClassesToTrackFuture (const Class &cls)
 
bool IsConsistentWithCurrentHierarchy () const
 
void RegisterDependencies (const Code &code) const
 
bool IsGuardedClass (intptr_t cid) const
 
- Public Member Functions inherited from dart::ValueObject
 ValueObject ()
 
 ~ValueObject ()
 

Static Public Member Functions

static bool HasSubclasses (const Class &cls)
 
static bool ConcreteSubclasses (const Class &cls, GrowableArray< intptr_t > *class_ids)
 
static bool IsImplemented (const Class &cls)
 
static bool HasSingleConcreteImplementation (const Class &interface, intptr_t *implementation_cid)
 
static bool ClassCanBeFuture (const Class &cls)
 

Detailed Description

Definition at line 25 of file cha.h.

Constructor & Destructor Documentation

◆ CHA()

dart::CHA::CHA ( Thread thread)
inlineexplicit

Definition at line 27 of file cha.h.

28 : thread_(thread), guarded_classes_(thread->zone(), 1) {}

Member Function Documentation

◆ AddToGuardedClassesForImplementorCid()

void dart::CHA::AddToGuardedClassesForImplementorCid ( const Class cls,
intptr_t  implementor_cid 
)

Definition at line 46 of file cha.cc.

47 {
48 ASSERT(implementor_cid != kIllegalCid);
49 ASSERT(implementor_cid != kDynamicCid);
50 AddToGuardedClasses(cls, -1, implementor_cid, false);
51}
#define ASSERT(E)
@ kIllegalCid
Definition class_id.h:214
@ kDynamicCid
Definition class_id.h:253

◆ AddToGuardedClassesForSubclassCount()

void dart::CHA::AddToGuardedClassesForSubclassCount ( const Class cls,
intptr_t  subclass_count 
)

Definition at line 40 of file cha.cc.

41 {
42 ASSERT(subclass_count >= 0);
43 AddToGuardedClasses(cls, subclass_count, kIllegalCid, false);
44}

◆ AddToGuardedClassesToTrackFuture()

void dart::CHA::AddToGuardedClassesToTrackFuture ( const Class cls)

Definition at line 53 of file cha.cc.

53 {
54 AddToGuardedClasses(cls, -1, kIllegalCid, true);
55}

◆ ClassCanBeFuture()

bool dart::CHA::ClassCanBeFuture ( const Class cls)
static

Definition at line 154 of file cha.cc.

154 {
155 if (cls.can_be_future()) {
156 return true;
157 }
158
159 // Class cannot be Future with the current set of
160 // finalized classes. However, as new classes are loaded
161 // and finalized, there could be a new subtype of [cls]
162 // which is also a subtype of Future.
163 // We should deoptimize in such cases.
164 Thread* thread = Thread::Current();
165 if (FLAG_use_cha_deopt || thread->isolate_group()->all_classes_finalized()) {
166 if (FLAG_use_cha_deopt) {
167 CHA& cha = thread->compiler_state().cha();
168 cha.AddToGuardedClassesToTrackFuture(cls);
169 }
170 return false;
171 }
172
173 // Conservatively assume that class can be Future.
174 return true;
175}
CHA(Thread *thread)
Definition cha.h:27
static Thread * Current()
Definition thread.h:361

◆ ConcreteSubclasses()

bool dart::CHA::ConcreteSubclasses ( const Class cls,
GrowableArray< intptr_t > *  class_ids 
)
static

Definition at line 90 of file cha.cc.

91 {
92 if (cls.InVMIsolateHeap()) return false;
93 if (cls.IsObjectClass()) return false;
94
95 if (!cls.is_abstract()) {
96 class_ids->Add(cls.id());
97 }
98
99 // This is invoked from precompiler only, we can use unsafe version of
100 // Class::direct_subclasses getter.
101 ASSERT(FLAG_precompiled_mode);
102 const GrowableObjectArray& direct_subclasses =
103 GrowableObjectArray::Handle(cls.direct_subclasses_unsafe());
104 if (direct_subclasses.IsNull()) {
105 return true;
106 }
107 Class& subclass = Class::Handle();
108 for (intptr_t i = 0; i < direct_subclasses.Length(); i++) {
109 subclass ^= direct_subclasses.At(i);
110 if (!ConcreteSubclasses(subclass, class_ids)) {
111 return false;
112 }
113 }
114 return true;
115}
void Add(const T &value)
static bool ConcreteSubclasses(const Class &cls, GrowableArray< intptr_t > *class_ids)
Definition cha.cc:90
static Object & Handle()
Definition object.h:407

◆ HasOverride()

bool dart::CHA::HasOverride ( const Class cls,
const String function_name,
intptr_t *  subclass_count 
)

Definition at line 221 of file cha.cc.

223 {
224 // Can't track dependencies for classes on the VM heap since those are
225 // read-only.
226 // TODO(fschneider): Enable tracking of CHA dependent code for VM heap
227 // classes.
228 if (cls.InVMIsolateHeap()) return true;
229
230 // Subclasses of Object are not tracked by CHA. Safely assume that overrides
231 // exist.
232 if (cls.IsObjectClass()) {
233 return true;
234 }
235
236 SafepointReadRwLocker ml(thread_, thread_->isolate_group()->program_lock());
237 const GrowableObjectArray& cls_direct_subclasses =
238 GrowableObjectArray::Handle(thread_->zone(), cls.direct_subclasses());
239 if (cls_direct_subclasses.IsNull()) {
240 return false;
241 }
242 Class& direct_subclass = Class::Handle(thread_->zone());
243 for (intptr_t i = 0; i < cls_direct_subclasses.Length(); i++) {
244 direct_subclass ^= cls_direct_subclasses.At(i);
245 // Unfinalized classes are treated as nonexistent for CHA purposes,
246 // as that means that no instance of that class exists at runtime.
247 if (!direct_subclass.is_finalized()) {
248 continue;
249 }
250
251 if (direct_subclass.LookupDynamicFunctionUnsafe(function_name) !=
252 Function::null()) {
253 return true;
254 }
255
256 if (HasOverride(direct_subclass, function_name, subclasses_count)) {
257 return true;
258 }
259
260 (*subclasses_count)++;
261 }
262
263 return false;
264}
bool HasOverride(const Class &cls, const String &function_name, intptr_t *subclass_count)
Definition cha.cc:221
SafepointRwLock * program_lock()
Definition isolate.h:532
static ObjectPtr null()
Definition object.h:433
Zone * zone() const
IsolateGroup * isolate_group() const
Definition thread.h:540
const char *const function_name

◆ HasSingleConcreteImplementation()

bool dart::CHA::HasSingleConcreteImplementation ( const Class interface,
intptr_t *  implementation_cid 
)
static

Definition at line 127 of file cha.cc.

128 {
129 intptr_t cid = interface.implementor_cid();
130 if ((cid == kIllegalCid) || (cid == kDynamicCid)) {
131 // No implementations / multiple implementations.
132 *implementation_cid = kDynamicCid;
133 return false;
134 }
135
136 Thread* thread = Thread::Current();
137 if (FLAG_use_cha_deopt || thread->isolate_group()->all_classes_finalized()) {
138 if (FLAG_trace_cha) {
139 THR_Print(" **(CHA) Type has one implementation: %s\n",
140 interface.ToCString());
141 }
142 if (FLAG_use_cha_deopt) {
143 CHA& cha = thread->compiler_state().cha();
144 cha.AddToGuardedClassesForImplementorCid(interface, cid);
145 }
146 *implementation_cid = cid;
147 return true;
148 } else {
149 *implementation_cid = kDynamicCid;
150 return false;
151 }
152}
#define THR_Print(format,...)
Definition log.h:20
const intptr_t cid

◆ HasSubclasses() [1/2]

bool dart::CHA::HasSubclasses ( const Class cls)
static

Definition at line 64 of file cha.cc.

64 {
65 ASSERT(!cls.IsNull());
66 ASSERT(!IsInternalOnlyClassId(cls.id()));
67 // Can't track dependencies for classes on the VM heap since those are
68 // read-only.
69 // TODO(fschneider): Enable tracking of CHA dependent code for VM heap
70 // classes.
71 if (cls.InVMIsolateHeap()) return true;
72
73 if (cls.IsObjectClass()) {
74 // Class Object has subclasses, although we do not keep track of them.
75 return true;
76 }
77 Thread* thread = Thread::Current();
78 SafepointReadRwLocker ml(thread, thread->isolate_group()->program_lock());
79 const GrowableObjectArray& direct_subclasses =
80 GrowableObjectArray::Handle(cls.direct_subclasses());
81 return !direct_subclasses.IsNull() && (direct_subclasses.Length() > 0);
82}
bool IsInternalOnlyClassId(intptr_t index)
Definition class_id.h:299

◆ HasSubclasses() [2/2]

bool dart::CHA::HasSubclasses ( intptr_t  cid) const

Definition at line 84 of file cha.cc.

84 {
85 const ClassTable& class_table = *thread_->isolate_group()->class_table();
86 Class& cls = Class::Handle(thread_->zone(), class_table.At(cid));
87 return HasSubclasses(cls);
88}
static bool HasSubclasses(const Class &cls)
Definition cha.cc:64
ClassTable * class_table() const
Definition isolate.h:491

◆ IsConsistentWithCurrentHierarchy()

bool dart::CHA::IsConsistentWithCurrentHierarchy ( ) const

Definition at line 196 of file cha.cc.

196 {
197 for (intptr_t i = 0; i < guarded_classes_.length(); i++) {
198 if (guarded_classes_[i].subclass_count != -1) {
199 intptr_t current_subclass_count =
200 CountFinalizedSubclasses(thread_, *guarded_classes_[i].cls);
201 if (guarded_classes_[i].subclass_count != current_subclass_count) {
202 return false; // New subclass appeared during compilation.
203 }
204 }
205 if (guarded_classes_[i].implementor_cid != kIllegalCid) {
206 intptr_t current_implementor_cid =
207 guarded_classes_[i].cls->implementor_cid();
208 if (guarded_classes_[i].implementor_cid != current_implementor_cid) {
209 return false; // New implementor appeared during compilation.
210 }
211 }
212 if (guarded_classes_[i].track_future) {
213 if (guarded_classes_[i].cls->can_be_future()) {
214 return false;
215 }
216 }
217 }
218 return true;
219}
intptr_t length() const
static intptr_t CountFinalizedSubclasses(Thread *thread, const Class &cls)
Definition cha.cc:177

◆ IsGuardedClass()

bool dart::CHA::IsGuardedClass ( intptr_t  cid) const

Definition at line 57 of file cha.cc.

57 {
58 for (intptr_t i = 0; i < guarded_classes_.length(); ++i) {
59 if (guarded_classes_[i].cls->id() == cid) return true;
60 }
61 return false;
62}

◆ IsImplemented()

bool dart::CHA::IsImplemented ( const Class cls)
static

Definition at line 117 of file cha.cc.

117 {
118 // Can't track dependencies for classes on the VM heap since those are
119 // read-only.
120 // TODO(fschneider): Enable tracking of CHA dependent code for VM heap
121 // classes.
122 if (cls.InVMIsolateHeap()) return true;
123
124 return cls.is_implemented();
125}

◆ RegisterDependencies()

void dart::CHA::RegisterDependencies ( const Code code) const

Definition at line 266 of file cha.cc.

266 {
267 for (intptr_t i = 0; i < guarded_classes_.length(); ++i) {
268 guarded_classes_[i].cls->RegisterCHACode(code);
269 }
270}

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