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