Index: src/interpreter/bytecode-register-allocator.h |
diff --git a/src/interpreter/bytecode-register-allocator.h b/src/interpreter/bytecode-register-allocator.h |
index 63b302a79e16645aa900cc808cc49c4e815ee9b9..ab57bf4e0079ac4158a6fc769cfdb4ac4291e454 100644 |
--- a/src/interpreter/bytecode-register-allocator.h |
+++ b/src/interpreter/bytecode-register-allocator.h |
@@ -5,6 +5,7 @@ |
#ifndef V8_INTERPRETER_BYTECODE_REGISTER_ALLOCATOR_H_ |
#define V8_INTERPRETER_BYTECODE_REGISTER_ALLOCATOR_H_ |
+#include "src/interpreter/bytecode-register.h" |
#include "src/interpreter/bytecodes.h" |
#include "src/zone/zone-containers.h" |
@@ -12,99 +13,98 @@ namespace v8 { |
namespace internal { |
namespace interpreter { |
-class BytecodeArrayBuilder; |
-class Register; |
-class TemporaryRegisterObserver; |
- |
-class TemporaryRegisterAllocator final { |
+class RegisterList { |
public: |
- TemporaryRegisterAllocator(Zone* zone, int start_index); |
- |
- // Borrow a temporary register. |
- int BorrowTemporaryRegister(); |
- |
- // Borrow a temporary register from the register range outside of |
- // |start_index| to |end_index|. |
- int BorrowTemporaryRegisterNotInRange(int start_index, int end_index); |
- |
- // Return a temporary register when no longer used. |
- void ReturnTemporaryRegister(int reg_index); |
- |
- // Ensure a run of consecutive registers is available. Each register in |
- // the range should be borrowed with BorrowConsecutiveTemporaryRegister(). |
- // Returns the start index of the run. |
- int PrepareForConsecutiveTemporaryRegisters(size_t count); |
+ RegisterList() : first_reg_index_(Register().index()), register_count_(0) {} |
+ RegisterList(int first_reg_index, int register_count) |
+ : first_reg_index_(first_reg_index), register_count_(register_count) {} |
- // Borrow a register from a range prepared with |
- // PrepareForConsecutiveTemporaryRegisters(). |
- void BorrowConsecutiveTemporaryRegister(int reg_index); |
+ // Returns a new RegisterList which is a truncated version of this list, with |
+ // |count| registers. |
+ const RegisterList Truncate(int new_count) { |
+ DCHECK_GE(new_count, 0); |
+ DCHECK_LT(new_count, register_count_); |
+ return RegisterList(first_reg_index_, new_count); |
+ } |
- // Returns true if |reg| is a temporary register and is currently |
- // borrowed. |
- bool RegisterIsLive(Register reg) const; |
+ const Register operator[](size_t i) const { |
+ DCHECK_LT(static_cast<int>(i), register_count_); |
+ return Register(first_reg_index_ + static_cast<int>(i)); |
+ } |
- // Returns the first register in the range of temporary registers. |
- Register first_temporary_register() const; |
+ const Register first_register() const { |
+ return (register_count() == 0) ? Register(0) : (*this)[0]; |
+ } |
- // Returns the last register in the range of temporary registers. |
- Register last_temporary_register() const; |
- |
- // Returns the start index of temporary register allocations. |
- int allocation_base() const { return allocation_base_; } |
- |
- // Returns the number of temporary register allocations made. |
- int allocation_count() const { return allocation_count_; } |
- |
- // Sets an observer for temporary register events. |
- void set_observer(TemporaryRegisterObserver* observer); |
+ int register_count() const { return register_count_; } |
private: |
- // Allocate a temporary register. |
- int AllocateTemporaryRegister(); |
- |
- ZoneSet<int> free_temporaries_; |
- int allocation_base_; |
- int allocation_count_; |
- TemporaryRegisterObserver* observer_; |
- |
- DISALLOW_COPY_AND_ASSIGN(TemporaryRegisterAllocator); |
+ int first_reg_index_; |
+ int register_count_; |
}; |
-class TemporaryRegisterObserver { |
- public: |
- virtual ~TemporaryRegisterObserver() {} |
- virtual void TemporaryRegisterFreeEvent(Register reg) = 0; |
-}; |
- |
-// A class that allows the instantiator to allocate temporary registers that are |
-// cleaned up when scope is closed. |
+// A class that allows the allocation of contiguous temporary registers. |
class BytecodeRegisterAllocator final { |
public: |
- explicit BytecodeRegisterAllocator(Zone* zone, |
- TemporaryRegisterAllocator* allocator); |
- ~BytecodeRegisterAllocator(); |
- Register NewRegister(); |
- |
- // Ensure |count| consecutive allocations are available. |
- void PrepareForConsecutiveAllocations(size_t count); |
- |
- // Get the next consecutive allocation after calling |
- // PrepareForConsecutiveAllocations. |
- Register NextConsecutiveRegister(); |
- |
- // Returns true if |reg| is allocated in this allocator. |
- bool RegisterIsAllocatedInThisScope(Register reg) const; |
- |
- // Returns true if unused consecutive allocations remain. |
- bool HasConsecutiveAllocations() const { return next_consecutive_count_ > 0; } |
+ // Enables observation of register allocation and free events. |
+ class Observer { |
+ public: |
+ virtual ~Observer() {} |
+ virtual void RegisterAllocateEvent(Register reg) = 0; |
+ virtual void RegisterListAllocateEvent(RegisterList reg_list) = 0; |
+ virtual void RegisterListFreeEvent(RegisterList reg_list) = 0; |
+ }; |
+ |
+ explicit BytecodeRegisterAllocator(int start_index) |
+ : next_register_index_(start_index), |
+ max_register_count_(start_index), |
+ observer_(nullptr) {} |
+ ~BytecodeRegisterAllocator() {} |
+ |
+ // Returns a new register. |
+ Register NewRegister() { |
+ Register reg(next_register_index_++); |
+ max_register_count_ = std::max(next_register_index_, max_register_count_); |
+ if (observer_) { |
+ observer_->RegisterAllocateEvent(reg); |
+ } |
+ return reg; |
+ } |
+ |
+ // Returns a consecutive list of |count| new registers. |
+ RegisterList NewRegisterList(int count) { |
+ RegisterList reg_list(next_register_index_, count); |
+ next_register_index_ += count; |
+ max_register_count_ = std::max(next_register_index_, max_register_count_); |
+ if (observer_) { |
+ observer_->RegisterListAllocateEvent(reg_list); |
+ } |
+ return reg_list; |
+ } |
+ |
+ // Release all registers above |register_index|. |
+ void ReleaseRegisters(int register_index) { |
+ if (observer_) { |
+ observer_->RegisterListFreeEvent( |
+ RegisterList(register_index, next_register_index_ - register_index)); |
+ } |
+ next_register_index_ = register_index; |
+ } |
+ |
+ // Returns true if the register |reg| is a live register. |
+ bool RegisterIsLive(Register reg) const { |
+ return reg.index() < next_register_index_; |
+ } |
+ |
+ void set_observer(Observer* observer) { observer_ = observer; } |
+ |
+ int next_register_index() const { return next_register_index_; } |
+ int maximum_register_count() const { return max_register_count_; } |
private: |
- TemporaryRegisterAllocator* base_allocator() const { return base_allocator_; } |
- |
- TemporaryRegisterAllocator* base_allocator_; |
- ZoneVector<int> allocated_; |
- int next_consecutive_register_; |
- int next_consecutive_count_; |
+ int next_register_index_; |
+ int max_register_count_; |
+ Observer* observer_; |
DISALLOW_COPY_AND_ASSIGN(BytecodeRegisterAllocator); |
}; |