• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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