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/flags.h" | 7 #include "vm/flags.h" |
8 #include "vm/hash_table.h" | 8 #include "vm/hash_table.h" |
9 #include "vm/heap.h" | 9 #include "vm/heap.h" |
10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
11 #include "vm/log.h" | 11 #include "vm/log.h" |
12 #include "vm/longjump.h" | 12 #include "vm/longjump.h" |
13 #include "vm/object_store.h" | 13 #include "vm/object_store.h" |
14 #include "vm/program_visitor.h" | 14 #include "vm/program_visitor.h" |
15 #include "vm/runtime_entry.h" | 15 #include "vm/runtime_entry.h" |
16 #include "vm/symbols.h" | 16 #include "vm/symbols.h" |
17 #include "vm/timeline.h" | 17 #include "vm/timeline.h" |
18 #include "vm/type_table.h" | 18 #include "vm/type_table.h" |
19 | 19 |
20 namespace dart { | 20 namespace dart { |
21 | 21 |
22 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); | 22 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); |
23 DEFINE_FLAG(bool, reify, true, "Reify type arguments of generic types."); | 23 DEFINE_FLAG(bool, reify, true, "Reify type arguments of generic types."); |
24 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); | 24 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); |
25 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization."); | 25 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization."); |
26 | 26 |
27 | |
28 bool ClassFinalizer::AllClassesFinalized() { | 27 bool ClassFinalizer::AllClassesFinalized() { |
29 ObjectStore* object_store = Isolate::Current()->object_store(); | 28 ObjectStore* object_store = Isolate::Current()->object_store(); |
30 const GrowableObjectArray& classes = | 29 const GrowableObjectArray& classes = |
31 GrowableObjectArray::Handle(object_store->pending_classes()); | 30 GrowableObjectArray::Handle(object_store->pending_classes()); |
32 return classes.Length() == 0; | 31 return classes.Length() == 0; |
33 } | 32 } |
34 | 33 |
35 | |
36 // Removes optimized code once we load more classes, since CHA based | 34 // Removes optimized code once we load more classes, since CHA based |
37 // optimizations may have become invalid. | 35 // optimizations may have become invalid. |
38 // Only methods which owner classes where subclasses can be invalid. | 36 // Only methods which owner classes where subclasses can be invalid. |
39 // TODO(srdjan): Be even more precise by recording the exact CHA optimization. | 37 // TODO(srdjan): Be even more precise by recording the exact CHA optimization. |
40 static void RemoveCHAOptimizedCode( | 38 static void RemoveCHAOptimizedCode( |
41 const Class& subclass, | 39 const Class& subclass, |
42 const GrowableArray<intptr_t>& added_subclass_to_cids) { | 40 const GrowableArray<intptr_t>& added_subclass_to_cids) { |
43 ASSERT(FLAG_use_cha_deopt); | 41 ASSERT(FLAG_use_cha_deopt); |
44 if (added_subclass_to_cids.is_empty()) { | 42 if (added_subclass_to_cids.is_empty()) { |
45 return; | 43 return; |
46 } | 44 } |
47 // Switch all functions' code to unoptimized. | 45 // Switch all functions' code to unoptimized. |
48 const ClassTable& class_table = *Isolate::Current()->class_table(); | 46 const ClassTable& class_table = *Isolate::Current()->class_table(); |
49 Class& cls = Class::Handle(); | 47 Class& cls = Class::Handle(); |
50 for (intptr_t i = 0; i < added_subclass_to_cids.length(); i++) { | 48 for (intptr_t i = 0; i < added_subclass_to_cids.length(); i++) { |
51 intptr_t cid = added_subclass_to_cids[i]; | 49 intptr_t cid = added_subclass_to_cids[i]; |
52 cls = class_table.At(cid); | 50 cls = class_table.At(cid); |
53 ASSERT(!cls.IsNull()); | 51 ASSERT(!cls.IsNull()); |
54 cls.DisableCHAOptimizedCode(subclass); | 52 cls.DisableCHAOptimizedCode(subclass); |
55 } | 53 } |
56 } | 54 } |
57 | 55 |
58 | |
59 void AddSuperType(const AbstractType& type, | 56 void AddSuperType(const AbstractType& type, |
60 GrowableArray<intptr_t>* finalized_super_classes) { | 57 GrowableArray<intptr_t>* finalized_super_classes) { |
61 ASSERT(type.HasResolvedTypeClass()); | 58 ASSERT(type.HasResolvedTypeClass()); |
62 ASSERT(!type.IsDynamicType()); | 59 ASSERT(!type.IsDynamicType()); |
63 if (type.IsObjectType()) { | 60 if (type.IsObjectType()) { |
64 return; | 61 return; |
65 } | 62 } |
66 const Class& cls = Class::Handle(type.type_class()); | 63 const Class& cls = Class::Handle(type.type_class()); |
67 ASSERT(cls.is_finalized()); | 64 ASSERT(cls.is_finalized()); |
68 const intptr_t cid = cls.id(); | 65 const intptr_t cid = cls.id(); |
69 for (intptr_t i = 0; i < finalized_super_classes->length(); i++) { | 66 for (intptr_t i = 0; i < finalized_super_classes->length(); i++) { |
70 if ((*finalized_super_classes)[i] == cid) { | 67 if ((*finalized_super_classes)[i] == cid) { |
71 // Already added. | 68 // Already added. |
72 return; | 69 return; |
73 } | 70 } |
74 } | 71 } |
75 finalized_super_classes->Add(cid); | 72 finalized_super_classes->Add(cid); |
76 const AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 73 const AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
77 AddSuperType(super_type, finalized_super_classes); | 74 AddSuperType(super_type, finalized_super_classes); |
78 } | 75 } |
79 | 76 |
80 | |
81 // Use array instead of set since we expect very few subclassed classes | 77 // Use array instead of set since we expect very few subclassed classes |
82 // to occur. | 78 // to occur. |
83 static void CollectFinalizedSuperClasses( | 79 static void CollectFinalizedSuperClasses( |
84 const Class& cls_, | 80 const Class& cls_, |
85 GrowableArray<intptr_t>* finalized_super_classes) { | 81 GrowableArray<intptr_t>* finalized_super_classes) { |
86 Class& cls = Class::Handle(cls_.raw()); | 82 Class& cls = Class::Handle(cls_.raw()); |
87 AbstractType& super_type = Type::Handle(); | 83 AbstractType& super_type = Type::Handle(); |
88 super_type = cls.super_type(); | 84 super_type = cls.super_type(); |
89 if (!super_type.IsNull()) { | 85 if (!super_type.IsNull()) { |
90 if (!super_type.IsMalformed() && super_type.HasResolvedTypeClass()) { | 86 if (!super_type.IsMalformed() && super_type.HasResolvedTypeClass()) { |
91 cls ^= super_type.type_class(); | 87 cls ^= super_type.type_class(); |
92 if (cls.is_finalized()) { | 88 if (cls.is_finalized()) { |
93 AddSuperType(super_type, finalized_super_classes); | 89 AddSuperType(super_type, finalized_super_classes); |
94 } | 90 } |
95 } | 91 } |
96 } | 92 } |
97 } | 93 } |
98 | 94 |
99 | |
100 static void CollectImmediateSuperInterfaces(const Class& cls, | 95 static void CollectImmediateSuperInterfaces(const Class& cls, |
101 GrowableArray<intptr_t>* cids) { | 96 GrowableArray<intptr_t>* cids) { |
102 const Array& interfaces = Array::Handle(cls.interfaces()); | 97 const Array& interfaces = Array::Handle(cls.interfaces()); |
103 Class& ifc = Class::Handle(); | 98 Class& ifc = Class::Handle(); |
104 AbstractType& type = AbstractType::Handle(); | 99 AbstractType& type = AbstractType::Handle(); |
105 for (intptr_t i = 0; i < interfaces.Length(); ++i) { | 100 for (intptr_t i = 0; i < interfaces.Length(); ++i) { |
106 type ^= interfaces.At(i); | 101 type ^= interfaces.At(i); |
107 if (type.IsMalformed()) continue; | 102 if (type.IsMalformed()) continue; |
108 if (!type.HasResolvedTypeClass()) continue; | 103 if (!type.HasResolvedTypeClass()) continue; |
109 ifc ^= type.type_class(); | 104 ifc ^= type.type_class(); |
110 for (intptr_t j = 0; j < cids->length(); ++j) { | 105 for (intptr_t j = 0; j < cids->length(); ++j) { |
111 if ((*cids)[j] == ifc.id()) { | 106 if ((*cids)[j] == ifc.id()) { |
112 // Already added. | 107 // Already added. |
113 return; | 108 return; |
114 } | 109 } |
115 } | 110 } |
116 cids->Add(ifc.id()); | 111 cids->Add(ifc.id()); |
117 } | 112 } |
118 } | 113 } |
119 | 114 |
120 | |
121 // Processing ObjectStore::pending_classes_ occurs: | 115 // Processing ObjectStore::pending_classes_ occurs: |
122 // a) when bootstrap process completes (VerifyBootstrapClasses). | 116 // a) when bootstrap process completes (VerifyBootstrapClasses). |
123 // b) after the user classes are loaded (dart_api). | 117 // b) after the user classes are loaded (dart_api). |
124 bool ClassFinalizer::ProcessPendingClasses(bool from_kernel) { | 118 bool ClassFinalizer::ProcessPendingClasses(bool from_kernel) { |
125 Thread* thread = Thread::Current(); | 119 Thread* thread = Thread::Current(); |
126 NOT_IN_PRODUCT(TimelineDurationScope tds(thread, Timeline::GetIsolateStream(), | 120 NOT_IN_PRODUCT(TimelineDurationScope tds(thread, Timeline::GetIsolateStream(), |
127 "ProcessPendingClasses")); | 121 "ProcessPendingClasses")); |
128 Isolate* isolate = thread->isolate(); | 122 Isolate* isolate = thread->isolate(); |
129 ASSERT(isolate != NULL); | 123 ASSERT(isolate != NULL); |
130 HANDLESCOPE(thread); | 124 HANDLESCOPE(thread); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 VerifyImplicitFieldOffsets(); // Verification after an error may fail. | 171 VerifyImplicitFieldOffsets(); // Verification after an error may fail. |
178 | 172 |
179 return true; | 173 return true; |
180 } else { | 174 } else { |
181 return false; | 175 return false; |
182 } | 176 } |
183 UNREACHABLE(); | 177 UNREACHABLE(); |
184 return true; | 178 return true; |
185 } | 179 } |
186 | 180 |
187 | |
188 // Adds all interfaces of cls into 'collected'. Duplicate entries may occur. | 181 // Adds all interfaces of cls into 'collected'. Duplicate entries may occur. |
189 // No cycles are allowed. | 182 // No cycles are allowed. |
190 void ClassFinalizer::CollectInterfaces(const Class& cls, | 183 void ClassFinalizer::CollectInterfaces(const Class& cls, |
191 GrowableArray<const Class*>* collected) { | 184 GrowableArray<const Class*>* collected) { |
192 Zone* zone = Thread::Current()->zone(); | 185 Zone* zone = Thread::Current()->zone(); |
193 const Array& interface_array = Array::Handle(zone, cls.interfaces()); | 186 const Array& interface_array = Array::Handle(zone, cls.interfaces()); |
194 AbstractType& interface = AbstractType::Handle(zone); | 187 AbstractType& interface = AbstractType::Handle(zone); |
195 Class& interface_class = Class::Handle(zone); | 188 Class& interface_class = Class::Handle(zone); |
196 for (intptr_t i = 0; i < interface_array.Length(); i++) { | 189 for (intptr_t i = 0; i < interface_array.Length(); i++) { |
197 interface ^= interface_array.At(i); | 190 interface ^= interface_array.At(i); |
198 interface_class = interface.type_class(); | 191 interface_class = interface.type_class(); |
199 collected->Add(&Class::ZoneHandle(zone, interface_class.raw())); | 192 collected->Add(&Class::ZoneHandle(zone, interface_class.raw())); |
200 CollectInterfaces(interface_class, collected); | 193 CollectInterfaces(interface_class, collected); |
201 } | 194 } |
202 } | 195 } |
203 | 196 |
204 | |
205 #if !defined(DART_PRECOMPILED_RUNTIME) | 197 #if !defined(DART_PRECOMPILED_RUNTIME) |
206 void ClassFinalizer::VerifyBootstrapClasses() { | 198 void ClassFinalizer::VerifyBootstrapClasses() { |
207 if (FLAG_trace_class_finalization) { | 199 if (FLAG_trace_class_finalization) { |
208 OS::Print("VerifyBootstrapClasses START.\n"); | 200 OS::Print("VerifyBootstrapClasses START.\n"); |
209 } | 201 } |
210 ObjectStore* object_store = Isolate::Current()->object_store(); | 202 ObjectStore* object_store = Isolate::Current()->object_store(); |
211 | 203 |
212 Class& cls = Class::Handle(); | 204 Class& cls = Class::Handle(); |
213 #if defined(DEBUG) | 205 #if defined(DEBUG) |
214 // Basic checking. | 206 // Basic checking. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 err.ToErrorCString()); | 255 err.ToErrorCString()); |
264 OS::Exit(255); | 256 OS::Exit(255); |
265 } | 257 } |
266 if (FLAG_trace_class_finalization) { | 258 if (FLAG_trace_class_finalization) { |
267 OS::Print("VerifyBootstrapClasses END.\n"); | 259 OS::Print("VerifyBootstrapClasses END.\n"); |
268 } | 260 } |
269 Isolate::Current()->heap()->Verify(); | 261 Isolate::Current()->heap()->Verify(); |
270 } | 262 } |
271 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 263 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
272 | 264 |
273 | |
274 static bool IsLoaded(const Type& type) { | 265 static bool IsLoaded(const Type& type) { |
275 if (type.HasResolvedTypeClass()) { | 266 if (type.HasResolvedTypeClass()) { |
276 return true; | 267 return true; |
277 } | 268 } |
278 const UnresolvedClass& unresolved_class = | 269 const UnresolvedClass& unresolved_class = |
279 UnresolvedClass::Handle(type.unresolved_class()); | 270 UnresolvedClass::Handle(type.unresolved_class()); |
280 const Object& prefix = | 271 const Object& prefix = |
281 Object::Handle(unresolved_class.library_or_library_prefix()); | 272 Object::Handle(unresolved_class.library_or_library_prefix()); |
282 if (prefix.IsNull()) { | 273 if (prefix.IsNull()) { |
283 return true; | 274 return true; |
284 } else if (prefix.IsLibraryPrefix()) { | 275 } else if (prefix.IsLibraryPrefix()) { |
285 return LibraryPrefix::Cast(prefix).is_loaded(); | 276 return LibraryPrefix::Cast(prefix).is_loaded(); |
286 } else { | 277 } else { |
287 return true; | 278 return true; |
288 } | 279 } |
289 } | 280 } |
290 | 281 |
291 | |
292 // Resolve unresolved_class in the library of cls, or return null. | 282 // Resolve unresolved_class in the library of cls, or return null. |
293 RawClass* ClassFinalizer::ResolveClass( | 283 RawClass* ClassFinalizer::ResolveClass( |
294 const Class& cls, | 284 const Class& cls, |
295 const UnresolvedClass& unresolved_class) { | 285 const UnresolvedClass& unresolved_class) { |
296 const String& class_name = String::Handle(unresolved_class.ident()); | 286 const String& class_name = String::Handle(unresolved_class.ident()); |
297 Library& lib = Library::Handle(); | 287 Library& lib = Library::Handle(); |
298 Class& resolved_class = Class::Handle(); | 288 Class& resolved_class = Class::Handle(); |
299 if (unresolved_class.library_or_library_prefix() == Object::null()) { | 289 if (unresolved_class.library_or_library_prefix() == Object::null()) { |
300 lib = cls.library(); | 290 lib = cls.library(); |
301 ASSERT(!lib.IsNull()); | 291 ASSERT(!lib.IsNull()); |
302 resolved_class = lib.LookupClass(class_name); | 292 resolved_class = lib.LookupClass(class_name); |
303 } else { | 293 } else { |
304 const Object& prefix = | 294 const Object& prefix = |
305 Object::Handle(unresolved_class.library_or_library_prefix()); | 295 Object::Handle(unresolved_class.library_or_library_prefix()); |
306 | 296 |
307 if (prefix.IsLibraryPrefix()) { | 297 if (prefix.IsLibraryPrefix()) { |
308 resolved_class = LibraryPrefix::Cast(prefix).LookupClass(class_name); | 298 resolved_class = LibraryPrefix::Cast(prefix).LookupClass(class_name); |
309 } else { | 299 } else { |
310 resolved_class = Library::Cast(prefix).LookupClass(class_name); | 300 resolved_class = Library::Cast(prefix).LookupClass(class_name); |
311 } | 301 } |
312 } | 302 } |
313 return resolved_class.raw(); | 303 return resolved_class.raw(); |
314 } | 304 } |
315 | 305 |
316 | |
317 void ClassFinalizer::ResolveRedirectingFactory(const Class& cls, | 306 void ClassFinalizer::ResolveRedirectingFactory(const Class& cls, |
318 const Function& factory) { | 307 const Function& factory) { |
319 const Function& target = Function::Handle(factory.RedirectionTarget()); | 308 const Function& target = Function::Handle(factory.RedirectionTarget()); |
320 if (target.IsNull()) { | 309 if (target.IsNull()) { |
321 Type& type = Type::Handle(factory.RedirectionType()); | 310 Type& type = Type::Handle(factory.RedirectionType()); |
322 if (!type.IsMalformed() && IsLoaded(type)) { | 311 if (!type.IsMalformed() && IsLoaded(type)) { |
323 const GrowableObjectArray& visited_factories = | 312 const GrowableObjectArray& visited_factories = |
324 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 313 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
325 ResolveRedirectingFactoryTarget(cls, factory, visited_factories); | 314 ResolveRedirectingFactoryTarget(cls, factory, visited_factories); |
326 } | 315 } |
327 if (factory.is_const()) { | 316 if (factory.is_const()) { |
328 type = factory.RedirectionType(); | 317 type = factory.RedirectionType(); |
329 if (type.IsMalformedOrMalbounded()) { | 318 if (type.IsMalformedOrMalbounded()) { |
330 ReportError(Error::Handle(type.error())); | 319 ReportError(Error::Handle(type.error())); |
331 } | 320 } |
332 } | 321 } |
333 } | 322 } |
334 } | 323 } |
335 | 324 |
336 | |
337 void ClassFinalizer::ResolveRedirectingFactoryTarget( | 325 void ClassFinalizer::ResolveRedirectingFactoryTarget( |
338 const Class& cls, | 326 const Class& cls, |
339 const Function& factory, | 327 const Function& factory, |
340 const GrowableObjectArray& visited_factories) { | 328 const GrowableObjectArray& visited_factories) { |
341 ASSERT(factory.IsRedirectingFactory()); | 329 ASSERT(factory.IsRedirectingFactory()); |
342 | 330 |
343 // Check for redirection cycle. | 331 // Check for redirection cycle. |
344 for (intptr_t i = 0; i < visited_factories.Length(); i++) { | 332 for (intptr_t i = 0; i < visited_factories.Length(); i++) { |
345 if (visited_factories.At(i) == factory.raw()) { | 333 if (visited_factories.At(i) == factory.raw()) { |
346 // A redirection cycle is reported as a compile-time error. | 334 // A redirection cycle is reported as a compile-time error. |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 FinalizeMalformedType(bound_error, script, target_type, | 463 FinalizeMalformedType(bound_error, script, target_type, |
476 "cannot resolve redirecting factory"); | 464 "cannot resolve redirecting factory"); |
477 target_target = Function::null(); | 465 target_target = Function::null(); |
478 } | 466 } |
479 } | 467 } |
480 } | 468 } |
481 factory.SetRedirectionType(target_type); | 469 factory.SetRedirectionType(target_type); |
482 factory.SetRedirectionTarget(target_target); | 470 factory.SetRedirectionTarget(target_target); |
483 } | 471 } |
484 | 472 |
485 | |
486 void ClassFinalizer::ResolveTypeClass(const Class& cls, const Type& type) { | 473 void ClassFinalizer::ResolveTypeClass(const Class& cls, const Type& type) { |
487 if (type.IsFinalized()) { | 474 if (type.IsFinalized()) { |
488 return; | 475 return; |
489 } | 476 } |
490 if (FLAG_trace_type_finalization) { | 477 if (FLAG_trace_type_finalization) { |
491 THR_Print("Resolve type class of '%s'\n", | 478 THR_Print("Resolve type class of '%s'\n", |
492 String::Handle(type.Name()).ToCString()); | 479 String::Handle(type.Name()).ToCString()); |
493 } | 480 } |
494 | 481 |
495 // Type parameters are always resolved in the parser in the correct | 482 // Type parameters are always resolved in the parser in the correct |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 (type.signature() != Function::null())); | 516 (type.signature() != Function::null())); |
530 | 517 |
531 // Replace FutureOr<T> type of async library with dynamic. | 518 // Replace FutureOr<T> type of async library with dynamic. |
532 if ((type_class.library() == Library::AsyncLibrary()) && | 519 if ((type_class.library() == Library::AsyncLibrary()) && |
533 (type_class.Name() == Symbols::FutureOr().raw())) { | 520 (type_class.Name() == Symbols::FutureOr().raw())) { |
534 Type::Cast(type).set_type_class(Class::Handle(Object::dynamic_class())); | 521 Type::Cast(type).set_type_class(Class::Handle(Object::dynamic_class())); |
535 type.set_arguments(Object::null_type_arguments()); | 522 type.set_arguments(Object::null_type_arguments()); |
536 } | 523 } |
537 } | 524 } |
538 | 525 |
539 | |
540 void ClassFinalizer::ResolveType(const Class& cls, const AbstractType& type) { | 526 void ClassFinalizer::ResolveType(const Class& cls, const AbstractType& type) { |
541 if (type.IsResolved()) { | 527 if (type.IsResolved()) { |
542 return; | 528 return; |
543 } | 529 } |
544 if (FLAG_trace_type_finalization) { | 530 if (FLAG_trace_type_finalization) { |
545 THR_Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString()); | 531 THR_Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString()); |
546 } | 532 } |
547 if (type.IsType()) { | 533 if (type.IsType()) { |
548 ResolveTypeClass(cls, Type::Cast(type)); | 534 ResolveTypeClass(cls, Type::Cast(type)); |
549 if (type.IsMalformed()) { | 535 if (type.IsMalformed()) { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 if (!scope_class.IsTypedefClass()) { | 592 if (!scope_class.IsTypedefClass()) { |
607 signature.set_owner(Object::Handle()); | 593 signature.set_owner(Object::Handle()); |
608 signature.set_token_pos(TokenPosition::kNoSource); | 594 signature.set_token_pos(TokenPosition::kNoSource); |
609 } | 595 } |
610 } | 596 } |
611 } | 597 } |
612 } | 598 } |
613 } | 599 } |
614 } | 600 } |
615 | 601 |
616 | |
617 void ClassFinalizer::FinalizeTypeParameters(const Class& cls, | 602 void ClassFinalizer::FinalizeTypeParameters(const Class& cls, |
618 PendingTypes* pending_types) { | 603 PendingTypes* pending_types) { |
619 if (FLAG_trace_type_finalization) { | 604 if (FLAG_trace_type_finalization) { |
620 THR_Print("Finalizing type parameters of '%s'\n", | 605 THR_Print("Finalizing type parameters of '%s'\n", |
621 String::Handle(cls.Name()).ToCString()); | 606 String::Handle(cls.Name()).ToCString()); |
622 } | 607 } |
623 if (cls.IsMixinApplication()) { | 608 if (cls.IsMixinApplication()) { |
624 // Setup the type parameters of the mixin application and finalize the | 609 // Setup the type parameters of the mixin application and finalize the |
625 // mixin type. | 610 // mixin type. |
626 ApplyMixinType(cls, pending_types); | 611 ApplyMixinType(cls, pending_types); |
627 } | 612 } |
628 // The type parameter bounds are not finalized here. | 613 // The type parameter bounds are not finalized here. |
629 const TypeArguments& type_parameters = | 614 const TypeArguments& type_parameters = |
630 TypeArguments::Handle(cls.type_parameters()); | 615 TypeArguments::Handle(cls.type_parameters()); |
631 if (!type_parameters.IsNull()) { | 616 if (!type_parameters.IsNull()) { |
632 TypeParameter& type_parameter = TypeParameter::Handle(); | 617 TypeParameter& type_parameter = TypeParameter::Handle(); |
633 const intptr_t num_types = type_parameters.Length(); | 618 const intptr_t num_types = type_parameters.Length(); |
634 for (intptr_t i = 0; i < num_types; i++) { | 619 for (intptr_t i = 0; i < num_types; i++) { |
635 type_parameter ^= type_parameters.TypeAt(i); | 620 type_parameter ^= type_parameters.TypeAt(i); |
636 type_parameter ^= | 621 type_parameter ^= |
637 FinalizeType(cls, type_parameter, kFinalize, pending_types); | 622 FinalizeType(cls, type_parameter, kFinalize, pending_types); |
638 type_parameters.SetTypeAt(i, type_parameter); | 623 type_parameters.SetTypeAt(i, type_parameter); |
639 } | 624 } |
640 } | 625 } |
641 } | 626 } |
642 | 627 |
643 | |
644 // This function reports a compilation error if the recursive 'type' T being | 628 // This function reports a compilation error if the recursive 'type' T being |
645 // finalized is a non-contractive type, i.e. if the induced type set S of P is | 629 // finalized is a non-contractive type, i.e. if the induced type set S of P is |
646 // not finite, where P is the instantiation of T with its own type parameters. | 630 // not finite, where P is the instantiation of T with its own type parameters. |
647 // The induced type set S consists of the super types of any type in S as well | 631 // The induced type set S consists of the super types of any type in S as well |
648 // as the type arguments of any parameterized type in S. | 632 // as the type arguments of any parameterized type in S. |
649 // The Dart Language Specification does not disallow the declaration and use of | 633 // The Dart Language Specification does not disallow the declaration and use of |
650 // non-contractive types (this may change). They are nevertheless disallowed | 634 // non-contractive types (this may change). They are nevertheless disallowed |
651 // as an implementation restriction in the VM since they cause divergence. | 635 // as an implementation restriction in the VM since they cause divergence. |
652 // A non-contractive type can be detected by looking at the queue of types | 636 // A non-contractive type can be detected by looking at the queue of types |
653 // pending finalization that are mutually recursive with the checked type. | 637 // pending finalization that are mutually recursive with the checked type. |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
712 instantiated_arguments, first_type_param, num_type_params)) { | 696 instantiated_arguments, first_type_param, num_type_params)) { |
713 const String& type_name = String::Handle(zone, type.Name()); | 697 const String& type_name = String::Handle(zone, type.Name()); |
714 ReportError(cls, type.token_pos(), "illegal recursive type '%s'", | 698 ReportError(cls, type.token_pos(), "illegal recursive type '%s'", |
715 type_name.ToCString()); | 699 type_name.ToCString()); |
716 } | 700 } |
717 } | 701 } |
718 } | 702 } |
719 } | 703 } |
720 } | 704 } |
721 | 705 |
722 | |
723 // Expand the type arguments of the given type and finalize its full type | 706 // Expand the type arguments of the given type and finalize its full type |
724 // argument vector. Return the number of type arguments (0 for a raw type). | 707 // argument vector. Return the number of type arguments (0 for a raw type). |
725 intptr_t ClassFinalizer::ExpandAndFinalizeTypeArguments( | 708 intptr_t ClassFinalizer::ExpandAndFinalizeTypeArguments( |
726 const Class& cls, | 709 const Class& cls, |
727 const AbstractType& type, | 710 const AbstractType& type, |
728 PendingTypes* pending_types) { | 711 PendingTypes* pending_types) { |
729 Zone* zone = Thread::Current()->zone(); | 712 Zone* zone = Thread::Current()->zone(); |
730 // The type class does not need to be finalized in order to finalize the type, | 713 // The type class does not need to be finalized in order to finalize the type, |
731 // however, it must at least be resolved (this was done as part of resolving | 714 // however, it must at least be resolved (this was done as part of resolving |
732 // the type itself, a precondition to calling FinalizeType). | 715 // the type itself, a precondition to calling FinalizeType). |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
832 } else { | 815 } else { |
833 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. | 816 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. |
834 } | 817 } |
835 } | 818 } |
836 | 819 |
837 ASSERT(full_arguments.IsNull() || | 820 ASSERT(full_arguments.IsNull() || |
838 !full_arguments.IsRaw(0, num_type_arguments)); | 821 !full_arguments.IsRaw(0, num_type_arguments)); |
839 return full_arguments.IsNull() ? 0 : full_arguments.Length(); | 822 return full_arguments.IsNull() ? 0 : full_arguments.Length(); |
840 } | 823 } |
841 | 824 |
842 | |
843 // Finalize the type argument vector 'arguments' of the type defined by the | 825 // Finalize the type argument vector 'arguments' of the type defined by the |
844 // class 'cls' parameterized with the type arguments 'cls_args'. | 826 // class 'cls' parameterized with the type arguments 'cls_args'. |
845 // The vector 'cls_args' is already initialized as a subvector at the correct | 827 // The vector 'cls_args' is already initialized as a subvector at the correct |
846 // position in the passed in 'arguments' vector. | 828 // position in the passed in 'arguments' vector. |
847 // The subvector 'cls_args' has length cls.NumTypeParameters() and starts at | 829 // The subvector 'cls_args' has length cls.NumTypeParameters() and starts at |
848 // offset cls.NumTypeArguments() - cls.NumTypeParameters() of the 'arguments' | 830 // offset cls.NumTypeArguments() - cls.NumTypeParameters() of the 'arguments' |
849 // vector. | 831 // vector. |
850 // The type argument vector of cls may overlap the type argument vector of its | 832 // The type argument vector of cls may overlap the type argument vector of its |
851 // super class. In case of an overlap, the overlapped type arguments of the | 833 // super class. In case of an overlap, the overlapped type arguments of the |
852 // super class are already initialized. The still uninitialized ones have an | 834 // super class are already initialized. The still uninitialized ones have an |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
997 } | 979 } |
998 } | 980 } |
999 } | 981 } |
1000 arguments.SetTypeAt(i, super_type_arg); | 982 arguments.SetTypeAt(i, super_type_arg); |
1001 } | 983 } |
1002 FinalizeTypeArguments(super_class, arguments, super_offset, bound_error, | 984 FinalizeTypeArguments(super_class, arguments, super_offset, bound_error, |
1003 pending_types, instantiation_trail); | 985 pending_types, instantiation_trail); |
1004 } | 986 } |
1005 } | 987 } |
1006 | 988 |
1007 | |
1008 // Check the type argument vector 'arguments' against the corresponding bounds | 989 // Check the type argument vector 'arguments' against the corresponding bounds |
1009 // of the type parameters of class 'cls' and, recursively, of its superclasses. | 990 // of the type parameters of class 'cls' and, recursively, of its superclasses. |
1010 // Replace a type argument that cannot be checked at compile time by a | 991 // Replace a type argument that cannot be checked at compile time by a |
1011 // BoundedType, thereby postponing the bound check to run time. | 992 // BoundedType, thereby postponing the bound check to run time. |
1012 // Return a bound error if a type argument is not within bound at compile time. | 993 // Return a bound error if a type argument is not within bound at compile time. |
1013 void ClassFinalizer::CheckTypeArgumentBounds(const Class& cls, | 994 void ClassFinalizer::CheckTypeArgumentBounds(const Class& cls, |
1014 const TypeArguments& arguments, | 995 const TypeArguments& arguments, |
1015 Error* bound_error) { | 996 Error* bound_error) { |
1016 if (!cls.is_type_finalized()) { | 997 if (!cls.is_type_finalized()) { |
1017 FinalizeTypeParameters(cls); | 998 FinalizeTypeParameters(cls); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1076 // bound check to run time, when the bound will be finalized. | 1057 // bound check to run time, when the bound will be finalized. |
1077 // The bound may not necessarily be 'IsBeingFinalized' yet, as is the | 1058 // The bound may not necessarily be 'IsBeingFinalized' yet, as is the |
1078 // case with a pair of type parameters of the same class referring to | 1059 // case with a pair of type parameters of the same class referring to |
1079 // each other via their bounds. | 1060 // each other via their bounds. |
1080 type_arg = BoundedType::New(type_arg, instantiated_bound, type_param); | 1061 type_arg = BoundedType::New(type_arg, instantiated_bound, type_param); |
1081 arguments.SetTypeAt(offset + i, type_arg); | 1062 arguments.SetTypeAt(offset + i, type_arg); |
1082 continue; | 1063 continue; |
1083 } | 1064 } |
1084 // Shortcut the special case where we check a type parameter against its | 1065 // Shortcut the special case where we check a type parameter against its |
1085 // declared upper bound. | 1066 // declared upper bound. |
1086 if (error.IsNull() && | 1067 if (error.IsNull() && !(type_arg.Equals(type_param) && |
1087 !(type_arg.Equals(type_param) && | 1068 instantiated_bound.Equals(declared_bound))) { |
1088 instantiated_bound.Equals(declared_bound))) { | |
1089 // If type_arg is a type parameter, its declared bound may not be | 1069 // If type_arg is a type parameter, its declared bound may not be |
1090 // finalized yet. | 1070 // finalized yet. |
1091 if (type_arg.IsTypeParameter()) { | 1071 if (type_arg.IsTypeParameter()) { |
1092 const Class& type_arg_cls = Class::Handle( | 1072 const Class& type_arg_cls = Class::Handle( |
1093 TypeParameter::Cast(type_arg).parameterized_class()); | 1073 TypeParameter::Cast(type_arg).parameterized_class()); |
1094 AbstractType& bound = | 1074 AbstractType& bound = |
1095 AbstractType::Handle(TypeParameter::Cast(type_arg).bound()); | 1075 AbstractType::Handle(TypeParameter::Cast(type_arg).bound()); |
1096 if (!bound.IsFinalized() && !bound.IsBeingFinalized()) { | 1076 if (!bound.IsFinalized() && !bound.IsBeingFinalized()) { |
1097 bound = FinalizeType(type_arg_cls, bound); | 1077 bound = FinalizeType(type_arg_cls, bound); |
1098 TypeParameter::Cast(type_arg).set_bound(bound); | 1078 TypeParameter::Cast(type_arg).set_bound(bound); |
(...skipping 14 matching lines...) Expand all Loading... |
1113 } | 1093 } |
1114 } | 1094 } |
1115 } | 1095 } |
1116 AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 1096 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
1117 if (!super_type.IsNull()) { | 1097 if (!super_type.IsNull()) { |
1118 const Class& super_class = Class::Handle(super_type.type_class()); | 1098 const Class& super_class = Class::Handle(super_type.type_class()); |
1119 CheckTypeArgumentBounds(super_class, arguments, bound_error); | 1099 CheckTypeArgumentBounds(super_class, arguments, bound_error); |
1120 } | 1100 } |
1121 } | 1101 } |
1122 | 1102 |
1123 | |
1124 void ClassFinalizer::CheckTypeBounds(const Class& cls, | 1103 void ClassFinalizer::CheckTypeBounds(const Class& cls, |
1125 const AbstractType& type) { | 1104 const AbstractType& type) { |
1126 Zone* zone = Thread::Current()->zone(); | 1105 Zone* zone = Thread::Current()->zone(); |
1127 ASSERT(type.IsType()); | 1106 ASSERT(type.IsType()); |
1128 ASSERT(type.IsFinalized()); | 1107 ASSERT(type.IsFinalized()); |
1129 ASSERT(!type.IsCanonical()); | 1108 ASSERT(!type.IsCanonical()); |
1130 TypeArguments& arguments = TypeArguments::Handle(zone, type.arguments()); | 1109 TypeArguments& arguments = TypeArguments::Handle(zone, type.arguments()); |
1131 if (arguments.IsNull()) { | 1110 if (arguments.IsNull()) { |
1132 return; | 1111 return; |
1133 } | 1112 } |
(...skipping 22 matching lines...) Expand all Loading... |
1156 bound_error.ToErrorCString()); | 1135 bound_error.ToErrorCString()); |
1157 } | 1136 } |
1158 } | 1137 } |
1159 } | 1138 } |
1160 if (FLAG_trace_type_finalization) { | 1139 if (FLAG_trace_type_finalization) { |
1161 THR_Print("Done checking bounds of type '%s': %s\n", | 1140 THR_Print("Done checking bounds of type '%s': %s\n", |
1162 String::Handle(zone, type.Name()).ToCString(), type.ToCString()); | 1141 String::Handle(zone, type.Name()).ToCString(), type.ToCString()); |
1163 } | 1142 } |
1164 } | 1143 } |
1165 | 1144 |
1166 | |
1167 RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls, | 1145 RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls, |
1168 const AbstractType& type, | 1146 const AbstractType& type, |
1169 FinalizationKind finalization, | 1147 FinalizationKind finalization, |
1170 PendingTypes* pending_types) { | 1148 PendingTypes* pending_types) { |
1171 // Only the 'root' type of the graph can be canonicalized, after all depending | 1149 // Only the 'root' type of the graph can be canonicalized, after all depending |
1172 // types have been bound checked. | 1150 // types have been bound checked. |
1173 ASSERT((pending_types == NULL) || (finalization < kCanonicalize)); | 1151 ASSERT((pending_types == NULL) || (finalization < kCanonicalize)); |
1174 if (type.IsFinalized()) { | 1152 if (type.IsFinalized()) { |
1175 // Ensure type is canonical if canonicalization is requested, unless type is | 1153 // Ensure type is canonical if canonicalization is requested, unless type is |
1176 // malformed. | 1154 // malformed. |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1342 THR_Print("Done canonicalizing type '%s'\n", | 1320 THR_Print("Done canonicalizing type '%s'\n", |
1343 String::Handle(zone, canonical_type.Name()).ToCString()); | 1321 String::Handle(zone, canonical_type.Name()).ToCString()); |
1344 return canonical_type.raw(); | 1322 return canonical_type.raw(); |
1345 } | 1323 } |
1346 return type.Canonicalize(); | 1324 return type.Canonicalize(); |
1347 } else { | 1325 } else { |
1348 return type.raw(); | 1326 return type.raw(); |
1349 } | 1327 } |
1350 } | 1328 } |
1351 | 1329 |
1352 | |
1353 void ClassFinalizer::ResolveSignature(const Class& cls, | 1330 void ClassFinalizer::ResolveSignature(const Class& cls, |
1354 const Function& function) { | 1331 const Function& function) { |
1355 AbstractType& type = AbstractType::Handle(); | 1332 AbstractType& type = AbstractType::Handle(); |
1356 // Resolve upper bounds of function type parameters. | 1333 // Resolve upper bounds of function type parameters. |
1357 const intptr_t num_type_params = function.NumTypeParameters(); | 1334 const intptr_t num_type_params = function.NumTypeParameters(); |
1358 if (num_type_params > 0) { | 1335 if (num_type_params > 0) { |
1359 TypeParameter& type_param = TypeParameter::Handle(); | 1336 TypeParameter& type_param = TypeParameter::Handle(); |
1360 const TypeArguments& type_params = | 1337 const TypeArguments& type_params = |
1361 TypeArguments::Handle(function.type_parameters()); | 1338 TypeArguments::Handle(function.type_parameters()); |
1362 for (intptr_t i = 0; i < num_type_params; i++) { | 1339 for (intptr_t i = 0; i < num_type_params; i++) { |
1363 type_param ^= type_params.TypeAt(i); | 1340 type_param ^= type_params.TypeAt(i); |
1364 type = type_param.bound(); | 1341 type = type_param.bound(); |
1365 ResolveType(cls, type); | 1342 ResolveType(cls, type); |
1366 } | 1343 } |
1367 } | 1344 } |
1368 // Resolve result type. | 1345 // Resolve result type. |
1369 type = function.result_type(); | 1346 type = function.result_type(); |
1370 // It is not a compile time error if this name does not resolve to a class or | 1347 // It is not a compile time error if this name does not resolve to a class or |
1371 // interface. | 1348 // interface. |
1372 ResolveType(cls, type); | 1349 ResolveType(cls, type); |
1373 // Resolve formal parameter types. | 1350 // Resolve formal parameter types. |
1374 const intptr_t num_parameters = function.NumParameters(); | 1351 const intptr_t num_parameters = function.NumParameters(); |
1375 for (intptr_t i = 0; i < num_parameters; i++) { | 1352 for (intptr_t i = 0; i < num_parameters; i++) { |
1376 type = function.ParameterTypeAt(i); | 1353 type = function.ParameterTypeAt(i); |
1377 ResolveType(cls, type); | 1354 ResolveType(cls, type); |
1378 } | 1355 } |
1379 } | 1356 } |
1380 | 1357 |
1381 | |
1382 void ClassFinalizer::FinalizeSignature(const Class& cls, | 1358 void ClassFinalizer::FinalizeSignature(const Class& cls, |
1383 const Function& function, | 1359 const Function& function, |
1384 FinalizationKind finalization) { | 1360 FinalizationKind finalization) { |
1385 AbstractType& type = AbstractType::Handle(); | 1361 AbstractType& type = AbstractType::Handle(); |
1386 AbstractType& finalized_type = AbstractType::Handle(); | 1362 AbstractType& finalized_type = AbstractType::Handle(); |
1387 // Finalize function type parameters and their upper bounds. | 1363 // Finalize function type parameters and their upper bounds. |
1388 const intptr_t num_parent_type_params = function.NumParentTypeParameters(); | 1364 const intptr_t num_parent_type_params = function.NumParentTypeParameters(); |
1389 const intptr_t num_type_params = function.NumTypeParameters(); | 1365 const intptr_t num_type_params = function.NumTypeParameters(); |
1390 if (num_type_params > 0) { | 1366 if (num_type_params > 0) { |
1391 TypeParameter& type_param = TypeParameter::Handle(); | 1367 TypeParameter& type_param = TypeParameter::Handle(); |
(...skipping 24 matching lines...) Expand all Loading... |
1416 for (intptr_t i = 0; i < num_parameters; i++) { | 1392 for (intptr_t i = 0; i < num_parameters; i++) { |
1417 type = function.ParameterTypeAt(i); | 1393 type = function.ParameterTypeAt(i); |
1418 finalized_type = FinalizeType(cls, type, finalization); | 1394 finalized_type = FinalizeType(cls, type, finalization); |
1419 // The parameter type may be malformed or malbounded. | 1395 // The parameter type may be malformed or malbounded. |
1420 if (type.raw() != finalized_type.raw()) { | 1396 if (type.raw() != finalized_type.raw()) { |
1421 function.SetParameterTypeAt(i, finalized_type); | 1397 function.SetParameterTypeAt(i, finalized_type); |
1422 } | 1398 } |
1423 } | 1399 } |
1424 } | 1400 } |
1425 | 1401 |
1426 | |
1427 // Check if an instance field, getter, or method of same name exists | 1402 // Check if an instance field, getter, or method of same name exists |
1428 // in any super class. | 1403 // in any super class. |
1429 static RawClass* FindSuperOwnerOfInstanceMember(const Class& cls, | 1404 static RawClass* FindSuperOwnerOfInstanceMember(const Class& cls, |
1430 const String& name, | 1405 const String& name, |
1431 const String& getter_name) { | 1406 const String& getter_name) { |
1432 Class& super_class = Class::Handle(); | 1407 Class& super_class = Class::Handle(); |
1433 Function& function = Function::Handle(); | 1408 Function& function = Function::Handle(); |
1434 Field& field = Field::Handle(); | 1409 Field& field = Field::Handle(); |
1435 super_class = cls.SuperClass(); | 1410 super_class = cls.SuperClass(); |
1436 while (!super_class.IsNull()) { | 1411 while (!super_class.IsNull()) { |
1437 function = super_class.LookupFunction(name); | 1412 function = super_class.LookupFunction(name); |
1438 if (!function.IsNull() && !function.is_static()) { | 1413 if (!function.IsNull() && !function.is_static()) { |
1439 return super_class.raw(); | 1414 return super_class.raw(); |
1440 } | 1415 } |
1441 function = super_class.LookupFunction(getter_name); | 1416 function = super_class.LookupFunction(getter_name); |
1442 if (!function.IsNull() && !function.is_static()) { | 1417 if (!function.IsNull() && !function.is_static()) { |
1443 return super_class.raw(); | 1418 return super_class.raw(); |
1444 } | 1419 } |
1445 field = super_class.LookupField(name); | 1420 field = super_class.LookupField(name); |
1446 if (!field.IsNull() && !field.is_static()) { | 1421 if (!field.IsNull() && !field.is_static()) { |
1447 return super_class.raw(); | 1422 return super_class.raw(); |
1448 } | 1423 } |
1449 super_class = super_class.SuperClass(); | 1424 super_class = super_class.SuperClass(); |
1450 } | 1425 } |
1451 return Class::null(); | 1426 return Class::null(); |
1452 } | 1427 } |
1453 | 1428 |
1454 | |
1455 // Check if an instance method of same name exists in any super class. | 1429 // Check if an instance method of same name exists in any super class. |
1456 static RawClass* FindSuperOwnerOfFunction(const Class& cls, | 1430 static RawClass* FindSuperOwnerOfFunction(const Class& cls, |
1457 const String& name) { | 1431 const String& name) { |
1458 Class& super_class = Class::Handle(); | 1432 Class& super_class = Class::Handle(); |
1459 Function& function = Function::Handle(); | 1433 Function& function = Function::Handle(); |
1460 super_class = cls.SuperClass(); | 1434 super_class = cls.SuperClass(); |
1461 while (!super_class.IsNull()) { | 1435 while (!super_class.IsNull()) { |
1462 function = super_class.LookupFunction(name); | 1436 function = super_class.LookupFunction(name); |
1463 if (!function.IsNull() && !function.is_static() && | 1437 if (!function.IsNull() && !function.is_static() && |
1464 !function.IsMethodExtractor()) { | 1438 !function.IsMethodExtractor()) { |
1465 return super_class.raw(); | 1439 return super_class.raw(); |
1466 } | 1440 } |
1467 super_class = super_class.SuperClass(); | 1441 super_class = super_class.SuperClass(); |
1468 } | 1442 } |
1469 return Class::null(); | 1443 return Class::null(); |
1470 } | 1444 } |
1471 | 1445 |
1472 | |
1473 // Resolve the upper bounds of the type parameters of class cls. | 1446 // Resolve the upper bounds of the type parameters of class cls. |
1474 void ClassFinalizer::ResolveUpperBounds(const Class& cls) { | 1447 void ClassFinalizer::ResolveUpperBounds(const Class& cls) { |
1475 const intptr_t num_type_params = cls.NumTypeParameters(); | 1448 const intptr_t num_type_params = cls.NumTypeParameters(); |
1476 TypeParameter& type_param = TypeParameter::Handle(); | 1449 TypeParameter& type_param = TypeParameter::Handle(); |
1477 AbstractType& bound = AbstractType::Handle(); | 1450 AbstractType& bound = AbstractType::Handle(); |
1478 const TypeArguments& type_params = | 1451 const TypeArguments& type_params = |
1479 TypeArguments::Handle(cls.type_parameters()); | 1452 TypeArguments::Handle(cls.type_parameters()); |
1480 ASSERT((type_params.IsNull() && (num_type_params == 0)) || | 1453 ASSERT((type_params.IsNull() && (num_type_params == 0)) || |
1481 (type_params.Length() == num_type_params)); | 1454 (type_params.Length() == num_type_params)); |
1482 // In a first pass, resolve all bounds. This guarantees that finalization | 1455 // In a first pass, resolve all bounds. This guarantees that finalization |
1483 // of mutually referencing bounds will not encounter an unresolved bound. | 1456 // of mutually referencing bounds will not encounter an unresolved bound. |
1484 for (intptr_t i = 0; i < num_type_params; i++) { | 1457 for (intptr_t i = 0; i < num_type_params; i++) { |
1485 type_param ^= type_params.TypeAt(i); | 1458 type_param ^= type_params.TypeAt(i); |
1486 bound = type_param.bound(); | 1459 bound = type_param.bound(); |
1487 ResolveType(cls, bound); | 1460 ResolveType(cls, bound); |
1488 } | 1461 } |
1489 } | 1462 } |
1490 | 1463 |
1491 | |
1492 // Finalize the upper bounds of the type parameters of class cls. | 1464 // Finalize the upper bounds of the type parameters of class cls. |
1493 void ClassFinalizer::FinalizeUpperBounds(const Class& cls, | 1465 void ClassFinalizer::FinalizeUpperBounds(const Class& cls, |
1494 FinalizationKind finalization) { | 1466 FinalizationKind finalization) { |
1495 const intptr_t num_type_params = cls.NumTypeParameters(); | 1467 const intptr_t num_type_params = cls.NumTypeParameters(); |
1496 TypeParameter& type_param = TypeParameter::Handle(); | 1468 TypeParameter& type_param = TypeParameter::Handle(); |
1497 AbstractType& bound = AbstractType::Handle(); | 1469 AbstractType& bound = AbstractType::Handle(); |
1498 const TypeArguments& type_params = | 1470 const TypeArguments& type_params = |
1499 TypeArguments::Handle(cls.type_parameters()); | 1471 TypeArguments::Handle(cls.type_parameters()); |
1500 ASSERT((type_params.IsNull() && (num_type_params == 0)) || | 1472 ASSERT((type_params.IsNull() && (num_type_params == 0)) || |
1501 (type_params.Length() == num_type_params)); | 1473 (type_params.Length() == num_type_params)); |
1502 for (intptr_t i = 0; i < num_type_params; i++) { | 1474 for (intptr_t i = 0; i < num_type_params; i++) { |
1503 type_param ^= type_params.TypeAt(i); | 1475 type_param ^= type_params.TypeAt(i); |
1504 bound = type_param.bound(); | 1476 bound = type_param.bound(); |
1505 // Bound may be finalized, but not canonical yet. | 1477 // Bound may be finalized, but not canonical yet. |
1506 if (bound.IsCanonical() || bound.IsBeingFinalized()) { | 1478 if (bound.IsCanonical() || bound.IsBeingFinalized()) { |
1507 // A bound involved in F-bounded quantification may form a cycle. | 1479 // A bound involved in F-bounded quantification may form a cycle. |
1508 continue; | 1480 continue; |
1509 } | 1481 } |
1510 bound = FinalizeType(cls, bound, finalization); | 1482 bound = FinalizeType(cls, bound, finalization); |
1511 type_param.set_bound(bound); | 1483 type_param.set_bound(bound); |
1512 } | 1484 } |
1513 } | 1485 } |
1514 | 1486 |
1515 | |
1516 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { | 1487 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { |
1517 // Note that getters and setters are explicitly listed as such in the list of | 1488 // Note that getters and setters are explicitly listed as such in the list of |
1518 // functions of a class, so we do not need to consider fields as implicitly | 1489 // functions of a class, so we do not need to consider fields as implicitly |
1519 // generating getters and setters. | 1490 // generating getters and setters. |
1520 // Most overriding conflicts are only static warnings, i.e. they are not | 1491 // Most overriding conflicts are only static warnings, i.e. they are not |
1521 // reported as compile-time errors by the vm. However, signature conflicts in | 1492 // reported as compile-time errors by the vm. However, signature conflicts in |
1522 // overrides can be reported if the flag --error_on_bad_override is specified. | 1493 // overrides can be reported if the flag --error_on_bad_override is specified. |
1523 // Static warning examples are: | 1494 // Static warning examples are: |
1524 // - a static getter 'v' conflicting with an inherited instance setter 'v='. | 1495 // - a static getter 'v' conflicting with an inherited instance setter 'v='. |
1525 // - a static setter 'v=' conflicting with an inherited instance member 'v'. | 1496 // - a static setter 'v=' conflicting with an inherited instance member 'v'. |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1765 ReportError(cls, function.token_pos(), | 1736 ReportError(cls, function.token_pos(), |
1766 "method '%s' of class '%s' conflicts with " | 1737 "method '%s' of class '%s' conflicts with " |
1767 "getter '%s' of super class '%s'", | 1738 "getter '%s' of super class '%s'", |
1768 name.ToCString(), class_name.ToCString(), name.ToCString(), | 1739 name.ToCString(), class_name.ToCString(), name.ToCString(), |
1769 super_cls_name.ToCString()); | 1740 super_cls_name.ToCString()); |
1770 } | 1741 } |
1771 } | 1742 } |
1772 } | 1743 } |
1773 } | 1744 } |
1774 | 1745 |
1775 | |
1776 // Clone the type parameters of the super class and of the mixin class of this | 1746 // Clone the type parameters of the super class and of the mixin class of this |
1777 // mixin application class and use them as the type parameters of this mixin | 1747 // mixin application class and use them as the type parameters of this mixin |
1778 // application class. Set the type arguments of the super type, of the mixin | 1748 // application class. Set the type arguments of the super type, of the mixin |
1779 // type (as well as of the interface type, which is identical to the mixin type) | 1749 // type (as well as of the interface type, which is identical to the mixin type) |
1780 // to refer to the respective type parameters of the mixin application class. | 1750 // to refer to the respective type parameters of the mixin application class. |
1781 // In other words, decorate this mixin application class with type parameters | 1751 // In other words, decorate this mixin application class with type parameters |
1782 // that forward to the super type and mixin type (and interface type). | 1752 // that forward to the super type and mixin type (and interface type). |
1783 // Example: | 1753 // Example: |
1784 // class S<T extends BT> { } | 1754 // class S<T extends BT> { } |
1785 // class M<T extends BT> { } | 1755 // class M<T extends BT> { } |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1957 } | 1927 } |
1958 // If the mixin class is a mixin application alias class, we insert a new | 1928 // If the mixin class is a mixin application alias class, we insert a new |
1959 // synthesized mixin application class in the super chain of this mixin | 1929 // synthesized mixin application class in the super chain of this mixin |
1960 // application class. The new class will have the aliased mixin as actual | 1930 // application class. The new class will have the aliased mixin as actual |
1961 // mixin. | 1931 // mixin. |
1962 if (mixin_class.is_mixin_app_alias()) { | 1932 if (mixin_class.is_mixin_app_alias()) { |
1963 ApplyMixinAppAlias(mixin_app_class, instantiator); | 1933 ApplyMixinAppAlias(mixin_app_class, instantiator); |
1964 } | 1934 } |
1965 } | 1935 } |
1966 | 1936 |
1967 | |
1968 /* Support for mixin alias. | 1937 /* Support for mixin alias. |
1969 Consider the following example: | 1938 Consider the following example: |
1970 | 1939 |
1971 class I<T> { } | 1940 class I<T> { } |
1972 class J<T> { } | 1941 class J<T> { } |
1973 class S<T extends num> { } | 1942 class S<T extends num> { } |
1974 class M<T extends Map> { } | 1943 class M<T extends Map> { } |
1975 class A<U, V extends List> = Object with M<Map<U, V>> implements I<V>; | 1944 class A<U, V extends List> = Object with M<Map<U, V>> implements I<V>; |
1976 class C<T, K extends T> = S<T> with A<T, List<K>> implements J<K>; | 1945 class C<T, K extends T> = S<T> with A<T, List<K>> implements J<K>; |
1977 | 1946 |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2227 String::Handle(inserted_class.Name()).ToCString(), | 2196 String::Handle(inserted_class.Name()).ToCString(), |
2228 TypeArguments::Handle(inserted_class.type_parameters()).ToCString(), | 2197 TypeArguments::Handle(inserted_class.type_parameters()).ToCString(), |
2229 String::Handle(zone, super_type.Name()).ToCString(), | 2198 String::Handle(zone, super_type.Name()).ToCString(), |
2230 num_super_type_params + num_aliased_mixin_type_params, | 2199 num_super_type_params + num_aliased_mixin_type_params, |
2231 super_type.ToCString(), | 2200 super_type.ToCString(), |
2232 String::Handle(mixin_app_class.Name()).ToCString(), | 2201 String::Handle(mixin_app_class.Name()).ToCString(), |
2233 TypeArguments::Handle(mixin_app_class.type_parameters()).ToCString()); | 2202 TypeArguments::Handle(mixin_app_class.type_parameters()).ToCString()); |
2234 } | 2203 } |
2235 } | 2204 } |
2236 | 2205 |
2237 | |
2238 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class, | 2206 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class, |
2239 PendingTypes* pending_types) { | 2207 PendingTypes* pending_types) { |
2240 if (mixin_app_class.is_mixin_type_applied()) { | 2208 if (mixin_app_class.is_mixin_type_applied()) { |
2241 return; | 2209 return; |
2242 } | 2210 } |
2243 Type& mixin_type = Type::Handle(mixin_app_class.mixin()); | 2211 Type& mixin_type = Type::Handle(mixin_app_class.mixin()); |
2244 ASSERT(!mixin_type.IsNull()); | 2212 ASSERT(!mixin_type.IsNull()); |
2245 ASSERT(mixin_type.HasResolvedTypeClass()); | 2213 ASSERT(mixin_type.HasResolvedTypeClass()); |
2246 const Class& mixin_class = Class::Handle(mixin_type.type_class()); | 2214 const Class& mixin_class = Class::Handle(mixin_type.type_class()); |
2247 | 2215 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2286 ASSERT(!mixin_type.IsBeingFinalized()); | 2254 ASSERT(!mixin_type.IsBeingFinalized()); |
2287 mixin_type ^= | 2255 mixin_type ^= |
2288 FinalizeType(mixin_app_class, mixin_type, kFinalize, pending_types); | 2256 FinalizeType(mixin_app_class, mixin_type, kFinalize, pending_types); |
2289 // The mixin type cannot be malbounded, since it merely substitutes the | 2257 // The mixin type cannot be malbounded, since it merely substitutes the |
2290 // type parameters of the mixin class with those of the mixin application | 2258 // type parameters of the mixin class with those of the mixin application |
2291 // class, but it does not instantiate them. | 2259 // class, but it does not instantiate them. |
2292 ASSERT(!mixin_type.IsMalbounded()); | 2260 ASSERT(!mixin_type.IsMalbounded()); |
2293 mixin_app_class.set_mixin(mixin_type); | 2261 mixin_app_class.set_mixin(mixin_type); |
2294 } | 2262 } |
2295 | 2263 |
2296 | |
2297 void ClassFinalizer::CreateForwardingConstructors( | 2264 void ClassFinalizer::CreateForwardingConstructors( |
2298 const Class& mixin_app, | 2265 const Class& mixin_app, |
2299 const Class& mixin_cls, | 2266 const Class& mixin_cls, |
2300 const GrowableObjectArray& cloned_funcs) { | 2267 const GrowableObjectArray& cloned_funcs) { |
2301 Thread* T = Thread::Current(); | 2268 Thread* T = Thread::Current(); |
2302 Zone* Z = T->zone(); | 2269 Zone* Z = T->zone(); |
2303 const String& mixin_name = String::Handle(Z, mixin_app.Name()); | 2270 const String& mixin_name = String::Handle(Z, mixin_app.Name()); |
2304 const Class& super_class = Class::Handle(Z, mixin_app.SuperClass()); | 2271 const Class& super_class = Class::Handle(Z, mixin_app.SuperClass()); |
2305 const String& super_name = String::Handle(Z, super_class.Name()); | 2272 const String& super_name = String::Handle(Z, super_class.Name()); |
2306 const Array& functions = Array::Handle(Z, super_class.functions()); | 2273 const Array& functions = Array::Handle(Z, super_class.functions()); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2349 // The parameter types of the cloned constructor are 'dynamic'. | 2316 // The parameter types of the cloned constructor are 'dynamic'. |
2350 clone.set_parameter_types(Array::Handle(Z, Array::New(num_parameters))); | 2317 clone.set_parameter_types(Array::Handle(Z, Array::New(num_parameters))); |
2351 for (intptr_t n = 0; n < num_parameters; n++) { | 2318 for (intptr_t n = 0; n < num_parameters; n++) { |
2352 clone.SetParameterTypeAt(n, Object::dynamic_type()); | 2319 clone.SetParameterTypeAt(n, Object::dynamic_type()); |
2353 } | 2320 } |
2354 cloned_funcs.Add(clone); | 2321 cloned_funcs.Add(clone); |
2355 } | 2322 } |
2356 } | 2323 } |
2357 } | 2324 } |
2358 | 2325 |
2359 | |
2360 void ClassFinalizer::ApplyMixinMembers(const Class& cls) { | 2326 void ClassFinalizer::ApplyMixinMembers(const Class& cls) { |
2361 Zone* zone = Thread::Current()->zone(); | 2327 Zone* zone = Thread::Current()->zone(); |
2362 const Type& mixin_type = Type::Handle(zone, cls.mixin()); | 2328 const Type& mixin_type = Type::Handle(zone, cls.mixin()); |
2363 ASSERT(!mixin_type.IsNull()); | 2329 ASSERT(!mixin_type.IsNull()); |
2364 ASSERT(mixin_type.HasResolvedTypeClass()); | 2330 ASSERT(mixin_type.HasResolvedTypeClass()); |
2365 const Class& mixin_cls = Class::Handle(zone, mixin_type.type_class()); | 2331 const Class& mixin_cls = Class::Handle(zone, mixin_type.type_class()); |
2366 FinalizeClass(mixin_cls); | 2332 FinalizeClass(mixin_cls); |
2367 // If the mixin is a mixin application alias class, there are no members to | 2333 // If the mixin is a mixin application alias class, there are no members to |
2368 // apply here. A new synthesized class representing the aliased mixin | 2334 // apply here. A new synthesized class representing the aliased mixin |
2369 // application class was inserted in the super chain of this mixin application | 2335 // application class was inserted in the super chain of this mixin application |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2449 } | 2415 } |
2450 } | 2416 } |
2451 cls.AddFields(cloned_fields); | 2417 cls.AddFields(cloned_fields); |
2452 | 2418 |
2453 if (FLAG_trace_class_finalization) { | 2419 if (FLAG_trace_class_finalization) { |
2454 THR_Print("Done applying mixin members of %s to %s\n", | 2420 THR_Print("Done applying mixin members of %s to %s\n", |
2455 mixin_cls.ToCString(), cls.ToCString()); | 2421 mixin_cls.ToCString(), cls.ToCString()); |
2456 } | 2422 } |
2457 } | 2423 } |
2458 | 2424 |
2459 | |
2460 void ClassFinalizer::FinalizeTypesInClass(const Class& cls) { | 2425 void ClassFinalizer::FinalizeTypesInClass(const Class& cls) { |
2461 Thread* thread = Thread::Current(); | 2426 Thread* thread = Thread::Current(); |
2462 HANDLESCOPE(thread); | 2427 HANDLESCOPE(thread); |
2463 if (cls.is_type_finalized()) { | 2428 if (cls.is_type_finalized()) { |
2464 return; | 2429 return; |
2465 } | 2430 } |
2466 if (FLAG_trace_class_finalization) { | 2431 if (FLAG_trace_class_finalization) { |
2467 THR_Print("Finalize types in %s\n", cls.ToCString()); | 2432 THR_Print("Finalize types in %s\n", cls.ToCString()); |
2468 } | 2433 } |
2469 if (!IsSuperCycleFree(cls)) { | 2434 if (!IsSuperCycleFree(cls)) { |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2608 // Marking the bootstrap classes as is_refinalize_after_patch seems cute but | 2573 // Marking the bootstrap classes as is_refinalize_after_patch seems cute but |
2609 // it causes other things to fail by violating their assumptions. Reenable | 2574 // it causes other things to fail by violating their assumptions. Reenable |
2610 // this ASSERT if it's important, remove it if it's just a sanity check and | 2575 // this ASSERT if it's important, remove it if it's just a sanity check and |
2611 // not required for correctness. | 2576 // not required for correctness. |
2612 // | 2577 // |
2613 // ASSERT((Array::Handle(cls.functions()).Length() == 0) || | 2578 // ASSERT((Array::Handle(cls.functions()).Length() == 0) || |
2614 // cls.is_refinalize_after_patch()); | 2579 // cls.is_refinalize_after_patch()); |
2615 } | 2580 } |
2616 } | 2581 } |
2617 | 2582 |
2618 | |
2619 void ClassFinalizer::FinalizeClass(const Class& cls) { | 2583 void ClassFinalizer::FinalizeClass(const Class& cls) { |
2620 Thread* thread = Thread::Current(); | 2584 Thread* thread = Thread::Current(); |
2621 HANDLESCOPE(thread); | 2585 HANDLESCOPE(thread); |
2622 ASSERT(cls.is_type_finalized()); | 2586 ASSERT(cls.is_type_finalized()); |
2623 if (cls.is_finalized()) { | 2587 if (cls.is_finalized()) { |
2624 return; | 2588 return; |
2625 } | 2589 } |
2626 if (FLAG_trace_class_finalization) { | 2590 if (FLAG_trace_class_finalization) { |
2627 THR_Print("Finalize %s\n", cls.ToCString()); | 2591 THR_Print("Finalize %s\n", cls.ToCString()); |
2628 } | 2592 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2685 GrowableArray<intptr_t> cids; | 2649 GrowableArray<intptr_t> cids; |
2686 CollectFinalizedSuperClasses(cls, &cids); | 2650 CollectFinalizedSuperClasses(cls, &cids); |
2687 CollectImmediateSuperInterfaces(cls, &cids); | 2651 CollectImmediateSuperInterfaces(cls, &cids); |
2688 RemoveCHAOptimizedCode(cls, cids); | 2652 RemoveCHAOptimizedCode(cls, cids); |
2689 } | 2653 } |
2690 if (cls.is_enum_class()) { | 2654 if (cls.is_enum_class()) { |
2691 AllocateEnumValues(cls); | 2655 AllocateEnumValues(cls); |
2692 } | 2656 } |
2693 } | 2657 } |
2694 | 2658 |
2695 | |
2696 // Allocate instances for each enumeration value, and populate the | 2659 // Allocate instances for each enumeration value, and populate the |
2697 // static field 'values'. | 2660 // static field 'values'. |
2698 // By allocating the instances programmatically, we save an implicit final | 2661 // By allocating the instances programmatically, we save an implicit final |
2699 // getter function object for each enumeration value and for the | 2662 // getter function object for each enumeration value and for the |
2700 // values field. We also don't have to generate the code for these getters | 2663 // values field. We also don't have to generate the code for these getters |
2701 // from thin air (no source code is available). | 2664 // from thin air (no source code is available). |
2702 void ClassFinalizer::AllocateEnumValues(const Class& enum_cls) { | 2665 void ClassFinalizer::AllocateEnumValues(const Class& enum_cls) { |
2703 Thread* thread = Thread::Current(); | 2666 Thread* thread = Thread::Current(); |
2704 Zone* zone = thread->zone(); | 2667 Zone* zone = thread->zone(); |
2705 const Field& index_field = | 2668 const Field& index_field = |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2766 field.RecordStore(enum_value); | 2729 field.RecordStore(enum_value); |
2767 intptr_t ord = Smi::Cast(ordinal_value).Value(); | 2730 intptr_t ord = Smi::Cast(ordinal_value).Value(); |
2768 ASSERT(ord < values_list.Length()); | 2731 ASSERT(ord < values_list.Length()); |
2769 values_list.SetAt(ord, enum_value); | 2732 values_list.SetAt(ord, enum_value); |
2770 } | 2733 } |
2771 values_list.MakeImmutable(); | 2734 values_list.MakeImmutable(); |
2772 values_list ^= values_list.CheckAndCanonicalize(thread, &error_msg); | 2735 values_list ^= values_list.CheckAndCanonicalize(thread, &error_msg); |
2773 ASSERT(!values_list.IsNull()); | 2736 ASSERT(!values_list.IsNull()); |
2774 } | 2737 } |
2775 | 2738 |
2776 | |
2777 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { | 2739 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { |
2778 Class& test1 = Class::Handle(cls.raw()); | 2740 Class& test1 = Class::Handle(cls.raw()); |
2779 Class& test2 = Class::Handle(cls.SuperClass()); | 2741 Class& test2 = Class::Handle(cls.SuperClass()); |
2780 // A finalized class has been checked for cycles. | 2742 // A finalized class has been checked for cycles. |
2781 // Using the hare and tortoise algorithm for locating cycles. | 2743 // Using the hare and tortoise algorithm for locating cycles. |
2782 while (!test1.is_type_finalized() && !test2.IsNull() && | 2744 while (!test1.is_type_finalized() && !test2.IsNull() && |
2783 !test2.is_type_finalized()) { | 2745 !test2.is_type_finalized()) { |
2784 if (test1.raw() == test2.raw()) { | 2746 if (test1.raw() == test2.raw()) { |
2785 // Found a cycle. | 2747 // Found a cycle. |
2786 return false; | 2748 return false; |
2787 } | 2749 } |
2788 test1 = test1.SuperClass(); | 2750 test1 = test1.SuperClass(); |
2789 test2 = test2.SuperClass(); | 2751 test2 = test2.SuperClass(); |
2790 if (!test2.IsNull()) { | 2752 if (!test2.IsNull()) { |
2791 test2 = test2.SuperClass(); | 2753 test2 = test2.SuperClass(); |
2792 } | 2754 } |
2793 } | 2755 } |
2794 // No cycles. | 2756 // No cycles. |
2795 return true; | 2757 return true; |
2796 } | 2758 } |
2797 | 2759 |
2798 | |
2799 // Returns false if a function type alias illegally refers to itself. | 2760 // Returns false if a function type alias illegally refers to itself. |
2800 bool ClassFinalizer::IsTypedefCycleFree(const Class& cls, | 2761 bool ClassFinalizer::IsTypedefCycleFree(const Class& cls, |
2801 const AbstractType& type, | 2762 const AbstractType& type, |
2802 GrowableArray<intptr_t>* visited) { | 2763 GrowableArray<intptr_t>* visited) { |
2803 ASSERT(visited != NULL); | 2764 ASSERT(visited != NULL); |
2804 ResolveType(cls, type); | 2765 ResolveType(cls, type); |
2805 bool checking_typedef = false; | 2766 bool checking_typedef = false; |
2806 if (type.IsType() && !type.IsMalformed()) { | 2767 if (type.IsType() && !type.IsMalformed()) { |
2807 AbstractType& other_type = AbstractType::Handle(); | 2768 AbstractType& other_type = AbstractType::Handle(); |
2808 if (type.IsFunctionType()) { | 2769 if (type.IsFunctionType()) { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2863 } | 2824 } |
2864 } | 2825 } |
2865 } | 2826 } |
2866 if (checking_typedef) { | 2827 if (checking_typedef) { |
2867 visited->RemoveLast(); | 2828 visited->RemoveLast(); |
2868 } | 2829 } |
2869 } | 2830 } |
2870 return true; | 2831 return true; |
2871 } | 2832 } |
2872 | 2833 |
2873 | |
2874 // Returns false if the mixin illegally refers to itself. | 2834 // Returns false if the mixin illegally refers to itself. |
2875 bool ClassFinalizer::IsMixinCycleFree(const Class& cls, | 2835 bool ClassFinalizer::IsMixinCycleFree(const Class& cls, |
2876 GrowableArray<intptr_t>* visited) { | 2836 GrowableArray<intptr_t>* visited) { |
2877 ASSERT(visited != NULL); | 2837 ASSERT(visited != NULL); |
2878 const intptr_t cls_index = cls.id(); | 2838 const intptr_t cls_index = cls.id(); |
2879 for (intptr_t i = 0; i < visited->length(); i++) { | 2839 for (intptr_t i = 0; i < visited->length(); i++) { |
2880 if ((*visited)[i] == cls_index) { | 2840 if ((*visited)[i] == cls_index) { |
2881 // We have already visited mixin 'cls'. We found a cycle. | 2841 // We have already visited mixin 'cls'. We found a cycle. |
2882 return false; | 2842 return false; |
2883 } | 2843 } |
(...skipping 11 matching lines...) Expand all Loading... |
2895 if (!IsMixinCycleFree(mixin_class, visited)) { | 2855 if (!IsMixinCycleFree(mixin_class, visited)) { |
2896 return false; | 2856 return false; |
2897 } | 2857 } |
2898 } | 2858 } |
2899 super_class = super_class.SuperClass(); | 2859 super_class = super_class.SuperClass(); |
2900 } while (!super_class.IsNull()); | 2860 } while (!super_class.IsNull()); |
2901 visited->RemoveLast(); | 2861 visited->RemoveLast(); |
2902 return true; | 2862 return true; |
2903 } | 2863 } |
2904 | 2864 |
2905 | |
2906 void ClassFinalizer::CollectTypeArguments( | 2865 void ClassFinalizer::CollectTypeArguments( |
2907 const Class& cls, | 2866 const Class& cls, |
2908 const Type& type, | 2867 const Type& type, |
2909 const GrowableObjectArray& collected_args) { | 2868 const GrowableObjectArray& collected_args) { |
2910 ASSERT(type.HasResolvedTypeClass()); | 2869 ASSERT(type.HasResolvedTypeClass()); |
2911 Class& type_class = Class::Handle(type.type_class()); | 2870 Class& type_class = Class::Handle(type.type_class()); |
2912 TypeArguments& type_args = TypeArguments::Handle(type.arguments()); | 2871 TypeArguments& type_args = TypeArguments::Handle(type.arguments()); |
2913 const intptr_t num_type_parameters = type_class.NumTypeParameters(); | 2872 const intptr_t num_type_parameters = type_class.NumTypeParameters(); |
2914 const intptr_t num_type_arguments = | 2873 const intptr_t num_type_arguments = |
2915 type_args.IsNull() ? 0 : type_args.Length(); | 2874 type_args.IsNull() ? 0 : type_args.Length(); |
(...skipping 16 matching lines...) Expand all Loading... |
2932 } | 2891 } |
2933 // Discard provided type arguments and treat type as raw. | 2892 // Discard provided type arguments and treat type as raw. |
2934 } | 2893 } |
2935 // Fill arguments with type dynamic. | 2894 // Fill arguments with type dynamic. |
2936 for (intptr_t i = 0; i < num_type_parameters; i++) { | 2895 for (intptr_t i = 0; i < num_type_parameters; i++) { |
2937 arg = Type::DynamicType(); | 2896 arg = Type::DynamicType(); |
2938 collected_args.Add(arg); | 2897 collected_args.Add(arg); |
2939 } | 2898 } |
2940 } | 2899 } |
2941 | 2900 |
2942 | |
2943 RawType* ClassFinalizer::ResolveMixinAppType( | 2901 RawType* ClassFinalizer::ResolveMixinAppType( |
2944 const Class& cls, | 2902 const Class& cls, |
2945 const MixinAppType& mixin_app_type) { | 2903 const MixinAppType& mixin_app_type) { |
2946 // Lookup or create mixin application classes in the library of cls | 2904 // Lookup or create mixin application classes in the library of cls |
2947 // and resolve super type and mixin types. | 2905 // and resolve super type and mixin types. |
2948 Thread* thread = Thread::Current(); | 2906 Thread* thread = Thread::Current(); |
2949 Zone* zone = thread->zone(); | 2907 Zone* zone = thread->zone(); |
2950 const Library& library = Library::Handle(zone, cls.library()); | 2908 const Library& library = Library::Handle(zone, cls.library()); |
2951 ASSERT(!library.IsNull()); | 2909 ASSERT(!library.IsNull()); |
2952 const Script& script = Script::Handle(zone, cls.script()); | 2910 const Script& script = Script::Handle(zone, cls.script()); |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3099 } | 3057 } |
3100 // The mixin application class at depth k is a subclass of mixin application | 3058 // The mixin application class at depth k is a subclass of mixin application |
3101 // class at depth k - 1. Build a new super type with the class at the highest | 3059 // class at depth k - 1. Build a new super type with the class at the highest |
3102 // depth (the last one processed by the loop above) as the type class and the | 3060 // depth (the last one processed by the loop above) as the type class and the |
3103 // collected type arguments from the super type and all mixin types. | 3061 // collected type arguments from the super type and all mixin types. |
3104 // This super type replaces the MixinAppType object in the class that extends | 3062 // This super type replaces the MixinAppType object in the class that extends |
3105 // the mixin application. | 3063 // the mixin application. |
3106 return Type::New(mixin_app_class, mixin_app_args, mixin_app_type.token_pos()); | 3064 return Type::New(mixin_app_class, mixin_app_args, mixin_app_type.token_pos()); |
3107 } | 3065 } |
3108 | 3066 |
3109 | |
3110 // Recursively walks the graph of explicitly declared super type and | 3067 // Recursively walks the graph of explicitly declared super type and |
3111 // interfaces, resolving unresolved super types and interfaces. | 3068 // interfaces, resolving unresolved super types and interfaces. |
3112 // Reports an error if there is an interface reference that cannot be | 3069 // Reports an error if there is an interface reference that cannot be |
3113 // resolved, or if there is a cycle in the graph. We detect cycles by | 3070 // resolved, or if there is a cycle in the graph. We detect cycles by |
3114 // remembering interfaces we've visited in each path through the | 3071 // remembering interfaces we've visited in each path through the |
3115 // graph. If we visit an interface a second time on a given path, | 3072 // graph. If we visit an interface a second time on a given path, |
3116 // we found a loop. | 3073 // we found a loop. |
3117 void ClassFinalizer::ResolveSuperTypeAndInterfaces( | 3074 void ClassFinalizer::ResolveSuperTypeAndInterfaces( |
3118 const Class& cls, | 3075 const Class& cls, |
3119 GrowableArray<intptr_t>* visited) { | 3076 GrowableArray<intptr_t>* visited) { |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3286 } | 3243 } |
3287 } | 3244 } |
3288 interface_class.set_is_implemented(); | 3245 interface_class.set_is_implemented(); |
3289 // Now resolve the super interfaces. | 3246 // Now resolve the super interfaces. |
3290 ResolveSuperTypeAndInterfaces(interface_class, visited); | 3247 ResolveSuperTypeAndInterfaces(interface_class, visited); |
3291 } | 3248 } |
3292 visited->RemoveLast(); | 3249 visited->RemoveLast(); |
3293 cls.set_is_cycle_free(); | 3250 cls.set_is_cycle_free(); |
3294 } | 3251 } |
3295 | 3252 |
3296 | |
3297 // A class is marked as constant if it has one constant constructor. | 3253 // A class is marked as constant if it has one constant constructor. |
3298 // A constant class can only have final instance fields. | 3254 // A constant class can only have final instance fields. |
3299 // Note: we must check for cycles before checking for const properties. | 3255 // Note: we must check for cycles before checking for const properties. |
3300 void ClassFinalizer::CheckForLegalConstClass(const Class& cls) { | 3256 void ClassFinalizer::CheckForLegalConstClass(const Class& cls) { |
3301 ASSERT(cls.is_const()); | 3257 ASSERT(cls.is_const()); |
3302 const Array& fields_array = Array::Handle(cls.fields()); | 3258 const Array& fields_array = Array::Handle(cls.fields()); |
3303 intptr_t len = fields_array.Length(); | 3259 intptr_t len = fields_array.Length(); |
3304 Field& field = Field::Handle(); | 3260 Field& field = Field::Handle(); |
3305 for (intptr_t i = 0; i < len; i++) { | 3261 for (intptr_t i = 0; i < len; i++) { |
3306 field ^= fields_array.At(i); | 3262 field ^= fields_array.At(i); |
3307 if (!field.is_static() && !field.is_final()) { | 3263 if (!field.is_static() && !field.is_final()) { |
3308 const String& class_name = String::Handle(cls.Name()); | 3264 const String& class_name = String::Handle(cls.Name()); |
3309 const String& field_name = String::Handle(field.name()); | 3265 const String& field_name = String::Handle(field.name()); |
3310 ReportError(cls, field.token_pos(), | 3266 ReportError(cls, field.token_pos(), |
3311 "const class '%s' has non-final field '%s'", | 3267 "const class '%s' has non-final field '%s'", |
3312 class_name.ToCString(), field_name.ToCString()); | 3268 class_name.ToCString(), field_name.ToCString()); |
3313 } | 3269 } |
3314 } | 3270 } |
3315 } | 3271 } |
3316 | 3272 |
3317 | |
3318 void ClassFinalizer::PrintClassInformation(const Class& cls) { | 3273 void ClassFinalizer::PrintClassInformation(const Class& cls) { |
3319 Thread* thread = Thread::Current(); | 3274 Thread* thread = Thread::Current(); |
3320 HANDLESCOPE(thread); | 3275 HANDLESCOPE(thread); |
3321 const String& class_name = String::Handle(cls.Name()); | 3276 const String& class_name = String::Handle(cls.Name()); |
3322 THR_Print("class '%s'", class_name.ToCString()); | 3277 THR_Print("class '%s'", class_name.ToCString()); |
3323 const Library& library = Library::Handle(cls.library()); | 3278 const Library& library = Library::Handle(cls.library()); |
3324 if (!library.IsNull()) { | 3279 if (!library.IsNull()) { |
3325 THR_Print(" library '%s%s':\n", String::Handle(library.url()).ToCString(), | 3280 THR_Print(" library '%s%s':\n", String::Handle(library.url()).ToCString(), |
3326 String::Handle(library.private_key()).ToCString()); | 3281 String::Handle(library.private_key()).ToCString()); |
3327 } else { | 3282 } else { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3381 if (!type.IsFinalized()) { | 3336 if (!type.IsFinalized()) { |
3382 type.SetIsFinalized(); | 3337 type.SetIsFinalized(); |
3383 // Do not canonicalize malformed types, since they contain an error field. | 3338 // Do not canonicalize malformed types, since they contain an error field. |
3384 } else { | 3339 } else { |
3385 // The only case where the malformed type was already finalized is when its | 3340 // The only case where the malformed type was already finalized is when its |
3386 // type arguments are not within bounds. In that case, we have a prev_error. | 3341 // type arguments are not within bounds. In that case, we have a prev_error. |
3387 ASSERT(!prev_error.IsNull()); | 3342 ASSERT(!prev_error.IsNull()); |
3388 } | 3343 } |
3389 } | 3344 } |
3390 | 3345 |
3391 | |
3392 RawType* ClassFinalizer::NewFinalizedMalformedType(const Error& prev_error, | 3346 RawType* ClassFinalizer::NewFinalizedMalformedType(const Error& prev_error, |
3393 const Script& script, | 3347 const Script& script, |
3394 TokenPosition type_pos, | 3348 TokenPosition type_pos, |
3395 const char* format, | 3349 const char* format, |
3396 ...) { | 3350 ...) { |
3397 va_list args; | 3351 va_list args; |
3398 va_start(args, format); | 3352 va_start(args, format); |
3399 const UnresolvedClass& unresolved_class = | 3353 const UnresolvedClass& unresolved_class = |
3400 UnresolvedClass::Handle(UnresolvedClass::New(LibraryPrefix::Handle(), | 3354 UnresolvedClass::Handle(UnresolvedClass::New(LibraryPrefix::Handle(), |
3401 Symbols::Empty(), type_pos)); | 3355 Symbols::Empty(), type_pos)); |
3402 const Type& type = Type::Handle( | 3356 const Type& type = Type::Handle( |
3403 Type::New(unresolved_class, Object::null_type_arguments(), type_pos)); | 3357 Type::New(unresolved_class, Object::null_type_arguments(), type_pos)); |
3404 MarkTypeMalformed(prev_error, script, type, format, args); | 3358 MarkTypeMalformed(prev_error, script, type, format, args); |
3405 va_end(args); | 3359 va_end(args); |
3406 ASSERT(type.IsMalformed()); | 3360 ASSERT(type.IsMalformed()); |
3407 ASSERT(type.IsFinalized()); | 3361 ASSERT(type.IsFinalized()); |
3408 return type.raw(); | 3362 return type.raw(); |
3409 } | 3363 } |
3410 | 3364 |
3411 | |
3412 void ClassFinalizer::FinalizeMalformedType(const Error& prev_error, | 3365 void ClassFinalizer::FinalizeMalformedType(const Error& prev_error, |
3413 const Script& script, | 3366 const Script& script, |
3414 const Type& type, | 3367 const Type& type, |
3415 const char* format, | 3368 const char* format, |
3416 ...) { | 3369 ...) { |
3417 va_list args; | 3370 va_list args; |
3418 va_start(args, format); | 3371 va_start(args, format); |
3419 MarkTypeMalformed(prev_error, script, type, format, args); | 3372 MarkTypeMalformed(prev_error, script, type, format, args); |
3420 va_end(args); | 3373 va_end(args); |
3421 } | 3374 } |
3422 | 3375 |
3423 | |
3424 void ClassFinalizer::FinalizeMalboundedType(const Error& prev_error, | 3376 void ClassFinalizer::FinalizeMalboundedType(const Error& prev_error, |
3425 const Script& script, | 3377 const Script& script, |
3426 const AbstractType& type, | 3378 const AbstractType& type, |
3427 const char* format, | 3379 const char* format, |
3428 ...) { | 3380 ...) { |
3429 va_list args; | 3381 va_list args; |
3430 va_start(args, format); | 3382 va_start(args, format); |
3431 LanguageError& error = LanguageError::Handle(LanguageError::NewFormattedV( | 3383 LanguageError& error = LanguageError::Handle(LanguageError::NewFormattedV( |
3432 prev_error, script, type.token_pos(), Report::AtLocation, | 3384 prev_error, script, type.token_pos(), Report::AtLocation, |
3433 Report::kMalboundedType, Heap::kOld, format, args)); | 3385 Report::kMalboundedType, Heap::kOld, format, args)); |
3434 va_end(args); | 3386 va_end(args); |
3435 if (Isolate::Current()->error_on_bad_type()) { | 3387 if (Isolate::Current()->error_on_bad_type()) { |
3436 ReportError(error); | 3388 ReportError(error); |
3437 } | 3389 } |
3438 type.set_error(error); | 3390 type.set_error(error); |
3439 if (!type.IsFinalized()) { | 3391 if (!type.IsFinalized()) { |
3440 type.SetIsFinalized(); | 3392 type.SetIsFinalized(); |
3441 // Do not canonicalize malbounded types. | 3393 // Do not canonicalize malbounded types. |
3442 } | 3394 } |
3443 } | 3395 } |
3444 | 3396 |
3445 | |
3446 void ClassFinalizer::ReportError(const Error& error) { | 3397 void ClassFinalizer::ReportError(const Error& error) { |
3447 Report::LongJump(error); | 3398 Report::LongJump(error); |
3448 UNREACHABLE(); | 3399 UNREACHABLE(); |
3449 } | 3400 } |
3450 | 3401 |
3451 | |
3452 void ClassFinalizer::ReportErrors(const Error& prev_error, | 3402 void ClassFinalizer::ReportErrors(const Error& prev_error, |
3453 const Class& cls, | 3403 const Class& cls, |
3454 TokenPosition token_pos, | 3404 TokenPosition token_pos, |
3455 const char* format, | 3405 const char* format, |
3456 ...) { | 3406 ...) { |
3457 va_list args; | 3407 va_list args; |
3458 va_start(args, format); | 3408 va_start(args, format); |
3459 const Script& script = Script::Handle(cls.script()); | 3409 const Script& script = Script::Handle(cls.script()); |
3460 Report::LongJumpV(prev_error, script, token_pos, format, args); | 3410 Report::LongJumpV(prev_error, script, token_pos, format, args); |
3461 va_end(args); | 3411 va_end(args); |
3462 UNREACHABLE(); | 3412 UNREACHABLE(); |
3463 } | 3413 } |
3464 | 3414 |
3465 | |
3466 void ClassFinalizer::ReportError(const Class& cls, | 3415 void ClassFinalizer::ReportError(const Class& cls, |
3467 TokenPosition token_pos, | 3416 TokenPosition token_pos, |
3468 const char* format, | 3417 const char* format, |
3469 ...) { | 3418 ...) { |
3470 va_list args; | 3419 va_list args; |
3471 va_start(args, format); | 3420 va_start(args, format); |
3472 const Script& script = Script::Handle(cls.script()); | 3421 const Script& script = Script::Handle(cls.script()); |
3473 Report::MessageV(Report::kError, script, token_pos, Report::AtLocation, | 3422 Report::MessageV(Report::kError, script, token_pos, Report::AtLocation, |
3474 format, args); | 3423 format, args); |
3475 va_end(args); | 3424 va_end(args); |
3476 UNREACHABLE(); | 3425 UNREACHABLE(); |
3477 } | 3426 } |
3478 | 3427 |
3479 | |
3480 void ClassFinalizer::VerifyImplicitFieldOffsets() { | 3428 void ClassFinalizer::VerifyImplicitFieldOffsets() { |
3481 #ifdef DEBUG | 3429 #ifdef DEBUG |
3482 Thread* thread = Thread::Current(); | 3430 Thread* thread = Thread::Current(); |
3483 Isolate* isolate = thread->isolate(); | 3431 Isolate* isolate = thread->isolate(); |
3484 Zone* zone = thread->zone(); | 3432 Zone* zone = thread->zone(); |
3485 const ClassTable& class_table = *(isolate->class_table()); | 3433 const ClassTable& class_table = *(isolate->class_table()); |
3486 Class& cls = Class::Handle(zone); | 3434 Class& cls = Class::Handle(zone); |
3487 Array& fields_array = Array::Handle(zone); | 3435 Array& fields_array = Array::Handle(zone); |
3488 Field& field = Field::Handle(zone); | 3436 Field& field = Field::Handle(zone); |
3489 String& name = String::Handle(zone); | 3437 String& name = String::Handle(zone); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3543 fields_array ^= cls.fields(); | 3491 fields_array ^= cls.fields(); |
3544 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); | 3492 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); |
3545 field ^= fields_array.At(0); | 3493 field ^= fields_array.At(0); |
3546 ASSERT(field.Offset() == ByteBuffer::data_offset()); | 3494 ASSERT(field.Offset() == ByteBuffer::data_offset()); |
3547 name ^= field.name(); | 3495 name ^= field.name(); |
3548 expected_name ^= String::New("_data"); | 3496 expected_name ^= String::New("_data"); |
3549 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3497 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
3550 #endif | 3498 #endif |
3551 } | 3499 } |
3552 | 3500 |
3553 | |
3554 void ClassFinalizer::SortClasses() { | 3501 void ClassFinalizer::SortClasses() { |
3555 Thread* T = Thread::Current(); | 3502 Thread* T = Thread::Current(); |
3556 Zone* Z = T->zone(); | 3503 Zone* Z = T->zone(); |
3557 Isolate* I = T->isolate(); | 3504 Isolate* I = T->isolate(); |
3558 ClassTable* table = I->class_table(); | 3505 ClassTable* table = I->class_table(); |
3559 intptr_t num_cids = table->NumCids(); | 3506 intptr_t num_cids = table->NumCids(); |
3560 intptr_t* old_to_new_cid = new intptr_t[num_cids]; | 3507 intptr_t* old_to_new_cid = new intptr_t[num_cids]; |
3561 for (intptr_t cid = 0; cid < kNumPredefinedCids; cid++) { | 3508 for (intptr_t cid = 0; cid < kNumPredefinedCids; cid++) { |
3562 old_to_new_cid[cid] = cid; // The predefined classes cannot change cids. | 3509 old_to_new_cid[cid] = cid; // The predefined classes cannot change cids. |
3563 } | 3510 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3617 } | 3564 } |
3618 } | 3565 } |
3619 } | 3566 } |
3620 ASSERT(next_new_cid == num_cids); | 3567 ASSERT(next_new_cid == num_cids); |
3621 | 3568 |
3622 RemapClassIds(old_to_new_cid); | 3569 RemapClassIds(old_to_new_cid); |
3623 delete[] old_to_new_cid; | 3570 delete[] old_to_new_cid; |
3624 RehashTypes(); // Types use cid's as part of their hashes. | 3571 RehashTypes(); // Types use cid's as part of their hashes. |
3625 } | 3572 } |
3626 | 3573 |
3627 | |
3628 class CidRewriteVisitor : public ObjectVisitor { | 3574 class CidRewriteVisitor : public ObjectVisitor { |
3629 public: | 3575 public: |
3630 explicit CidRewriteVisitor(intptr_t* old_to_new_cids) | 3576 explicit CidRewriteVisitor(intptr_t* old_to_new_cids) |
3631 : old_to_new_cids_(old_to_new_cids) {} | 3577 : old_to_new_cids_(old_to_new_cids) {} |
3632 | 3578 |
3633 intptr_t Map(intptr_t cid) { | 3579 intptr_t Map(intptr_t cid) { |
3634 ASSERT(cid != -1); | 3580 ASSERT(cid != -1); |
3635 return old_to_new_cids_[cid]; | 3581 return old_to_new_cids_[cid]; |
3636 } | 3582 } |
3637 | 3583 |
(...skipping 24 matching lines...) Expand all Loading... |
3662 // which are write-protected. | 3608 // which are write-protected. |
3663 obj->SetClassId(new_cid); | 3609 obj->SetClassId(new_cid); |
3664 } | 3610 } |
3665 } | 3611 } |
3666 } | 3612 } |
3667 | 3613 |
3668 private: | 3614 private: |
3669 intptr_t* old_to_new_cids_; | 3615 intptr_t* old_to_new_cids_; |
3670 }; | 3616 }; |
3671 | 3617 |
3672 | |
3673 void ClassFinalizer::RemapClassIds(intptr_t* old_to_new_cid) { | 3618 void ClassFinalizer::RemapClassIds(intptr_t* old_to_new_cid) { |
3674 Isolate* I = Thread::Current()->isolate(); | 3619 Isolate* I = Thread::Current()->isolate(); |
3675 | 3620 |
3676 // Code, ICData, allocation stubs have now-invalid cids. | 3621 // Code, ICData, allocation stubs have now-invalid cids. |
3677 ClearAllCode(); | 3622 ClearAllCode(); |
3678 | 3623 |
3679 { | 3624 { |
3680 HeapIterationScope his; | 3625 HeapIterationScope his; |
3681 I->set_remapping_cids(true); | 3626 I->set_remapping_cids(true); |
3682 | 3627 |
3683 // Update the class table. Do it before rewriting cids in headers, as the | 3628 // Update the class table. Do it before rewriting cids in headers, as the |
3684 // heap walkers load an object's size *after* calling the visitor. | 3629 // heap walkers load an object's size *after* calling the visitor. |
3685 I->class_table()->Remap(old_to_new_cid); | 3630 I->class_table()->Remap(old_to_new_cid); |
3686 | 3631 |
3687 // Rewrite cids in headers and cids in Classes, Fields, Types and | 3632 // Rewrite cids in headers and cids in Classes, Fields, Types and |
3688 // TypeParameters. | 3633 // TypeParameters. |
3689 { | 3634 { |
3690 CidRewriteVisitor visitor(old_to_new_cid); | 3635 CidRewriteVisitor visitor(old_to_new_cid); |
3691 I->heap()->VisitObjects(&visitor); | 3636 I->heap()->VisitObjects(&visitor); |
3692 } | 3637 } |
3693 I->set_remapping_cids(false); | 3638 I->set_remapping_cids(false); |
3694 } | 3639 } |
3695 | 3640 |
3696 #if defined(DEBUG) | 3641 #if defined(DEBUG) |
3697 I->class_table()->Validate(); | 3642 I->class_table()->Validate(); |
3698 I->heap()->Verify(); | 3643 I->heap()->Verify(); |
3699 #endif | 3644 #endif |
3700 } | 3645 } |
3701 | 3646 |
3702 | |
3703 class ClearTypeHashVisitor : public ObjectVisitor { | 3647 class ClearTypeHashVisitor : public ObjectVisitor { |
3704 public: | 3648 public: |
3705 explicit ClearTypeHashVisitor(Zone* zone) | 3649 explicit ClearTypeHashVisitor(Zone* zone) |
3706 : type_param_(TypeParameter::Handle(zone)), | 3650 : type_param_(TypeParameter::Handle(zone)), |
3707 type_(Type::Handle(zone)), | 3651 type_(Type::Handle(zone)), |
3708 type_args_(TypeArguments::Handle(zone)), | 3652 type_args_(TypeArguments::Handle(zone)), |
3709 bounded_type_(BoundedType::Handle(zone)) {} | 3653 bounded_type_(BoundedType::Handle(zone)) {} |
3710 | 3654 |
3711 void VisitObject(RawObject* obj) { | 3655 void VisitObject(RawObject* obj) { |
3712 if (obj->IsTypeParameter()) { | 3656 if (obj->IsTypeParameter()) { |
(...skipping 11 matching lines...) Expand all Loading... |
3724 } | 3668 } |
3725 } | 3669 } |
3726 | 3670 |
3727 private: | 3671 private: |
3728 TypeParameter& type_param_; | 3672 TypeParameter& type_param_; |
3729 Type& type_; | 3673 Type& type_; |
3730 TypeArguments& type_args_; | 3674 TypeArguments& type_args_; |
3731 BoundedType& bounded_type_; | 3675 BoundedType& bounded_type_; |
3732 }; | 3676 }; |
3733 | 3677 |
3734 | |
3735 void ClassFinalizer::RehashTypes() { | 3678 void ClassFinalizer::RehashTypes() { |
3736 Thread* T = Thread::Current(); | 3679 Thread* T = Thread::Current(); |
3737 Zone* Z = T->zone(); | 3680 Zone* Z = T->zone(); |
3738 Isolate* I = T->isolate(); | 3681 Isolate* I = T->isolate(); |
3739 | 3682 |
3740 // Clear all cached hash values. | 3683 // Clear all cached hash values. |
3741 { | 3684 { |
3742 HeapIterationScope his; | 3685 HeapIterationScope his; |
3743 ClearTypeHashVisitor visitor(Z); | 3686 ClearTypeHashVisitor visitor(Z); |
3744 I->heap()->VisitObjects(&visitor); | 3687 I->heap()->VisitObjects(&visitor); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3791 HashTables::New<CanonicalTypeArgumentsSet>(dict_size, Heap::kOld); | 3734 HashTables::New<CanonicalTypeArgumentsSet>(dict_size, Heap::kOld); |
3792 CanonicalTypeArgumentsSet typeargs_table(Z, typeargs_array.raw()); | 3735 CanonicalTypeArgumentsSet typeargs_table(Z, typeargs_array.raw()); |
3793 for (intptr_t i = 0; i < typeargs.Length(); i++) { | 3736 for (intptr_t i = 0; i < typeargs.Length(); i++) { |
3794 typearg ^= typeargs.At(i); | 3737 typearg ^= typeargs.At(i); |
3795 bool present = typeargs_table.Insert(typearg); | 3738 bool present = typeargs_table.Insert(typearg); |
3796 ASSERT(!present || typearg.IsRecursive()); | 3739 ASSERT(!present || typearg.IsRecursive()); |
3797 } | 3740 } |
3798 object_store->set_canonical_type_arguments(typeargs_table.Release()); | 3741 object_store->set_canonical_type_arguments(typeargs_table.Release()); |
3799 } | 3742 } |
3800 | 3743 |
3801 | |
3802 void ClassFinalizer::ClearAllCode() { | 3744 void ClassFinalizer::ClearAllCode() { |
3803 class ClearCodeFunctionVisitor : public FunctionVisitor { | 3745 class ClearCodeFunctionVisitor : public FunctionVisitor { |
3804 void Visit(const Function& function) { | 3746 void Visit(const Function& function) { |
3805 function.ClearCode(); | 3747 function.ClearCode(); |
3806 function.ClearICDataArray(); | 3748 function.ClearICDataArray(); |
3807 } | 3749 } |
3808 }; | 3750 }; |
3809 ClearCodeFunctionVisitor function_visitor; | 3751 ClearCodeFunctionVisitor function_visitor; |
3810 ProgramVisitor::VisitFunctions(&function_visitor); | 3752 ProgramVisitor::VisitFunctions(&function_visitor); |
3811 | 3753 |
3812 class ClearCodeClassVisitor : public ClassVisitor { | 3754 class ClearCodeClassVisitor : public ClassVisitor { |
3813 void Visit(const Class& cls) { cls.DisableAllocationStub(); } | 3755 void Visit(const Class& cls) { cls.DisableAllocationStub(); } |
3814 }; | 3756 }; |
3815 ClearCodeClassVisitor class_visitor; | 3757 ClearCodeClassVisitor class_visitor; |
3816 ProgramVisitor::VisitClasses(&class_visitor); | 3758 ProgramVisitor::VisitClasses(&class_visitor); |
3817 } | 3759 } |
3818 | 3760 |
3819 } // namespace dart | 3761 } // namespace dart |
OLD | NEW |