11cb0ef41Sopenharmony_ci// Copyright 2022 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_MAGLEV_MAGLEV_REGISTER_FRAME_ARRAY_H_ 61cb0ef41Sopenharmony_ci#define V8_MAGLEV_MAGLEV_REGISTER_FRAME_ARRAY_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include "src/interpreter/bytecode-register.h" 91cb0ef41Sopenharmony_ci#include "src/maglev/maglev-compilation-unit.h" 101cb0ef41Sopenharmony_ci#include "src/zone/zone.h" 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_cinamespace v8 { 131cb0ef41Sopenharmony_cinamespace internal { 141cb0ef41Sopenharmony_cinamespace maglev { 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ci// Vector of values associated with a bytecode's register frame. Indexable by 171cb0ef41Sopenharmony_ci// interpreter register. 181cb0ef41Sopenharmony_citemplate <typename T> 191cb0ef41Sopenharmony_ciclass RegisterFrameArray { 201cb0ef41Sopenharmony_ci public: 211cb0ef41Sopenharmony_ci explicit RegisterFrameArray(const MaglevCompilationUnit& info) { 221cb0ef41Sopenharmony_ci // The first local is at index zero, parameters are behind it with 231cb0ef41Sopenharmony_ci // negative indices, and the unoptimized frame header is between the two, 241cb0ef41Sopenharmony_ci // so the entire frame state including parameters is the distance from the 251cb0ef41Sopenharmony_ci // last parameter to the last local frame register, plus one to include both 261cb0ef41Sopenharmony_ci // ends. 271cb0ef41Sopenharmony_ci interpreter::Register last_local = 281cb0ef41Sopenharmony_ci interpreter::Register(info.register_count() - 1); 291cb0ef41Sopenharmony_ci interpreter::Register last_param = 301cb0ef41Sopenharmony_ci interpreter::Register::FromParameterIndex(info.parameter_count() - 1); 311cb0ef41Sopenharmony_ci DCHECK_LT(last_param.index(), 0); 321cb0ef41Sopenharmony_ci T* frame = 331cb0ef41Sopenharmony_ci info.zone()->NewArray<T>(last_local.index() - last_param.index() + 1); 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci // Set frame_start_ to a "butterfly" pointer into the middle of the above 361cb0ef41Sopenharmony_ci // Zone-allocated array. Parameters are at a negative index, so we have to 371cb0ef41Sopenharmony_ci // subtract it from the above frame pointer. 381cb0ef41Sopenharmony_ci frame_start_ = frame - last_param.index(); 391cb0ef41Sopenharmony_ci } 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ci // Disallow copy (use CopyFrom instead). 421cb0ef41Sopenharmony_ci RegisterFrameArray(const RegisterFrameArray& other) V8_NOEXCEPT = delete; 431cb0ef41Sopenharmony_ci RegisterFrameArray& operator=(const RegisterFrameArray& other) 441cb0ef41Sopenharmony_ci V8_NOEXCEPT = delete; 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci // Allow move. 471cb0ef41Sopenharmony_ci RegisterFrameArray(RegisterFrameArray&& other) V8_NOEXCEPT = default; 481cb0ef41Sopenharmony_ci RegisterFrameArray& operator=(RegisterFrameArray&& other) 491cb0ef41Sopenharmony_ci V8_NOEXCEPT = default; 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ci void CopyFrom(const MaglevCompilationUnit& info, 521cb0ef41Sopenharmony_ci const RegisterFrameArray& other, 531cb0ef41Sopenharmony_ci const compiler::BytecodeLivenessState* liveness) { 541cb0ef41Sopenharmony_ci interpreter::Register last_param = 551cb0ef41Sopenharmony_ci interpreter::Register::FromParameterIndex(info.parameter_count() - 1); 561cb0ef41Sopenharmony_ci int end = 1; 571cb0ef41Sopenharmony_ci if (!liveness) { 581cb0ef41Sopenharmony_ci interpreter::Register last_local = 591cb0ef41Sopenharmony_ci interpreter::Register(info.register_count() - 1); 601cb0ef41Sopenharmony_ci end = last_local.index(); 611cb0ef41Sopenharmony_ci } 621cb0ef41Sopenharmony_ci // All parameters are live. 631cb0ef41Sopenharmony_ci for (int index = last_param.index(); index <= end; ++index) { 641cb0ef41Sopenharmony_ci interpreter::Register reg(index); 651cb0ef41Sopenharmony_ci (*this)[reg] = other[reg]; 661cb0ef41Sopenharmony_ci } 671cb0ef41Sopenharmony_ci if (liveness) { 681cb0ef41Sopenharmony_ci for (int index : *liveness) { 691cb0ef41Sopenharmony_ci interpreter::Register reg(index); 701cb0ef41Sopenharmony_ci (*this)[reg] = other[reg]; 711cb0ef41Sopenharmony_ci } 721cb0ef41Sopenharmony_ci } 731cb0ef41Sopenharmony_ci } 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci T& operator[](interpreter::Register reg) { return frame_start_[reg.index()]; } 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ci const T& operator[](interpreter::Register reg) const { 781cb0ef41Sopenharmony_ci return frame_start_[reg.index()]; 791cb0ef41Sopenharmony_ci } 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_ci private: 821cb0ef41Sopenharmony_ci static int DataSize(int register_count, int parameter_count) { 831cb0ef41Sopenharmony_ci // The first local is at index zero, parameters are behind it with 841cb0ef41Sopenharmony_ci // negative indices, and the unoptimized frame header is between the two, 851cb0ef41Sopenharmony_ci // so the entire frame state including parameters is the distance from the 861cb0ef41Sopenharmony_ci // last parameter to the last local frame register, plus one to include both 871cb0ef41Sopenharmony_ci // ends. 881cb0ef41Sopenharmony_ci interpreter::Register last_local = 891cb0ef41Sopenharmony_ci interpreter::Register(register_count - 1); 901cb0ef41Sopenharmony_ci interpreter::Register last_param = 911cb0ef41Sopenharmony_ci interpreter::Register::FromParameterIndex(parameter_count - 1); 921cb0ef41Sopenharmony_ci return last_local.index() - last_param.index() + 1; 931cb0ef41Sopenharmony_ci } 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ci T* data_begin(int parameter_count) const { 961cb0ef41Sopenharmony_ci return frame_start_ + 971cb0ef41Sopenharmony_ci interpreter::Register::FromParameterIndex(parameter_count - 1) 981cb0ef41Sopenharmony_ci .index(); 991cb0ef41Sopenharmony_ci } 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ci // Butterfly pointer for registers, pointing into the middle of a 1021cb0ef41Sopenharmony_ci // Zone-allocated Node array. 1031cb0ef41Sopenharmony_ci // | 1041cb0ef41Sopenharmony_ci // v 1051cb0ef41Sopenharmony_ci // [Parameters] [Unoptimized Frame Header] [Locals] 1061cb0ef41Sopenharmony_ci T* frame_start_ = nullptr; 1071cb0ef41Sopenharmony_ci}; 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci} // namespace maglev 1101cb0ef41Sopenharmony_ci} // namespace internal 1111cb0ef41Sopenharmony_ci} // namespace v8 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ci#endif // V8_MAGLEV_MAGLEV_REGISTER_FRAME_ARRAY_H_ 114