| 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 1637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |