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