Chromium Code Reviews| Index: runtime/vm/cha.cc |
| diff --git a/runtime/vm/cha.cc b/runtime/vm/cha.cc |
| index 57214bb10fe32e6562bc4dea38da5d956cbe972c..2187a693b0881baca11951ef57c2851e355973a5 100644 |
| --- a/runtime/vm/cha.cc |
| +++ b/runtime/vm/cha.cc |
| @@ -12,13 +12,26 @@ |
| namespace dart { |
| -void CHA::AddToLeafClasses(const Class& cls) { |
| - for (intptr_t i = 0; i < leaf_classes_.length(); i++) { |
| - if (leaf_classes_[i]->raw() == cls.raw()) { |
| +void CHA::AddToGuardedClasses(const Class& cls, intptr_t subclass_count) { |
| + for (intptr_t i = 0; i < guarded_classes_.length(); i++) { |
| + if (guarded_classes_[i].cls->raw() == cls.raw()) { |
| return; |
| } |
| } |
| - leaf_classes_.Add(&Class::ZoneHandle(thread_->zone(), cls.raw())); |
| + GuardedClassInfo info = { |
| + &Class::ZoneHandle(thread_->zone(), cls.raw()), |
| + subclass_count |
| + }; |
| + guarded_classes_.Add(info); |
| + return; |
| +} |
| + |
| + |
| +bool CHA::IsGuardedClass(intptr_t cid) const { |
| + for (intptr_t i = 0; i < guarded_classes_.length(); ++i) { |
| + if (guarded_classes_[i].cls->id() == cid) return true; |
| + } |
| + return false; |
| } |
| @@ -86,7 +99,39 @@ bool CHA::IsImplemented(const Class& cls) { |
| } |
| -bool CHA::HasOverride(const Class& cls, const String& function_name) { |
| +static intptr_t CountFinalizedSubclasses(Thread* thread, const Class& cls) { |
| + intptr_t count = 0; |
| + const GrowableObjectArray& cls_direct_subclasses = |
| + GrowableObjectArray::Handle(thread->zone(), cls.direct_subclasses()); |
| + if (cls_direct_subclasses.IsNull()) return count; |
| + Class& direct_subclass = Class::Handle(thread->zone()); |
| + for (intptr_t i = 0; i < cls_direct_subclasses.Length(); i++) { |
| + direct_subclass ^= cls_direct_subclasses.At(i); |
| + // Unfinalized classes are treated as non-existent for CHA purposes, |
| + // as that means that no instance of that class exists at runtime. |
| + const bool is_finalized = direct_subclass.is_finalized(); |
| + if (is_finalized) count++; |
|
Florian Schneider
2016/05/20 11:23:28
else continue?
Non-finalized class can't have fin
Vyacheslav Egorov (Google)
2016/05/20 11:31:21
Done.
|
| + count += CountFinalizedSubclasses(thread, direct_subclass); |
| + } |
| + return count; |
| +} |
| + |
| + |
| +bool CHA::IsConsistentWithCurrentHierarchy() const { |
| + for (intptr_t i = 0; i < guarded_classes_.length(); i++) { |
| + const intptr_t subclass_count = |
| + CountFinalizedSubclasses(thread_, *guarded_classes_[i].cls); |
| + if (guarded_classes_[i].subclass_count != subclass_count) { |
| + return false; |
| + } |
| + } |
| + return true; |
| +} |
| + |
| + |
| +bool CHA::HasOverride(const Class& cls, |
| + const String& function_name, |
| + intptr_t* subclasses_count) { |
| // Can't track dependencies for classes on the VM heap since those are |
| // read-only. |
| // TODO(fschneider): Enable tracking of CHA dependent code for VM heap |
| @@ -109,16 +154,28 @@ bool CHA::HasOverride(const Class& cls, const String& function_name) { |
| direct_subclass ^= cls_direct_subclasses.At(i); |
| // Unfinalized classes are treated as non-existent for CHA purposes, |
| // as that means that no instance of that class exists at runtime. |
| - if (direct_subclass.is_finalized() && |
| + const bool is_finalized = direct_subclass.is_finalized(); |
| + if (is_finalized && |
| (direct_subclass.LookupDynamicFunction(function_name) != |
| Function::null())) { |
| return true; |
| } |
| - if (HasOverride(direct_subclass, function_name)) { |
| + if (HasOverride(direct_subclass, function_name, subclasses_count)) { |
|
Florian Schneider
2016/05/20 11:23:28
Same here: No need to recurse if !is_finalized.
Vyacheslav Egorov (Google)
2016/05/20 11:31:21
Done.
|
| return true; |
| } |
| + if (is_finalized) { |
| + (*subclasses_count)++; |
| + } |
| } |
| return false; |
| } |
| + |
| +void CHA::RegisterDependencies(const Code& code) const { |
| + for (intptr_t i = 0; i < guarded_classes_.length(); ++i) { |
| + guarded_classes_[i].cls->RegisterCHACode(code); |
| + } |
| +} |
| + |
| + |
| } // namespace dart |