@@ -54,31 +54,16 @@ DEFINE_FLAG(bool,
5454DECLARE_FLAG (bool , inline_alloc);
5555DECLARE_FLAG (bool , use_slow_path);
5656
57- class SubclassFinder {
57+ class SubtypeFinder {
5858 public:
59- SubclassFinder (Zone* zone,
60- GrowableArray<intptr_t >* cids,
61- bool include_abstract)
59+ SubtypeFinder (Zone* zone,
60+ GrowableArray<intptr_t >* cids,
61+ bool include_abstract)
6262 : array_handles_(zone),
6363 class_handles_ (zone),
6464 cids_(cids),
6565 include_abstract_(include_abstract) {}
6666
67- void ScanSubClasses (const Class& klass) {
68- if (include_abstract_ || !klass.is_abstract ()) {
69- cids_->Add (klass.id ());
70- }
71- ScopedHandle<GrowableObjectArray> array (&array_handles_);
72- ScopedHandle<Class> subclass (&class_handles_);
73- *array = klass.direct_subclasses ();
74- if (!array->IsNull ()) {
75- for (intptr_t i = 0 ; i < array->Length (); ++i) {
76- *subclass ^= array->At (i);
77- ScanSubClasses (*subclass);
78- }
79- }
80- }
81-
8267 void ScanImplementorClasses (const Class& klass) {
8368 // An implementor of [klass] is
8469 // * the [klass] itself.
@@ -134,36 +119,9 @@ const CidRangeVector& HierarchyInfo::SubtypeRangesForClass(
134119 CidRangeVector& ranges = (*cid_ranges)[klass.id ()];
135120 if (ranges.length () == 0 ) {
136121 if (!FLAG_precompiled_mode) {
137- BuildRangesForJIT (table, &ranges, klass, /* use_subtype_test=*/ true ,
138- include_abstract, exclude_null);
139- } else {
140- BuildRangesFor (table, &ranges, klass, /* use_subtype_test=*/ true ,
141- include_abstract, exclude_null);
142- }
143- }
144- return ranges;
145- }
146-
147- const CidRangeVector& HierarchyInfo::SubclassRangesForClass (
148- const Class& klass) {
149- ClassTable* table = thread ()->isolate_group ()->class_table ();
150- const intptr_t cid_count = table->NumCids ();
151- if (cid_subclass_ranges_ == nullptr ) {
152- cid_subclass_ranges_.reset (new CidRangeVector[cid_count]);
153- }
154-
155- CidRangeVector& ranges = cid_subclass_ranges_[klass.id ()];
156- if (ranges.length () == 0 ) {
157- if (!FLAG_precompiled_mode) {
158- BuildRangesForJIT (table, &ranges, klass,
159- /* use_subtype_test=*/ true ,
160- /* include_abstract=*/ false ,
161- /* exclude_null=*/ false );
122+ BuildRangesForJIT (table, &ranges, klass, include_abstract, exclude_null);
162123 } else {
163- BuildRangesFor (table, &ranges, klass,
164- /* use_subtype_test=*/ false ,
165- /* include_abstract=*/ false ,
166- /* exclude_null=*/ false );
124+ BuildRangesFor (table, &ranges, klass, include_abstract, exclude_null);
167125 }
168126 }
169127 return ranges;
@@ -175,18 +133,12 @@ const CidRangeVector& HierarchyInfo::SubclassRangesForClass(
175133void HierarchyInfo::BuildRangesFor (ClassTable* table,
176134 CidRangeVector* ranges,
177135 const Class& klass,
178- bool use_subtype_test,
179136 bool include_abstract,
180137 bool exclude_null) {
181138 Zone* zone = thread ()->zone ();
182- ClassTable* class_table = thread ()->isolate_group ()->class_table ();
183-
184- // Only really used if `use_subtype_test == true`.
185139 const Type& dst_type = Type::Handle (zone, Type::RawCast (klass.RareType ()));
186140 AbstractType& cls_type = AbstractType::Handle (zone);
187-
188141 Class& cls = Class::Handle (zone);
189- AbstractType& super_type = AbstractType::Handle (zone);
190142 const intptr_t cid_count = table->NumCids ();
191143
192144 // Iterate over all cids to find the ones to be included in the ranges.
@@ -210,24 +162,14 @@ void HierarchyInfo::BuildRangesFor(ClassTable* table,
210162 if (!include_abstract && cls.is_abstract ()) continue ;
211163 if (cls.IsTopLevel ()) continue ;
212164
213- // We are either interested in [CidRange]es of subclasses or subtypes.
165+ // We are interested in [CidRange]es of subtypes.
214166 bool test_succeeded = false ;
215167 if (cid == kNullCid ) {
216168 ASSERT (exclude_null);
217169 test_succeeded = false ;
218- } else if (use_subtype_test) {
170+ } else {
219171 cls_type = cls.RareType ();
220172 test_succeeded = cls_type.IsSubtypeOf (dst_type, Heap::kNew );
221- } else {
222- while (!cls.IsObjectClass ()) {
223- if (cls.ptr () == klass.ptr ()) {
224- test_succeeded = true ;
225- break ;
226- }
227- super_type = cls.super_type ();
228- const intptr_t type_class_id = super_type.type_class_id ();
229- cls = class_table->At (type_class_id);
230- }
231173 }
232174
233175 if (test_succeeded) {
@@ -245,41 +187,31 @@ void HierarchyInfo::BuildRangesFor(ClassTable* table,
245187 }
246188 }
247189
248- // Construct last range (either close open one, or add invalid) .
190+ // Construct last range if there is a open one .
249191 if (start != -1 ) {
250192 ASSERT (start <= end);
251193 CidRange range (start, end);
252194 ranges->Add (range);
253- } else if (ranges->length () == 0 ) {
254- CidRange range;
255- ASSERT (range.IsIllegalRange ());
256- ranges->Add (range);
257195 }
258196}
259197
260198void HierarchyInfo::BuildRangesForJIT (ClassTable* table,
261199 CidRangeVector* ranges,
262200 const Class& dst_klass,
263- bool use_subtype_test,
264201 bool include_abstract,
265202 bool exclude_null) {
266203 if (dst_klass.InVMIsolateHeap ()) {
267- BuildRangesFor (table, ranges, dst_klass, use_subtype_test, include_abstract,
268- exclude_null);
204+ BuildRangesFor (table, ranges, dst_klass, include_abstract, exclude_null);
269205 return ;
270206 }
271207
272208 Zone* zone = thread ()->zone ();
273209 GrowableArray<intptr_t > cids;
274- SubclassFinder finder (zone, &cids, include_abstract);
210+ SubtypeFinder finder (zone, &cids, include_abstract);
275211 {
276212 SafepointReadRwLocker ml (thread (),
277213 thread ()->isolate_group ()->program_lock ());
278- if (use_subtype_test) {
279- finder.ScanImplementorClasses (dst_klass);
280- } else {
281- finder.ScanSubClasses (dst_klass);
282- }
214+ finder.ScanImplementorClasses (dst_klass);
283215 }
284216
285217 // Sort all collected cids.
@@ -429,17 +361,6 @@ bool HierarchyInfo::CanUseGenericSubtypeRangeCheckFor(
429361 ASSERT (type_class.NumTypeParameters () > 0 &&
430362 type.arguments () != TypeArguments::null ());
431363
432- // If the type class is implemented the different implementations might have
433- // their type argument vector stored at different offsets and we can therefore
434- // not perform our optimized [CidRange]-based implementation.
435- //
436- // TODO(kustermann): If the class is implemented but all implementations
437- // store the instantator type argument vector at the same offset we can
438- // still do it!
439- if (type_class.is_implemented ()) {
440- return false ;
441- }
442-
443364 const TypeArguments& ta =
444365 TypeArguments::Handle (zone, Type::Cast (type).arguments ());
445366 ASSERT (ta.Length () == num_type_arguments);
@@ -477,11 +398,10 @@ bool HierarchyInfo::InstanceOfHasClassRange(const AbstractType& type,
477398 /* exclude_null=*/ true );
478399 if (ranges.length () == 1 ) {
479400 const CidRangeValue& range = ranges[0 ];
480- if (!range.IsIllegalRange ()) {
481- *lower_limit = range.cid_start ;
482- *upper_limit = range.cid_end ;
483- return true ;
484- }
401+ ASSERT (!range.IsIllegalRange ());
402+ *lower_limit = range.cid_start ;
403+ *upper_limit = range.cid_end ;
404+ return true ;
485405 }
486406 }
487407 return false ;
0 commit comments