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 #ifndef VM_OBJECT_H_ | 5 #ifndef VM_OBJECT_H_ |
6 #define VM_OBJECT_H_ | 6 #define VM_OBJECT_H_ |
7 | 7 |
8 #include "include/dart_api.h" | 8 #include "include/dart_api.h" |
9 #include "platform/assert.h" | 9 #include "platform/assert.h" |
10 #include "platform/utils.h" | 10 #include "platform/utils.h" |
(...skipping 3529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3540 RawArray* arguments_descriptor() const { | 3540 RawArray* arguments_descriptor() const { |
3541 return raw_ptr()->args_descriptor_; | 3541 return raw_ptr()->args_descriptor_; |
3542 } | 3542 } |
3543 | 3543 |
3544 intptr_t NumArgsTested() const; | 3544 intptr_t NumArgsTested() const; |
3545 | 3545 |
3546 intptr_t deopt_id() const { | 3546 intptr_t deopt_id() const { |
3547 return raw_ptr()->deopt_id_; | 3547 return raw_ptr()->deopt_id_; |
3548 } | 3548 } |
3549 | 3549 |
| 3550 uint32_t range_feedback() const { |
| 3551 return raw_ptr()->range_feedback_; |
| 3552 } |
| 3553 |
3550 #define DEOPT_REASONS(V) \ | 3554 #define DEOPT_REASONS(V) \ |
3551 V(Unknown) \ | 3555 V(Unknown) \ |
3552 V(InstanceGetter) \ | 3556 V(InstanceGetter) \ |
3553 V(PolymorphicInstanceCallTestFail) \ | 3557 V(PolymorphicInstanceCallTestFail) \ |
3554 V(InstanceCallNoICData) \ | 3558 V(InstanceCallNoICData) \ |
3555 V(IntegerToDouble) \ | 3559 V(IntegerToDouble) \ |
3556 V(BinarySmiOp) \ | 3560 V(BinarySmiOp) \ |
3557 V(BinaryMintOp) \ | 3561 V(BinaryMintOp) \ |
3558 V(UnaryMintOp) \ | 3562 V(UnaryMintOp) \ |
3559 V(ShiftMintOp) \ | 3563 V(ShiftMintOp) \ |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3634 } | 3638 } |
3635 | 3639 |
3636 static intptr_t ic_data_offset() { | 3640 static intptr_t ic_data_offset() { |
3637 return OFFSET_OF(RawICData, ic_data_); | 3641 return OFFSET_OF(RawICData, ic_data_); |
3638 } | 3642 } |
3639 | 3643 |
3640 static intptr_t owner_offset() { | 3644 static intptr_t owner_offset() { |
3641 return OFFSET_OF(RawICData, owner_); | 3645 return OFFSET_OF(RawICData, owner_); |
3642 } | 3646 } |
3643 | 3647 |
| 3648 static intptr_t range_feedback_offset() { |
| 3649 return OFFSET_OF(RawICData, range_feedback_); |
| 3650 } |
| 3651 |
3644 // Used for unoptimized static calls when no class-ids are checked. | 3652 // Used for unoptimized static calls when no class-ids are checked. |
3645 void AddTarget(const Function& target) const; | 3653 void AddTarget(const Function& target) const; |
3646 | 3654 |
3647 // Adding checks. | 3655 // Adding checks. |
3648 | 3656 |
3649 // Adds one more class test to ICData. Length of 'classes' must be equal to | 3657 // Adds one more class test to ICData. Length of 'classes' must be equal to |
3650 // the number of arguments tested. Use only for num_args_tested > 1. | 3658 // the number of arguments tested. Use only for num_args_tested > 1. |
3651 void AddCheck(const GrowableArray<intptr_t>& class_ids, | 3659 void AddCheck(const GrowableArray<intptr_t>& class_ids, |
3652 const Function& target) const; | 3660 const Function& target) const; |
3653 // Adds sorted so that Smi is the first class-id. Use only for | 3661 // Adds sorted so that Smi is the first class-id. Use only for |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3708 | 3716 |
3709 static intptr_t CountIndexFor(intptr_t num_args) { | 3717 static intptr_t CountIndexFor(intptr_t num_args) { |
3710 return (num_args + 1); | 3718 return (num_args + 1); |
3711 } | 3719 } |
3712 | 3720 |
3713 bool IsUsedAt(intptr_t i) const; | 3721 bool IsUsedAt(intptr_t i) const; |
3714 | 3722 |
3715 void GetUsedCidsForTwoArgs(GrowableArray<intptr_t>* first, | 3723 void GetUsedCidsForTwoArgs(GrowableArray<intptr_t>* first, |
3716 GrowableArray<intptr_t>* second) const; | 3724 GrowableArray<intptr_t>* second) const; |
3717 | 3725 |
| 3726 // Range feedback tracking functionality. |
| 3727 |
| 3728 // For arithmetic operations we store range information for inputs and the |
| 3729 // result. The goal is to discover: |
| 3730 // |
| 3731 // - on 32-bit platforms: |
| 3732 // - when Mint operation is actually a int32/uint32 operation; |
| 3733 // - when Smi operation produces non-smi results; |
| 3734 // |
| 3735 // - on 64-bit platforms: |
| 3736 // - when Smi operation is actually int32/uint32 operation; |
| 3737 // - when Mint operation produces non-smi results; |
| 3738 // |
| 3739 enum RangeFeedback { |
| 3740 kSmiRange, |
| 3741 kInt32Range, |
| 3742 kUint32Range, |
| 3743 kInt64Range |
| 3744 }; |
| 3745 |
| 3746 // We use 4 bits per operand/result feedback. Our lattice allows us to |
| 3747 // express the following states: |
| 3748 // |
| 3749 // - usmi 0000 [used only on 32bit platforms] |
| 3750 // - smi 0001 |
| 3751 // - uint31 0010 |
| 3752 // - int32 0011 |
| 3753 // - uint32 0100 |
| 3754 // - int33 x1x1 |
| 3755 // - int64 1xxx |
| 3756 // |
| 3757 // DecodeRangeFeedbackAt() helper maps these states into the RangeFeedback |
| 3758 // enumeration. |
| 3759 enum { |
| 3760 kSignedRangeBit = 1 << 0, |
| 3761 kInt32RangeBit = 1 << 1, |
| 3762 kUint32RangeBit = 1 << 2, |
| 3763 kInt64RangeBit = 1 << 3, |
| 3764 kBitsPerRangeFeedback = 4, |
| 3765 kRangeFeedbackMask = (1 << kBitsPerRangeFeedback) - 1 |
| 3766 }; |
| 3767 |
| 3768 static bool IsValidRangeFeedbackIndex(intptr_t index) { |
| 3769 return (0 <= index) && (index < 3); |
| 3770 } |
| 3771 |
| 3772 static const char* RangeFeedbackToString(RangeFeedback feedback) { |
| 3773 switch (feedback) { |
| 3774 case kSmiRange: |
| 3775 return "smi"; |
| 3776 case kInt32Range: |
| 3777 return "int32"; |
| 3778 case kUint32Range: |
| 3779 return "uint32"; |
| 3780 case kInt64Range: |
| 3781 return "int64"; |
| 3782 default: |
| 3783 UNREACHABLE(); |
| 3784 return "?"; |
| 3785 } |
| 3786 } |
| 3787 |
| 3788 // It is only meaningful to interptret range feedback stored in the ICData |
| 3789 // when all checks are Mint or Smi. |
| 3790 bool HasRangeFeedback() const; |
| 3791 RangeFeedback DecodeRangeFeedbackAt(intptr_t idx) const; |
| 3792 |
3718 private: | 3793 private: |
3719 RawArray* ic_data() const { | 3794 RawArray* ic_data() const { |
3720 return raw_ptr()->ic_data_; | 3795 return raw_ptr()->ic_data_; |
3721 } | 3796 } |
3722 | 3797 |
3723 void set_owner(const Function& value) const; | 3798 void set_owner(const Function& value) const; |
3724 void set_target_name(const String& value) const; | 3799 void set_target_name(const String& value) const; |
3725 void set_arguments_descriptor(const Array& value) const; | 3800 void set_arguments_descriptor(const Array& value) const; |
3726 void set_deopt_id(intptr_t value) const; | 3801 void set_deopt_id(intptr_t value) const; |
3727 void SetNumArgsTested(intptr_t value) const; | 3802 void SetNumArgsTested(intptr_t value) const; |
3728 void set_ic_data(const Array& value) const; | 3803 void set_ic_data(const Array& value) const; |
3729 void set_state_bits(uint32_t bits) const; | 3804 void set_state_bits(uint32_t bits) const; |
| 3805 void set_range_feedback(uint32_t feedback); |
3730 | 3806 |
3731 enum { | 3807 enum { |
3732 kNumArgsTestedPos = 0, | 3808 kNumArgsTestedPos = 0, |
3733 kNumArgsTestedSize = 2, | 3809 kNumArgsTestedSize = 2, |
3734 kDeoptReasonPos = kNumArgsTestedPos + kNumArgsTestedSize, | 3810 kDeoptReasonPos = kNumArgsTestedPos + kNumArgsTestedSize, |
3735 kDeoptReasonSize = kDeoptNumReasons, | 3811 kDeoptReasonSize = kDeoptNumReasons, |
3736 kIssuedJSWarningBit = kDeoptReasonPos + kDeoptReasonSize, | 3812 kIssuedJSWarningBit = kDeoptReasonPos + kDeoptReasonSize, |
3737 }; | 3813 }; |
3738 | 3814 |
3739 class NumArgsTestedBits : public BitField<uint32_t, | 3815 class NumArgsTestedBits : public BitField<uint32_t, |
(...skipping 3852 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7592 | 7668 |
7593 | 7669 |
7594 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, | 7670 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, |
7595 intptr_t index) { | 7671 intptr_t index) { |
7596 return array.At((index * kEntryLength) + kTargetFunctionIndex); | 7672 return array.At((index * kEntryLength) + kTargetFunctionIndex); |
7597 } | 7673 } |
7598 | 7674 |
7599 } // namespace dart | 7675 } // namespace dart |
7600 | 7676 |
7601 #endif // VM_OBJECT_H_ | 7677 #endif // VM_OBJECT_H_ |
OLD | NEW |