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

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

Issue 15689012: More cleanup to avoid creation of redundant handles (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 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.h » ('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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 const GrowableObjectArray& pending_classes, 90 const GrowableObjectArray& pending_classes,
91 GrowableArray<intptr_t>* finalized_super_classes) { 91 GrowableArray<intptr_t>* finalized_super_classes) {
92 Class& cls = Class::Handle(); 92 Class& cls = Class::Handle();
93 AbstractType& super_type = Type::Handle(); 93 AbstractType& super_type = Type::Handle();
94 for (intptr_t i = 0; i < pending_classes.Length(); i++) { 94 for (intptr_t i = 0; i < pending_classes.Length(); i++) {
95 cls ^= pending_classes.At(i); 95 cls ^= pending_classes.At(i);
96 ASSERT(!cls.is_finalized()); 96 ASSERT(!cls.is_finalized());
97 super_type = cls.super_type(); 97 super_type = cls.super_type();
98 if (!super_type.IsNull()) { 98 if (!super_type.IsNull()) {
99 if (!super_type.IsMalformed() && 99 if (!super_type.IsMalformed() &&
100 super_type.HasResolvedTypeClass() && 100 super_type.HasResolvedTypeClass()) {
101 Class::Handle(super_type.type_class()).is_finalized()) { 101 cls ^= super_type.type_class();
102 AddSuperType(super_type, finalized_super_classes); 102 if (cls.is_finalized()) {
103 AddSuperType(super_type, finalized_super_classes);
104 }
103 } 105 }
104 } 106 }
105 } 107 }
106 } 108 }
107 109
108 110
109 // Class finalization occurs: 111 // Class finalization occurs:
110 // a) when bootstrap process completes (VerifyBootstrapClasses). 112 // a) when bootstrap process completes (VerifyBootstrapClasses).
111 // b) after the user classes are loaded (dart_api). 113 // b) after the user classes are loaded (dart_api).
112 bool ClassFinalizer::FinalizePendingClasses() { 114 bool ClassFinalizer::FinalizePendingClasses() {
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 const Script& script = Script::Handle(cls.script()); 369 const Script& script = Script::Handle(cls.script());
368 ReportError(script, factory.token_pos(), 370 ReportError(script, factory.token_pos(),
369 "constructor '%s' must be const as required by redirecting" 371 "constructor '%s' must be const as required by redirecting"
370 "const factory '%s'", 372 "const factory '%s'",
371 String::Handle(target.name()).ToCString(), 373 String::Handle(target.name()).ToCString(),
372 String::Handle(factory.name()).ToCString()); 374 String::Handle(factory.name()).ToCString());
373 } 375 }
374 376
375 // Update redirection data with resolved target. 377 // Update redirection data with resolved target.
376 factory.SetRedirectionTarget(target); 378 factory.SetRedirectionTarget(target);
377 factory.SetRedirectionIdentifier(String::Handle()); // Not needed anymore. 379 // Not needed anymore.
380 factory.SetRedirectionIdentifier(String::null_object());
378 if (!target.IsRedirectingFactory()) { 381 if (!target.IsRedirectingFactory()) {
379 return; 382 return;
380 } 383 }
381 384
382 // The target is itself a redirecting factory. Recursively resolve its own 385 // The target is itself a redirecting factory. Recursively resolve its own
383 // target and update the current redirection data to point to the end target 386 // target and update the current redirection data to point to the end target
384 // of the redirection chain. 387 // of the redirection chain.
385 ResolveRedirectingFactoryTarget(target_class, target, visited_factories); 388 ResolveRedirectingFactoryTarget(target_class, target, visited_factories);
386 Type& target_type = Type::Handle(target.RedirectionType()); 389 Type& target_type = Type::Handle(target.RedirectionType());
387 Function& target_target = Function::Handle(target.RedirectionTarget()); 390 Function& target_target = Function::Handle(target.RedirectionTarget());
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
875 parameterized_type.UserVisibleName()); 878 parameterized_type.UserVisibleName());
876 const Type& malformed_bound = Type::Handle( 879 const Type& malformed_bound = Type::Handle(
877 NewFinalizedMalformedType(bound_error, 880 NewFinalizedMalformedType(bound_error,
878 cls, 881 cls,
879 parameterized_type.token_pos(), 882 parameterized_type.token_pos(),
880 bound_finalization, 883 bound_finalization,
881 "type '%s' has an out of bound type argument", 884 "type '%s' has an out of bound type argument",
882 parameterized_type_name.ToCString())); 885 parameterized_type_name.ToCString()));
883 return BoundedType::New(parameterized_type, 886 return BoundedType::New(parameterized_type,
884 malformed_bound, 887 malformed_bound,
885 TypeParameter::Handle()); 888 TypeParameter::null_object());
886 } 889 }
887 890
888 if (finalization >= kCanonicalize) { 891 if (finalization >= kCanonicalize) {
889 return parameterized_type.Canonicalize(); 892 return parameterized_type.Canonicalize();
890 } else { 893 } else {
891 return parameterized_type.raw(); 894 return parameterized_type.raw();
892 } 895 }
893 } 896 }
894 897
895 898
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after
1431 ResolveAndFinalizeSignature(cls, sig_function); 1434 ResolveAndFinalizeSignature(cls, sig_function);
1432 1435
1433 // Resolve and finalize the signature type of this signature class. 1436 // Resolve and finalize the signature type of this signature class.
1434 const Type& sig_type = Type::Handle(cls.SignatureType()); 1437 const Type& sig_type = Type::Handle(cls.SignatureType());
1435 FinalizeType(cls, sig_type, kCanonicalizeWellFormed); 1438 FinalizeType(cls, sig_type, kCanonicalizeWellFormed);
1436 return; 1439 return;
1437 } 1440 }
1438 // Finalize interface types (but not necessarily interface classes). 1441 // Finalize interface types (but not necessarily interface classes).
1439 Array& interface_types = Array::Handle(cls.interfaces()); 1442 Array& interface_types = Array::Handle(cls.interfaces());
1440 AbstractType& interface_type = AbstractType::Handle(); 1443 AbstractType& interface_type = AbstractType::Handle();
1444 AbstractType& seen_interf = AbstractType::Handle();
1441 for (intptr_t i = 0; i < interface_types.Length(); i++) { 1445 for (intptr_t i = 0; i < interface_types.Length(); i++) {
1442 interface_type ^= interface_types.At(i); 1446 interface_type ^= interface_types.At(i);
1443 interface_type = FinalizeType(cls, interface_type, kCanonicalizeWellFormed); 1447 interface_type = FinalizeType(cls, interface_type, kCanonicalizeWellFormed);
1444 interface_types.SetAt(i, interface_type); 1448 interface_types.SetAt(i, interface_type);
1445 1449
1446 // Check whether the interface is duplicated. We need to wait with 1450 // Check whether the interface is duplicated. We need to wait with
1447 // this check until the super type and interface types are finalized, 1451 // this check until the super type and interface types are finalized,
1448 // so that we can use Type::Equals() for the test. 1452 // so that we can use Type::Equals() for the test.
1449 ASSERT(interface_type.IsFinalized()); 1453 ASSERT(interface_type.IsFinalized());
1450 ASSERT(super_type.IsNull() || super_type.IsFinalized()); 1454 ASSERT(super_type.IsNull() || super_type.IsFinalized());
1451 if (!super_type.IsNull() && interface_type.Equals(super_type)) { 1455 if (!super_type.IsNull() && interface_type.Equals(super_type)) {
1452 const Script& script = Script::Handle(cls.script()); 1456 const Script& script = Script::Handle(cls.script());
1453 ReportError(script, cls.token_pos(), 1457 ReportError(script, cls.token_pos(),
1454 "super type '%s' may not be listed in " 1458 "super type '%s' may not be listed in "
1455 "implements clause of class '%s'", 1459 "implements clause of class '%s'",
1456 String::Handle(super_type.Name()).ToCString(), 1460 String::Handle(super_type.Name()).ToCString(),
1457 String::Handle(cls.Name()).ToCString()); 1461 String::Handle(cls.Name()).ToCString());
1458 } 1462 }
1459 AbstractType& seen_interf = AbstractType::Handle();
1460 for (intptr_t j = 0; j < i; j++) { 1463 for (intptr_t j = 0; j < i; j++) {
1461 seen_interf ^= interface_types.At(j); 1464 seen_interf ^= interface_types.At(j);
1462 if (interface_type.Equals(seen_interf)) { 1465 if (interface_type.Equals(seen_interf)) {
1463 const Script& script = Script::Handle(cls.script()); 1466 const Script& script = Script::Handle(cls.script());
1464 ReportError(script, cls.token_pos(), 1467 ReportError(script, cls.token_pos(),
1465 "interface '%s' appears twice in " 1468 "interface '%s' appears twice in "
1466 "implements clause of class '%s'", 1469 "implements clause of class '%s'",
1467 String::Handle(interface_type.Name()).ToCString(), 1470 String::Handle(interface_type.Name()).ToCString(),
1468 String::Handle(cls.Name()).ToCString()); 1471 String::Handle(cls.Name()).ToCString());
1469 } 1472 }
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1616 // Resolve super type and all mixin types. 1619 // Resolve super type and all mixin types.
1617 const GrowableObjectArray& type_args = 1620 const GrowableObjectArray& type_args =
1618 GrowableObjectArray::Handle(GrowableObjectArray::New()); 1621 GrowableObjectArray::Handle(GrowableObjectArray::New());
1619 AbstractType& type = AbstractType::Handle(mixin_app.super_type()); 1622 AbstractType& type = AbstractType::Handle(mixin_app.super_type());
1620 ResolveType(cls, type, kCanonicalizeWellFormed); 1623 ResolveType(cls, type, kCanonicalizeWellFormed);
1621 ASSERT(type.HasResolvedTypeClass()); 1624 ASSERT(type.HasResolvedTypeClass());
1622 // TODO(hausner): May need to handle BoundedType here. 1625 // TODO(hausner): May need to handle BoundedType here.
1623 ASSERT(type.IsType()); 1626 ASSERT(type.IsType());
1624 CollectTypeArguments(cls, Type::Cast(type), type_args); 1627 CollectTypeArguments(cls, Type::Cast(type), type_args);
1625 const Array& mixins = Array::Handle(mixin_app.mixin_types()); 1628 const Array& mixins = Array::Handle(mixin_app.mixin_types());
1629 Class& mixin_app_class = Class::Handle();
1626 for (int i = 0; i < mixins.Length(); i++) { 1630 for (int i = 0; i < mixins.Length(); i++) {
1627 type ^= mixins.At(i); 1631 type ^= mixins.At(i);
1628 ASSERT(type.HasResolvedTypeClass()); // Newly created class in parser. 1632 ASSERT(type.HasResolvedTypeClass()); // Newly created class in parser.
1629 const Class& mixin_app_class = Class::Handle(type.type_class()); 1633 mixin_app_class ^= type.type_class();
1630 type = mixin_app_class.mixin(); 1634 type = mixin_app_class.mixin();
1631 ASSERT(!type.IsNull()); 1635 ASSERT(!type.IsNull());
1632 ResolveType(cls, type, kCanonicalizeWellFormed); 1636 ResolveType(cls, type, kCanonicalizeWellFormed);
1633 ASSERT(type.HasResolvedTypeClass()); 1637 ASSERT(type.HasResolvedTypeClass());
1634 ASSERT(type.IsType()); 1638 ASSERT(type.IsType());
1635 CollectTypeArguments(cls, Type::Cast(type), type_args); 1639 CollectTypeArguments(cls, Type::Cast(type), type_args);
1636 } 1640 }
1637 const TypeArguments& mixin_app_args = 1641 const TypeArguments& mixin_app_args =
1638 TypeArguments::Handle(TypeArguments::New(type_args.Length())); 1642 TypeArguments::Handle(TypeArguments::New(type_args.Length()));
1639 for (int i = 0; i < type_args.Length(); i++) { 1643 for (int i = 0; i < type_args.Length(); i++) {
1640 type ^= type_args.At(i); 1644 type ^= type_args.At(i);
1641 mixin_app_args.SetTypeAt(i, type); 1645 mixin_app_args.SetTypeAt(i, type);
1642 } 1646 }
1643 if (FLAG_trace_class_finalization) { 1647 if (FLAG_trace_class_finalization) {
1644 OS::Print("ResolveMixinAppType: mixin appl type args: %s\n", 1648 OS::Print("ResolveMixinAppType: mixin appl type args: %s\n",
1645 mixin_app_args.ToCString()); 1649 mixin_app_args.ToCString());
1646 } 1650 }
1647 // The last element in the mixins array is the lowest mixin application 1651 // The last element in the mixins array is the lowest mixin application
1648 // type in the mixin chain. Build a new super type with its type class 1652 // type in the mixin chain. Build a new super type with its type class
1649 // and the collected type arguments from the super type and all 1653 // and the collected type arguments from the super type and all
1650 // mixin types. This super type replaces the MixinAppType object 1654 // mixin types. This super type replaces the MixinAppType object
1651 // in the class that extends the mixin application. 1655 // in the class that extends the mixin application.
1652 type ^= mixins.At(mixins.Length() - 1); 1656 type ^= mixins.At(mixins.Length() - 1);
1653 const Class& resolved_mixin_app_class = Class::Handle(type.type_class()); 1657 mixin_app_class ^= type.type_class();
1654 Type& resolved_mixin_app_type = Type::Handle(); 1658 return Type::New(mixin_app_class,
1655 resolved_mixin_app_type = Type::New(resolved_mixin_app_class, 1659 mixin_app_args,
1656 mixin_app_args, 1660 mixin_app.token_pos());
1657 mixin_app.token_pos());
1658 return resolved_mixin_app_type.raw();
1659 } 1661 }
1660 1662
1661 1663
1662 // Recursively walks the graph of explicitly declared super type and 1664 // Recursively walks the graph of explicitly declared super type and
1663 // interfaces, resolving unresolved super types and interfaces. 1665 // interfaces, resolving unresolved super types and interfaces.
1664 // Reports an error if there is an interface reference that cannot be 1666 // Reports an error if there is an interface reference that cannot be
1665 // resolved, or if there is a cycle in the graph. We detect cycles by 1667 // resolved, or if there is a cycle in the graph. We detect cycles by
1666 // remembering interfaces we've visited in each path through the 1668 // remembering interfaces we've visited in each path through the
1667 // graph. If we visit an interface a second time on a given path, 1669 // graph. If we visit an interface a second time on a given path,
1668 // we found a loop. 1670 // we found a loop.
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
1908 } 1910 }
1909 } 1911 }
1910 // In checked mode, always mark the type as malformed. 1912 // In checked mode, always mark the type as malformed.
1911 // In production mode, mark the type as malformed only if its type class is 1913 // In production mode, mark the type as malformed only if its type class is
1912 // not resolved. 1914 // not resolved.
1913 // In both mode, make the type raw, since it may not be possible to 1915 // In both mode, make the type raw, since it may not be possible to
1914 // properly finalize its type arguments. 1916 // properly finalize its type arguments.
1915 if (FLAG_enable_type_checks || !type.HasResolvedTypeClass()) { 1917 if (FLAG_enable_type_checks || !type.HasResolvedTypeClass()) {
1916 type.set_malformed_error(error); 1918 type.set_malformed_error(error);
1917 } 1919 }
1918 type.set_arguments(AbstractTypeArguments::Handle()); 1920 type.set_arguments(AbstractTypeArguments::null_object());
1919 if (!type.IsFinalized()) { 1921 if (!type.IsFinalized()) {
1920 type.SetIsFinalized(); 1922 type.SetIsFinalized();
1921 // Do not canonicalize malformed types, since they may not be resolved. 1923 // Do not canonicalize malformed types, since they may not be resolved.
1922 } else { 1924 } else {
1923 // The only case where the malformed type was already finalized is when its 1925 // The only case where the malformed type was already finalized is when its
1924 // type arguments are not within bounds. In that case, we have a prev_error. 1926 // type arguments are not within bounds. In that case, we have a prev_error.
1925 ASSERT(!prev_error.IsNull()); 1927 ASSERT(!prev_error.IsNull());
1926 } 1928 }
1927 } 1929 }
1928 1930
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
2042 expected_name ^= String::New("_offset"); 2044 expected_name ^= String::New("_offset");
2043 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 2045 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
2044 field ^= fields_array.At(2); 2046 field ^= fields_array.At(2);
2045 ASSERT(field.Offset() == TypedDataView::length_offset()); 2047 ASSERT(field.Offset() == TypedDataView::length_offset());
2046 name ^= field.name(); 2048 name ^= field.name();
2047 ASSERT(name.Equals("length")); 2049 ASSERT(name.Equals("length"));
2048 #endif 2050 #endif
2049 } 2051 }
2050 2052
2051 } // namespace dart 2053 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/object.h » ('j') | runtime/vm/object.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698