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), | |
199 deconstruct_frame_if_needed_(false), | |
200 return_block_deconstructs_(false) {} | |
216 | 201 |
217 Frame* frame() const { return frame_; } | 202 Frame* frame() const { return frame_; } |
203 void MarkHasFrame(bool state); | |
218 | 204 |
219 int sp_delta() const { return sp_delta_; } | 205 int sp_delta() const { return sp_delta_; } |
220 void ClearSPDelta() { sp_delta_ = 0; } | 206 void ClearSPDelta() { sp_delta_ = 0; } |
221 void IncreaseSPDelta(int amount) { sp_delta_ += amount; } | 207 void IncreaseSPDelta(int amount) { sp_delta_ += amount; } |
222 | 208 |
223 bool access_frame_with_fp() const { return access_frame_with_fp_; } | 209 bool access_frame_with_fp() const { return access_frame_with_fp_; } |
210 | |
211 // Regardless of how we access slots on the stack - using sp or fp - do we | |
212 // have a frame, at the current stage in code generation. | |
213 bool has_frame() const { return has_frame_; } | |
214 bool deconstruct_frame_if_needed() const { | |
215 return deconstruct_frame_if_needed_; | |
216 } | |
217 void set_deconstruct_frame_if_needed(bool deconstruct) { | |
danno
2016/03/22 18:10:09
I don't think this is needed, either. See code-gen
| |
218 deconstruct_frame_if_needed_ = deconstruct; | |
219 } | |
220 | |
221 bool return_block_deconstructs() const { return return_block_deconstructs_; } | |
222 void MarkReturnBlockDeconstructs() { | |
danno
2016/03/22 18:10:09
I don't think belongs on the frame_access_state, a
| |
223 DCHECK(!return_block_deconstructs_); | |
224 return_block_deconstructs_ = true; | |
225 } | |
224 void SetFrameAccessToDefault(); | 226 void SetFrameAccessToDefault(); |
225 void SetFrameAccessToFP() { access_frame_with_fp_ = true; } | 227 void SetFrameAccessToFP() { access_frame_with_fp_ = true; } |
226 void SetFrameAccessToSP() { access_frame_with_fp_ = false; } | 228 void SetFrameAccessToSP() { access_frame_with_fp_ = false; } |
227 | 229 |
228 int GetSPToFPSlotCount() const { | 230 int GetSPToFPSlotCount() const { |
229 return frame_->GetSPToFPSlotCount() + sp_delta(); | 231 int frame_slot_count = |
232 (has_frame() ? frame()->GetTotalFrameSlotCount() : kElidedFrameSlots) - | |
233 StandardFrameConstants::kFixedSlotCountAboveFp; | |
234 return frame_slot_count + sp_delta(); | |
230 } | 235 } |
231 int GetSPToFPOffset() const { return GetSPToFPSlotCount() * kPointerSize; } | 236 int GetSPToFPOffset() const { return GetSPToFPSlotCount() * kPointerSize; } |
232 | 237 |
233 // Get the frame offset for a given spill slot. The location depends on the | 238 // 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 | 239 // calling convention and the specific frame layout, and may thus be |
235 // architecture-specific. Negative spill slots indicate arguments on the | 240 // architecture-specific. Negative spill slots indicate arguments on the |
236 // caller's frame. | 241 // caller's frame. |
237 FrameOffset GetFrameOffset(int spill_slot) const; | 242 FrameOffset GetFrameOffset(int spill_slot) const; |
238 | 243 |
239 private: | 244 private: |
240 Frame* const frame_; | 245 Frame* const frame_; |
241 bool access_frame_with_fp_; | 246 bool access_frame_with_fp_; |
242 int sp_delta_; | 247 int sp_delta_; |
248 bool has_frame_; | |
249 bool deconstruct_frame_if_needed_; | |
250 bool return_block_deconstructs_; | |
243 }; | 251 }; |
244 } // namespace compiler | 252 } // namespace compiler |
245 } // namespace internal | 253 } // namespace internal |
246 } // namespace v8 | 254 } // namespace v8 |
247 | 255 |
248 #endif // V8_COMPILER_FRAME_H_ | 256 #endif // V8_COMPILER_FRAME_H_ |
OLD | NEW |