Flutter Engine
The Flutter Engine
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 160 of file cha.cc.

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

◆ ConcreteSubclasses()

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

Definition at line 93 of file cha.cc.

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

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

◆ HasSingleConcreteImplementation()

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

Definition at line 132 of file cha.cc.

133 {
134 intptr_t cid = interface.implementor_cid();
135 if ((cid == kIllegalCid) || (cid == kDynamicCid) ||
136 interface.has_dynamically_extendable_subtypes()) {
137 // No implementations / multiple implementations.
138 *implementation_cid = kDynamicCid;
139 return false;
140 }
141
142 Thread* thread = Thread::Current();
143 if (FLAG_use_cha_deopt || thread->isolate_group()->all_classes_finalized()) {
144 if (FLAG_trace_cha) {
145 THR_Print(" **(CHA) Type has one implementation: %s\n",
146 interface.ToCString());
147 }
148 if (FLAG_use_cha_deopt) {
149 CHA& cha = thread->compiler_state().cha();
150 cha.AddToGuardedClassesForImplementorCid(interface, cid);
151 }
152 *implementation_cid = cid;
153 return true;
154 } else {
155 *implementation_cid = kDynamicCid;
156 return false;
157 }
158}
#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
78 if (cls.has_dynamically_extendable_subtypes()) return true;
79
80 Thread* thread = Thread::Current();
81 SafepointReadRwLocker ml(thread, thread->isolate_group()->program_lock());
82 const GrowableObjectArray& direct_subclasses =
83 GrowableObjectArray::Handle(cls.direct_subclasses());
84 return !direct_subclasses.IsNull() && (direct_subclasses.Length() > 0);
85}
bool IsInternalOnlyClassId(intptr_t index)
Definition: class_id.h:299

◆ HasSubclasses() [2/2]

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

Definition at line 87 of file cha.cc.

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

◆ IsConsistentWithCurrentHierarchy()

bool dart::CHA::IsConsistentWithCurrentHierarchy ( ) const

Definition at line 202 of file cha.cc.

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

◆ 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 121 of file cha.cc.

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

◆ RegisterDependencies()

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

Definition at line 272 of file cha.cc.

272 {
273 for (intptr_t i = 0; i < guarded_classes_.length(); ++i) {
274 guarded_classes_[i].cls->RegisterCHACode(code);
275 }
276}

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