| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/class_finalizer.h" | 5 #include "vm/class_finalizer.h" |
| 6 | 6 |
| 7 #include "vm/code_generator.h" | 7 #include "vm/code_generator.h" |
| 8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
| 9 #include "vm/heap.h" | 9 #include "vm/heap.h" |
| 10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
| (...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 517 for (intptr_t i = 0; i < num_arguments; i++) { | 517 for (intptr_t i = 0; i < num_arguments; i++) { |
| 518 type_argument = arguments.TypeAt(i); | 518 type_argument = arguments.TypeAt(i); |
| 519 ResolveType(cls, type_argument); | 519 ResolveType(cls, type_argument); |
| 520 } | 520 } |
| 521 } | 521 } |
| 522 } | 522 } |
| 523 | 523 |
| 524 | 524 |
| 525 void ClassFinalizer::FinalizeTypeParameters( | 525 void ClassFinalizer::FinalizeTypeParameters( |
| 526 const Class& cls, | 526 const Class& cls, |
| 527 GrowableObjectArray* pending_types) { | 527 PendingTypes* pending_types) { |
| 528 if (FLAG_trace_type_finalization) { | 528 if (FLAG_trace_type_finalization) { |
| 529 ISL_Print("Finalizing type parameters of '%s'\n", | 529 ISL_Print("Finalizing type parameters of '%s'\n", |
| 530 String::Handle(cls.Name()).ToCString()); | 530 String::Handle(cls.Name()).ToCString()); |
| 531 } | 531 } |
| 532 if (cls.IsMixinApplication()) { | 532 if (cls.IsMixinApplication()) { |
| 533 // Setup the type parameters of the mixin application and finalize the | 533 // Setup the type parameters of the mixin application and finalize the |
| 534 // mixin type. | 534 // mixin type. |
| 535 ApplyMixinType(cls, pending_types); | 535 ApplyMixinType(cls, pending_types); |
| 536 } | 536 } |
| 537 // The type parameter bounds are not finalized here. | 537 // The type parameter bounds are not finalized here. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 555 // not finite, where P is the instantiation of T with its own type parameters. | 555 // not finite, where P is the instantiation of T with its own type parameters. |
| 556 // The induced type set S consists of the super types of any type in S as well | 556 // The induced type set S consists of the super types of any type in S as well |
| 557 // as the type arguments of any parameterized type in S. | 557 // as the type arguments of any parameterized type in S. |
| 558 // The Dart Language Specification does not disallow the declaration and use of | 558 // The Dart Language Specification does not disallow the declaration and use of |
| 559 // non-contractive types (this may change). They are nevertheless disallowed | 559 // non-contractive types (this may change). They are nevertheless disallowed |
| 560 // as an implementation restriction in the VM since they cause divergence. | 560 // as an implementation restriction in the VM since they cause divergence. |
| 561 // A non-contractive type can be detected by looking at the queue of types | 561 // A non-contractive type can be detected by looking at the queue of types |
| 562 // pending finalization that are mutually recursive with the checked type. | 562 // pending finalization that are mutually recursive with the checked type. |
| 563 void ClassFinalizer::CheckRecursiveType(const Class& cls, | 563 void ClassFinalizer::CheckRecursiveType(const Class& cls, |
| 564 const Type& type, | 564 const Type& type, |
| 565 GrowableObjectArray* pending_types) { | 565 PendingTypes* pending_types) { |
| 566 Isolate* isolate = Isolate::Current(); | 566 Isolate* isolate = Isolate::Current(); |
| 567 if (FLAG_trace_type_finalization) { | 567 if (FLAG_trace_type_finalization) { |
| 568 ISL_Print("Checking recursive type '%s': %s\n", | 568 ISL_Print("Checking recursive type '%s': %s\n", |
| 569 String::Handle(type.Name()).ToCString(), | 569 String::Handle(type.Name()).ToCString(), |
| 570 type.ToCString()); | 570 type.ToCString()); |
| 571 } | 571 } |
| 572 const Class& type_cls = Class::Handle(isolate, type.type_class()); | 572 const Class& type_cls = Class::Handle(isolate, type.type_class()); |
| 573 const TypeArguments& arguments = | 573 const TypeArguments& arguments = |
| 574 TypeArguments::Handle(isolate, type.arguments()); | 574 TypeArguments::Handle(isolate, type.arguments()); |
| 575 // A type can only be recursive via its type arguments. | 575 // A type can only be recursive via its type arguments. |
| 576 ASSERT(!arguments.IsNull()); | 576 ASSERT(!arguments.IsNull()); |
| 577 const intptr_t num_type_args = arguments.Length(); | 577 const intptr_t num_type_args = arguments.Length(); |
| 578 ASSERT(num_type_args > 0); | 578 ASSERT(num_type_args > 0); |
| 579 ASSERT(num_type_args == type_cls.NumTypeArguments()); | 579 ASSERT(num_type_args == type_cls.NumTypeArguments()); |
| 580 const intptr_t num_type_params = type_cls.NumTypeParameters(); | 580 const intptr_t num_type_params = type_cls.NumTypeParameters(); |
| 581 const intptr_t first_type_param = num_type_args - num_type_params; | 581 const intptr_t first_type_param = num_type_args - num_type_params; |
| 582 // If the type is not generic (num_type_params == 0) or if its type parameters | 582 // If the type is not generic (num_type_params == 0) or if its type parameters |
| 583 // are instantiated, no divergence can occur. Note that if the type parameters | 583 // are instantiated, no divergence can occur. Note that if the type parameters |
| 584 // are null, i.e. if the generic type is raw, they are considered | 584 // are null, i.e. if the generic type is raw, they are considered |
| 585 // instantiated and no divergence can occur. | 585 // instantiated and no divergence can occur. |
| 586 if ((num_type_params == 0) || | 586 if ((num_type_params == 0) || |
| 587 arguments.IsSubvectorInstantiated(first_type_param, num_type_params)) { | 587 arguments.IsSubvectorInstantiated(first_type_param, num_type_params)) { |
| 588 return; | 588 return; |
| 589 } | 589 } |
| 590 // The type parameters are not instantiated. Verify that there is no other | 590 // The type parameters are not instantiated. Verify that there is no other |
| 591 // type pending finalization with the same type class, but different | 591 // type pending finalization with the same type class, but different |
| 592 // uninstantiated type parameters. | 592 // uninstantiated type parameters. |
| 593 Type& pending_type = Type::Handle(isolate); | |
| 594 TypeArguments& pending_arguments = TypeArguments::Handle(isolate); | 593 TypeArguments& pending_arguments = TypeArguments::Handle(isolate); |
| 595 const intptr_t num_pending_types = pending_types->Length(); | 594 const intptr_t num_pending_types = pending_types->length(); |
| 596 for (intptr_t i = num_pending_types - 1; i >= 0; i--) { | 595 for (intptr_t i = num_pending_types - 1; i >= 0; i--) { |
| 597 pending_type ^= pending_types->At(i); | 596 const Type& pending_type = Type::Cast(pending_types->At(i)); |
| 598 if (FLAG_trace_type_finalization) { | 597 if (FLAG_trace_type_finalization) { |
| 599 ISL_Print(" Comparing with pending type '%s': %s\n", | 598 ISL_Print(" Comparing with pending type '%s': %s\n", |
| 600 String::Handle(pending_type.Name()).ToCString(), | 599 String::Handle(pending_type.Name()).ToCString(), |
| 601 pending_type.ToCString()); | 600 pending_type.ToCString()); |
| 602 } | 601 } |
| 603 if ((pending_type.raw() != type.raw()) && | 602 if ((pending_type.raw() != type.raw()) && |
| 604 (pending_type.type_class() == type_cls.raw())) { | 603 (pending_type.type_class() == type_cls.raw())) { |
| 605 pending_arguments = pending_type.arguments(); | 604 pending_arguments = pending_type.arguments(); |
| 606 if (!pending_arguments.IsSubvectorEquivalent(arguments, | 605 if (!pending_arguments.IsSubvectorEquivalent(arguments, |
| 607 first_type_param, | 606 first_type_param, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 // It is too early to canonicalize the type arguments of the vector, because | 648 // It is too early to canonicalize the type arguments of the vector, because |
| 650 // several type argument vectors may be mutually recursive and finalized at the | 649 // several type argument vectors may be mutually recursive and finalized at the |
| 651 // same time. Canonicalization happens when pending types are processed. | 650 // same time. Canonicalization happens when pending types are processed. |
| 652 // The trail is required to correctly instantiate a recursive type argument | 651 // The trail is required to correctly instantiate a recursive type argument |
| 653 // of the super type. | 652 // of the super type. |
| 654 void ClassFinalizer::FinalizeTypeArguments( | 653 void ClassFinalizer::FinalizeTypeArguments( |
| 655 const Class& cls, | 654 const Class& cls, |
| 656 const TypeArguments& arguments, | 655 const TypeArguments& arguments, |
| 657 intptr_t num_uninitialized_arguments, | 656 intptr_t num_uninitialized_arguments, |
| 658 Error* bound_error, | 657 Error* bound_error, |
| 659 GrowableObjectArray* pending_types, | 658 PendingTypes* pending_types, |
| 660 TrailPtr trail) { | 659 TrailPtr trail) { |
| 661 ASSERT(arguments.Length() >= cls.NumTypeArguments()); | 660 ASSERT(arguments.Length() >= cls.NumTypeArguments()); |
| 662 if (!cls.is_type_finalized()) { | 661 if (!cls.is_type_finalized()) { |
| 663 FinalizeTypeParameters(cls, pending_types); | 662 FinalizeTypeParameters(cls, pending_types); |
| 664 ResolveUpperBounds(cls); | 663 ResolveUpperBounds(cls); |
| 665 } | 664 } |
| 666 AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 665 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
| 667 if (!super_type.IsNull()) { | 666 if (!super_type.IsNull()) { |
| 668 const Class& super_class = Class::Handle(super_type.type_class()); | 667 const Class& super_class = Class::Handle(super_type.type_class()); |
| 669 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 668 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 900 bound_error.ToCString()); | 899 bound_error.ToCString()); |
| 901 } | 900 } |
| 902 } | 901 } |
| 903 } | 902 } |
| 904 | 903 |
| 905 | 904 |
| 906 RawAbstractType* ClassFinalizer::FinalizeType( | 905 RawAbstractType* ClassFinalizer::FinalizeType( |
| 907 const Class& cls, | 906 const Class& cls, |
| 908 const AbstractType& type, | 907 const AbstractType& type, |
| 909 FinalizationKind finalization, | 908 FinalizationKind finalization, |
| 910 GrowableObjectArray* pending_types) { | 909 PendingTypes* pending_types) { |
| 911 // Only the 'root' type of the graph can be canonicalized, after all depending | 910 // Only the 'root' type of the graph can be canonicalized, after all depending |
| 912 // types have been bound checked. | 911 // types have been bound checked. |
| 913 ASSERT((pending_types == NULL) || (finalization < kCanonicalize)); | 912 ASSERT((pending_types == NULL) || (finalization < kCanonicalize)); |
| 914 if (type.IsFinalized()) { | 913 if (type.IsFinalized()) { |
| 915 // Ensure type is canonical if canonicalization is requested, unless type is | 914 // Ensure type is canonical if canonicalization is requested, unless type is |
| 916 // malformed. | 915 // malformed. |
| 917 if ((finalization >= kCanonicalize) && !type.IsMalformed()) { | 916 if ((finalization >= kCanonicalize) && !type.IsMalformed()) { |
| 918 return type.Canonicalize(); | 917 return type.Canonicalize(); |
| 919 } | 918 } |
| 920 return type.raw(); | 919 return type.raw(); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 // We do not canonicalize type parameters. | 974 // We do not canonicalize type parameters. |
| 976 return type_parameter.raw(); | 975 return type_parameter.raw(); |
| 977 } | 976 } |
| 978 | 977 |
| 979 // At this point, we can only have a parameterized_type. | 978 // At this point, we can only have a parameterized_type. |
| 980 const Type& parameterized_type = Type::Cast(type); | 979 const Type& parameterized_type = Type::Cast(type); |
| 981 | 980 |
| 982 // This type is the root type of the type graph if no pending types queue is | 981 // This type is the root type of the type graph if no pending types queue is |
| 983 // allocated yet. | 982 // allocated yet. |
| 984 const bool is_root_type = (pending_types == NULL); | 983 const bool is_root_type = (pending_types == NULL); |
| 985 GrowableObjectArray& types = GrowableObjectArray::Handle(Z); | |
| 986 if (is_root_type) { | 984 if (is_root_type) { |
| 987 types = GrowableObjectArray::New(); | 985 pending_types = new PendingTypes(Z, 4); |
| 988 pending_types = &types; | |
| 989 } | 986 } |
| 990 | 987 |
| 991 // The type class does not need to be finalized in order to finalize the type, | 988 // The type class does not need to be finalized in order to finalize the type, |
| 992 // however, it must at least be resolved (this was done as part of resolving | 989 // however, it must at least be resolved (this was done as part of resolving |
| 993 // the type itself, a precondition to calling FinalizeType). | 990 // the type itself, a precondition to calling FinalizeType). |
| 994 // Also, the interfaces of the type class must be resolved and the type | 991 // Also, the interfaces of the type class must be resolved and the type |
| 995 // parameters of the type class must be finalized. | 992 // parameters of the type class must be finalized. |
| 996 Class& type_class = Class::Handle(Z, parameterized_type.type_class()); | 993 Class& type_class = Class::Handle(Z, parameterized_type.type_class()); |
| 997 if (!type_class.is_type_finalized()) { | 994 if (!type_class.is_type_finalized()) { |
| 998 FinalizeTypeParameters(type_class, pending_types); | 995 FinalizeTypeParameters(type_class, pending_types); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1114 ASSERT(full_arguments.IsNull() || | 1111 ASSERT(full_arguments.IsNull() || |
| 1115 !full_arguments.IsRaw(0, num_type_arguments)); | 1112 !full_arguments.IsRaw(0, num_type_arguments)); |
| 1116 // Mark the type as finalized. | 1113 // Mark the type as finalized. |
| 1117 parameterized_type.SetIsFinalized(); | 1114 parameterized_type.SetIsFinalized(); |
| 1118 // Do not yet remove the type from the pending_types array. | 1115 // Do not yet remove the type from the pending_types array. |
| 1119 } | 1116 } |
| 1120 | 1117 |
| 1121 // If we are done finalizing a graph of mutually recursive types, check their | 1118 // If we are done finalizing a graph of mutually recursive types, check their |
| 1122 // bounds. | 1119 // bounds. |
| 1123 if (is_root_type) { | 1120 if (is_root_type) { |
| 1124 Type& type = Type::Handle(Z); | 1121 for (intptr_t i = pending_types->length() - 1; i >= 0; i--) { |
| 1125 for (intptr_t i = types.Length() - 1; i >= 0; i--) { | 1122 CheckTypeBounds(cls, Type::Cast(pending_types->At(i))); |
| 1126 type ^= types.At(i); | |
| 1127 CheckTypeBounds(cls, type); | |
| 1128 if (FLAG_trace_type_finalization && type.IsRecursive()) { | 1123 if (FLAG_trace_type_finalization && type.IsRecursive()) { |
| 1129 ISL_Print("Done finalizing recursive type '%s': %s\n", | 1124 ISL_Print("Done finalizing recursive type '%s': %s\n", |
| 1130 String::Handle(Z, type.Name()).ToCString(), | 1125 String::Handle(Z, type.Name()).ToCString(), |
| 1131 type.ToCString()); | 1126 type.ToCString()); |
| 1132 } | 1127 } |
| 1133 } | 1128 } |
| 1134 } | 1129 } |
| 1135 | 1130 |
| 1136 // If the type class is a signature class, we are currently finalizing a | 1131 // If the type class is a signature class, we are currently finalizing a |
| 1137 // signature type, i.e. finalizing the result type and parameter types of the | 1132 // signature type, i.e. finalizing the result type and parameter types of the |
| (...skipping 863 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2001 num_super_type_params + num_aliased_mixin_type_params, | 1996 num_super_type_params + num_aliased_mixin_type_params, |
| 2002 super_type.ToCString(), | 1997 super_type.ToCString(), |
| 2003 String::Handle(mixin_app_class.Name()).ToCString(), | 1998 String::Handle(mixin_app_class.Name()).ToCString(), |
| 2004 TypeArguments::Handle( | 1999 TypeArguments::Handle( |
| 2005 mixin_app_class.type_parameters()).ToCString()); | 2000 mixin_app_class.type_parameters()).ToCString()); |
| 2006 } | 2001 } |
| 2007 } | 2002 } |
| 2008 | 2003 |
| 2009 | 2004 |
| 2010 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class, | 2005 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class, |
| 2011 GrowableObjectArray* pending_types) { | 2006 PendingTypes* pending_types) { |
| 2012 if (mixin_app_class.is_mixin_type_applied()) { | 2007 if (mixin_app_class.is_mixin_type_applied()) { |
| 2013 return; | 2008 return; |
| 2014 } | 2009 } |
| 2015 Type& mixin_type = Type::Handle(mixin_app_class.mixin()); | 2010 Type& mixin_type = Type::Handle(mixin_app_class.mixin()); |
| 2016 ASSERT(!mixin_type.IsNull()); | 2011 ASSERT(!mixin_type.IsNull()); |
| 2017 ASSERT(mixin_type.HasResolvedTypeClass()); | 2012 ASSERT(mixin_type.HasResolvedTypeClass()); |
| 2018 const Class& mixin_class = Class::Handle(mixin_type.type_class()); | 2013 const Class& mixin_class = Class::Handle(mixin_type.type_class()); |
| 2019 | 2014 |
| 2020 if (FLAG_trace_class_finalization) { | 2015 if (FLAG_trace_class_finalization) { |
| 2021 ISL_Print("Applying mixin type '%s' to %s at pos %" Pd "\n", | 2016 ISL_Print("Applying mixin type '%s' to %s at pos %" Pd "\n", |
| (...skipping 1198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3220 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); | 3215 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); |
| 3221 field ^= fields_array.At(0); | 3216 field ^= fields_array.At(0); |
| 3222 ASSERT(field.Offset() == ByteBuffer::data_offset()); | 3217 ASSERT(field.Offset() == ByteBuffer::data_offset()); |
| 3223 name ^= field.name(); | 3218 name ^= field.name(); |
| 3224 expected_name ^= String::New("_data"); | 3219 expected_name ^= String::New("_data"); |
| 3225 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3220 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 3226 #endif | 3221 #endif |
| 3227 } | 3222 } |
| 3228 | 3223 |
| 3229 } // namespace dart | 3224 } // namespace dart |
| OLD | NEW |