OLD | NEW |
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 bool CHA::HasSubclasses(intptr_t cid) { |
| 16 Isolate* isolate = Isolate::Current(); |
| 17 const bool has_subclasses = HasSubclassesSafe(cid); |
| 18 if (!has_subclasses) { |
| 19 isolate->set_cha_used(true); |
| 20 } |
| 21 return has_subclasses; |
| 22 } |
| 23 |
| 24 |
| 25 bool CHA::HasSubclassesSafe(intptr_t cid) { |
16 ASSERT(cid >= kInstanceCid); | 26 ASSERT(cid >= kInstanceCid); |
17 const ClassTable& class_table = *Isolate::Current()->class_table(); | 27 Isolate* isolate = Isolate::Current(); |
18 const Class& cls = Class::Handle(class_table.At(cid)); | 28 const ClassTable& class_table = *isolate->class_table(); |
| 29 const Class& cls = Class::Handle(isolate, class_table.At(cid)); |
19 ASSERT(!cls.IsNull()); | 30 ASSERT(!cls.IsNull()); |
20 if (cls.IsObjectClass()) { | 31 if (cls.IsObjectClass()) { |
21 // Class Object has subclasses, although we do not keep track of them. | 32 // Class Object has subclasses, although we do not keep track of them. |
22 return true; | 33 return true; |
23 } | 34 } |
24 const GrowableObjectArray& cls_direct_subclasses = | 35 const GrowableObjectArray& cls_direct_subclasses = |
25 GrowableObjectArray::Handle(cls.direct_subclasses()); | 36 GrowableObjectArray::Handle(isolate, cls.direct_subclasses()); |
26 return | 37 return |
27 !cls_direct_subclasses.IsNull() && (cls_direct_subclasses.Length() > 0); | 38 !cls_direct_subclasses.IsNull() && (cls_direct_subclasses.Length() > 0); |
28 } | 39 } |
29 | 40 |
30 | 41 |
31 // Returns true if the given array of cids contains the given cid. | 42 // Returns true if the given array of cids contains the given cid. |
32 static bool ContainsCid(ZoneGrowableArray<intptr_t>* cids, intptr_t cid) { | 43 static bool ContainsCid(ZoneGrowableArray<intptr_t>* cids, intptr_t cid) { |
33 for (intptr_t i = 0; i < cids->length(); i++) { | 44 for (intptr_t i = 0; i < cids->length(); i++) { |
34 if ((*cids)[i] == cid) { | 45 if ((*cids)[i] == cid) { |
35 return true; | 46 return true; |
(...skipping 18 matching lines...) Expand all Loading... |
54 if (!ContainsCid(cids, direct_subclass_id)) { | 65 if (!ContainsCid(cids, direct_subclass_id)) { |
55 cids->Add(direct_subclass_id); | 66 cids->Add(direct_subclass_id); |
56 CollectSubclassIds(cids, direct_subclass); | 67 CollectSubclassIds(cids, direct_subclass); |
57 } | 68 } |
58 } | 69 } |
59 } | 70 } |
60 | 71 |
61 | 72 |
62 ZoneGrowableArray<intptr_t>* CHA::GetSubclassIdsOf(intptr_t cid) { | 73 ZoneGrowableArray<intptr_t>* CHA::GetSubclassIdsOf(intptr_t cid) { |
63 ASSERT(cid > kInstanceCid); | 74 ASSERT(cid > kInstanceCid); |
64 const ClassTable& class_table = *Isolate::Current()->class_table(); | 75 Isolate* isolate = Isolate::Current(); |
65 const Class& cls = Class::Handle(class_table.At(cid)); | 76 const ClassTable& class_table = *isolate->class_table(); |
| 77 const Class& cls = Class::Handle(isolate, class_table.At(cid)); |
66 ASSERT(!cls.IsNull()); | 78 ASSERT(!cls.IsNull()); |
67 ZoneGrowableArray<intptr_t>* ids = new ZoneGrowableArray<intptr_t>(); | 79 ZoneGrowableArray<intptr_t>* ids = new ZoneGrowableArray<intptr_t>(); |
68 CollectSubclassIds(ids, cls); | 80 CollectSubclassIds(ids, cls); |
| 81 isolate->set_cha_used(true); |
69 return ids; | 82 return ids; |
70 } | 83 } |
71 | 84 |
72 | 85 |
73 bool CHA::HasOverride(const Class& cls, const String& function_name) { | 86 bool CHA::HasOverride(const Class& cls, const String& function_name) { |
| 87 Isolate* isolate = Isolate::Current(); |
74 const GrowableObjectArray& cls_direct_subclasses = | 88 const GrowableObjectArray& cls_direct_subclasses = |
75 GrowableObjectArray::Handle(cls.direct_subclasses()); | 89 GrowableObjectArray::Handle(isolate, cls.direct_subclasses()); |
76 // Subclasses of Object are not tracked by CHA. Safely assume that overrides | 90 // Subclasses of Object are not tracked by CHA. Safely assume that overrides |
77 // exist. | 91 // exist. |
78 if (cls.IsObjectClass()) return true; | 92 if (cls.IsObjectClass()) { |
| 93 return true; |
| 94 } |
79 | 95 |
80 if (cls_direct_subclasses.IsNull()) { | 96 if (cls_direct_subclasses.IsNull()) { |
| 97 isolate->set_cha_used(true); |
81 return false; | 98 return false; |
82 } | 99 } |
83 Class& direct_subclass = Class::Handle(); | 100 Class& direct_subclass = Class::Handle(isolate); |
84 for (intptr_t i = 0; i < cls_direct_subclasses.Length(); i++) { | 101 for (intptr_t i = 0; i < cls_direct_subclasses.Length(); i++) { |
85 direct_subclass ^= cls_direct_subclasses.At(i); | 102 direct_subclass ^= cls_direct_subclasses.At(i); |
86 // Unfinalized classes are treated as non-existent for CHA purposes, | 103 // Unfinalized classes are treated as non-existent for CHA purposes, |
87 // as that means that no instance of that class exists at runtime. | 104 // as that means that no instance of that class exists at runtime. |
88 if (direct_subclass.is_finalized() && | 105 if (direct_subclass.is_finalized() && |
89 (direct_subclass.LookupDynamicFunction(function_name) != | 106 (direct_subclass.LookupDynamicFunction(function_name) != |
90 Function::null())) { | 107 Function::null())) { |
91 return true; | 108 return true; |
92 } | 109 } |
93 if (HasOverride(direct_subclass, function_name)) { | 110 if (HasOverride(direct_subclass, function_name)) { |
94 return true; | 111 return true; |
95 } | 112 } |
96 } | 113 } |
| 114 isolate->set_cha_used(true); |
97 return false; | 115 return false; |
98 } | 116 } |
99 | 117 |
100 | 118 |
101 ZoneGrowableArray<Function*>* CHA::GetNamedInstanceFunctionsOf( | 119 ZoneGrowableArray<Function*>* CHA::GetNamedInstanceFunctionsOf( |
102 const ZoneGrowableArray<intptr_t>& cids, | 120 const ZoneGrowableArray<intptr_t>& cids, |
103 const String& function_name) { | 121 const String& function_name) { |
| 122 Isolate* isolate = Isolate::Current(); |
104 ASSERT(!function_name.IsNull()); | 123 ASSERT(!function_name.IsNull()); |
105 const ClassTable& class_table = *Isolate::Current()->class_table(); | 124 const ClassTable& class_table = *isolate->class_table(); |
106 ZoneGrowableArray<Function*>* functions = new ZoneGrowableArray<Function*>(); | 125 ZoneGrowableArray<Function*>* functions = new ZoneGrowableArray<Function*>(); |
107 Class& cls = Class::Handle(); | 126 Class& cls = Class::Handle(isolate); |
108 Function& cls_function = Function::Handle(); | 127 Function& cls_function = Function::Handle(isolate); |
109 for (intptr_t i = 0; i < cids.length(); i++) { | 128 for (intptr_t i = 0; i < cids.length(); i++) { |
110 const intptr_t cid = cids[i]; | 129 const intptr_t cid = cids[i]; |
111 ASSERT(cid > kInstanceCid); | 130 ASSERT(cid > kInstanceCid); |
112 cls = class_table.At(cid); | 131 cls = class_table.At(cid); |
113 cls_function = cls.LookupDynamicFunction(function_name); | 132 cls_function = cls.LookupDynamicFunction(function_name); |
114 if (!cls_function.IsNull()) { | 133 if (!cls_function.IsNull()) { |
115 functions->Add(&Function::ZoneHandle(cls_function.raw())); | 134 functions->Add(&Function::ZoneHandle(isolate, cls_function.raw())); |
116 } | 135 } |
117 } | 136 } |
| 137 isolate->set_cha_used(true); |
118 return functions; | 138 return functions; |
119 } | 139 } |
120 | 140 |
121 | 141 |
122 ZoneGrowableArray<Function*>* CHA::GetOverridesOf(const Function& function) { | 142 ZoneGrowableArray<Function*>* CHA::GetOverridesOf(const Function& function) { |
123 ASSERT(!function.IsNull()); | 143 ASSERT(!function.IsNull()); |
124 ASSERT(function.IsDynamicFunction()); | 144 ASSERT(function.IsDynamicFunction()); |
125 const Class& function_owner = Class::Handle(function.Owner()); | 145 Isolate* isolate = Isolate::Current(); |
126 const String& function_name = String::Handle(function.name()); | 146 const Class& function_owner = Class::Handle(isolate, function.Owner()); |
| 147 const String& function_name = String::Handle(isolate, function.name()); |
127 ZoneGrowableArray<intptr_t>* cids = new ZoneGrowableArray<intptr_t>(); | 148 ZoneGrowableArray<intptr_t>* cids = new ZoneGrowableArray<intptr_t>(); |
128 CollectSubclassIds(cids, function_owner); | 149 CollectSubclassIds(cids, function_owner); |
| 150 isolate->set_cha_used(true); |
129 return GetNamedInstanceFunctionsOf(*cids, function_name); | 151 return GetNamedInstanceFunctionsOf(*cids, function_name); |
130 } | 152 } |
131 | 153 |
132 } // namespace dart | 154 } // namespace dart |
OLD | NEW |