• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   class Observer {
21    public:
~Observer()22     virtual ~Observer() {}
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 
BytecodeRegisterAllocator(int start_index)28   explicit BytecodeRegisterAllocator(int start_index)
29       : next_register_index_(start_index),
30         max_register_count_(start_index),
31         observer_(nullptr) {}
~BytecodeRegisterAllocator()32   ~BytecodeRegisterAllocator() {}
33 
34   // Returns a new register.
NewRegister()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.
NewRegisterList(int count)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.
NewGrowableRegisterList()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.
GrowRegisterList(RegisterList * reg_list)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|.
ReleaseRegisters(int 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.
RegisterIsLive(Register reg)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.
AllLiveRegisters()91   RegisterList AllLiveRegisters() const {
92     return RegisterList(0, next_register_index());
93   }
94 
set_observer(Observer * observer)95   void set_observer(Observer* observer) { observer_ = observer; }
96 
next_register_index()97   int next_register_index() const { return next_register_index_; }
maximum_register_count()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_
114