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 |