Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(152)

Side by Side Diff: runtime/vm/class_finalizer.cc

Issue 25569002: Do not share type arguments of mixin types, but clone them to avoid finalization (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/object.h » ('j') | runtime/vm/object.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/heap.h" 8 #include "vm/heap.h"
9 #include "vm/isolate.h" 9 #include "vm/isolate.h"
10 #include "vm/longjump.h" 10 #include "vm/longjump.h"
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 for (intptr_t i = 0; i < num_arguments; i++) { 499 for (intptr_t i = 0; i < num_arguments; i++) {
500 type_argument = arguments.TypeAt(i); 500 type_argument = arguments.TypeAt(i);
501 ResolveType(cls, type_argument, finalization); 501 ResolveType(cls, type_argument, finalization);
502 } 502 }
503 } 503 }
504 } 504 }
505 505
506 506
507 void ClassFinalizer::FinalizeTypeParameters(const Class& cls) { 507 void ClassFinalizer::FinalizeTypeParameters(const Class& cls) {
508 if (cls.IsMixinApplication()) { 508 if (cls.IsMixinApplication()) {
509 // Copy the type parameters to the mixin application. 509 // Setup the type parameters of the mixin application and finalize the
510 // mixin type.
510 ApplyMixinType(cls); 511 ApplyMixinType(cls);
511 // Finalize the mixin type.
512 Type& mixin_type = Type::Handle(cls.mixin());
513 mixin_type ^= FinalizeType(cls, mixin_type, kCanonicalizeWellFormed);
514 // TODO(regis): Check for a malbounded mixin_type.
515 cls.set_mixin(mixin_type);
516 } 512 }
517 // The type parameter bounds are not finalized here. 513 // The type parameter bounds are not finalized here.
518 const TypeArguments& type_parameters = 514 const TypeArguments& type_parameters =
519 TypeArguments::Handle(cls.type_parameters()); 515 TypeArguments::Handle(cls.type_parameters());
520 if (!type_parameters.IsNull()) { 516 if (!type_parameters.IsNull()) {
521 TypeParameter& type_parameter = TypeParameter::Handle(); 517 TypeParameter& type_parameter = TypeParameter::Handle();
522 const intptr_t num_types = type_parameters.Length(); 518 const intptr_t num_types = type_parameters.Length();
523 for (intptr_t i = 0; i < num_types; i++) { 519 for (intptr_t i = 0; i < num_types; i++) {
524 type_parameter ^= type_parameters.TypeAt(i); 520 type_parameter ^= type_parameters.TypeAt(i);
525 type_parameter ^= FinalizeType(cls, 521 type_parameter ^= FinalizeType(cls,
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 const Class& parameterized_class = 734 const Class& parameterized_class =
739 Class::Handle(type_parameter.parameterized_class()); 735 Class::Handle(type_parameter.parameterized_class());
740 ASSERT(!parameterized_class.IsNull()); 736 ASSERT(!parameterized_class.IsNull());
741 // The index must reflect the position of this type parameter in the type 737 // The index must reflect the position of this type parameter in the type
742 // arguments vector of its parameterized class. The offset to add is the 738 // arguments vector of its parameterized class. The offset to add is the
743 // number of type arguments in the super type, which is equal to the 739 // number of type arguments in the super type, which is equal to the
744 // difference in number of type arguments and type parameters of the 740 // difference in number of type arguments and type parameters of the
745 // parameterized class. 741 // parameterized class.
746 const intptr_t offset = parameterized_class.NumTypeArguments() - 742 const intptr_t offset = parameterized_class.NumTypeArguments() -
747 parameterized_class.NumTypeParameters(); 743 parameterized_class.NumTypeParameters();
748 type_parameter.set_index(type_parameter.index() + offset); 744 // Calling NumTypeParameters() may finalize this type parameter if it
749 type_parameter.set_is_finalized(); 745 // belongs to a mixin application class.
746 if (!type_parameter.IsFinalized()) {
747 type_parameter.set_index(type_parameter.index() + offset);
748 type_parameter.set_is_finalized();
749 } else {
750 ASSERT(cls.IsMixinApplication());
751 }
750 // We do not canonicalize type parameters. 752 // We do not canonicalize type parameters.
751 return type_parameter.raw(); 753 return type_parameter.raw();
752 } 754 }
753 755
754 // At this point, we can only have a parameterized_type. 756 // At this point, we can only have a parameterized_type.
755 const Type& parameterized_type = Type::Cast(type); 757 const Type& parameterized_type = Type::Cast(type);
756 758
757 // Types illegally referring to themselves should have been detected earlier. 759 // Types illegally referring to themselves should have been detected earlier.
758 ASSERT(!parameterized_type.IsBeingFinalized()); 760 ASSERT(!parameterized_type.IsBeingFinalized());
759 761
(...skipping 917 matching lines...) Expand 10 before | Expand all | Expand 10 after
1677 ResolveSuperTypeAndInterfaces(mixin_app_class, &visited_interfaces); 1679 ResolveSuperTypeAndInterfaces(mixin_app_class, &visited_interfaces);
1678 1680
1679 if (FLAG_trace_class_finalization) { 1681 if (FLAG_trace_class_finalization) {
1680 OS::Print("Done applying mixin type '%s' to class '%s' %s extending '%s'\n", 1682 OS::Print("Done applying mixin type '%s' to class '%s' %s extending '%s'\n",
1681 String::Handle(mixin_type.Name()).ToCString(), 1683 String::Handle(mixin_type.Name()).ToCString(),
1682 String::Handle(mixin_app_class.Name()).ToCString(), 1684 String::Handle(mixin_app_class.Name()).ToCString(),
1683 TypeArguments::Handle( 1685 TypeArguments::Handle(
1684 mixin_app_class.type_parameters()).ToCString(), 1686 mixin_app_class.type_parameters()).ToCString(),
1685 AbstractType::Handle(mixin_app_class.super_type()).ToCString()); 1687 AbstractType::Handle(mixin_app_class.super_type()).ToCString());
1686 } 1688 }
1689 // Mark the application class as having been applied its mixin type in order
1690 // to avoid cycles while finalizing its mixin type.
1687 mixin_app_class.set_is_mixin_type_applied(); 1691 mixin_app_class.set_is_mixin_type_applied();
1692 // Finalize the mixin type, which may have been changed in case
1693 // mixin_app_class is a typedef.
1694 mixin_type = mixin_app_class.mixin();
1695 ASSERT(!mixin_type.IsBeingFinalized());
1696 mixin_type ^=
1697 FinalizeType(mixin_app_class, mixin_type, kCanonicalizeWellFormed);
1698 // TODO(regis): Check for a malbounded mixin_type.
1699 mixin_app_class.set_mixin(mixin_type);
1688 } 1700 }
1689 1701
1690 1702
1691 void ClassFinalizer::CreateForwardingConstructors( 1703 void ClassFinalizer::CreateForwardingConstructors(
1692 const Class& mixin_app, 1704 const Class& mixin_app,
1693 const GrowableObjectArray& cloned_funcs) { 1705 const GrowableObjectArray& cloned_funcs) {
1694 const String& mixin_name = String::Handle(mixin_app.Name()); 1706 const String& mixin_name = String::Handle(mixin_app.Name());
1695 const Class& super_class = Class::Handle(mixin_app.SuperClass()); 1707 const Class& super_class = Class::Handle(mixin_app.SuperClass());
1696 const String& super_name = String::Handle(super_class.Name()); 1708 const String& super_name = String::Handle(super_class.Name());
1697 const Type& dynamic_type = Type::Handle(Type::DynamicType()); 1709 const Type& dynamic_type = Type::Handle(Type::DynamicType());
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
2125 AbstractTypeArguments& type_args = 2137 AbstractTypeArguments& type_args =
2126 AbstractTypeArguments::Handle(type.arguments()); 2138 AbstractTypeArguments::Handle(type.arguments());
2127 const intptr_t num_type_parameters = type_class.NumTypeParameters(); 2139 const intptr_t num_type_parameters = type_class.NumTypeParameters();
2128 const intptr_t num_type_arguments = 2140 const intptr_t num_type_arguments =
2129 type_args.IsNull() ? 0 : type_args.Length(); 2141 type_args.IsNull() ? 0 : type_args.Length();
2130 AbstractType& arg = AbstractType::Handle(); 2142 AbstractType& arg = AbstractType::Handle();
2131 if (num_type_arguments > 0) { 2143 if (num_type_arguments > 0) {
2132 if (num_type_arguments == num_type_parameters) { 2144 if (num_type_arguments == num_type_parameters) {
2133 for (intptr_t i = 0; i < num_type_arguments; i++) { 2145 for (intptr_t i = 0; i < num_type_arguments; i++) {
2134 arg = type_args.TypeAt(i); 2146 arg = type_args.TypeAt(i);
2147 arg = arg.CloneUnfinalized();
2148 ASSERT(!arg.IsBeingFinalized());
2135 collected_args.Add(arg); 2149 collected_args.Add(arg);
2136 } 2150 }
2137 return; 2151 return;
2138 } 2152 }
2139 if (FLAG_error_on_bad_type) { 2153 if (FLAG_error_on_bad_type) {
2140 const Script& script = Script::Handle(cls.script()); 2154 const Script& script = Script::Handle(cls.script());
2141 const String& type_class_name = String::Handle(type_class.Name()); 2155 const String& type_class_name = String::Handle(type_class.Name());
2142 ReportError(Error::Handle(), // No previous error. 2156 ReportError(Error::Handle(), // No previous error.
2143 script, type.token_pos(), 2157 script, type.token_pos(),
2144 "wrong number of type arguments for class '%s'", 2158 "wrong number of type arguments for class '%s'",
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
2597 expected_name ^= String::New("_offset"); 2611 expected_name ^= String::New("_offset");
2598 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 2612 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
2599 field ^= fields_array.At(2); 2613 field ^= fields_array.At(2);
2600 ASSERT(field.Offset() == TypedDataView::length_offset()); 2614 ASSERT(field.Offset() == TypedDataView::length_offset());
2601 name ^= field.name(); 2615 name ^= field.name();
2602 ASSERT(name.Equals("length")); 2616 ASSERT(name.Equals("length"));
2603 #endif 2617 #endif
2604 } 2618 }
2605 2619
2606 } // namespace dart 2620 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/object.h » ('j') | runtime/vm/object.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698