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 3 // found in the LICENSE file. 4 5 #ifndef V8_COMPILER_FRAME_H_ 6 #define V8_COMPILER_FRAME_H_ 7 8 #include "src/v8.h" 9 10 #include "src/data-flow.h" 11 12 namespace v8 { 13 namespace internal { 14 namespace compiler { 15 16 // Collects the spill slot requirements and the allocated general and double 17 // registers for a compiled function. Frames are usually populated by the 18 // register allocator and are used by Linkage to generate code for the prologue 19 // and epilogue to compiled code. 20 class Frame { 21 public: Frame()22 Frame() 23 : register_save_area_size_(0), 24 spill_slot_count_(0), 25 double_spill_slot_count_(0), 26 allocated_registers_(NULL), 27 allocated_double_registers_(NULL) {} 28 GetSpillSlotCount()29 inline int GetSpillSlotCount() { return spill_slot_count_; } GetDoubleSpillSlotCount()30 inline int GetDoubleSpillSlotCount() { return double_spill_slot_count_; } 31 SetAllocatedRegisters(BitVector * regs)32 void SetAllocatedRegisters(BitVector* regs) { 33 DCHECK(allocated_registers_ == NULL); 34 allocated_registers_ = regs; 35 } 36 SetAllocatedDoubleRegisters(BitVector * regs)37 void SetAllocatedDoubleRegisters(BitVector* regs) { 38 DCHECK(allocated_double_registers_ == NULL); 39 allocated_double_registers_ = regs; 40 } 41 DidAllocateDoubleRegisters()42 bool DidAllocateDoubleRegisters() { 43 return !allocated_double_registers_->IsEmpty(); 44 } 45 SetRegisterSaveAreaSize(int size)46 void SetRegisterSaveAreaSize(int size) { 47 DCHECK(IsAligned(size, kPointerSize)); 48 register_save_area_size_ = size; 49 } 50 GetRegisterSaveAreaSize()51 int GetRegisterSaveAreaSize() { return register_save_area_size_; } 52 AllocateSpillSlot(bool is_double)53 int AllocateSpillSlot(bool is_double) { 54 // If 32-bit, skip one if the new slot is a double. 55 if (is_double) { 56 if (kDoubleSize > kPointerSize) { 57 DCHECK(kDoubleSize == kPointerSize * 2); 58 spill_slot_count_++; 59 spill_slot_count_ |= 1; 60 } 61 double_spill_slot_count_++; 62 } 63 return spill_slot_count_++; 64 } 65 66 private: 67 int register_save_area_size_; 68 int spill_slot_count_; 69 int double_spill_slot_count_; 70 BitVector* allocated_registers_; 71 BitVector* allocated_double_registers_; 72 }; 73 74 75 // Represents an offset from either the stack pointer or frame pointer. 76 class FrameOffset { 77 public: from_stack_pointer()78 inline bool from_stack_pointer() { return (offset_ & 1) == kFromSp; } from_frame_pointer()79 inline bool from_frame_pointer() { return (offset_ & 1) == kFromFp; } offset()80 inline int offset() { return offset_ & ~1; } 81 FromStackPointer(int offset)82 inline static FrameOffset FromStackPointer(int offset) { 83 DCHECK((offset & 1) == 0); 84 return FrameOffset(offset | kFromSp); 85 } 86 FromFramePointer(int offset)87 inline static FrameOffset FromFramePointer(int offset) { 88 DCHECK((offset & 1) == 0); 89 return FrameOffset(offset | kFromFp); 90 } 91 92 private: FrameOffset(int offset)93 explicit FrameOffset(int offset) : offset_(offset) {} 94 95 int offset_; // Encodes SP or FP in the low order bit. 96 97 static const int kFromSp = 1; 98 static const int kFromFp = 0; 99 }; 100 } 101 } 102 } // namespace v8::internal::compiler 103 104 #endif // V8_COMPILER_FRAME_H_ 105