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