1 // Copyright 2022 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_MAGLEV_MAGLEV_REGISTER_FRAME_ARRAY_H_ 6 #define V8_MAGLEV_MAGLEV_REGISTER_FRAME_ARRAY_H_ 7 8 #include "src/interpreter/bytecode-register.h" 9 #include "src/maglev/maglev-compilation-unit.h" 10 #include "src/zone/zone.h" 11 12 namespace v8 { 13 namespace internal { 14 namespace maglev { 15 16 // Vector of values associated with a bytecode's register frame. Indexable by 17 // interpreter register. 18 template <typename T> 19 class RegisterFrameArray { 20 public: RegisterFrameArray(const MaglevCompilationUnit & info)21 explicit RegisterFrameArray(const MaglevCompilationUnit& info) { 22 // The first local is at index zero, parameters are behind it with 23 // negative indices, and the unoptimized frame header is between the two, 24 // so the entire frame state including parameters is the distance from the 25 // last parameter to the last local frame register, plus one to include both 26 // ends. 27 interpreter::Register last_local = 28 interpreter::Register(info.register_count() - 1); 29 interpreter::Register last_param = 30 interpreter::Register::FromParameterIndex(info.parameter_count() - 1); 31 DCHECK_LT(last_param.index(), 0); 32 T* frame = 33 info.zone()->NewArray<T>(last_local.index() - last_param.index() + 1); 34 35 // Set frame_start_ to a "butterfly" pointer into the middle of the above 36 // Zone-allocated array. Parameters are at a negative index, so we have to 37 // subtract it from the above frame pointer. 38 frame_start_ = frame - last_param.index(); 39 } 40 41 // Disallow copy (use CopyFrom instead). 42 RegisterFrameArray(const RegisterFrameArray& other) V8_NOEXCEPT = delete; 43 RegisterFrameArray& operator=(const RegisterFrameArray& other) 44 V8_NOEXCEPT = delete; 45 46 // Allow move. 47 RegisterFrameArray(RegisterFrameArray&& other) V8_NOEXCEPT = default; 48 RegisterFrameArray& operator=(RegisterFrameArray&& other) 49 V8_NOEXCEPT = default; 50 CopyFrom(const MaglevCompilationUnit & info,const RegisterFrameArray & other,const compiler::BytecodeLivenessState * liveness)51 void CopyFrom(const MaglevCompilationUnit& info, 52 const RegisterFrameArray& other, 53 const compiler::BytecodeLivenessState* liveness) { 54 interpreter::Register last_param = 55 interpreter::Register::FromParameterIndex(info.parameter_count() - 1); 56 int end = 1; 57 if (!liveness) { 58 interpreter::Register last_local = 59 interpreter::Register(info.register_count() - 1); 60 end = last_local.index(); 61 } 62 // All parameters are live. 63 for (int index = last_param.index(); index <= end; ++index) { 64 interpreter::Register reg(index); 65 (*this)[reg] = other[reg]; 66 } 67 if (liveness) { 68 for (int index : *liveness) { 69 interpreter::Register reg(index); 70 (*this)[reg] = other[reg]; 71 } 72 } 73 } 74 75 T& operator[](interpreter::Register reg) { return frame_start_[reg.index()]; } 76 77 const T& operator[](interpreter::Register reg) const { 78 return frame_start_[reg.index()]; 79 } 80 81 private: DataSize(int register_count,int parameter_count)82 static int DataSize(int register_count, int parameter_count) { 83 // The first local is at index zero, parameters are behind it with 84 // negative indices, and the unoptimized frame header is between the two, 85 // so the entire frame state including parameters is the distance from the 86 // last parameter to the last local frame register, plus one to include both 87 // ends. 88 interpreter::Register last_local = 89 interpreter::Register(register_count - 1); 90 interpreter::Register last_param = 91 interpreter::Register::FromParameterIndex(parameter_count - 1); 92 return last_local.index() - last_param.index() + 1; 93 } 94 data_begin(int parameter_count)95 T* data_begin(int parameter_count) const { 96 return frame_start_ + 97 interpreter::Register::FromParameterIndex(parameter_count - 1) 98 .index(); 99 } 100 101 // Butterfly pointer for registers, pointing into the middle of a 102 // Zone-allocated Node array. 103 // | 104 // v 105 // [Parameters] [Unoptimized Frame Header] [Locals] 106 T* frame_start_ = nullptr; 107 }; 108 109 } // namespace maglev 110 } // namespace internal 111 } // namespace v8 112 113 #endif // V8_MAGLEV_MAGLEV_REGISTER_FRAME_ARRAY_H_ 114