| 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 |