| 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_DEOPTIMIZER_H_ | 5 #ifndef V8_DEOPTIMIZER_H_ |
| 6 #define V8_DEOPTIMIZER_H_ | 6 #define V8_DEOPTIMIZER_H_ |
| 7 | 7 |
| 8 #include "src/allocation.h" | 8 #include "src/allocation.h" |
| 9 #include "src/deoptimize-reason.h" | 9 #include "src/deoptimize-reason.h" |
| 10 #include "src/macro-assembler.h" | 10 #include "src/macro-assembler.h" |
| 11 #include "src/source-position.h" | 11 #include "src/source-position.h" |
| 12 #include "src/zone/zone-chunk-list.h" | 12 #include "src/zone/zone-chunk-list.h" |
| 13 | 13 |
| 14 namespace v8 { | 14 namespace v8 { |
| 15 namespace internal { | 15 namespace internal { |
| 16 | 16 |
| 17 class FrameDescription; | 17 class FrameDescription; |
| 18 class TranslationIterator; | 18 class TranslationIterator; |
| 19 class DeoptimizedFrameInfo; | 19 class DeoptimizedFrameInfo; |
| 20 class TranslatedState; | 20 class TranslatedState; |
| 21 class RegisterValues; | 21 class RegisterValues; |
| 22 | 22 |
| 23 // Safety wrapper for a 32-bit floating-point value to make sure we don't loose |
| 24 // the exact bit pattern during deoptimization when passing this value. Note |
| 25 // that there is intentionally no way to construct it from a {float} value. |
| 26 class Float32 { |
| 27 public: |
| 28 Float32() : bit_pattern_(0) {} |
| 29 uint32_t get_bits() const { return bit_pattern_; } |
| 30 float get_scalar() const { return bit_cast<float>(bit_pattern_); } |
| 31 static Float32 FromBits(uint32_t bits) { return Float32(bits); } |
| 32 |
| 33 private: |
| 34 explicit Float32(uint32_t bit_pattern) : bit_pattern_(bit_pattern) {} |
| 35 uint32_t bit_pattern_; |
| 36 }; |
| 37 |
| 38 // Safety wrapper for a 64-bit floating-point value to make sure we don't loose |
| 39 // the exact bit pattern during deoptimization when passing this value. Note |
| 40 // that there is intentionally no way to construct it from a {double} value. |
| 41 class Float64 { |
| 42 public: |
| 43 Float64() : bit_pattern_(0) {} |
| 44 uint64_t get_bits() const { return bit_pattern_; } |
| 45 double get_scalar() const { return bit_cast<double>(bit_pattern_); } |
| 46 bool is_hole_nan() const { return bit_pattern_ == kHoleNanInt64; } |
| 47 static Float64 FromBits(uint64_t bits) { return Float64(bits); } |
| 48 |
| 49 private: |
| 50 explicit Float64(uint64_t bit_pattern) : bit_pattern_(bit_pattern) {} |
| 51 uint64_t bit_pattern_; |
| 52 }; |
| 53 |
| 23 class TranslatedValue { | 54 class TranslatedValue { |
| 24 public: | 55 public: |
| 25 // Allocation-less getter of the value. | 56 // Allocation-less getter of the value. |
| 26 // Returns heap()->arguments_marker() if allocation would be | 57 // Returns heap()->arguments_marker() if allocation would be |
| 27 // necessary to get the value. | 58 // necessary to get the value. |
| 28 Object* GetRawValue() const; | 59 Object* GetRawValue() const; |
| 29 Handle<Object> GetValue(); | 60 Handle<Object> GetValue(); |
| 30 | 61 |
| 31 bool IsMaterializedObject() const; | 62 bool IsMaterializedObject() const; |
| 32 bool IsMaterializableByDebugger() const; | 63 bool IsMaterializableByDebugger() const; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 57 : kind_(kind), container_(container) {} | 88 : kind_(kind), container_(container) {} |
| 58 Kind kind() const { return kind_; } | 89 Kind kind() const { return kind_; } |
| 59 void Handlify(); | 90 void Handlify(); |
| 60 int GetChildrenCount() const; | 91 int GetChildrenCount() const; |
| 61 | 92 |
| 62 static TranslatedValue NewArgumentsObject(TranslatedState* container, | 93 static TranslatedValue NewArgumentsObject(TranslatedState* container, |
| 63 int length, int object_index); | 94 int length, int object_index); |
| 64 static TranslatedValue NewDeferredObject(TranslatedState* container, | 95 static TranslatedValue NewDeferredObject(TranslatedState* container, |
| 65 int length, int object_index); | 96 int length, int object_index); |
| 66 static TranslatedValue NewDuplicateObject(TranslatedState* container, int id); | 97 static TranslatedValue NewDuplicateObject(TranslatedState* container, int id); |
| 67 static TranslatedValue NewFloat(TranslatedState* container, float value); | 98 static TranslatedValue NewFloat(TranslatedState* container, Float32 value); |
| 68 static TranslatedValue NewDouble(TranslatedState* container, double value); | 99 static TranslatedValue NewDouble(TranslatedState* container, Float64 value); |
| 69 static TranslatedValue NewInt32(TranslatedState* container, int32_t value); | 100 static TranslatedValue NewInt32(TranslatedState* container, int32_t value); |
| 70 static TranslatedValue NewUInt32(TranslatedState* container, uint32_t value); | 101 static TranslatedValue NewUInt32(TranslatedState* container, uint32_t value); |
| 71 static TranslatedValue NewBool(TranslatedState* container, uint32_t value); | 102 static TranslatedValue NewBool(TranslatedState* container, uint32_t value); |
| 72 static TranslatedValue NewTagged(TranslatedState* container, Object* literal); | 103 static TranslatedValue NewTagged(TranslatedState* container, Object* literal); |
| 73 static TranslatedValue NewInvalid(TranslatedState* container); | 104 static TranslatedValue NewInvalid(TranslatedState* container); |
| 74 | 105 |
| 75 Isolate* isolate() const; | 106 Isolate* isolate() const; |
| 76 void MaterializeSimple(); | 107 void MaterializeSimple(); |
| 77 | 108 |
| 78 Kind kind_; | 109 Kind kind_; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 91 }; | 122 }; |
| 92 | 123 |
| 93 union { | 124 union { |
| 94 // kind kTagged. After handlification it is always nullptr. | 125 // kind kTagged. After handlification it is always nullptr. |
| 95 Object* raw_literal_; | 126 Object* raw_literal_; |
| 96 // kind is kUInt32 or kBoolBit. | 127 // kind is kUInt32 or kBoolBit. |
| 97 uint32_t uint32_value_; | 128 uint32_t uint32_value_; |
| 98 // kind is kInt32. | 129 // kind is kInt32. |
| 99 int32_t int32_value_; | 130 int32_t int32_value_; |
| 100 // kind is kFloat | 131 // kind is kFloat |
| 101 float float_value_; | 132 Float32 float_value_; |
| 102 // kind is kDouble | 133 // kind is kDouble |
| 103 double double_value_; | 134 Float64 double_value_; |
| 104 // kind is kDuplicatedObject or kArgumentsObject or kCapturedObject. | 135 // kind is kDuplicatedObject or kArgumentsObject or kCapturedObject. |
| 105 MaterializedObjectInfo materialization_info_; | 136 MaterializedObjectInfo materialization_info_; |
| 106 }; | 137 }; |
| 107 | 138 |
| 108 // Checked accessors for the union members. | 139 // Checked accessors for the union members. |
| 109 Object* raw_literal() const; | 140 Object* raw_literal() const; |
| 110 int32_t int32_value() const; | 141 int32_t int32_value() const; |
| 111 uint32_t uint32_value() const; | 142 uint32_t uint32_value() const; |
| 112 float float_value() const; | 143 Float32 float_value() const; |
| 113 double double_value() const; | 144 Float64 double_value() const; |
| 114 int object_length() const; | 145 int object_length() const; |
| 115 int object_index() const; | 146 int object_index() const; |
| 116 }; | 147 }; |
| 117 | 148 |
| 118 | 149 |
| 119 class TranslatedFrame { | 150 class TranslatedFrame { |
| 120 public: | 151 public: |
| 121 enum Kind { | 152 enum Kind { |
| 122 kFunction, | 153 kFunction, |
| 123 kInterpretedFunction, | 154 kInterpretedFunction, |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 | 322 |
| 292 void UpdateFromPreviouslyMaterializedObjects(); | 323 void UpdateFromPreviouslyMaterializedObjects(); |
| 293 Handle<Object> MaterializeAt(int frame_index, int* value_index); | 324 Handle<Object> MaterializeAt(int frame_index, int* value_index); |
| 294 Handle<Object> MaterializeObjectAt(int object_index); | 325 Handle<Object> MaterializeObjectAt(int object_index); |
| 295 class CapturedObjectMaterializer; | 326 class CapturedObjectMaterializer; |
| 296 Handle<Object> MaterializeCapturedObjectAt(TranslatedValue* slot, | 327 Handle<Object> MaterializeCapturedObjectAt(TranslatedValue* slot, |
| 297 int frame_index, int* value_index); | 328 int frame_index, int* value_index); |
| 298 bool GetAdaptedArguments(Handle<JSObject>* result, int frame_index); | 329 bool GetAdaptedArguments(Handle<JSObject>* result, int frame_index); |
| 299 | 330 |
| 300 static uint32_t GetUInt32Slot(Address fp, int slot_index); | 331 static uint32_t GetUInt32Slot(Address fp, int slot_index); |
| 332 static Float32 GetFloatSlot(Address fp, int slot_index); |
| 333 static Float64 GetDoubleSlot(Address fp, int slot_index); |
| 301 | 334 |
| 302 std::vector<TranslatedFrame> frames_; | 335 std::vector<TranslatedFrame> frames_; |
| 303 Isolate* isolate_; | 336 Isolate* isolate_; |
| 304 Address stack_frame_pointer_; | 337 Address stack_frame_pointer_; |
| 305 bool has_adapted_arguments_; | 338 bool has_adapted_arguments_; |
| 306 | 339 |
| 307 struct ObjectPosition { | 340 struct ObjectPosition { |
| 308 int frame_index_; | 341 int frame_index_; |
| 309 int value_index_; | 342 int value_index_; |
| 310 }; | 343 }; |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 645 // improperly detects an array bounds overflow in optimized debug builds | 678 // improperly detects an array bounds overflow in optimized debug builds |
| 646 // when using a plain DCHECK. | 679 // when using a plain DCHECK. |
| 647 if (n >= arraysize(registers_)) { | 680 if (n >= arraysize(registers_)) { |
| 648 DCHECK(false); | 681 DCHECK(false); |
| 649 return 0; | 682 return 0; |
| 650 } | 683 } |
| 651 #endif | 684 #endif |
| 652 return registers_[n]; | 685 return registers_[n]; |
| 653 } | 686 } |
| 654 | 687 |
| 655 float GetFloatRegister(unsigned n) const { | 688 Float32 GetFloatRegister(unsigned n) const { |
| 656 DCHECK(n < arraysize(float_registers_)); | 689 DCHECK(n < arraysize(float_registers_)); |
| 657 return float_registers_[n]; | 690 return float_registers_[n]; |
| 658 } | 691 } |
| 659 | 692 |
| 660 double GetDoubleRegister(unsigned n) const { | 693 Float64 GetDoubleRegister(unsigned n) const { |
| 661 DCHECK(n < arraysize(double_registers_)); | 694 DCHECK(n < arraysize(double_registers_)); |
| 662 return double_registers_[n]; | 695 return double_registers_[n]; |
| 663 } | 696 } |
| 664 | 697 |
| 665 void SetRegister(unsigned n, intptr_t value) { | 698 void SetRegister(unsigned n, intptr_t value) { |
| 666 DCHECK(n < arraysize(registers_)); | 699 DCHECK(n < arraysize(registers_)); |
| 667 registers_[n] = value; | 700 registers_[n] = value; |
| 668 } | 701 } |
| 669 | 702 |
| 670 void SetFloatRegister(unsigned n, float value) { | 703 void SetFloatRegister(unsigned n, Float32 value) { |
| 671 DCHECK(n < arraysize(float_registers_)); | 704 DCHECK(n < arraysize(float_registers_)); |
| 672 float_registers_[n] = value; | 705 float_registers_[n] = value; |
| 673 } | 706 } |
| 674 | 707 |
| 675 void SetDoubleRegister(unsigned n, double value) { | 708 void SetDoubleRegister(unsigned n, Float64 value) { |
| 676 DCHECK(n < arraysize(double_registers_)); | 709 DCHECK(n < arraysize(double_registers_)); |
| 677 double_registers_[n] = value; | 710 double_registers_[n] = value; |
| 678 } | 711 } |
| 679 | 712 |
| 713 // Generated code is writing directly into the below arrays, make sure their |
| 714 // element sizes fit what the machine instructions expect. |
| 715 static_assert(sizeof(Float32) == kFloatSize, "size mismatch"); |
| 716 static_assert(sizeof(Float64) == kDoubleSize, "size mismatch"); |
| 717 |
| 680 intptr_t registers_[Register::kNumRegisters]; | 718 intptr_t registers_[Register::kNumRegisters]; |
| 681 float float_registers_[FloatRegister::kMaxNumRegisters]; | 719 Float32 float_registers_[FloatRegister::kMaxNumRegisters]; |
| 682 double double_registers_[DoubleRegister::kMaxNumRegisters]; | 720 Float64 double_registers_[DoubleRegister::kMaxNumRegisters]; |
| 683 }; | 721 }; |
| 684 | 722 |
| 685 | 723 |
| 686 class FrameDescription { | 724 class FrameDescription { |
| 687 public: | 725 public: |
| 688 explicit FrameDescription(uint32_t frame_size, int parameter_count = 0); | 726 explicit FrameDescription(uint32_t frame_size, int parameter_count = 0); |
| 689 | 727 |
| 690 void* operator new(size_t size, uint32_t frame_size) { | 728 void* operator new(size_t size, uint32_t frame_size) { |
| 691 // Subtracts kPointerSize, as the member frame_content_ already supplies | 729 // Subtracts kPointerSize, as the member frame_content_ already supplies |
| 692 // the first element of the area to store the frame. | 730 // the first element of the area to store the frame. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 725 void SetCallerPc(unsigned offset, intptr_t value); | 763 void SetCallerPc(unsigned offset, intptr_t value); |
| 726 | 764 |
| 727 void SetCallerFp(unsigned offset, intptr_t value); | 765 void SetCallerFp(unsigned offset, intptr_t value); |
| 728 | 766 |
| 729 void SetCallerConstantPool(unsigned offset, intptr_t value); | 767 void SetCallerConstantPool(unsigned offset, intptr_t value); |
| 730 | 768 |
| 731 intptr_t GetRegister(unsigned n) const { | 769 intptr_t GetRegister(unsigned n) const { |
| 732 return register_values_.GetRegister(n); | 770 return register_values_.GetRegister(n); |
| 733 } | 771 } |
| 734 | 772 |
| 735 double GetDoubleRegister(unsigned n) const { | 773 Float64 GetDoubleRegister(unsigned n) const { |
| 736 return register_values_.GetDoubleRegister(n); | 774 return register_values_.GetDoubleRegister(n); |
| 737 } | 775 } |
| 738 | 776 |
| 739 void SetRegister(unsigned n, intptr_t value) { | 777 void SetRegister(unsigned n, intptr_t value) { |
| 740 register_values_.SetRegister(n, value); | 778 register_values_.SetRegister(n, value); |
| 741 } | 779 } |
| 742 | 780 |
| 743 void SetDoubleRegister(unsigned n, double value) { | 781 void SetDoubleRegister(unsigned n, Float64 value) { |
| 744 register_values_.SetDoubleRegister(n, value); | 782 register_values_.SetDoubleRegister(n, value); |
| 745 } | 783 } |
| 746 | 784 |
| 747 intptr_t GetTop() const { return top_; } | 785 intptr_t GetTop() const { return top_; } |
| 748 void SetTop(intptr_t top) { top_ = top; } | 786 void SetTop(intptr_t top) { top_ = top; } |
| 749 | 787 |
| 750 intptr_t GetPc() const { return pc_; } | 788 intptr_t GetPc() const { return pc_; } |
| 751 void SetPc(intptr_t pc) { pc_ = pc; } | 789 void SetPc(intptr_t pc) { pc_ = pc; } |
| 752 | 790 |
| 753 intptr_t GetFp() const { return fp_; } | 791 intptr_t GetFp() const { return fp_; } |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1059 std::vector<Handle<Object> > expression_stack_; | 1097 std::vector<Handle<Object> > expression_stack_; |
| 1060 int source_position_; | 1098 int source_position_; |
| 1061 | 1099 |
| 1062 friend class Deoptimizer; | 1100 friend class Deoptimizer; |
| 1063 }; | 1101 }; |
| 1064 | 1102 |
| 1065 } // namespace internal | 1103 } // namespace internal |
| 1066 } // namespace v8 | 1104 } // namespace v8 |
| 1067 | 1105 |
| 1068 #endif // V8_DEOPTIMIZER_H_ | 1106 #endif // V8_DEOPTIMIZER_H_ |
| OLD | NEW |