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

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

Issue 1580643004: Fix finalization of recursive type graph with bounds (issue 25389). (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 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
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 3858 matching lines...) Expand 10 before | Expand all | Expand 10 after
3869 Array& interfaces = Array::Handle(zone, thsi.interfaces()); 3869 Array& interfaces = Array::Handle(zone, thsi.interfaces());
3870 AbstractType& interface = AbstractType::Handle(zone); 3870 AbstractType& interface = AbstractType::Handle(zone);
3871 Class& interface_class = Class::Handle(zone); 3871 Class& interface_class = Class::Handle(zone);
3872 TypeArguments& interface_args = TypeArguments::Handle(zone); 3872 TypeArguments& interface_args = TypeArguments::Handle(zone);
3873 Error& error = Error::Handle(zone); 3873 Error& error = Error::Handle(zone);
3874 for (intptr_t i = 0; i < interfaces.Length(); i++) { 3874 for (intptr_t i = 0; i < interfaces.Length(); i++) {
3875 interface ^= interfaces.At(i); 3875 interface ^= interfaces.At(i);
3876 if (!interface.IsFinalized()) { 3876 if (!interface.IsFinalized()) {
3877 // We may be checking bounds at finalization time and can encounter 3877 // We may be checking bounds at finalization time and can encounter
3878 // a still unfinalized interface. 3878 // a still unfinalized interface.
3879 if (interface.IsBeingFinalized()) {
3880 // Interface is part of a still unfinalized recursive type graph.
3881 // Skip it. The caller will create a bounded type to be checked at
3882 // runtime if this type test returns false at compile time.
3883 continue;
3884 }
3879 ClassFinalizer::FinalizeType( 3885 ClassFinalizer::FinalizeType(
3880 thsi, interface, ClassFinalizer::kCanonicalize); 3886 thsi, interface, ClassFinalizer::kCanonicalize);
3881 interfaces.SetAt(i, interface); 3887 interfaces.SetAt(i, interface);
3882 } 3888 }
3883 if (interface.IsMalbounded()) { 3889 if (interface.IsMalbounded()) {
3884 // Return the first bound error to the caller if it requests it. 3890 // Return the first bound error to the caller if it requests it.
3885 if ((bound_error != NULL) && bound_error->IsNull()) { 3891 if ((bound_error != NULL) && bound_error->IsNull()) {
3886 *bound_error = interface.error(); 3892 *bound_error = interface.error();
3887 } 3893 }
3888 continue; // Another interface may work better. 3894 continue; // Another interface may work better.
(...skipping 11617 matching lines...) Expand 10 before | Expand all | Expand 10 after
15506 // Build the bound name without causing divergence. 15512 // Build the bound name without causing divergence.
15507 const AbstractType& bound = AbstractType::Handle( 15513 const AbstractType& bound = AbstractType::Handle(
15508 zone, BoundedType::Cast(*this).bound()); 15514 zone, BoundedType::Cast(*this).bound());
15509 String& bound_name = String::Handle(zone); 15515 String& bound_name = String::Handle(zone);
15510 if (bound.IsTypeParameter()) { 15516 if (bound.IsTypeParameter()) {
15511 bound_name = TypeParameter::Cast(bound).name(); 15517 bound_name = TypeParameter::Cast(bound).name();
15512 pieces.Add(bound_name); 15518 pieces.Add(bound_name);
15513 } else if (bound.IsType()) { 15519 } else if (bound.IsType()) {
15514 const Class& cls = Class::Handle(zone, Type::Cast(bound).type_class()); 15520 const Class& cls = Class::Handle(zone, Type::Cast(bound).type_class());
15515 bound_name = cls.Name(); 15521 bound_name = cls.Name();
15522 pieces.Add(bound_name);
15516 if (Type::Cast(bound).arguments() != TypeArguments::null()) { 15523 if (Type::Cast(bound).arguments() != TypeArguments::null()) {
15517 pieces.Add(bound_name);
15518 pieces.Add(Symbols::OptimizedOut()); 15524 pieces.Add(Symbols::OptimizedOut());
15519 } 15525 }
15520 } else { 15526 } else {
15521 pieces.Add(Symbols::OptimizedOut()); 15527 pieces.Add(Symbols::OptimizedOut());
15522 } 15528 }
15523 return Symbols::FromConcatAll(pieces); 15529 return Symbols::FromConcatAll(pieces);
15524 } 15530 }
15525 if (IsTypeParameter()) { 15531 if (IsTypeParameter()) {
15526 return TypeParameter::Cast(*this).name(); 15532 return TypeParameter::Cast(*this).name();
15527 } 15533 }
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
15720 ASSERT(Isolate::Current()->flags().type_checks()); 15726 ASSERT(Isolate::Current()->flags().type_checks());
15721 if ((bound_error != NULL) && bound_error->IsNull()) { 15727 if ((bound_error != NULL) && bound_error->IsNull()) {
15722 *bound_error = other.error(); 15728 *bound_error = other.error();
15723 } 15729 }
15724 return false; 15730 return false;
15725 } 15731 }
15726 if (IsBoundedType() || other.IsBoundedType()) { 15732 if (IsBoundedType() || other.IsBoundedType()) {
15727 if (Equals(other)) { 15733 if (Equals(other)) {
15728 return true; 15734 return true;
15729 } 15735 }
15736 // Redundant check if other type is equal to the upper bound of this type.
15737 if (IsBoundedType() &&
15738 AbstractType::Handle(BoundedType::Cast(*this).bound()).Equals(other)) {
15739 return true;
15740 }
15730 return false; // TODO(regis): We should return "maybe after instantiation". 15741 return false; // TODO(regis): We should return "maybe after instantiation".
15731 } 15742 }
15732 // Type parameters cannot be handled by Class::TypeTest(). 15743 // Type parameters cannot be handled by Class::TypeTest().
15733 // When comparing two uninstantiated function types, one returning type 15744 // When comparing two uninstantiated function types, one returning type
15734 // parameter K, the other returning type parameter V, we cannot assume that K 15745 // parameter K, the other returning type parameter V, we cannot assume that K
15735 // is a subtype of V, or vice versa. We only return true if K equals V, as 15746 // is a subtype of V, or vice versa. We only return true if K equals V, as
15736 // defined by TypeParameter::Equals. 15747 // defined by TypeParameter::Equals.
15737 // The same rule applies when checking the upper bound of a still 15748 // The same rule applies when checking the upper bound of a still
15738 // uninstantiated type at compile time. Returning false will defer the test 15749 // uninstantiated type at compile time. Returning false will defer the test
15739 // to run time. 15750 // to run time.
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
16137 if (from_index > 0) { 16148 if (from_index > 0) {
16138 // Verify that the type arguments of the super class match, since they 16149 // Verify that the type arguments of the super class match, since they
16139 // depend solely on the type parameters that were just verified to match. 16150 // depend solely on the type parameters that were just verified to match.
16140 ASSERT(type_args.Length() >= (from_index + num_type_params)); 16151 ASSERT(type_args.Length() >= (from_index + num_type_params));
16141 ASSERT(other_type_args.Length() >= (from_index + num_type_params)); 16152 ASSERT(other_type_args.Length() >= (from_index + num_type_params));
16142 AbstractType& type_arg = AbstractType::Handle(zone); 16153 AbstractType& type_arg = AbstractType::Handle(zone);
16143 AbstractType& other_type_arg = AbstractType::Handle(zone); 16154 AbstractType& other_type_arg = AbstractType::Handle(zone);
16144 for (intptr_t i = 0; i < from_index; i++) { 16155 for (intptr_t i = 0; i < from_index; i++) {
16145 type_arg = type_args.TypeAt(i); 16156 type_arg = type_args.TypeAt(i);
16146 other_type_arg = other_type_args.TypeAt(i); 16157 other_type_arg = other_type_args.TypeAt(i);
16158 // Ignore bounds of bounded types.
16159 while (type_arg.IsBoundedType()) {
16160 type_arg = BoundedType::Cast(type_arg).type();
16161 }
16162 while (other_type_arg.IsBoundedType()) {
16163 other_type_arg = BoundedType::Cast(other_type_arg).type();
16164 }
16147 ASSERT(type_arg.IsEquivalent(other_type_arg, trail)); 16165 ASSERT(type_arg.IsEquivalent(other_type_arg, trail));
16148 } 16166 }
16149 } 16167 }
16150 #endif 16168 #endif
16151 return true; 16169 return true;
16152 } 16170 }
16153 16171
16154 16172
16155 bool Type::IsRecursive() const { 16173 bool Type::IsRecursive() const {
16156 return TypeArguments::Handle(arguments()).IsRecursive(); 16174 return TypeArguments::Handle(arguments()).IsRecursive();
(...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after
16966 ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType()); 16984 ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType());
16967 const TypeParameter& type_param = TypeParameter::Handle(type_parameter()); 16985 const TypeParameter& type_param = TypeParameter::Handle(type_parameter());
16968 if (!upper_bound.IsInstantiated()) { 16986 if (!upper_bound.IsInstantiated()) {
16969 upper_bound = upper_bound.InstantiateFrom(instantiator_type_arguments, 16987 upper_bound = upper_bound.InstantiateFrom(instantiator_type_arguments,
16970 bound_error, 16988 bound_error,
16971 trail, 16989 trail,
16972 space); 16990 space);
16973 // Instantiated upper_bound may not be finalized. See comment above. 16991 // Instantiated upper_bound may not be finalized. See comment above.
16974 } 16992 }
16975 if (bound_error->IsNull()) { 16993 if (bound_error->IsNull()) {
16976 if (!type_param.CheckBound(bounded_type, upper_bound, bound_error) && 16994 if (bounded_type.IsBeingFinalized() ||
16977 bound_error->IsNull()) { 16995 upper_bound.IsBeingFinalized() ||
16996 (!type_param.CheckBound(bounded_type, upper_bound, bound_error) &&
16997 bound_error->IsNull())) {
16978 // We cannot determine yet whether the bounded_type is below the 16998 // We cannot determine yet whether the bounded_type is below the
16979 // upper_bound, because one or both of them is still uninstantiated. 16999 // upper_bound, because one or both of them is still being finalized or
16980 ASSERT(!bounded_type.IsInstantiated() || !upper_bound.IsInstantiated()); 17000 // uninstantiated.
16981 // Postpone bound check by returning a new BoundedType with partially 17001 ASSERT(bounded_type.IsBeingFinalized() ||
16982 // instantiated bounded_type and upper_bound, but keeping type_param. 17002 upper_bound.IsBeingFinalized() ||
17003 !bounded_type.IsInstantiated() ||
17004 !upper_bound.IsInstantiated());
17005 // Postpone bound check by returning a new BoundedType with unfinalized
17006 // or partially instantiated bounded_type and upper_bound, but keeping
17007 // type_param.
16983 bounded_type = BoundedType::New(bounded_type, upper_bound, type_param); 17008 bounded_type = BoundedType::New(bounded_type, upper_bound, type_param);
16984 } 17009 }
16985 } 17010 }
16986 } 17011 }
16987 return bounded_type.raw(); 17012 return bounded_type.raw();
16988 } 17013 }
16989 17014
16990 17015
16991 RawAbstractType* BoundedType::CloneUnfinalized() const { 17016 RawAbstractType* BoundedType::CloneUnfinalized() const {
16992 if (IsFinalized()) { 17017 if (IsFinalized()) {
(...skipping 5040 matching lines...) Expand 10 before | Expand all | Expand 10 after
22033 return tag_label.ToCString(); 22058 return tag_label.ToCString();
22034 } 22059 }
22035 22060
22036 22061
22037 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { 22062 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const {
22038 Instance::PrintJSONImpl(stream, ref); 22063 Instance::PrintJSONImpl(stream, ref);
22039 } 22064 }
22040 22065
22041 22066
22042 } // namespace dart 22067 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698