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