diff options
Diffstat (limited to 'deps/v8/src/compiler/frame.h')
-rw-r--r-- | deps/v8/src/compiler/frame.h | 141 |
1 files changed, 109 insertions, 32 deletions
diff --git a/deps/v8/src/compiler/frame.h b/deps/v8/src/compiler/frame.h index 2850a8c1a1..aa823b6ba8 100644 --- a/deps/v8/src/compiler/frame.h +++ b/deps/v8/src/compiler/frame.h @@ -6,25 +6,93 @@ #define V8_COMPILER_FRAME_H_ #include "src/bit-vector.h" +#include "src/frames.h" namespace v8 { namespace internal { namespace compiler { -// Collects the spill slot requirements and the allocated general and double -// registers 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. +// 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. +// +// 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. The second is the +// region for spill slots, which is immediately below the fixed header and grows +// as the register allocator needs to spill to the stack and asks the frame for +// more space. The third region, which contains the callee-saved registers must +// be 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. +// +// Every pointer in a frame has a slot id. On 32-bit platforms, doubles consume +// two slots. +// +// Stack slot indices >= 0 access the callee stack with slot 0 corresponding to +// the callee's saved return address and 1 corresponding to the saved frame +// pointer. Some frames have additional information stored in the fixed header, +// for example JSFunctions store the function context and marker in the fixed +// header, with slot index 2 corresponding to the current function context and 3 +// corresponding to the frame marker/JSFunction. The frame region immediately +// below the fixed header contains spill slots starting a 4 for JsFunctions. The +// callee-saved frame region below that starts at 4+spilled_slot_count. Callee +// stack slots corresponding to parameters are accessible through negative slot +// ids. +// +// Every slot of a caller or callee frame is accessible by the register +// allocator and gap resolver with a SpillSlotOperand containing its +// corresponding slot id. +// +// Below an example JSFunction Frame with slot ids, frame regions and contents: +// +// slot JS frame +// +-----------------+---------------------------- +// -n-1 | parameter 0 | ^ +// |- - - - - - - - -| | +// -n | | Caller +// ... | ... | frame slots +// -2 | parameter n-1 | (slot < 0) +// |- - - - - - - - -| | +// -1 | parameter n | v +// -----+-----------------+---------------------------- +// 0 | return addr | ^ ^ +// |- - - - - - - - -| | | +// 1 | saved frame ptr | Fixed | +// |- - - - - - - - -| Header <-- frame ptr | +// 2 | Context | | | +// |- - - - - - - - -| | | +// 3 |JSFunction/Marker| v | +// +-----------------+---- | +// 4 | spill 1 | ^ Callee +// |- - - - - - - - -| | frame slots +// ... | ... | Spill slots (slot >= 0) +// |- - - - - - - - -| | | +// m+4 | spill m | v | +// +-----------------+---- | +// m+5 | callee-saved 1 | ^ | +// |- - - - - - - - -| | | +// | ... | Callee-saved | +// |- - - - - - - - -| | | +// m+r+4 | callee-saved r | v v +// -----+-----------------+----- <-- stack ptr --------- +// class Frame : public ZoneObject { public: - Frame() - : register_save_area_size_(0), - spill_slot_count_(0), - osr_stack_slot_count_(0), - allocated_registers_(NULL), - allocated_double_registers_(NULL) {} + explicit Frame(int fixed_frame_size_in_slots); - inline int GetSpillSlotCount() { return spill_slot_count_; } + inline int GetTotalFrameSlotCount() { return frame_slot_count_; } + + inline int GetSavedCalleeRegisterSlotCount() { + return spilled_callee_register_slot_count_; + } + inline int GetSpillSlotCount() { return stack_slot_count_; } + + inline void SetElidedFrameSizeInSlots(int slots) { + DCHECK_EQ(0, spilled_callee_register_slot_count_); + DCHECK_EQ(0, stack_slot_count_); + frame_slot_count_ = slots; + } void SetAllocatedRegisters(BitVector* regs) { DCHECK(allocated_registers_ == NULL); @@ -40,41 +108,50 @@ class Frame : public ZoneObject { return !allocated_double_registers_->IsEmpty(); } - void SetRegisterSaveAreaSize(int size) { - DCHECK(IsAligned(size, kPointerSize)); - register_save_area_size_ = size; + int AlignSavedCalleeRegisterSlots() { + DCHECK_EQ(0, spilled_callee_register_slot_count_); + int frame_slot_count_before = frame_slot_count_; + frame_slot_count_ = RoundUp(frame_slot_count_, 2); + return frame_slot_count_before - frame_slot_count_; } - int GetRegisterSaveAreaSize() { return register_save_area_size_; } + void AllocateSavedCalleeRegisterSlots(int count) { + frame_slot_count_ += count; + spilled_callee_register_slot_count_ += count; + } - // OSR stack slots, including locals and expression stack slots. - void SetOsrStackSlotCount(int slots) { - DCHECK(slots >= 0); - osr_stack_slot_count_ = slots; + int AllocateSpillSlot(int width) { + DCHECK_EQ(0, spilled_callee_register_slot_count_); + int frame_slot_count_before = frame_slot_count_; + int slot = AllocateAlignedFrameSlot(width); + stack_slot_count_ += (frame_slot_count_ - frame_slot_count_before); + return slot; } - int GetOsrStackSlotCount() { return osr_stack_slot_count_; } + int ReserveSpillSlots(size_t slot_count) { + DCHECK_EQ(0, spilled_callee_register_slot_count_); + DCHECK_EQ(0, stack_slot_count_); + stack_slot_count_ += static_cast<int>(slot_count); + frame_slot_count_ += static_cast<int>(slot_count); + return frame_slot_count_ - 1; + } - int AllocateSpillSlot(int width) { + private: + int AllocateAlignedFrameSlot(int width) { DCHECK(width == 4 || width == 8); // Skip one slot if necessary. if (width > kPointerSize) { DCHECK(width == kPointerSize * 2); - spill_slot_count_++; - spill_slot_count_ |= 1; + frame_slot_count_++; + frame_slot_count_ |= 1; } - return spill_slot_count_++; - } - - void ReserveSpillSlots(size_t slot_count) { - DCHECK_EQ(0, spill_slot_count_); // can only reserve before allocation. - spill_slot_count_ = static_cast<int>(slot_count); + return frame_slot_count_++; } private: - int register_save_area_size_; - int spill_slot_count_; - int osr_stack_slot_count_; + int frame_slot_count_; + int spilled_callee_register_slot_count_; + int stack_slot_count_; BitVector* allocated_registers_; BitVector* allocated_double_registers_; |