Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(413)

Side by Side Diff: runtime/vm/cha.cc

Issue 2002583002: Background compiler should validate CHA decisions before committing the code. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/cha.h" 5 #include "vm/cha.h"
6 #include "vm/class_table.h" 6 #include "vm/class_table.h"
7 #include "vm/flags.h" 7 #include "vm/flags.h"
8 #include "vm/freelist.h" 8 #include "vm/freelist.h"
9 #include "vm/object.h" 9 #include "vm/object.h"
10 #include "vm/raw_object.h" 10 #include "vm/raw_object.h"
11 #include "vm/visitor.h" 11 #include "vm/visitor.h"
12 12
13 namespace dart { 13 namespace dart {
14 14
15 void CHA::AddToLeafClasses(const Class& cls) { 15 void CHA::AddToGuardedClasses(const Class& cls, intptr_t subclass_count) {
16 for (intptr_t i = 0; i < leaf_classes_.length(); i++) { 16 for (intptr_t i = 0; i < guarded_classes_.length(); i++) {
17 if (leaf_classes_[i]->raw() == cls.raw()) { 17 if (guarded_classes_[i].cls->raw() == cls.raw()) {
18 return; 18 return;
19 } 19 }
20 } 20 }
21 leaf_classes_.Add(&Class::ZoneHandle(thread_->zone(), cls.raw())); 21 GuardedClassInfo info = {
22 &Class::ZoneHandle(thread_->zone(), cls.raw()),
23 subclass_count
24 };
25 guarded_classes_.Add(info);
26 return;
22 } 27 }
23 28
24 29
30 bool CHA::IsGuardedClass(intptr_t cid) const {
31 for (intptr_t i = 0; i < guarded_classes_.length(); ++i) {
32 if (guarded_classes_[i].cls->id() == cid) return true;
33 }
34 return false;
35 }
36
37
25 bool CHA::HasSubclasses(const Class& cls) { 38 bool CHA::HasSubclasses(const Class& cls) {
26 ASSERT(!cls.IsNull()); 39 ASSERT(!cls.IsNull());
27 ASSERT(cls.id() >= kInstanceCid); 40 ASSERT(cls.id() >= kInstanceCid);
28 // Can't track dependencies for classes on the VM heap since those are 41 // Can't track dependencies for classes on the VM heap since those are
29 // read-only. 42 // read-only.
30 // TODO(fschneider): Enable tracking of CHA dependent code for VM heap 43 // TODO(fschneider): Enable tracking of CHA dependent code for VM heap
31 // classes. 44 // classes.
32 if (cls.InVMHeap()) return true; 45 if (cls.InVMHeap()) return true;
33 46
34 if (cls.IsObjectClass()) { 47 if (cls.IsObjectClass()) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 // Can't track dependencies for classes on the VM heap since those are 92 // Can't track dependencies for classes on the VM heap since those are
80 // read-only. 93 // read-only.
81 // TODO(fschneider): Enable tracking of CHA dependent code for VM heap 94 // TODO(fschneider): Enable tracking of CHA dependent code for VM heap
82 // classes. 95 // classes.
83 if (cls.InVMHeap()) return true; 96 if (cls.InVMHeap()) return true;
84 97
85 return cls.is_implemented(); 98 return cls.is_implemented();
86 } 99 }
87 100
88 101
89 bool CHA::HasOverride(const Class& cls, const String& function_name) { 102 static intptr_t CountFinalizedSubclasses(Thread* thread, const Class& cls) {
103 intptr_t count = 0;
104 const GrowableObjectArray& cls_direct_subclasses =
105 GrowableObjectArray::Handle(thread->zone(), cls.direct_subclasses());
106 if (cls_direct_subclasses.IsNull()) return count;
107 Class& direct_subclass = Class::Handle(thread->zone());
108 for (intptr_t i = 0; i < cls_direct_subclasses.Length(); i++) {
109 direct_subclass ^= cls_direct_subclasses.At(i);
110 // Unfinalized classes are treated as non-existent for CHA purposes,
111 // as that means that no instance of that class exists at runtime.
112 const bool is_finalized = direct_subclass.is_finalized();
113 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.
114 count += CountFinalizedSubclasses(thread, direct_subclass);
115 }
116 return count;
117 }
118
119
120 bool CHA::IsConsistentWithCurrentHierarchy() const {
121 for (intptr_t i = 0; i < guarded_classes_.length(); i++) {
122 const intptr_t subclass_count =
123 CountFinalizedSubclasses(thread_, *guarded_classes_[i].cls);
124 if (guarded_classes_[i].subclass_count != subclass_count) {
125 return false;
126 }
127 }
128 return true;
129 }
130
131
132 bool CHA::HasOverride(const Class& cls,
133 const String& function_name,
134 intptr_t* subclasses_count) {
90 // Can't track dependencies for classes on the VM heap since those are 135 // Can't track dependencies for classes on the VM heap since those are
91 // read-only. 136 // read-only.
92 // TODO(fschneider): Enable tracking of CHA dependent code for VM heap 137 // TODO(fschneider): Enable tracking of CHA dependent code for VM heap
93 // classes. 138 // classes.
94 if (cls.InVMHeap()) return true; 139 if (cls.InVMHeap()) return true;
95 140
96 // Subclasses of Object are not tracked by CHA. Safely assume that overrides 141 // Subclasses of Object are not tracked by CHA. Safely assume that overrides
97 // exist. 142 // exist.
98 if (cls.IsObjectClass()) { 143 if (cls.IsObjectClass()) {
99 return true; 144 return true;
100 } 145 }
101 146
102 const GrowableObjectArray& cls_direct_subclasses = 147 const GrowableObjectArray& cls_direct_subclasses =
103 GrowableObjectArray::Handle(thread_->zone(), cls.direct_subclasses()); 148 GrowableObjectArray::Handle(thread_->zone(), cls.direct_subclasses());
104 if (cls_direct_subclasses.IsNull()) { 149 if (cls_direct_subclasses.IsNull()) {
105 return false; 150 return false;
106 } 151 }
107 Class& direct_subclass = Class::Handle(thread_->zone()); 152 Class& direct_subclass = Class::Handle(thread_->zone());
108 for (intptr_t i = 0; i < cls_direct_subclasses.Length(); i++) { 153 for (intptr_t i = 0; i < cls_direct_subclasses.Length(); i++) {
109 direct_subclass ^= cls_direct_subclasses.At(i); 154 direct_subclass ^= cls_direct_subclasses.At(i);
110 // Unfinalized classes are treated as non-existent for CHA purposes, 155 // Unfinalized classes are treated as non-existent for CHA purposes,
111 // as that means that no instance of that class exists at runtime. 156 // as that means that no instance of that class exists at runtime.
112 if (direct_subclass.is_finalized() && 157 const bool is_finalized = direct_subclass.is_finalized();
158 if (is_finalized &&
113 (direct_subclass.LookupDynamicFunction(function_name) != 159 (direct_subclass.LookupDynamicFunction(function_name) !=
114 Function::null())) { 160 Function::null())) {
115 return true; 161 return true;
116 } 162 }
117 if (HasOverride(direct_subclass, function_name)) { 163 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.
118 return true; 164 return true;
119 } 165 }
166 if (is_finalized) {
167 (*subclasses_count)++;
168 }
120 } 169 }
121 return false; 170 return false;
122 } 171 }
123 172
173
174 void CHA::RegisterDependencies(const Code& code) const {
175 for (intptr_t i = 0; i < guarded_classes_.length(); ++i) {
176 guarded_classes_[i].cls->RegisterCHACode(code);
177 }
178 }
179
180
124 } // namespace dart 181 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698