OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_COMPILER_FRAME_H_ | 5 #ifndef V8_COMPILER_FRAME_H_ |
6 #define V8_COMPILER_FRAME_H_ | 6 #define V8_COMPILER_FRAME_H_ |
7 | 7 |
8 #include "src/bit-vector.h" | 8 #include "src/bit-vector.h" |
9 #include "src/frames.h" | 9 #include "src/frames.h" |
10 | 10 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 // | ... | Callee-saved | | 74 // | ... | Callee-saved | |
75 // |- - - - - - - - -| | | | 75 // |- - - - - - - - -| | | |
76 // m+r+3 | callee-saved r | v v | 76 // m+r+3 | callee-saved r | v v |
77 // -----+-----------------+----- <-- stack ptr ------------- | 77 // -----+-----------------+----- <-- stack ptr ------------- |
78 // | 78 // |
79 class Frame : public ZoneObject { | 79 class Frame : public ZoneObject { |
80 public: | 80 public: |
81 explicit Frame(int fixed_frame_size_in_slots, | 81 explicit Frame(int fixed_frame_size_in_slots, |
82 const CallDescriptor* descriptor); | 82 const CallDescriptor* descriptor); |
83 | 83 |
84 inline bool needs_frame() const { return needs_frame_; } | |
85 inline void MarkNeedsFrame() { needs_frame_ = true; } | |
86 | |
87 inline int GetTotalFrameSlotCount() const { return frame_slot_count_; } | 84 inline int GetTotalFrameSlotCount() const { return frame_slot_count_; } |
88 | 85 |
89 inline int GetSPToFPSlotCount() const { | |
90 return GetTotalFrameSlotCount() - | |
91 StandardFrameConstants::kFixedSlotCountAboveFp; | |
92 } | |
93 inline int GetSavedCalleeRegisterSlotCount() const { | 86 inline int GetSavedCalleeRegisterSlotCount() const { |
94 return callee_saved_slot_count_; | 87 return callee_saved_slot_count_; |
95 } | 88 } |
96 inline int GetSpillSlotCount() const { return spill_slot_count_; } | 89 inline int GetSpillSlotCount() const { return spill_slot_count_; } |
97 | 90 |
98 inline void SetElidedFrameSizeInSlots(int slots) { | |
99 DCHECK_EQ(0, callee_saved_slot_count_); | |
100 DCHECK_EQ(0, spill_slot_count_); | |
101 frame_slot_count_ = slots; | |
102 } | |
103 | |
104 void SetAllocatedRegisters(BitVector* regs) { | 91 void SetAllocatedRegisters(BitVector* regs) { |
105 DCHECK(allocated_registers_ == nullptr); | 92 DCHECK(allocated_registers_ == nullptr); |
106 allocated_registers_ = regs; | 93 allocated_registers_ = regs; |
107 } | 94 } |
108 | 95 |
109 void SetAllocatedDoubleRegisters(BitVector* regs) { | 96 void SetAllocatedDoubleRegisters(BitVector* regs) { |
110 DCHECK(allocated_double_registers_ == nullptr); | 97 DCHECK(allocated_double_registers_ == nullptr); |
111 allocated_double_registers_ = regs; | 98 allocated_double_registers_ = regs; |
112 } | 99 } |
113 | 100 |
114 bool DidAllocateDoubleRegisters() const { | 101 bool DidAllocateDoubleRegisters() const { |
115 return !allocated_double_registers_->IsEmpty(); | 102 return !allocated_double_registers_->IsEmpty(); |
116 } | 103 } |
117 | 104 |
118 int AlignSavedCalleeRegisterSlots(int alignment = kDoubleSize) { | 105 int AlignSavedCalleeRegisterSlots(int alignment = kDoubleSize) { |
119 DCHECK_EQ(0, callee_saved_slot_count_); | 106 DCHECK_EQ(0, callee_saved_slot_count_); |
120 int alignment_slots = alignment / kPointerSize; | 107 int alignment_slots = alignment / kPointerSize; |
121 int delta = alignment_slots - (frame_slot_count_ & (alignment_slots - 1)); | 108 int delta = alignment_slots - (frame_slot_count_ & (alignment_slots - 1)); |
122 if (delta != alignment_slots) { | 109 if (delta != alignment_slots) { |
123 DCHECK(needs_frame_); | |
124 frame_slot_count_ += delta; | 110 frame_slot_count_ += delta; |
125 } | 111 } |
126 return delta; | 112 return delta; |
127 } | 113 } |
128 | 114 |
129 void AllocateSavedCalleeRegisterSlots(int count) { | 115 void AllocateSavedCalleeRegisterSlots(int count) { |
130 needs_frame_ = true; | |
131 frame_slot_count_ += count; | 116 frame_slot_count_ += count; |
132 callee_saved_slot_count_ += count; | 117 callee_saved_slot_count_ += count; |
133 } | 118 } |
134 | 119 |
135 int AllocateSpillSlot(int width) { | 120 int AllocateSpillSlot(int width) { |
136 DCHECK_EQ(0, callee_saved_slot_count_); | 121 DCHECK_EQ(0, callee_saved_slot_count_); |
137 needs_frame_ = true; | |
138 int frame_slot_count_before = frame_slot_count_; | 122 int frame_slot_count_before = frame_slot_count_; |
139 int slot = AllocateAlignedFrameSlot(width); | 123 int slot = AllocateAlignedFrameSlot(width); |
140 spill_slot_count_ += (frame_slot_count_ - frame_slot_count_before); | 124 spill_slot_count_ += (frame_slot_count_ - frame_slot_count_before); |
141 return slot; | 125 return slot; |
142 } | 126 } |
143 | 127 |
144 int AlignFrame(int alignment = kDoubleSize); | 128 int AlignFrame(int alignment = kDoubleSize); |
145 | 129 |
146 int ReserveSpillSlots(size_t slot_count) { | 130 int ReserveSpillSlots(size_t slot_count) { |
147 DCHECK_EQ(0, callee_saved_slot_count_); | 131 DCHECK_EQ(0, callee_saved_slot_count_); |
148 DCHECK_EQ(0, spill_slot_count_); | 132 DCHECK_EQ(0, spill_slot_count_); |
149 needs_frame_ = true; | |
150 spill_slot_count_ += static_cast<int>(slot_count); | 133 spill_slot_count_ += static_cast<int>(slot_count); |
151 frame_slot_count_ += static_cast<int>(slot_count); | 134 frame_slot_count_ += static_cast<int>(slot_count); |
152 return frame_slot_count_ - 1; | 135 return frame_slot_count_ - 1; |
153 } | 136 } |
154 | 137 |
155 static const int kContextSlot = 2 + StandardFrameConstants::kCPSlotCount; | 138 static const int kContextSlot = 2 + StandardFrameConstants::kCPSlotCount; |
156 static const int kJSFunctionSlot = 3 + StandardFrameConstants::kCPSlotCount; | 139 static const int kJSFunctionSlot = 3 + StandardFrameConstants::kCPSlotCount; |
157 | 140 |
158 private: | 141 private: |
159 int AllocateAlignedFrameSlot(int width) { | 142 int AllocateAlignedFrameSlot(int width) { |
160 DCHECK(width == 4 || width == 8); | 143 DCHECK(width == 4 || width == 8); |
161 // Skip one slot if necessary. | 144 // Skip one slot if necessary. |
162 if (width > kPointerSize) { | 145 if (width > kPointerSize) { |
163 DCHECK(width == kPointerSize * 2); | 146 DCHECK(width == kPointerSize * 2); |
164 frame_slot_count_++; | 147 frame_slot_count_++; |
165 frame_slot_count_ |= 1; | 148 frame_slot_count_ |= 1; |
166 } | 149 } |
167 return frame_slot_count_++; | 150 return frame_slot_count_++; |
168 } | 151 } |
169 | 152 |
170 private: | 153 private: |
171 bool needs_frame_; | |
172 int frame_slot_count_; | 154 int frame_slot_count_; |
173 int callee_saved_slot_count_; | 155 int callee_saved_slot_count_; |
174 int spill_slot_count_; | 156 int spill_slot_count_; |
175 BitVector* allocated_registers_; | 157 BitVector* allocated_registers_; |
176 BitVector* allocated_double_registers_; | 158 BitVector* allocated_double_registers_; |
177 | 159 |
178 DISALLOW_COPY_AND_ASSIGN(Frame); | 160 DISALLOW_COPY_AND_ASSIGN(Frame); |
179 }; | 161 }; |
180 | 162 |
181 | 163 |
(...skipping 21 matching lines...) Expand all Loading... |
203 | 185 |
204 static const int kFromSp = 1; | 186 static const int kFromSp = 1; |
205 static const int kFromFp = 0; | 187 static const int kFromFp = 0; |
206 }; | 188 }; |
207 | 189 |
208 // Encapsulates the mutable state maintained during code generation about the | 190 // Encapsulates the mutable state maintained during code generation about the |
209 // current function's frame. | 191 // current function's frame. |
210 class FrameAccessState : public ZoneObject { | 192 class FrameAccessState : public ZoneObject { |
211 public: | 193 public: |
212 explicit FrameAccessState(Frame* const frame) | 194 explicit FrameAccessState(Frame* const frame) |
213 : frame_(frame), access_frame_with_fp_(false), sp_delta_(0) { | 195 : frame_(frame), |
214 SetFrameAccessToDefault(); | 196 access_frame_with_fp_(false), |
215 } | 197 sp_delta_(0), |
| 198 has_frame_(false) {} |
216 | 199 |
217 Frame* frame() const { return frame_; } | 200 Frame* frame() const { return frame_; } |
| 201 void MarkHasFrame(bool state); |
218 | 202 |
219 int sp_delta() const { return sp_delta_; } | 203 int sp_delta() const { return sp_delta_; } |
220 void ClearSPDelta() { sp_delta_ = 0; } | 204 void ClearSPDelta() { sp_delta_ = 0; } |
221 void IncreaseSPDelta(int amount) { sp_delta_ += amount; } | 205 void IncreaseSPDelta(int amount) { sp_delta_ += amount; } |
222 | 206 |
223 bool access_frame_with_fp() const { return access_frame_with_fp_; } | 207 bool access_frame_with_fp() const { return access_frame_with_fp_; } |
| 208 |
| 209 // Regardless of how we access slots on the stack - using sp or fp - do we |
| 210 // have a frame, at the current stage in code generation. |
| 211 bool has_frame() const { return has_frame_; } |
| 212 |
224 void SetFrameAccessToDefault(); | 213 void SetFrameAccessToDefault(); |
225 void SetFrameAccessToFP() { access_frame_with_fp_ = true; } | 214 void SetFrameAccessToFP() { access_frame_with_fp_ = true; } |
226 void SetFrameAccessToSP() { access_frame_with_fp_ = false; } | 215 void SetFrameAccessToSP() { access_frame_with_fp_ = false; } |
227 | 216 |
228 int GetSPToFPSlotCount() const { | 217 int GetSPToFPSlotCount() const { |
229 return frame_->GetSPToFPSlotCount() + sp_delta(); | 218 int frame_slot_count = |
| 219 (has_frame() ? frame()->GetTotalFrameSlotCount() : kElidedFrameSlots) - |
| 220 StandardFrameConstants::kFixedSlotCountAboveFp; |
| 221 return frame_slot_count + sp_delta(); |
230 } | 222 } |
231 int GetSPToFPOffset() const { return GetSPToFPSlotCount() * kPointerSize; } | 223 int GetSPToFPOffset() const { return GetSPToFPSlotCount() * kPointerSize; } |
232 | 224 |
233 // Get the frame offset for a given spill slot. The location depends on the | 225 // Get the frame offset for a given spill slot. The location depends on the |
234 // calling convention and the specific frame layout, and may thus be | 226 // calling convention and the specific frame layout, and may thus be |
235 // architecture-specific. Negative spill slots indicate arguments on the | 227 // architecture-specific. Negative spill slots indicate arguments on the |
236 // caller's frame. | 228 // caller's frame. |
237 FrameOffset GetFrameOffset(int spill_slot) const; | 229 FrameOffset GetFrameOffset(int spill_slot) const; |
238 | 230 |
239 private: | 231 private: |
240 Frame* const frame_; | 232 Frame* const frame_; |
241 bool access_frame_with_fp_; | 233 bool access_frame_with_fp_; |
242 int sp_delta_; | 234 int sp_delta_; |
| 235 bool has_frame_; |
243 }; | 236 }; |
244 } // namespace compiler | 237 } // namespace compiler |
245 } // namespace internal | 238 } // namespace internal |
246 } // namespace v8 | 239 } // namespace v8 |
247 | 240 |
248 #endif // V8_COMPILER_FRAME_H_ | 241 #endif // V8_COMPILER_FRAME_H_ |
OLD | NEW |