v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
bytecode-register.h
Go to the documentation of this file.
1// Copyright 2015 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_INTERPRETER_BYTECODE_REGISTER_H_
6#define V8_INTERPRETER_BYTECODE_REGISTER_H_
7
8#include <optional>
9
10#include "src/base/macros.h"
12#include "src/common/globals.h"
15
16namespace v8 {
17namespace internal {
18namespace interpreter {
19
24
25// An interpreter Register which is located in the function's Register file
26// in its stack-frame. Register hold parameters, this, and expression values.
28 public:
29 constexpr explicit Register(int index = kInvalidIndex) : index_(index) {}
30
31 constexpr int index() const { return index_; }
32 constexpr bool is_parameter() const { return index() < 0; }
33 constexpr bool is_valid() const { return index_ != kInvalidIndex; }
34
35 static constexpr Register FromParameterIndex(int index);
36 constexpr int ToParameterIndex() const;
37
38 static constexpr Register receiver() { return FromParameterIndex(0); }
39 constexpr bool is_receiver() const { return ToParameterIndex() == 0; }
40
41 // Returns an invalid register.
42 static constexpr Register invalid_value() { return Register(); }
43
44 // Returns the register for the function's closure object.
45 static constexpr Register function_closure();
46 constexpr bool is_function_closure() const;
47
48 // Returns the register which holds the current context object.
49 static constexpr Register current_context();
50 constexpr bool is_current_context() const;
51
52 // Returns the register for the bytecode array.
53 static constexpr Register bytecode_array();
54 constexpr bool is_bytecode_array() const;
55
56 // Returns the register for the saved bytecode offset.
57 static constexpr Register bytecode_offset();
58 constexpr bool is_bytecode_offset() const;
59
60 // Returns the register for the cached feedback vector.
61 static constexpr Register feedback_vector();
62 constexpr bool is_feedback_vector() const;
63
64 // Returns the register for the argument count.
65 static constexpr Register argument_count();
66
67 // Returns a register that can be used to represent the accumulator
68 // within code in the interpreter, but should never be emitted in
69 // bytecode.
70 static constexpr Register virtual_accumulator();
71
72 constexpr OperandSize SizeOfOperand() const;
73
74 constexpr int32_t ToOperand() const {
75 return kRegisterFileStartOffset - index_;
76 }
77 static constexpr Register FromOperand(int32_t operand) {
78 return Register(kRegisterFileStartOffset - operand);
79 }
80
81 static constexpr Register FromShortStar(Bytecode bytecode) {
82 DCHECK(Bytecodes::IsShortStar(bytecode));
83 return Register(static_cast<int>(Bytecode::kStar0) -
84 static_cast<int>(bytecode));
85 }
86
87 constexpr std::optional<Bytecode> TryToShortStar() const {
88 if (index() >= 0 && index() < Bytecodes::kShortStarCount) {
89 Bytecode bytecode =
90 static_cast<Bytecode>(static_cast<int>(Bytecode::kStar0) - index());
91 DCHECK_GE(bytecode, Bytecode::kFirstShortStar);
92 DCHECK_LE(bytecode, Bytecode::kLastShortStar);
93 return bytecode;
94 }
95 return {};
96 }
97
98 std::string ToString() const;
99
100 constexpr bool operator==(const Register& other) const {
101 return index() == other.index();
102 }
103 constexpr bool operator!=(const Register& other) const {
104 return index() != other.index();
105 }
106 constexpr bool operator<(const Register& other) const {
107 return index() < other.index();
108 }
109 constexpr bool operator<=(const Register& other) const {
110 return index() <= other.index();
111 }
112 constexpr bool operator>(const Register& other) const {
113 return index() > other.index();
114 }
115 constexpr bool operator>=(const Register& other) const {
116 return index() >= other.index();
117 }
118
119 private:
121
122 static constexpr int kInvalidIndex = kMaxInt;
123
124 static constexpr int kRegisterFileStartOffset =
125 OffsetFromFPToRegisterIndex(0);
126 static constexpr int kFirstParamRegisterIndex =
127 OffsetFromFPToRegisterIndex(InterpreterFrameConstants::kFirstParamFromFp);
128 static constexpr int kFunctionClosureRegisterIndex =
129 OffsetFromFPToRegisterIndex(StandardFrameConstants::kFunctionOffset);
130 static constexpr int kCurrentContextRegisterIndex =
131 OffsetFromFPToRegisterIndex(StandardFrameConstants::kContextOffset);
132 static constexpr int kBytecodeArrayRegisterIndex =
133 OffsetFromFPToRegisterIndex(
134 InterpreterFrameConstants::kBytecodeArrayFromFp);
135 static constexpr int kBytecodeOffsetRegisterIndex =
136 OffsetFromFPToRegisterIndex(
137 InterpreterFrameConstants::kBytecodeOffsetFromFp);
138 static constexpr int kFeedbackVectorRegisterIndex =
139 OffsetFromFPToRegisterIndex(
140 InterpreterFrameConstants::kFeedbackVectorFromFp);
141 static constexpr int kCallerPCOffsetRegisterIndex =
142 OffsetFromFPToRegisterIndex(InterpreterFrameConstants::kCallerPCOffset);
143 static constexpr int kArgumentCountRegisterIndex =
144 OffsetFromFPToRegisterIndex(InterpreterFrameConstants::kArgCOffset);
145
147};
148
150 public:
152 : first_reg_index_(Register::invalid_value().index()),
153 register_count_(0) {}
154 explicit RegisterList(Register r) : RegisterList(r.index(), 1) {}
155
156 // Returns a new RegisterList which is a truncated version of this list, with
157 // |count| registers.
158 const RegisterList Truncate(int new_count) {
159 DCHECK_GE(new_count, 0);
160 DCHECK_LT(new_count, register_count_);
161 return RegisterList(first_reg_index_, new_count);
162 }
163 const RegisterList PopLeft() const {
164 DCHECK_GE(register_count_, 0);
165 return RegisterList(first_reg_index_ + 1, register_count_ - 1);
166 }
167
168 const Register operator[](size_t i) const {
169 DCHECK_LT(static_cast<int>(i), register_count_);
170 return Register(first_reg_index_ + static_cast<int>(i));
171 }
172
173 const Register first_register() const {
174 return (register_count() == 0) ? Register(0) : (*this)[0];
175 }
176
177 const Register last_register() const {
178 return (register_count() == 0) ? Register(0) : (*this)[register_count_ - 1];
179 }
180
181 int register_count() const { return register_count_; }
182
183 private:
185 friend class BytecodeDecoder;
186 friend class InterpreterTester;
187 friend class BytecodeUtils;
189 friend class CallArguments;
190
191 RegisterList(int first_reg_index, int register_count)
192 : first_reg_index_(first_reg_index), register_count_(register_count) {}
193
194 // Increases the size of the register list by one.
195 void IncrementRegisterCount() { register_count_++; }
196
199};
200
201constexpr Register Register::FromParameterIndex(int index) {
202 DCHECK_GE(index, 0);
203 int register_index = kFirstParamRegisterIndex - index;
204 DCHECK_LT(register_index, 0);
205 return Register(register_index);
206}
207
208constexpr int Register::ToParameterIndex() const {
209 DCHECK(is_parameter());
210 return kFirstParamRegisterIndex - index();
211}
212
213constexpr Register Register::function_closure() {
214 return Register(kFunctionClosureRegisterIndex);
215}
216
217constexpr bool Register::is_function_closure() const {
218 return index() == kFunctionClosureRegisterIndex;
219}
220
221constexpr Register Register::current_context() {
222 return Register(kCurrentContextRegisterIndex);
223}
224
225constexpr bool Register::is_current_context() const {
226 return index() == kCurrentContextRegisterIndex;
227}
228
229constexpr Register Register::bytecode_array() {
230 return Register(kBytecodeArrayRegisterIndex);
231}
232
233constexpr bool Register::is_bytecode_array() const {
234 return index() == kBytecodeArrayRegisterIndex;
235}
236
237constexpr Register Register::bytecode_offset() {
238 return Register(kBytecodeOffsetRegisterIndex);
239}
240
241constexpr bool Register::is_bytecode_offset() const {
242 return index() == kBytecodeOffsetRegisterIndex;
243}
244
245constexpr Register Register::feedback_vector() {
246 return Register(kFeedbackVectorRegisterIndex);
247}
248
249constexpr bool Register::is_feedback_vector() const {
250 return index() == kFeedbackVectorRegisterIndex;
251}
252
253// static
254constexpr Register Register::virtual_accumulator() {
255 return Register(kCallerPCOffsetRegisterIndex);
256}
257
258// static
259constexpr Register Register::argument_count() {
260 return Register(kArgumentCountRegisterIndex);
261}
262
263constexpr OperandSize Register::SizeOfOperand() const {
264 int32_t operand = ToOperand();
265 if (operand >= kMinInt8 && operand <= kMaxInt8) {
266 return OperandSize::kByte;
267 } else if (operand >= kMinInt16 && operand <= kMaxInt16) {
268 return OperandSize::kShort;
269 } else {
270 return OperandSize::kQuad;
271 }
272}
273
274} // namespace interpreter
275} // namespace internal
276} // namespace v8
277
278#endif // V8_INTERPRETER_BYTECODE_REGISTER_H_
interpreter::Bytecode bytecode
Definition builtins.cc:43
const Register operator[](size_t i) const
RegisterList(int first_reg_index, int register_count)
const RegisterList Truncate(int new_count)
constexpr bool operator>=(const Register &other) const
constexpr std::optional< Bytecode > TryToShortStar() const
constexpr bool operator<=(const Register &other) const
static constexpr Register FromOperand(int32_t operand)
static constexpr Register FromShortStar(Bytecode bytecode)
constexpr int32_t ToOperand() const
static constexpr Register receiver()
constexpr bool operator<(const Register &other) const
static constexpr Register invalid_value()
constexpr bool operator!=(const Register &other) const
constexpr bool operator>(const Register &other) const
constexpr bool operator==(const Register &other) const
constexpr Register(int index=kInvalidIndex)
Register const index_
constexpr const char * ToString(DataViewOp op)
OptionalOpIndex index
int32_t offset
int r
Definition mul-fft.cc:298
constexpr int OffsetFromFPToRegisterIndex(int offset)
constexpr int kMaxInt8
Definition globals.h:376
constexpr int kMinInt16
Definition globals.h:381
constexpr int kSystemPointerSize
Definition globals.h:410
constexpr int kMinInt8
Definition globals.h:377
constexpr int kMaxInt16
Definition globals.h:380
#define DCHECK_LE(v1, v2)
Definition logging.h:490
#define DCHECK_GE(v1, v2)
Definition logging.h:488
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_LT(v1, v2)
Definition logging.h:489
#define DISALLOW_NEW_AND_DELETE()
Definition macros.h:155
#define V8_EXPORT_PRIVATE
Definition macros.h:460