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

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

Issue 463103002: Fix bug with CHA dependencies by recording a set of classes for registering code. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 4 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 | Annotate | Revision Log
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 bool CHA::HasSubclasses(intptr_t cid) { 15 void CHA::AddToCHAClasses(Class* cls) {
Vyacheslav Egorov (Google) 2014/08/13 11:40:28 Accept an normal Handle here?
Florian Schneider 2014/08/13 12:08:57 Done.
16 Isolate* isolate = Isolate::Current(); 16 for (intptr_t i = 0; i < cha_classes_.length(); i++) {
17 const bool has_subclasses = HasSubclassesSafe(cid); 17 if (cha_classes_[i]->raw() == cls->raw()) {
18 if (!has_subclasses) { 18 return;
19 isolate->set_cha_used(true); 19 }
20 } 20 }
21 return has_subclasses; 21 cha_classes_.Add(cls);
Vyacheslav Egorov (Google) 2014/08/13 11:40:27 Rewrap into ZoneHandle here.
Florian Schneider 2014/08/13 12:08:57 Done.
22 } 22 }
23 23
24 24
25 bool CHA::HasSubclassesSafe(intptr_t cid) { 25 // Return true if the class is private to our internal libraries (not extendable
26 ASSERT(cid >= kInstanceCid); 26 // or implementable by users).
Vyacheslav Egorov (Google) 2014/08/13 11:40:28 The key point is that it can't be extended later a
27 Isolate* isolate = Isolate::Current(); 27 // (TODO): Allow more libraries.
Vyacheslav Egorov (Google) 2014/08/13 11:40:27 TODO(fschneider) ? :) strange TODO syntax.
Florian Schneider 2014/08/13 12:08:58 Done.
28 const ClassTable& class_table = *isolate->class_table(); 28 static bool IsKnownPrivateClass(const Class& type_class) {
29 const Class& cls = Class::Handle(isolate, class_table.At(cid)); 29 if (!Library::IsPrivate(String::Handle(type_class.Name()))) return false;
30 const Library& library = Library::Handle(type_class.library());
31 if (library.raw() == Library::CoreLibrary()) return true;
32 if (library.raw() == Library::CollectionLibrary()) return true;
33 if (library.raw() == Library::TypedDataLibrary()) return true;
34 if (library.raw() == Library::MathLibrary()) return true;
35 return false;
36 }
37
38
39 bool CHA::HasSubclasses(const Class& cls) {
30 ASSERT(!cls.IsNull()); 40 ASSERT(!cls.IsNull());
41 ASSERT(cls.id() >= kInstanceCid);
42 // Can't track dependencies for classes on the VM heap since those are
43 // read-only.
44 // TODO(fschneider): Enable tracking of CHA dependent code for VM heap
45 // classes.
46 if (cls.InVMHeap()) return true;
47
31 if (cls.IsObjectClass()) { 48 if (cls.IsObjectClass()) {
32 // Class Object has subclasses, although we do not keep track of them. 49 // Class Object has subclasses, although we do not keep track of them.
33 return true; 50 return true;
34 } 51 }
35 const GrowableObjectArray& cls_direct_subclasses = 52 const GrowableObjectArray& direct_subclasses =
36 GrowableObjectArray::Handle(isolate, cls.direct_subclasses()); 53 GrowableObjectArray::Handle(isolate_, cls.direct_subclasses());
37 return 54 bool result =
38 !cls_direct_subclasses.IsNull() && (cls_direct_subclasses.Length() > 0); 55 !direct_subclasses.IsNull() && (direct_subclasses.Length() > 0);
56 if (!result && !IsKnownPrivateClass(cls)) {
57 AddToCHAClasses(&Class::ZoneHandle(cls.raw()));
Vyacheslav Egorov (Google) 2014/08/13 11:40:28 I think you should move IsKnownPrivateClass into t
Florian Schneider 2014/08/13 12:08:58 Done.
58 }
59 return result;
39 } 60 }
40 61
41 62
42 // Returns true if the given array of cids contains the given cid. 63 bool CHA::HasSubclasses(intptr_t cid) {
43 static bool ContainsCid(ZoneGrowableArray<intptr_t>* cids, intptr_t cid) { 64 const ClassTable& class_table = *isolate_->class_table();
44 for (intptr_t i = 0; i < cids->length(); i++) { 65 Class& cls = Class::Handle(isolate_, class_table.At(cid));
45 if ((*cids)[i] == cid) { 66 return HasSubclasses(cls);
46 return true;
47 }
48 }
49 return false;
50 } 67 }
51 68
52 69
53 // Recursively collect direct and indirect subclass ids of cls. 70 bool CHA::IsImplemented(const Class& cls) {
54 static void CollectSubclassIds(ZoneGrowableArray<intptr_t>* cids, 71 // Can't track dependencies for classes on the VM heap since those are
55 const Class& cls) { 72 // read-only.
56 const GrowableObjectArray& cls_direct_subclasses = 73 // TODO(fschneider): Enable tracking of CHA dependent code for VM heap
57 GrowableObjectArray::Handle(cls.direct_subclasses()); 74 // classes.
58 if (cls_direct_subclasses.IsNull()) { 75 if (cls.InVMHeap()) return true;
59 return; 76
77 bool result = cls.is_implemented();
78 if (!result && !IsKnownPrivateClass(cls)) {
79 AddToCHAClasses(&Class::ZoneHandle(cls.raw()));
60 } 80 }
61 Class& direct_subclass = Class::Handle(); 81 return result;
62 for (intptr_t i = 0; i < cls_direct_subclasses.Length(); i++) {
63 direct_subclass ^= cls_direct_subclasses.At(i);
64 intptr_t direct_subclass_id = direct_subclass.id();
65 if (!ContainsCid(cids, direct_subclass_id)) {
66 cids->Add(direct_subclass_id);
67 CollectSubclassIds(cids, direct_subclass);
68 }
69 }
70 }
71
72
73 ZoneGrowableArray<intptr_t>* CHA::GetSubclassIdsOf(intptr_t cid) {
74 ASSERT(cid > kInstanceCid);
75 Isolate* isolate = Isolate::Current();
76 const ClassTable& class_table = *isolate->class_table();
77 const Class& cls = Class::Handle(isolate, class_table.At(cid));
78 ASSERT(!cls.IsNull());
79 ZoneGrowableArray<intptr_t>* ids = new ZoneGrowableArray<intptr_t>();
80 CollectSubclassIds(ids, cls);
81 isolate->set_cha_used(true);
82 return ids;
83 } 82 }
84 83
85 84
86 bool CHA::HasOverride(const Class& cls, const String& function_name) { 85 bool CHA::HasOverride(const Class& cls, const String& function_name) {
87 Isolate* isolate = Isolate::Current();
88 const GrowableObjectArray& cls_direct_subclasses = 86 const GrowableObjectArray& cls_direct_subclasses =
89 GrowableObjectArray::Handle(isolate, cls.direct_subclasses()); 87 GrowableObjectArray::Handle(isolate_, cls.direct_subclasses());
90 // Subclasses of Object are not tracked by CHA. Safely assume that overrides 88 // Subclasses of Object are not tracked by CHA. Safely assume that overrides
91 // exist. 89 // exist.
92 if (cls.IsObjectClass()) { 90 if (cls.IsObjectClass()) {
93 return true; 91 return true;
94 } 92 }
95 93
94 bool is_known_private_class = IsKnownPrivateClass(cls);
96 if (cls_direct_subclasses.IsNull()) { 95 if (cls_direct_subclasses.IsNull()) {
97 isolate->set_cha_used(true); 96 if (!is_known_private_class) {
97 AddToCHAClasses(&Class::ZoneHandle(cls.raw()));
98 }
98 return false; 99 return false;
99 } 100 }
100 Class& direct_subclass = Class::Handle(isolate); 101 Class& direct_subclass = Class::Handle(isolate_);
101 for (intptr_t i = 0; i < cls_direct_subclasses.Length(); i++) { 102 for (intptr_t i = 0; i < cls_direct_subclasses.Length(); i++) {
102 direct_subclass ^= cls_direct_subclasses.At(i); 103 direct_subclass ^= cls_direct_subclasses.At(i);
103 // Unfinalized classes are treated as non-existent for CHA purposes, 104 // Unfinalized classes are treated as non-existent for CHA purposes,
104 // as that means that no instance of that class exists at runtime. 105 // as that means that no instance of that class exists at runtime.
105 if (direct_subclass.is_finalized() && 106 if (direct_subclass.is_finalized() &&
106 (direct_subclass.LookupDynamicFunction(function_name) != 107 (direct_subclass.LookupDynamicFunction(function_name) !=
107 Function::null())) { 108 Function::null())) {
108 return true; 109 return true;
109 } 110 }
110 if (HasOverride(direct_subclass, function_name)) { 111 if (HasOverride(direct_subclass, function_name)) {
111 return true; 112 return true;
112 } 113 }
113 } 114 }
114 isolate->set_cha_used(true); 115 if (!is_known_private_class) {
116 AddToCHAClasses(&Class::ZoneHandle(cls.raw()));
117 }
115 return false; 118 return false;
116 } 119 }
117 120
118
119 ZoneGrowableArray<Function*>* CHA::GetNamedInstanceFunctionsOf(
120 const ZoneGrowableArray<intptr_t>& cids,
121 const String& function_name) {
122 Isolate* isolate = Isolate::Current();
123 ASSERT(!function_name.IsNull());
124 const ClassTable& class_table = *isolate->class_table();
125 ZoneGrowableArray<Function*>* functions = new ZoneGrowableArray<Function*>();
126 Class& cls = Class::Handle(isolate);
127 Function& cls_function = Function::Handle(isolate);
128 for (intptr_t i = 0; i < cids.length(); i++) {
129 const intptr_t cid = cids[i];
130 ASSERT(cid > kInstanceCid);
131 cls = class_table.At(cid);
132 cls_function = cls.LookupDynamicFunction(function_name);
133 if (!cls_function.IsNull()) {
134 functions->Add(&Function::ZoneHandle(isolate, cls_function.raw()));
135 }
136 }
137 isolate->set_cha_used(true);
138 return functions;
139 }
140
141
142 ZoneGrowableArray<Function*>* CHA::GetOverridesOf(const Function& function) {
143 ASSERT(!function.IsNull());
144 ASSERT(function.IsDynamicFunction());
145 Isolate* isolate = Isolate::Current();
146 const Class& function_owner = Class::Handle(isolate, function.Owner());
147 const String& function_name = String::Handle(isolate, function.name());
148 ZoneGrowableArray<intptr_t>* cids = new ZoneGrowableArray<intptr_t>();
149 CollectSubclassIds(cids, function_owner);
150 isolate->set_cha_used(true);
151 return GetNamedInstanceFunctionsOf(*cids, function_name);
152 }
153
154 } // namespace dart 121 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/cha.h ('k') | runtime/vm/cha_test.cc » ('j') | runtime/vm/class_finalizer.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698