V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
bytecode-register-allocator.h
1 // Copyright 2015 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_INTERPRETER_BYTECODE_REGISTER_ALLOCATOR_H_
6 #define V8_INTERPRETER_BYTECODE_REGISTER_ALLOCATOR_H_
7 
8 #include "src/interpreter/bytecode-register.h"
9 #include "src/interpreter/bytecodes.h"
10 #include "src/zone/zone-containers.h"
11 
12 namespace v8 {
13 namespace internal {
14 namespace interpreter {
15 
16 // A class that allows the allocation of contiguous temporary registers.
18  public:
19  // Enables observation of register allocation and free events.
20  class Observer {
21  public:
22  virtual ~Observer() = default;
23  virtual void RegisterAllocateEvent(Register reg) = 0;
24  virtual void RegisterListAllocateEvent(RegisterList reg_list) = 0;
25  virtual void RegisterListFreeEvent(RegisterList reg_list) = 0;
26  };
27 
28  explicit BytecodeRegisterAllocator(int start_index)
29  : next_register_index_(start_index),
30  max_register_count_(start_index),
31  observer_(nullptr) {}
32  ~BytecodeRegisterAllocator() = default;
33 
34  // Returns a new register.
35  Register NewRegister() {
36  Register reg(next_register_index_++);
37  max_register_count_ = std::max(next_register_index_, max_register_count_);
38  if (observer_) {
39  observer_->RegisterAllocateEvent(reg);
40  }
41  return reg;
42  }
43 
44  // Returns a consecutive list of |count| new registers.
45  RegisterList NewRegisterList(int count) {
46  RegisterList reg_list(next_register_index_, count);
47  next_register_index_ += count;
48  max_register_count_ = std::max(next_register_index_, max_register_count_);
49  if (observer_) {
50  observer_->RegisterListAllocateEvent(reg_list);
51  }
52  return reg_list;
53  }
54 
55  // Returns a growable register list.
56  RegisterList NewGrowableRegisterList() {
57  RegisterList reg_list(next_register_index_, 0);
58  return reg_list;
59  }
60 
61  // Appends a new register to |reg_list| increasing it's count by one and
62  // returning the register added.
63  //
64  // Note: no other new registers must be currently allocated since the register
65  // list was originally allocated.
66  Register GrowRegisterList(RegisterList* reg_list) {
67  Register reg(NewRegister());
68  reg_list->IncrementRegisterCount();
69  // If the following CHECK fails then a register was allocated (and not
70  // freed) between the creation of the RegisterList and this call to add a
71  // Register.
72  CHECK_EQ(reg.index(), reg_list->last_register().index());
73  return reg;
74  }
75 
76  // Release all registers above |register_index|.
77  void ReleaseRegisters(int register_index) {
78  int count = next_register_index_ - register_index;
79  next_register_index_ = register_index;
80  if (observer_) {
81  observer_->RegisterListFreeEvent(RegisterList(register_index, count));
82  }
83  }
84 
85  // Returns true if the register |reg| is a live register.
86  bool RegisterIsLive(Register reg) const {
87  return reg.index() < next_register_index_;
88  }
89 
90  // Returns a register list for all currently live registers.
91  RegisterList AllLiveRegisters() const {
92  return RegisterList(0, next_register_index());
93  }
94 
95  void set_observer(Observer* observer) { observer_ = observer; }
96 
97  int next_register_index() const { return next_register_index_; }
98  int maximum_register_count() const { return max_register_count_; }
99 
100  private:
101  int next_register_index_;
102  int max_register_count_;
103  Observer* observer_;
104 
105  DISALLOW_COPY_AND_ASSIGN(BytecodeRegisterAllocator);
106 };
107 
108 } // namespace interpreter
109 } // namespace internal
110 } // namespace v8
111 
112 
113 #endif // V8_INTERPRETER_BYTECODE_REGISTER_ALLOCATOR_H_
Definition: libplatform.h:13