Line data Source code
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.
17 : class BytecodeRegisterAllocator final {
18 : public:
19 : // Enables observation of register allocation and free events.
20 2138304 : class Observer {
21 : public:
22 0 : 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 2138851 : observer_(nullptr) {}
32 : ~BytecodeRegisterAllocator() = default;
33 :
34 : // Returns a new register.
35 21832085 : Register NewRegister() {
36 21832085 : Register reg(next_register_index_++);
37 43664170 : max_register_count_ = std::max(next_register_index_, max_register_count_);
38 21832085 : if (observer_) {
39 21830477 : observer_->RegisterAllocateEvent(reg);
40 : }
41 21832019 : return reg;
42 : }
43 :
44 : // Returns a consecutive list of |count| new registers.
45 699362 : RegisterList NewRegisterList(int count) {
46 699362 : RegisterList reg_list(next_register_index_, count);
47 699362 : next_register_index_ += count;
48 1398724 : max_register_count_ = std::max(next_register_index_, max_register_count_);
49 699362 : if (observer_) {
50 699044 : observer_->RegisterListAllocateEvent(reg_list);
51 : }
52 699363 : 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 8365799 : Register GrowRegisterList(RegisterList* reg_list) {
67 8365799 : 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 8365905 : CHECK_EQ(reg.index(), reg_list->last_register().index());
73 8365905 : return reg;
74 : }
75 :
76 : // Release all registers above |register_index|.
77 : void ReleaseRegisters(int register_index) {
78 81399206 : int count = next_register_index_ - register_index;
79 81399207 : next_register_index_ = register_index;
80 81399207 : if (observer_) {
81 162782612 : 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 5 : 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 2138321 : 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_
|