Home | History | Annotate | Download | only in compiler
      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:
     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.
     76 class 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