11cb0ef41Sopenharmony_ci// Copyright 2015 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef V8_INTERPRETER_BYTECODE_REGISTER_ALLOCATOR_H_ 61cb0ef41Sopenharmony_ci#define V8_INTERPRETER_BYTECODE_REGISTER_ALLOCATOR_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include "src/interpreter/bytecode-register.h" 91cb0ef41Sopenharmony_ci#include "src/interpreter/bytecodes.h" 101cb0ef41Sopenharmony_ci#include "src/zone/zone-containers.h" 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_cinamespace v8 { 131cb0ef41Sopenharmony_cinamespace internal { 141cb0ef41Sopenharmony_cinamespace interpreter { 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ci// A class that allows the allocation of contiguous temporary registers. 171cb0ef41Sopenharmony_ciclass BytecodeRegisterAllocator final { 181cb0ef41Sopenharmony_ci public: 191cb0ef41Sopenharmony_ci // Enables observation of register allocation and free events. 201cb0ef41Sopenharmony_ci class Observer { 211cb0ef41Sopenharmony_ci public: 221cb0ef41Sopenharmony_ci virtual ~Observer() = default; 231cb0ef41Sopenharmony_ci virtual void RegisterAllocateEvent(Register reg) = 0; 241cb0ef41Sopenharmony_ci virtual void RegisterListAllocateEvent(RegisterList reg_list) = 0; 251cb0ef41Sopenharmony_ci virtual void RegisterListFreeEvent(RegisterList reg_list) = 0; 261cb0ef41Sopenharmony_ci }; 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ci explicit BytecodeRegisterAllocator(int start_index) 291cb0ef41Sopenharmony_ci : next_register_index_(start_index), 301cb0ef41Sopenharmony_ci max_register_count_(start_index), 311cb0ef41Sopenharmony_ci observer_(nullptr) {} 321cb0ef41Sopenharmony_ci ~BytecodeRegisterAllocator() = default; 331cb0ef41Sopenharmony_ci BytecodeRegisterAllocator(const BytecodeRegisterAllocator&) = delete; 341cb0ef41Sopenharmony_ci BytecodeRegisterAllocator& operator=(const BytecodeRegisterAllocator&) = 351cb0ef41Sopenharmony_ci delete; 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_ci // Returns a new register. 381cb0ef41Sopenharmony_ci Register NewRegister() { 391cb0ef41Sopenharmony_ci Register reg(next_register_index_++); 401cb0ef41Sopenharmony_ci max_register_count_ = std::max(next_register_index_, max_register_count_); 411cb0ef41Sopenharmony_ci if (observer_) { 421cb0ef41Sopenharmony_ci observer_->RegisterAllocateEvent(reg); 431cb0ef41Sopenharmony_ci } 441cb0ef41Sopenharmony_ci return reg; 451cb0ef41Sopenharmony_ci } 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci // Returns a consecutive list of |count| new registers. 481cb0ef41Sopenharmony_ci RegisterList NewRegisterList(int count) { 491cb0ef41Sopenharmony_ci RegisterList reg_list(next_register_index_, count); 501cb0ef41Sopenharmony_ci next_register_index_ += count; 511cb0ef41Sopenharmony_ci max_register_count_ = std::max(next_register_index_, max_register_count_); 521cb0ef41Sopenharmony_ci if (observer_) { 531cb0ef41Sopenharmony_ci observer_->RegisterListAllocateEvent(reg_list); 541cb0ef41Sopenharmony_ci } 551cb0ef41Sopenharmony_ci return reg_list; 561cb0ef41Sopenharmony_ci } 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_ci // Returns a growable register list. 591cb0ef41Sopenharmony_ci RegisterList NewGrowableRegisterList() { 601cb0ef41Sopenharmony_ci RegisterList reg_list(next_register_index_, 0); 611cb0ef41Sopenharmony_ci return reg_list; 621cb0ef41Sopenharmony_ci } 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ci // Appends a new register to |reg_list| increasing it's count by one and 651cb0ef41Sopenharmony_ci // returning the register added. 661cb0ef41Sopenharmony_ci // 671cb0ef41Sopenharmony_ci // Note: no other new registers must be currently allocated since the register 681cb0ef41Sopenharmony_ci // list was originally allocated. 691cb0ef41Sopenharmony_ci Register GrowRegisterList(RegisterList* reg_list) { 701cb0ef41Sopenharmony_ci Register reg(NewRegister()); 711cb0ef41Sopenharmony_ci reg_list->IncrementRegisterCount(); 721cb0ef41Sopenharmony_ci // If the following CHECK fails then a register was allocated (and not 731cb0ef41Sopenharmony_ci // freed) between the creation of the RegisterList and this call to add a 741cb0ef41Sopenharmony_ci // Register. 751cb0ef41Sopenharmony_ci CHECK_EQ(reg.index(), reg_list->last_register().index()); 761cb0ef41Sopenharmony_ci return reg; 771cb0ef41Sopenharmony_ci } 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci // Release all registers above |register_index|. 801cb0ef41Sopenharmony_ci void ReleaseRegisters(int register_index) { 811cb0ef41Sopenharmony_ci int count = next_register_index_ - register_index; 821cb0ef41Sopenharmony_ci next_register_index_ = register_index; 831cb0ef41Sopenharmony_ci if (observer_) { 841cb0ef41Sopenharmony_ci observer_->RegisterListFreeEvent(RegisterList(register_index, count)); 851cb0ef41Sopenharmony_ci } 861cb0ef41Sopenharmony_ci } 871cb0ef41Sopenharmony_ci 881cb0ef41Sopenharmony_ci // Returns true if the register |reg| is a live register. 891cb0ef41Sopenharmony_ci bool RegisterIsLive(Register reg) const { 901cb0ef41Sopenharmony_ci return reg.index() < next_register_index_; 911cb0ef41Sopenharmony_ci } 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ci // Returns a register list for all currently live registers. 941cb0ef41Sopenharmony_ci RegisterList AllLiveRegisters() const { 951cb0ef41Sopenharmony_ci return RegisterList(0, next_register_index()); 961cb0ef41Sopenharmony_ci } 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci void set_observer(Observer* observer) { observer_ = observer; } 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci int next_register_index() const { return next_register_index_; } 1011cb0ef41Sopenharmony_ci int maximum_register_count() const { return max_register_count_; } 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_ci private: 1041cb0ef41Sopenharmony_ci int next_register_index_; 1051cb0ef41Sopenharmony_ci int max_register_count_; 1061cb0ef41Sopenharmony_ci Observer* observer_; 1071cb0ef41Sopenharmony_ci}; 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci} // namespace interpreter 1101cb0ef41Sopenharmony_ci} // namespace internal 1111cb0ef41Sopenharmony_ci} // namespace v8 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_ci#endif // V8_INTERPRETER_BYTECODE_REGISTER_ALLOCATOR_H_ 115