| 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 | 
|---|