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

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