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

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

Issue 26955002: Overlap type arguments of a type with the type arguments of its super type (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 | « runtime/vm/object.h ('k') | no next file » | 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 30 matching lines...) Expand all
41 #include "vm/symbols.h" 41 #include "vm/symbols.h"
42 #include "vm/timer.h" 42 #include "vm/timer.h"
43 #include "vm/unicode.h" 43 #include "vm/unicode.h"
44 44
45 namespace dart { 45 namespace dart {
46 46
47 DEFINE_FLAG(int, huge_method_cutoff_in_code_size, 200000, 47 DEFINE_FLAG(int, huge_method_cutoff_in_code_size, 200000,
48 "Huge method cutoff in unoptimized code size (in bytes)."); 48 "Huge method cutoff in unoptimized code size (in bytes).");
49 DEFINE_FLAG(int, huge_method_cutoff_in_tokens, 20000, 49 DEFINE_FLAG(int, huge_method_cutoff_in_tokens, 20000,
50 "Huge method cutoff in tokens: Disables optimizations for huge methods."); 50 "Huge method cutoff in tokens: Disables optimizations for huge methods.");
51 DEFINE_FLAG(bool, overlap_type_arguments, true,
52 "When possible, partially or fully overlap the type arguments of a type "
53 "with the type arguments of its super type.");
51 DEFINE_FLAG(bool, show_internal_names, false, 54 DEFINE_FLAG(bool, show_internal_names, false,
52 "Show names of internal classes (e.g. \"OneByteString\") in error messages " 55 "Show names of internal classes (e.g. \"OneByteString\") in error messages "
53 "instead of showing the corresponding interface names (e.g. \"String\")"); 56 "instead of showing the corresponding interface names (e.g. \"String\")");
54 DEFINE_FLAG(bool, trace_disabling_optimized_code, false, 57 DEFINE_FLAG(bool, trace_disabling_optimized_code, false,
55 "Trace disabling optimized code."); 58 "Trace disabling optimized code.");
56 DEFINE_FLAG(bool, throw_on_javascript_int_overflow, false, 59 DEFINE_FLAG(bool, throw_on_javascript_int_overflow, false,
57 "Throw an exception when the result of an integer calculation will not " 60 "Throw an exception when the result of an integer calculation will not "
58 "fit into a javascript integer."); 61 "fit into a javascript integer.");
59 DECLARE_FLAG(bool, eliminate_type_checks); 62 DECLARE_FLAG(bool, eliminate_type_checks);
60 DECLARE_FLAG(bool, enable_type_checks); 63 DECLARE_FLAG(bool, enable_type_checks);
(...skipping 1637 matching lines...) Expand 10 before | Expand all | Expand 10 after
1698 ClassFinalizer::ApplyMixinType(*this); 1701 ClassFinalizer::ApplyMixinType(*this);
1699 } 1702 }
1700 if (type_parameters() == TypeArguments::null()) { 1703 if (type_parameters() == TypeArguments::null()) {
1701 return 0; 1704 return 0;
1702 } 1705 }
1703 const TypeArguments& type_params = TypeArguments::Handle(type_parameters()); 1706 const TypeArguments& type_params = TypeArguments::Handle(type_parameters());
1704 return type_params.Length(); 1707 return type_params.Length();
1705 } 1708 }
1706 1709
1707 1710
1711 intptr_t Class::NumOwnTypeArguments() const {
1712 Isolate* isolate = Isolate::Current();
1713 const intptr_t num_type_params = NumTypeParameters();
1714 if (!FLAG_overlap_type_arguments ||
1715 (num_type_params == 0) ||
1716 (super_type() == AbstractType::null()) ||
1717 (super_type() == isolate->object_store()->object_type())) {
1718 return num_type_params;
1719 }
1720 ASSERT(!IsMixinApplication() || is_mixin_type_applied());
1721 const AbstractType& sup_type = AbstractType::Handle(isolate, super_type());
1722 ASSERT(sup_type.IsResolved());
1723 const AbstractTypeArguments& sup_type_args =
1724 AbstractTypeArguments::Handle(isolate, sup_type.arguments());
1725 if (sup_type_args.IsNull()) {
1726 // The super type is raw or the super class is non generic.
1727 // In either case, overlapping is not possible.
1728 return num_type_params;
1729 }
1730 const intptr_t num_sup_type_args = sup_type_args.Length();
1731 // At this point, the super type may or may not be finalized. In either case,
1732 // the result of this function must remain the same.
1733 // The value of num_sup_type_args may increase when the super type is
1734 // finalized, but the last num_sup_type_args type arguments will not be
1735 // modified by finalization, only shifted to higher indices in the vector.
1736 // They may however get wrapped in a BoundedType, which we skip.
1737 const AbstractTypeArguments& type_params =
1738 AbstractTypeArguments::Handle(isolate, type_parameters());
1739 // Determine the maximum overlap of a prefix of the vector consisting of the
1740 // type parameters of this class with a suffix of the vector consisting of the
1741 // type arguments of the super type of this class.
1742 // The number of own type arguments of this class is the number of its type
1743 // parameters minus the number of type arguments in the overlap.
1744 // Attempt to overlap the whole vector of type parameters; reduce the size
1745 // of the vector (keeping the first type parameter) until it fits or until
1746 // its size is zero.
1747 TypeParameter& type_param = TypeParameter::Handle(isolate);
1748 AbstractType& sup_type_arg = AbstractType::Handle(isolate);
1749 for (intptr_t num_overlapping_type_args =
1750 (num_type_params < num_sup_type_args) ?
1751 num_type_params : num_sup_type_args;
1752 num_overlapping_type_args > 0; num_overlapping_type_args--) {
1753 intptr_t i = 0;
1754 for (; i < num_overlapping_type_args; i++) {
1755 type_param ^= type_params.TypeAt(i);
1756 sup_type_arg = sup_type_args.TypeAt(
1757 num_sup_type_args - num_overlapping_type_args + i);
1758 // BoundedType can nest in case the finalized super type has bounded type
1759 // arguments that overlap multiple times in its own super class chain.
1760 while (sup_type_arg.IsBoundedType()) {
1761 sup_type_arg = BoundedType::Cast(sup_type_arg).type();
1762 }
1763 if (!type_param.Equals(sup_type_arg)) break;
1764 }
1765 if (i == num_overlapping_type_args) {
1766 // Overlap found.
1767 return num_type_params - num_overlapping_type_args;
1768 }
1769 }
1770 // No overlap found.
1771 return num_type_params;
1772 }
1773
1774
1708 intptr_t Class::NumTypeArguments() const { 1775 intptr_t Class::NumTypeArguments() const {
1709 // To work properly, this call requires the super class of this class to be 1776 // To work properly, this call requires the super class of this class to be
1710 // resolved, which is checked by the type_class() call on the super type. 1777 // resolved, which is checked by the type_class() call on the super type.
1711 // Note that calling type_class() on a MixinAppType fails. 1778 // Note that calling type_class() on a MixinAppType fails.
1712 Isolate* isolate = Isolate::Current(); 1779 Isolate* isolate = Isolate::Current();
1713 Class& cls = Class::Handle(isolate); 1780 Class& cls = Class::Handle(isolate);
1714 TypeArguments& type_params = TypeArguments::Handle(isolate);
1715 AbstractType& sup_type = AbstractType::Handle(isolate); 1781 AbstractType& sup_type = AbstractType::Handle(isolate);
1716 cls = raw(); 1782 cls = raw();
1717 intptr_t num_type_args = 0; 1783 intptr_t num_type_args = 0;
1718
1719 do { 1784 do {
1720 if (cls.IsSignatureClass()) { 1785 if (cls.IsSignatureClass()) {
1721 Function& signature_fun = Function::Handle(isolate); 1786 Function& signature_fun = Function::Handle(isolate);
1722 signature_fun ^= cls.signature_function(); 1787 signature_fun ^= cls.signature_function();
1723 if (!signature_fun.is_static() && 1788 if (!signature_fun.is_static() &&
1724 !signature_fun.HasInstantiatedSignature()) { 1789 !signature_fun.HasInstantiatedSignature()) {
1725 cls = signature_fun.Owner(); 1790 cls = signature_fun.Owner();
1726 } 1791 }
1727 } 1792 }
1728 // Calling NumTypeParameters() on a mixin application class will setup the 1793 // Calling NumOwnTypeArguments() on a mixin application class will setup the
1729 // type parameters if not already done. 1794 // type parameters if not already done.
1730 if (cls.NumTypeParameters() > 0) { 1795 num_type_args += cls.NumOwnTypeArguments();
1731 type_params ^= cls.type_parameters();
1732 num_type_args += type_params.Length();
1733 }
1734 // Super type of Object class is null. 1796 // Super type of Object class is null.
1735 if (cls.super_type() == AbstractType::null() || 1797 if ((cls.super_type() == AbstractType::null()) ||
1736 cls.super_type() == isolate->object_store()->object_type()) { 1798 (cls.super_type() == isolate->object_store()->object_type())) {
1737 break; 1799 break;
1738 } 1800 }
1739 sup_type = cls.super_type(); 1801 sup_type = cls.super_type();
1740 cls = sup_type.type_class(); 1802 cls = sup_type.type_class();
1741 } while (true); 1803 } while (true);
1742 return num_type_args; 1804 return num_type_args;
1743 } 1805 }
1744 1806
1745 1807
1746 // More efficient than calling NumTypeArguments(). 1808 // More efficient than calling NumTypeArguments().
(...skipping 1646 matching lines...) Expand 10 before | Expand all | Expand 10 after
3393 return false; 3455 return false;
3394 } 3456 }
3395 } 3457 }
3396 return true; 3458 return true;
3397 // Note that it is not necessary to verify at runtime that the instantiator 3459 // Note that it is not necessary to verify at runtime that the instantiator
3398 // type vector is long enough, since this uninstantiated vector contains as 3460 // type vector is long enough, since this uninstantiated vector contains as
3399 // many different type parameters as it is long. 3461 // many different type parameters as it is long.
3400 } 3462 }
3401 3463
3402 3464
3465 // Return true if this uninstantiated type argument vector, once instantiated
3466 // at runtime, is a prefix of the type argument vector of its instantiator.
3403 bool TypeArguments::CanShareInstantiatorTypeArguments( 3467 bool TypeArguments::CanShareInstantiatorTypeArguments(
3404 const Class& instantiator_class) const { 3468 const Class& instantiator_class) const {
3405 ASSERT(!IsInstantiated()); 3469 ASSERT(!IsInstantiated());
3470 const intptr_t num_type_args = Length();
3406 const intptr_t num_instantiator_type_args = 3471 const intptr_t num_instantiator_type_args =
3407 instantiator_class.NumTypeArguments(); 3472 instantiator_class.NumTypeArguments();
3473 if (num_type_args > num_instantiator_type_args) {
3474 // This vector cannot be a prefix of a shorter vector.
3475 return false;
3476 }
3408 const intptr_t num_instantiator_type_params = 3477 const intptr_t num_instantiator_type_params =
3409 instantiator_class.NumTypeParameters(); 3478 instantiator_class.NumTypeParameters();
3410 const intptr_t num_super_instantiator_type_args = 3479 const intptr_t first_type_param_offset =
3411 num_instantiator_type_args - num_instantiator_type_params; 3480 num_instantiator_type_args - num_instantiator_type_params;
3412 const intptr_t num_type_args = Length(); 3481 // At compile time, the type argument vector of the instantiator consists of
3413 // As a first requirement in order to share the instantiator type argument 3482 // the type argument vector of its super type, which may refer to the type
3414 // vector, this type argument vector must refer to the type parameters of the 3483 // parameters of the instantiator class, followed by (or overlapping partially
3415 // instantiator class in declaration order. It does not need to contain all 3484 // or fully with) the type parameters of the instantiator class in declaration
3416 // type parameters. 3485 // order.
3417 if (num_type_args < num_super_instantiator_type_args) { 3486 // In other words, the only variables are the type parameters of the
3418 return false; 3487 // instantiator class.
3419 } 3488 // This uninstantiated type argument vector is also expressed in terms of the
3489 // type parameters of the instantiator class. Therefore, in order to be a
3490 // prefix once instantiated at runtime, every one of its type argument must be
3491 // equal to the type argument of the instantiator vector at the same index.
3492
3493 // As a first requirement, the last num_instantiator_type_params type
3494 // arguments of this type argument vector must refer to the corresponding type
3495 // parameters of the instantiator class.
3420 AbstractType& type_arg = AbstractType::Handle(); 3496 AbstractType& type_arg = AbstractType::Handle();
3421 for (intptr_t i = num_super_instantiator_type_args; i < num_type_args; i++) { 3497 for (intptr_t i = first_type_param_offset; i < num_type_args; i++) {
3422 type_arg = TypeAt(i); 3498 type_arg = TypeAt(i);
3423 if (!type_arg.IsTypeParameter()) { 3499 if (!type_arg.IsTypeParameter()) {
3424 return false; 3500 return false;
3425 } 3501 }
3426 const TypeParameter& type_param = TypeParameter::Cast(type_arg); 3502 const TypeParameter& type_param = TypeParameter::Cast(type_arg);
3427 ASSERT(type_param.IsFinalized()); 3503 ASSERT(type_param.IsFinalized());
3428 if ((type_param.index() != i)) { 3504 if ((type_param.index() != i)) {
3429 return false; 3505 return false;
3430 } 3506 }
3431 } 3507 }
3432 // As a second requirement, the type arguments corresponding to the super type 3508 // As a second requirement, the type arguments corresponding to the super type
3433 // must be identical. 3509 // must be identical. Overlapping ones have already been checked starting at
3434 if (num_super_instantiator_type_args == 0) { 3510 // first_type_param_offset.
3511 if (first_type_param_offset == 0) {
3435 return true; 3512 return true;
3436 } 3513 }
3437 AbstractType& super_type = AbstractType::Handle( 3514 AbstractType& super_type = AbstractType::Handle(
3438 instantiator_class.super_type()); 3515 instantiator_class.super_type());
3439 const AbstractTypeArguments& super_type_args = AbstractTypeArguments::Handle( 3516 const AbstractTypeArguments& super_type_args = AbstractTypeArguments::Handle(
3440 super_type.arguments()); 3517 super_type.arguments());
3441 if (super_type_args.IsNull()) { 3518 if (super_type_args.IsNull()) {
3442 return false; 3519 return false;
3443 } 3520 }
3444 AbstractType& super_type_arg = AbstractType::Handle(); 3521 AbstractType& super_type_arg = AbstractType::Handle();
3445 for (intptr_t i = 0; i < num_super_instantiator_type_args; i++) { 3522 for (intptr_t i = 0;
3523 (i < first_type_param_offset) && (i < num_type_args); i++) {
3446 type_arg = TypeAt(i); 3524 type_arg = TypeAt(i);
3447 super_type_arg = super_type_args.TypeAt(i); 3525 super_type_arg = super_type_args.TypeAt(i);
3448 if (!type_arg.Equals(super_type_arg)) { 3526 if (!type_arg.Equals(super_type_arg)) {
3449 return false; 3527 return false;
3450 } 3528 }
3451 } 3529 }
3452 return true; 3530 return true;
3453 } 3531 }
3454 3532
3455 3533
(...skipping 8165 matching lines...) Expand 10 before | Expand all | Expand 10 after
11621 11699
11622 11700
11623 bool TypeParameter::Equals(const Instance& other) const { 11701 bool TypeParameter::Equals(const Instance& other) const {
11624 if (raw() == other.raw()) { 11702 if (raw() == other.raw()) {
11625 return true; 11703 return true;
11626 } 11704 }
11627 if (!other.IsTypeParameter()) { 11705 if (!other.IsTypeParameter()) {
11628 return false; 11706 return false;
11629 } 11707 }
11630 const TypeParameter& other_type_param = TypeParameter::Cast(other); 11708 const TypeParameter& other_type_param = TypeParameter::Cast(other);
11631 ASSERT(other_type_param.IsFinalized());
11632 if (parameterized_class() != other_type_param.parameterized_class()) { 11709 if (parameterized_class() != other_type_param.parameterized_class()) {
11633 return false; 11710 return false;
11634 } 11711 }
11635 if (IsFinalized() != other_type_param.IsFinalized()) { 11712 if (IsFinalized() == other_type_param.IsFinalized()) {
11636 return false; 11713 return index() == other_type_param.index();
11637 } 11714 }
11638 if (index() != other_type_param.index()) { 11715 return name() == other_type_param.name();
11639 return false;
11640 }
11641 return true;
11642 } 11716 }
11643 11717
11644 11718
11645 void TypeParameter::set_parameterized_class(const Class& value) const { 11719 void TypeParameter::set_parameterized_class(const Class& value) const {
11646 // Set value may be null. 11720 // Set value may be null.
11647 StorePointer(&raw_ptr()->parameterized_class_, value.raw()); 11721 StorePointer(&raw_ptr()->parameterized_class_, value.raw());
11648 } 11722 }
11649 11723
11650 11724
11651 void TypeParameter::set_index(intptr_t value) const { 11725 void TypeParameter::set_index(intptr_t value) const {
(...skipping 3696 matching lines...) Expand 10 before | Expand all | Expand 10 after
15348 return "_MirrorReference"; 15422 return "_MirrorReference";
15349 } 15423 }
15350 15424
15351 15425
15352 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { 15426 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const {
15353 JSONObject jsobj(stream); 15427 JSONObject jsobj(stream);
15354 } 15428 }
15355 15429
15356 15430
15357 } // namespace dart 15431 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698