Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |