OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/class_finalizer.h" | 5 #include "vm/class_finalizer.h" |
6 | 6 |
7 #include "vm/code_generator.h" | 7 #include "vm/code_generator.h" |
8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
9 #include "vm/heap.h" | 9 #include "vm/heap.h" |
10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
86 if (!super_type.IsMalformed() && super_type.HasResolvedTypeClass()) { | 86 if (!super_type.IsMalformed() && super_type.HasResolvedTypeClass()) { |
87 cls ^= super_type.type_class(); | 87 cls ^= super_type.type_class(); |
88 if (cls.is_finalized()) { | 88 if (cls.is_finalized()) { |
89 AddSuperType(super_type, finalized_super_classes); | 89 AddSuperType(super_type, finalized_super_classes); |
90 } | 90 } |
91 } | 91 } |
92 } | 92 } |
93 } | 93 } |
94 | 94 |
95 | 95 |
96 static void CollectImmediateSuperInterfaces( | |
97 const Class& cls, GrowableArray<intptr_t>* cids) { | |
98 const Array& interfaces = Array::Handle(cls.interfaces()); | |
99 Class& ifc = Class::Handle(); | |
100 AbstractType& type = AbstractType::Handle(); | |
101 for (intptr_t i = 0; i < interfaces.Length(); ++i) { | |
102 type ^= interfaces.At(i); | |
103 ifc ^= type.type_class(); | |
Vyacheslav Egorov (Google)
2014/08/13 11:40:28
I wonder if you need to skip Malformed types here?
Florian Schneider
2014/08/13 12:08:58
Done.
| |
104 for (intptr_t j = 0; j < cids->length(); ++j) { | |
105 if ((*cids)[j] == ifc.id()) { | |
106 // Already added. | |
107 return; | |
108 } | |
109 } | |
110 cids->Add(ifc.id()); | |
111 } | |
112 } | |
113 | |
114 | |
96 // Processing ObjectStore::pending_classes_ occurs: | 115 // Processing ObjectStore::pending_classes_ occurs: |
97 // a) when bootstrap process completes (VerifyBootstrapClasses). | 116 // a) when bootstrap process completes (VerifyBootstrapClasses). |
98 // b) after the user classes are loaded (dart_api). | 117 // b) after the user classes are loaded (dart_api). |
99 bool ClassFinalizer::ProcessPendingClasses() { | 118 bool ClassFinalizer::ProcessPendingClasses() { |
100 Isolate* isolate = Isolate::Current(); | 119 Isolate* isolate = Isolate::Current(); |
101 ASSERT(isolate != NULL); | 120 ASSERT(isolate != NULL); |
102 HANDLESCOPE(isolate); | 121 HANDLESCOPE(isolate); |
103 ObjectStore* object_store = isolate->object_store(); | 122 ObjectStore* object_store = isolate->object_store(); |
104 const Error& error = Error::Handle(isolate, object_store->sticky_error()); | 123 const Error& error = Error::Handle(isolate, object_store->sticky_error()); |
105 if (!error.IsNull()) { | 124 if (!error.IsNull()) { |
(...skipping 2174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2280 } | 2299 } |
2281 if (FLAG_trace_class_finalization) { | 2300 if (FLAG_trace_class_finalization) { |
2282 OS::Print("Finalize %s\n", cls.ToCString()); | 2301 OS::Print("Finalize %s\n", cls.ToCString()); |
2283 } | 2302 } |
2284 if (cls.IsMixinApplication()) { | 2303 if (cls.IsMixinApplication()) { |
2285 // Copy instance methods and fields from the mixin class. | 2304 // Copy instance methods and fields from the mixin class. |
2286 // This has to happen before the check whether the methods of | 2305 // This has to happen before the check whether the methods of |
2287 // the class conflict with inherited methods. | 2306 // the class conflict with inherited methods. |
2288 ApplyMixinMembers(cls); | 2307 ApplyMixinMembers(cls); |
2289 } | 2308 } |
2290 GrowableArray<intptr_t> added_subclass_to_cids; | |
2291 CollectFinalizedSuperClasses(cls, &added_subclass_to_cids); | |
2292 // Ensure super class is finalized. | 2309 // Ensure super class is finalized. |
2293 const Class& super = Class::Handle(cls.SuperClass()); | 2310 const Class& super = Class::Handle(cls.SuperClass()); |
2294 if (!super.IsNull()) { | 2311 if (!super.IsNull()) { |
2295 FinalizeClass(super); | 2312 FinalizeClass(super); |
2296 } | 2313 } |
2297 // Mark as parsed and finalized. | 2314 // Mark as parsed and finalized. |
2298 cls.Finalize(); | 2315 cls.Finalize(); |
2299 // Mixin app alias classes may still lack their forwarding constructor. | 2316 // Mixin app alias classes may still lack their forwarding constructor. |
2300 if (cls.is_mixin_app_alias() && | 2317 if (cls.is_mixin_app_alias() && |
2301 (cls.functions() == Object::empty_array().raw())) { | 2318 (cls.functions() == Object::empty_array().raw())) { |
2302 const GrowableObjectArray& cloned_funcs = | 2319 const GrowableObjectArray& cloned_funcs = |
2303 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 2320 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
2304 CreateForwardingConstructors(cls, cloned_funcs); | 2321 CreateForwardingConstructors(cls, cloned_funcs); |
2305 const Array& functions = Array::Handle(Array::MakeArray(cloned_funcs)); | 2322 const Array& functions = Array::Handle(Array::MakeArray(cloned_funcs)); |
2306 cls.SetFunctions(functions); | 2323 cls.SetFunctions(functions); |
2307 } | 2324 } |
2308 // Every class should have at least a constructor, unless it is a top level | 2325 // Every class should have at least a constructor, unless it is a top level |
2309 // class or a signature class. | 2326 // class or a signature class. |
2310 ASSERT(cls.IsTopLevel() || | 2327 ASSERT(cls.IsTopLevel() || |
2311 cls.IsSignatureClass() || | 2328 cls.IsSignatureClass() || |
2312 (Array::Handle(cls.functions()).Length() > 0)); | 2329 (Array::Handle(cls.functions()).Length() > 0)); |
2313 // Resolve and finalize all member types. | 2330 // Resolve and finalize all member types. |
2314 ResolveAndFinalizeMemberTypes(cls); | 2331 ResolveAndFinalizeMemberTypes(cls); |
2315 // Run additional checks after all types are finalized. | 2332 // Run additional checks after all types are finalized. |
2316 if (cls.is_const()) { | 2333 if (cls.is_const()) { |
2317 CheckForLegalConstClass(cls); | 2334 CheckForLegalConstClass(cls); |
2318 } | 2335 } |
2319 if (FLAG_use_cha) { | 2336 if (FLAG_use_cha) { |
2320 RemoveCHAOptimizedCode(added_subclass_to_cids); | 2337 GrowableArray<intptr_t> cids; |
2338 CollectFinalizedSuperClasses(cls, &cids); | |
2339 CollectImmediateSuperInterfaces(cls, &cids); | |
2340 RemoveCHAOptimizedCode(cids); | |
2321 } | 2341 } |
2322 } | 2342 } |
2323 | 2343 |
2324 | 2344 |
2325 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { | 2345 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { |
2326 Class& test1 = Class::Handle(cls.raw()); | 2346 Class& test1 = Class::Handle(cls.raw()); |
2327 Class& test2 = Class::Handle(cls.SuperClass()); | 2347 Class& test2 = Class::Handle(cls.SuperClass()); |
2328 // A finalized class has been checked for cycles. | 2348 // A finalized class has been checked for cycles. |
2329 // Using the hare and tortoise algorithm for locating cycles. | 2349 // Using the hare and tortoise algorithm for locating cycles. |
2330 while (!test1.is_type_finalized() && | 2350 while (!test1.is_type_finalized() && |
(...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3056 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); | 3076 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); |
3057 field ^= fields_array.At(0); | 3077 field ^= fields_array.At(0); |
3058 ASSERT(field.Offset() == ByteBuffer::data_offset()); | 3078 ASSERT(field.Offset() == ByteBuffer::data_offset()); |
3059 name ^= field.name(); | 3079 name ^= field.name(); |
3060 expected_name ^= String::New("_data"); | 3080 expected_name ^= String::New("_data"); |
3061 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3081 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
3062 #endif | 3082 #endif |
3063 } | 3083 } |
3064 | 3084 |
3065 } // namespace dart | 3085 } // namespace dart |
OLD | NEW |