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

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: address comments 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
« no previous file with comments | « runtime/vm/cha.h ('k') | runtime/vm/cha_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 if (!direct_subclass.is_finalized()) {
113 continue;
114 }
115
116 count += 1 + CountFinalizedSubclasses(thread, direct_subclass);
117 }
118 return count;
119 }
120
121
122 bool CHA::IsConsistentWithCurrentHierarchy() const {
123 for (intptr_t i = 0; i < guarded_classes_.length(); i++) {
124 const intptr_t subclass_count =
125 CountFinalizedSubclasses(thread_, *guarded_classes_[i].cls);
126 if (guarded_classes_[i].subclass_count != subclass_count) {
127 return false;
128 }
129 }
130 return true;
131 }
132
133
134 bool CHA::HasOverride(const Class& cls,
135 const String& function_name,
136 intptr_t* subclasses_count) {
90 // Can't track dependencies for classes on the VM heap since those are 137 // Can't track dependencies for classes on the VM heap since those are
91 // read-only. 138 // read-only.
92 // TODO(fschneider): Enable tracking of CHA dependent code for VM heap 139 // TODO(fschneider): Enable tracking of CHA dependent code for VM heap
93 // classes. 140 // classes.
94 if (cls.InVMHeap()) return true; 141 if (cls.InVMHeap()) return true;
95 142
96 // Subclasses of Object are not tracked by CHA. Safely assume that overrides 143 // Subclasses of Object are not tracked by CHA. Safely assume that overrides
97 // exist. 144 // exist.
98 if (cls.IsObjectClass()) { 145 if (cls.IsObjectClass()) {
99 return true; 146 return true;
100 } 147 }
101 148
102 const GrowableObjectArray& cls_direct_subclasses = 149 const GrowableObjectArray& cls_direct_subclasses =
103 GrowableObjectArray::Handle(thread_->zone(), cls.direct_subclasses()); 150 GrowableObjectArray::Handle(thread_->zone(), cls.direct_subclasses());
104 if (cls_direct_subclasses.IsNull()) { 151 if (cls_direct_subclasses.IsNull()) {
105 return false; 152 return false;
106 } 153 }
107 Class& direct_subclass = Class::Handle(thread_->zone()); 154 Class& direct_subclass = Class::Handle(thread_->zone());
108 for (intptr_t i = 0; i < cls_direct_subclasses.Length(); i++) { 155 for (intptr_t i = 0; i < cls_direct_subclasses.Length(); i++) {
109 direct_subclass ^= cls_direct_subclasses.At(i); 156 direct_subclass ^= cls_direct_subclasses.At(i);
110 // Unfinalized classes are treated as non-existent for CHA purposes, 157 // Unfinalized classes are treated as non-existent for CHA purposes,
111 // as that means that no instance of that class exists at runtime. 158 // as that means that no instance of that class exists at runtime.
112 if (direct_subclass.is_finalized() && 159 if (!direct_subclass.is_finalized()) {
113 (direct_subclass.LookupDynamicFunction(function_name) != 160 continue;
114 Function::null())) { 161 }
162
163 if (direct_subclass.LookupDynamicFunction(function_name) !=
164 Function::null()) {
115 return true; 165 return true;
116 } 166 }
117 if (HasOverride(direct_subclass, function_name)) { 167
168 if (HasOverride(direct_subclass, function_name, subclasses_count)) {
118 return true; 169 return true;
119 } 170 }
171
172 (*subclasses_count)++;
120 } 173 }
174
121 return false; 175 return false;
122 } 176 }
123 177
178
179 void CHA::RegisterDependencies(const Code& code) const {
180 for (intptr_t i = 0; i < guarded_classes_.length(); ++i) {
181 guarded_classes_[i].cls->RegisterCHACode(code);
182 }
183 }
184
185
124 } // namespace dart 186 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/cha.h ('k') | runtime/vm/cha_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698