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: 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 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) {} 32 ~BytecodeRegisterAllocator() = default; 33 BytecodeRegisterAllocator(const BytecodeRegisterAllocator&) = delete; 34 BytecodeRegisterAllocator& operator=(const BytecodeRegisterAllocator&) = 35 delete; 36 37 // Returns a new register. NewRegister()38 Register NewRegister() { 39 Register reg(next_register_index_++); 40 max_register_count_ = std::max(next_register_index_, max_register_count_); 41 if (observer_) { 42 observer_->RegisterAllocateEvent(reg); 43 } 44 return reg; 45 } 46 47 // Returns a consecutive list of |count| new registers. NewRegisterList(int count)48 RegisterList NewRegisterList(int count) { 49 RegisterList reg_list(next_register_index_, count); 50 next_register_index_ += count; 51 max_register_count_ = std::max(next_register_index_, max_register_count_); 52 if (observer_) { 53 observer_->RegisterListAllocateEvent(reg_list); 54 } 55 return reg_list; 56 } 57 58 // Returns a growable register list. NewGrowableRegisterList()59 RegisterList NewGrowableRegisterList() { 60 RegisterList reg_list(next_register_index_, 0); 61 return reg_list; 62 } 63 64 // Appends a new register to |reg_list| increasing it's count by one and 65 // returning the register added. 66 // 67 // Note: no other new registers must be currently allocated since the register 68 // list was originally allocated. GrowRegisterList(RegisterList* reg_list)69 Register GrowRegisterList(RegisterList* reg_list) { 70 Register reg(NewRegister()); 71 reg_list->IncrementRegisterCount(); 72 // If the following CHECK fails then a register was allocated (and not 73 // freed) between the creation of the RegisterList and this call to add a 74 // Register. 75 CHECK_EQ(reg.index(), reg_list->last_register().index()); 76 return reg; 77 } 78 79 // Release all registers above |register_index|. ReleaseRegisters(int register_index)80 void ReleaseRegisters(int register_index) { 81 int count = next_register_index_ - register_index; 82 next_register_index_ = register_index; 83 if (observer_) { 84 observer_->RegisterListFreeEvent(RegisterList(register_index, count)); 85 } 86 } 87 88 // Returns true if the register |reg| is a live register. RegisterIsLive(Register reg) const89 bool RegisterIsLive(Register reg) const { 90 return reg.index() < next_register_index_; 91 } 92 93 // Returns a register list for all currently live registers. AllLiveRegisters() const94 RegisterList AllLiveRegisters() const { 95 return RegisterList(0, next_register_index()); 96 } 97 set_observer(Observer* observer)98 void set_observer(Observer* observer) { observer_ = observer; } 99 next_register_index() const100 int next_register_index() const { return next_register_index_; } maximum_register_count() const101 int maximum_register_count() const { return max_register_count_; } 102 103 private: 104 int next_register_index_; 105 int max_register_count_; 106 Observer* observer_; 107 }; 108 109 } // namespace interpreter 110 } // namespace internal 111 } // namespace v8 112 113 114 #endif // V8_INTERPRETER_BYTECODE_REGISTER_ALLOCATOR_H_ 115