| Index: src/compiler/frame.h
|
| diff --git a/src/compiler/frame.h b/src/compiler/frame.h
|
| index 886294b33c1e6878e48052b9d46bff3074a255f2..e82036ff5a14535c52258ee9e775de47a2eb5f7f 100644
|
| --- a/src/compiler/frame.h
|
| +++ b/src/compiler/frame.h
|
| @@ -12,11 +12,17 @@ namespace v8 {
|
| namespace internal {
|
| namespace compiler {
|
|
|
| +class CallDescriptor;
|
| +
|
| // Collects the spill slot and other frame slot requirements for a compiled
|
| // function. Frames are usually populated by the register allocator and are used
|
| -// by Linkage to generate code for the prologue and epilogue to compiled code.
|
| +// by Linkage to generate code for the prologue and epilogue to compiled
|
| +// code. Frame objects must be considered immutable once they've been
|
| +// instantiated and the basic information about the frame has been collected
|
| +// into them. Mutable state associated with the frame is stored separately in
|
| +// FrameAccessState.
|
| //
|
| -// Frames are divided up into four regions.
|
| +// Frames are divided up into three regions.
|
| // - The first is the fixed header, which always has a constant size and can be
|
| // predicted before code generation begins depending on the type of code being
|
| // generated.
|
| @@ -27,8 +33,6 @@ namespace compiler {
|
| // reserved after register allocation, since its size can only be precisely
|
| // determined after register allocation once the number of used callee-saved
|
| // register is certain.
|
| -// - The fourth region is used to pass arguments to other functions. It should
|
| -// be empty except when a call is being prepared.
|
| //
|
| // Every pointer in a frame has a slot id. On 32-bit platforms, doubles consume
|
| // two slots.
|
| @@ -78,18 +82,26 @@ namespace compiler {
|
| // |- - - - - - - - -| | |
|
| // | ... | Callee-saved |
|
| // |- - - - - - - - -| | |
|
| -// m+r+4 | callee-saved r | v |
|
| -// +-----------------+---- |
|
| -// | parameter 0 | ^ |
|
| -// |- - - - - - - - -| | |
|
| -// | ... | Outgoing parameters |
|
| -// |- - - - - - - - -| | (for function calls) |
|
| -// | parameter p | v v
|
| +// m+r+4 | callee-saved r | v v
|
| // -----+-----------------+----- <-- stack ptr -------------
|
| //
|
| class Frame : public ZoneObject {
|
| public:
|
| - explicit Frame(int fixed_frame_size_in_slots);
|
| + explicit Frame(int fixed_frame_size_in_slots,
|
| + const CallDescriptor* descriptor);
|
| +
|
| + static int FPOffsetToSlot(int frame_offset) {
|
| + return StandardFrameConstants::kFixedSlotCountAboveFp - 1 -
|
| + frame_offset / kPointerSize;
|
| + }
|
| +
|
| + static int SlotToFPOffset(int slot) {
|
| + return (StandardFrameConstants::kFixedSlotCountAboveFp - 1 - slot) *
|
| + kPointerSize;
|
| + }
|
| +
|
| + inline bool needs_frame() const { return needs_frame_; }
|
| + inline void MarkNeedsFrame() { needs_frame_ = true; }
|
|
|
| inline int GetTotalFrameSlotCount() const { return frame_slot_count_; }
|
|
|
| @@ -97,9 +109,6 @@ class Frame : public ZoneObject {
|
| return GetTotalFrameSlotCount() -
|
| StandardFrameConstants::kFixedSlotCountAboveFp;
|
| }
|
| - inline int GetOutgoingParameterSlotCount() const {
|
| - return outgoing_parameter_slot_count_;
|
| - }
|
| inline int GetSavedCalleeRegisterSlotCount() const {
|
| return callee_saved_slot_count_;
|
| }
|
| @@ -125,32 +134,23 @@ class Frame : public ZoneObject {
|
| return !allocated_double_registers_->IsEmpty();
|
| }
|
|
|
| - void AllocateOutgoingParameterSlots(int count) {
|
| - outgoing_parameter_slot_count_ += count;
|
| - frame_slot_count_ += count;
|
| - }
|
| -
|
| - void ClearOutgoingParameterSlots() {
|
| - frame_slot_count_ -= outgoing_parameter_slot_count_;
|
| - outgoing_parameter_slot_count_ = 0;
|
| - }
|
| -
|
| int AlignSavedCalleeRegisterSlots() {
|
| DCHECK_EQ(0, callee_saved_slot_count_);
|
| + needs_frame_ = true;
|
| int delta = frame_slot_count_ & 1;
|
| frame_slot_count_ += delta;
|
| return delta;
|
| }
|
|
|
| void AllocateSavedCalleeRegisterSlots(int count) {
|
| - DCHECK_EQ(0, outgoing_parameter_slot_count_);
|
| + needs_frame_ = true;
|
| frame_slot_count_ += count;
|
| callee_saved_slot_count_ += count;
|
| }
|
|
|
| int AllocateSpillSlot(int width) {
|
| - DCHECK_EQ(0, outgoing_parameter_slot_count_);
|
| DCHECK_EQ(0, callee_saved_slot_count_);
|
| + needs_frame_ = true;
|
| int frame_slot_count_before = frame_slot_count_;
|
| int slot = AllocateAlignedFrameSlot(width);
|
| spill_slot_count_ += (frame_slot_count_ - frame_slot_count_before);
|
| @@ -158,9 +158,9 @@ class Frame : public ZoneObject {
|
| }
|
|
|
| int ReserveSpillSlots(size_t slot_count) {
|
| - DCHECK_EQ(0, outgoing_parameter_slot_count_);
|
| DCHECK_EQ(0, callee_saved_slot_count_);
|
| DCHECK_EQ(0, spill_slot_count_);
|
| + needs_frame_ = true;
|
| spill_slot_count_ += static_cast<int>(slot_count);
|
| frame_slot_count_ += static_cast<int>(slot_count);
|
| return frame_slot_count_ - 1;
|
| @@ -182,8 +182,8 @@ class Frame : public ZoneObject {
|
| }
|
|
|
| private:
|
| + bool needs_frame_;
|
| int frame_slot_count_;
|
| - int outgoing_parameter_slot_count_;
|
| int callee_saved_slot_count_;
|
| int spill_slot_count_;
|
| BitVector* allocated_registers_;
|
| @@ -218,6 +218,38 @@ class FrameOffset {
|
| static const int kFromSp = 1;
|
| static const int kFromFp = 0;
|
| };
|
| +
|
| +// Encapsulates the mutable state maintained during code generation about the
|
| +// current function's frame.
|
| +class FrameAccessState : public ZoneObject {
|
| + public:
|
| + explicit FrameAccessState(Frame* const frame)
|
| + : frame_(frame), access_frame_with_fp_(false), sp_delta_(0) {
|
| + SetFrameAccessToDefault();
|
| + }
|
| +
|
| + Frame* const frame() const { return frame_; }
|
| +
|
| + int sp_delta() const { return sp_delta_; }
|
| + void ClearSPDelta() { sp_delta_ = 0; }
|
| + void IncreaseSPDelta(int amount) { sp_delta_ += amount; }
|
| +
|
| + bool access_frame_with_fp() const { return access_frame_with_fp_; }
|
| + void SetFrameAccessToDefault();
|
| + void SetFrameAccessToFP() { access_frame_with_fp_ = true; }
|
| + void SetFrameAccessToSP() { access_frame_with_fp_ = false; }
|
| +
|
| + // Get the frame offset for a given spill slot. The location depends on the
|
| + // calling convention and the specific frame layout, and may thus be
|
| + // architecture-specific. Negative spill slots indicate arguments on the
|
| + // caller's frame.
|
| + FrameOffset GetFrameOffset(int spill_slot) const;
|
| +
|
| + private:
|
| + Frame* const frame_;
|
| + bool access_frame_with_fp_;
|
| + int sp_delta_;
|
| +};
|
| } // namespace compiler
|
| } // namespace internal
|
| } // namespace v8
|
|
|