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 12namespace v8 { 13namespace internal { 14namespace 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. 20class Frame { 21 public: 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 29 inline int GetSpillSlotCount() { return spill_slot_count_; } 30 inline int GetDoubleSpillSlotCount() { return double_spill_slot_count_; } 31 32 void SetAllocatedRegisters(BitVector* regs) { 33 DCHECK(allocated_registers_ == NULL); 34 allocated_registers_ = regs; 35 } 36 37 void SetAllocatedDoubleRegisters(BitVector* regs) { 38 DCHECK(allocated_double_registers_ == NULL); 39 allocated_double_registers_ = regs; 40 } 41 42 bool DidAllocateDoubleRegisters() { 43 return !allocated_double_registers_->IsEmpty(); 44 } 45 46 void SetRegisterSaveAreaSize(int size) { 47 DCHECK(IsAligned(size, kPointerSize)); 48 register_save_area_size_ = size; 49 } 50 51 int GetRegisterSaveAreaSize() { return register_save_area_size_; } 52 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. 76class FrameOffset { 77 public: 78 inline bool from_stack_pointer() { return (offset_ & 1) == kFromSp; } 79 inline bool from_frame_pointer() { return (offset_ & 1) == kFromFp; } 80 inline int offset() { return offset_ & ~1; } 81 82 inline static FrameOffset FromStackPointer(int offset) { 83 DCHECK((offset & 1) == 0); 84 return FrameOffset(offset | kFromSp); 85 } 86 87 inline static FrameOffset FromFramePointer(int offset) { 88 DCHECK((offset & 1) == 0); 89 return FrameOffset(offset | kFromFp); 90 } 91 92 private: 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