OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_HYDROGEN_INSTRUCTIONS_H_ | 5 #ifndef V8_HYDROGEN_INSTRUCTIONS_H_ |
6 #define V8_HYDROGEN_INSTRUCTIONS_H_ | 6 #define V8_HYDROGEN_INSTRUCTIONS_H_ |
7 | 7 |
| 8 #include <cstring> |
8 #include <iosfwd> | 9 #include <iosfwd> |
9 | 10 |
10 #include "src/v8.h" | 11 #include "src/v8.h" |
11 | 12 |
12 #include "src/allocation.h" | 13 #include "src/allocation.h" |
13 #include "src/base/bits.h" | 14 #include "src/base/bits.h" |
14 #include "src/bit-vector.h" | 15 #include "src/bit-vector.h" |
15 #include "src/code-stubs.h" | 16 #include "src/code-stubs.h" |
16 #include "src/conversions.h" | 17 #include "src/conversions.h" |
17 #include "src/deoptimizer.h" | 18 #include "src/deoptimizer.h" |
(...skipping 3458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3476 | 3477 |
3477 // Note that we cannot DCE captured objects as they are used to replay | 3478 // Note that we cannot DCE captured objects as they are used to replay |
3478 // the environment. This method is here as an explicit reminder. | 3479 // the environment. This method is here as an explicit reminder. |
3479 // TODO(mstarzinger): Turn HSimulates into full snapshots maybe? | 3480 // TODO(mstarzinger): Turn HSimulates into full snapshots maybe? |
3480 bool IsDeletable() const FINAL { return false; } | 3481 bool IsDeletable() const FINAL { return false; } |
3481 }; | 3482 }; |
3482 | 3483 |
3483 | 3484 |
3484 class HConstant FINAL : public HTemplateInstruction<0> { | 3485 class HConstant FINAL : public HTemplateInstruction<0> { |
3485 public: | 3486 public: |
| 3487 enum Special { kHoleNaN }; |
| 3488 |
| 3489 DECLARE_INSTRUCTION_FACTORY_P1(HConstant, Special); |
3486 DECLARE_INSTRUCTION_FACTORY_P1(HConstant, int32_t); | 3490 DECLARE_INSTRUCTION_FACTORY_P1(HConstant, int32_t); |
3487 DECLARE_INSTRUCTION_FACTORY_P2(HConstant, int32_t, Representation); | 3491 DECLARE_INSTRUCTION_FACTORY_P2(HConstant, int32_t, Representation); |
3488 DECLARE_INSTRUCTION_FACTORY_P1(HConstant, double); | 3492 DECLARE_INSTRUCTION_FACTORY_P1(HConstant, double); |
3489 DECLARE_INSTRUCTION_FACTORY_P1(HConstant, Handle<Object>); | 3493 DECLARE_INSTRUCTION_FACTORY_P1(HConstant, Handle<Object>); |
3490 DECLARE_INSTRUCTION_FACTORY_P1(HConstant, ExternalReference); | 3494 DECLARE_INSTRUCTION_FACTORY_P1(HConstant, ExternalReference); |
3491 | 3495 |
3492 static HConstant* CreateAndInsertAfter(Zone* zone, | 3496 static HConstant* CreateAndInsertAfter(Zone* zone, |
3493 HValue* context, | 3497 HValue* context, |
3494 int32_t value, | 3498 int32_t value, |
3495 Representation representation, | 3499 Representation representation, |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3543 isolate->factory()->NewNumber(double_value_, TENURED)); | 3547 isolate->factory()->NewNumber(double_value_, TENURED)); |
3544 } | 3548 } |
3545 AllowDeferredHandleDereference smi_check; | 3549 AllowDeferredHandleDereference smi_check; |
3546 DCHECK(HasInteger32Value() || !object_.handle()->IsSmi()); | 3550 DCHECK(HasInteger32Value() || !object_.handle()->IsSmi()); |
3547 return object_.handle(); | 3551 return object_.handle(); |
3548 } | 3552 } |
3549 | 3553 |
3550 bool IsSpecialDouble() const { | 3554 bool IsSpecialDouble() const { |
3551 return HasDoubleValue() && | 3555 return HasDoubleValue() && |
3552 (bit_cast<int64_t>(double_value_) == bit_cast<int64_t>(-0.0) || | 3556 (bit_cast<int64_t>(double_value_) == bit_cast<int64_t>(-0.0) || |
3553 FixedDoubleArray::is_the_hole_nan(double_value_) || | |
3554 std::isnan(double_value_)); | 3557 std::isnan(double_value_)); |
3555 } | 3558 } |
3556 | 3559 |
3557 bool NotInNewSpace() const { | 3560 bool NotInNewSpace() const { |
3558 return IsNotInNewSpaceField::decode(bit_field_); | 3561 return IsNotInNewSpaceField::decode(bit_field_); |
3559 } | 3562 } |
3560 | 3563 |
3561 bool ImmortalImmovable() const; | 3564 bool ImmortalImmovable() const; |
3562 | 3565 |
3563 bool IsCell() const { | 3566 bool IsCell() const { |
(...skipping 26 matching lines...) Expand all Loading... |
3590 return int32_value_; | 3593 return int32_value_; |
3591 } | 3594 } |
3592 bool HasSmiValue() const { return HasSmiValueField::decode(bit_field_); } | 3595 bool HasSmiValue() const { return HasSmiValueField::decode(bit_field_); } |
3593 bool HasDoubleValue() const { | 3596 bool HasDoubleValue() const { |
3594 return HasDoubleValueField::decode(bit_field_); | 3597 return HasDoubleValueField::decode(bit_field_); |
3595 } | 3598 } |
3596 double DoubleValue() const { | 3599 double DoubleValue() const { |
3597 DCHECK(HasDoubleValue()); | 3600 DCHECK(HasDoubleValue()); |
3598 return double_value_; | 3601 return double_value_; |
3599 } | 3602 } |
| 3603 uint64_t DoubleValueAsBits() const { |
| 3604 uint64_t bits; |
| 3605 DCHECK(HasDoubleValue()); |
| 3606 STATIC_ASSERT(sizeof(bits) == sizeof(double_value_)); |
| 3607 std::memcpy(&bits, &double_value_, sizeof(bits)); |
| 3608 return bits; |
| 3609 } |
3600 bool IsTheHole() const { | 3610 bool IsTheHole() const { |
3601 if (HasDoubleValue() && FixedDoubleArray::is_the_hole_nan(double_value_)) { | 3611 if (HasDoubleValue() && DoubleValueAsBits() == kHoleNanInt64) { |
3602 return true; | 3612 return true; |
3603 } | 3613 } |
3604 return object_.IsInitialized() && | 3614 return object_.IsInitialized() && |
3605 object_.IsKnownGlobal(isolate()->heap()->the_hole_value()); | 3615 object_.IsKnownGlobal(isolate()->heap()->the_hole_value()); |
3606 } | 3616 } |
3607 bool HasNumberValue() const { return HasDoubleValue(); } | 3617 bool HasNumberValue() const { return HasDoubleValue(); } |
3608 int32_t NumberValueAsInteger32() const { | 3618 int32_t NumberValueAsInteger32() const { |
3609 DCHECK(HasNumberValue()); | 3619 DCHECK(HasNumberValue()); |
3610 // Irrespective of whether a numeric HConstant can be safely | 3620 // Irrespective of whether a numeric HConstant can be safely |
3611 // represented as an int32, we store the (in some cases lossy) | 3621 // represented as an int32, we store the (in some cases lossy) |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3654 bool HasObjectMap() const { return !object_map_.IsNull(); } | 3664 bool HasObjectMap() const { return !object_map_.IsNull(); } |
3655 Unique<Map> ObjectMap() const { | 3665 Unique<Map> ObjectMap() const { |
3656 DCHECK(HasObjectMap()); | 3666 DCHECK(HasObjectMap()); |
3657 return object_map_; | 3667 return object_map_; |
3658 } | 3668 } |
3659 | 3669 |
3660 intptr_t Hashcode() OVERRIDE { | 3670 intptr_t Hashcode() OVERRIDE { |
3661 if (HasInteger32Value()) { | 3671 if (HasInteger32Value()) { |
3662 return static_cast<intptr_t>(int32_value_); | 3672 return static_cast<intptr_t>(int32_value_); |
3663 } else if (HasDoubleValue()) { | 3673 } else if (HasDoubleValue()) { |
3664 return static_cast<intptr_t>(bit_cast<int64_t>(double_value_)); | 3674 uint64_t bits = DoubleValueAsBits(); |
| 3675 if (sizeof(bits) > sizeof(intptr_t)) { |
| 3676 bits ^= (bits >> 32); |
| 3677 } |
| 3678 return static_cast<intptr_t>(bits); |
3665 } else if (HasExternalReferenceValue()) { | 3679 } else if (HasExternalReferenceValue()) { |
3666 return reinterpret_cast<intptr_t>(external_reference_value_.address()); | 3680 return reinterpret_cast<intptr_t>(external_reference_value_.address()); |
3667 } else { | 3681 } else { |
3668 DCHECK(!object_.handle().is_null()); | 3682 DCHECK(!object_.handle().is_null()); |
3669 return object_.Hashcode(); | 3683 return object_.Hashcode(); |
3670 } | 3684 } |
3671 } | 3685 } |
3672 | 3686 |
3673 void FinalizeUniqueness() OVERRIDE { | 3687 void FinalizeUniqueness() OVERRIDE { |
3674 if (!HasDoubleValue() && !HasExternalReferenceValue()) { | 3688 if (!HasDoubleValue() && !HasExternalReferenceValue()) { |
(...skipping 10 matching lines...) Expand all Loading... |
3685 return object_.IsInitialized() && object_ == other; | 3699 return object_.IsInitialized() && object_ == other; |
3686 } | 3700 } |
3687 | 3701 |
3688 bool DataEquals(HValue* other) OVERRIDE { | 3702 bool DataEquals(HValue* other) OVERRIDE { |
3689 HConstant* other_constant = HConstant::cast(other); | 3703 HConstant* other_constant = HConstant::cast(other); |
3690 if (HasInteger32Value()) { | 3704 if (HasInteger32Value()) { |
3691 return other_constant->HasInteger32Value() && | 3705 return other_constant->HasInteger32Value() && |
3692 int32_value_ == other_constant->int32_value_; | 3706 int32_value_ == other_constant->int32_value_; |
3693 } else if (HasDoubleValue()) { | 3707 } else if (HasDoubleValue()) { |
3694 return other_constant->HasDoubleValue() && | 3708 return other_constant->HasDoubleValue() && |
3695 bit_cast<int64_t>(double_value_) == | 3709 std::memcmp(&double_value_, &other_constant->double_value_, |
3696 bit_cast<int64_t>(other_constant->double_value_); | 3710 sizeof(double_value_)) == 0; |
3697 } else if (HasExternalReferenceValue()) { | 3711 } else if (HasExternalReferenceValue()) { |
3698 return other_constant->HasExternalReferenceValue() && | 3712 return other_constant->HasExternalReferenceValue() && |
3699 external_reference_value_ == | 3713 external_reference_value_ == |
3700 other_constant->external_reference_value_; | 3714 other_constant->external_reference_value_; |
3701 } else { | 3715 } else { |
3702 if (other_constant->HasInteger32Value() || | 3716 if (other_constant->HasInteger32Value() || |
3703 other_constant->HasDoubleValue() || | 3717 other_constant->HasDoubleValue() || |
3704 other_constant->HasExternalReferenceValue()) { | 3718 other_constant->HasExternalReferenceValue()) { |
3705 return false; | 3719 return false; |
3706 } | 3720 } |
3707 DCHECK(!object_.handle().is_null()); | 3721 DCHECK(!object_.handle().is_null()); |
3708 return other_constant->object_ == object_; | 3722 return other_constant->object_ == object_; |
3709 } | 3723 } |
3710 } | 3724 } |
3711 | 3725 |
3712 #ifdef DEBUG | 3726 #ifdef DEBUG |
3713 void Verify() OVERRIDE {} | 3727 void Verify() OVERRIDE {} |
3714 #endif | 3728 #endif |
3715 | 3729 |
3716 DECLARE_CONCRETE_INSTRUCTION(Constant) | 3730 DECLARE_CONCRETE_INSTRUCTION(Constant) |
3717 | 3731 |
3718 protected: | 3732 protected: |
3719 Range* InferRange(Zone* zone) OVERRIDE; | 3733 Range* InferRange(Zone* zone) OVERRIDE; |
3720 | 3734 |
3721 private: | 3735 private: |
3722 friend class HGraph; | 3736 friend class HGraph; |
| 3737 explicit HConstant(Special special); |
3723 explicit HConstant(Handle<Object> handle, | 3738 explicit HConstant(Handle<Object> handle, |
3724 Representation r = Representation::None()); | 3739 Representation r = Representation::None()); |
3725 HConstant(int32_t value, | 3740 HConstant(int32_t value, |
3726 Representation r = Representation::None(), | 3741 Representation r = Representation::None(), |
3727 bool is_not_in_new_space = true, | 3742 bool is_not_in_new_space = true, |
3728 Unique<Object> optional = Unique<Object>(Handle<Object>::null())); | 3743 Unique<Object> optional = Unique<Object>(Handle<Object>::null())); |
3729 HConstant(double value, | 3744 HConstant(double value, |
3730 Representation r = Representation::None(), | 3745 Representation r = Representation::None(), |
3731 bool is_not_in_new_space = true, | 3746 bool is_not_in_new_space = true, |
3732 Unique<Object> optional = Unique<Object>(Handle<Object>::null())); | 3747 Unique<Object> optional = Unique<Object>(Handle<Object>::null())); |
(...skipping 4296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8029 }; | 8044 }; |
8030 | 8045 |
8031 | 8046 |
8032 | 8047 |
8033 #undef DECLARE_INSTRUCTION | 8048 #undef DECLARE_INSTRUCTION |
8034 #undef DECLARE_CONCRETE_INSTRUCTION | 8049 #undef DECLARE_CONCRETE_INSTRUCTION |
8035 | 8050 |
8036 } } // namespace v8::internal | 8051 } } // namespace v8::internal |
8037 | 8052 |
8038 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 8053 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |