// 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 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_; }

 private:
  // Allocate a temporary register.
  int AllocateTemporaryRegister();

  ZoneSet<int> free_temporaries_;
  int allocation_base_;
  int allocation_count_;

  DISALLOW_COPY_AND_ASSIGN(TemporaryRegisterAllocator);
};

// A class than 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_
