blob: b8f737be79386641907f6903123f592f23be838b [file] [log] [blame]
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_INTERPRETER_BYTECODE_REGISTER_ALLOCATOR_H_
#define V8_INTERPRETER_BYTECODE_REGISTER_ALLOCATOR_H_
#include "src/interpreter/bytecodes.h"
#include "src/zone-containers.h"
namespace v8 {
namespace internal {
namespace interpreter {
class BytecodeArrayBuilder;
class Register;
class TemporaryRegisterObserver;
class TemporaryRegisterAllocator final {
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);
// Borrow a register from a range prepared with
// PrepareForConsecutiveTemporaryRegisters().
void BorrowConsecutiveTemporaryRegister(int reg_index);
// Returns true if |reg| is a temporary register and is currently
// borrowed.
bool RegisterIsLive(Register reg) const;
// Returns the first register in the range of temporary registers.
Register first_temporary_register() const;
// 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);
private:
// Allocate a temporary register.
int AllocateTemporaryRegister();
ZoneSet<int> free_temporaries_;
int allocation_base_;
int allocation_count_;
TemporaryRegisterObserver* observer_;
DISALLOW_COPY_AND_ASSIGN(TemporaryRegisterAllocator);
};
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.
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; }
private:
TemporaryRegisterAllocator* base_allocator() const { return base_allocator_; }
TemporaryRegisterAllocator* base_allocator_;
ZoneVector<int> allocated_;
int next_consecutive_register_;
int next_consecutive_count_;
DISALLOW_COPY_AND_ASSIGN(BytecodeRegisterAllocator);
};
} // namespace interpreter
} // namespace internal
} // namespace v8
#endif // V8_INTERPRETER_BYTECODE_REGISTER_ALLOCATOR_H_