Line data Source code
1 : // Copyright 2017 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_NODE_H_
6 : #define V8_INTERPRETER_BYTECODE_NODE_H_
7 :
8 : #include <algorithm>
9 :
10 : #include "src/globals.h"
11 : #include "src/interpreter/bytecode-source-info.h"
12 : #include "src/interpreter/bytecodes.h"
13 :
14 : namespace v8 {
15 : namespace internal {
16 : namespace interpreter {
17 :
18 : // A container for a generated bytecode, it's operands, and source information.
19 : class V8_EXPORT_PRIVATE BytecodeNode final {
20 : public:
21 : V8_INLINE BytecodeNode(Bytecode bytecode,
22 : BytecodeSourceInfo source_info = BytecodeSourceInfo())
23 : : bytecode_(bytecode),
24 : operand_count_(0),
25 : operand_scale_(OperandScale::kSingle),
26 16 : source_info_(source_info) {
27 : DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count());
28 : }
29 :
30 : V8_INLINE BytecodeNode(Bytecode bytecode, uint32_t operand0,
31 : BytecodeSourceInfo source_info = BytecodeSourceInfo())
32 : : bytecode_(bytecode),
33 : operand_count_(1),
34 : operand_scale_(OperandScale::kSingle),
35 32 : source_info_(source_info) {
36 : DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count());
37 : SetOperand(0, operand0);
38 : }
39 :
40 : V8_INLINE BytecodeNode(Bytecode bytecode, uint32_t operand0,
41 : uint32_t operand1,
42 : BytecodeSourceInfo source_info = BytecodeSourceInfo())
43 : : bytecode_(bytecode),
44 : operand_count_(2),
45 : operand_scale_(OperandScale::kSingle),
46 4 : source_info_(source_info) {
47 : DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count());
48 : SetOperand(0, operand0);
49 : SetOperand(1, operand1);
50 : }
51 :
52 : V8_INLINE BytecodeNode(Bytecode bytecode, uint32_t operand0,
53 : uint32_t operand1, uint32_t operand2,
54 : BytecodeSourceInfo source_info = BytecodeSourceInfo())
55 : : bytecode_(bytecode),
56 : operand_count_(3),
57 : operand_scale_(OperandScale::kSingle),
58 0 : source_info_(source_info) {
59 : DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count());
60 : SetOperand(0, operand0);
61 : SetOperand(1, operand1);
62 : SetOperand(2, operand2);
63 : }
64 :
65 : V8_INLINE BytecodeNode(Bytecode bytecode, uint32_t operand0,
66 : uint32_t operand1, uint32_t operand2,
67 : uint32_t operand3,
68 : BytecodeSourceInfo source_info = BytecodeSourceInfo())
69 : : bytecode_(bytecode),
70 : operand_count_(4),
71 : operand_scale_(OperandScale::kSingle),
72 7 : source_info_(source_info) {
73 : DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count());
74 : SetOperand(0, operand0);
75 : SetOperand(1, operand1);
76 : SetOperand(2, operand2);
77 : SetOperand(3, operand3);
78 : }
79 :
80 : V8_INLINE BytecodeNode(Bytecode bytecode, uint32_t operand0,
81 : uint32_t operand1, uint32_t operand2,
82 : uint32_t operand3, uint32_t operand4,
83 : BytecodeSourceInfo source_info = BytecodeSourceInfo())
84 : : bytecode_(bytecode),
85 : operand_count_(5),
86 : operand_scale_(OperandScale::kSingle),
87 : source_info_(source_info) {
88 : DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count());
89 : SetOperand(0, operand0);
90 : SetOperand(1, operand1);
91 : SetOperand(2, operand2);
92 : SetOperand(3, operand3);
93 : SetOperand(4, operand4);
94 : }
95 :
96 : #define DEFINE_BYTECODE_NODE_CREATOR(Name, ...) \
97 : template <typename... Operands> \
98 : V8_INLINE static BytecodeNode Name(BytecodeSourceInfo source_info, \
99 : Operands... operands) { \
100 : return Create<Bytecode::k##Name, __VA_ARGS__>(source_info, operands...); \
101 : }
102 : BYTECODE_LIST(DEFINE_BYTECODE_NODE_CREATOR)
103 : #undef DEFINE_BYTECODE_NODE_CREATOR
104 :
105 : // Print to stream |os|.
106 : void Print(std::ostream& os) const;
107 :
108 : Bytecode bytecode() const { return bytecode_; }
109 :
110 : uint32_t operand(int i) const {
111 : DCHECK_LT(i, operand_count());
112 8 : return operands_[i];
113 : }
114 80036349 : const uint32_t* operands() const { return operands_; }
115 :
116 4149545 : void update_operand0(uint32_t operand0) { SetOperand(0, operand0); }
117 :
118 : int operand_count() const { return operand_count_; }
119 : OperandScale operand_scale() const { return operand_scale_; }
120 :
121 : const BytecodeSourceInfo& source_info() const { return source_info_; }
122 : void set_source_info(BytecodeSourceInfo source_info) {
123 3475854 : source_info_ = source_info;
124 : }
125 :
126 : bool operator==(const BytecodeNode& other) const;
127 1 : bool operator!=(const BytecodeNode& other) const { return !(*this == other); }
128 :
129 : private:
130 : template <Bytecode bytecode, AccumulatorUse accumulator_use,
131 : OperandType... operand_types>
132 : friend class BytecodeNodeBuilder;
133 :
134 : V8_INLINE BytecodeNode(Bytecode bytecode, int operand_count,
135 : OperandScale operand_scale,
136 : BytecodeSourceInfo source_info, uint32_t operand0 = 0,
137 : uint32_t operand1 = 0, uint32_t operand2 = 0,
138 : uint32_t operand3 = 0, uint32_t operand4 = 0)
139 : : bytecode_(bytecode),
140 : operand_count_(operand_count),
141 : operand_scale_(operand_scale),
142 80301513 : source_info_(source_info) {
143 : DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count);
144 80301513 : operands_[0] = operand0;
145 80301513 : operands_[1] = operand1;
146 80301513 : operands_[2] = operand2;
147 80301513 : operands_[3] = operand3;
148 80301513 : operands_[4] = operand4;
149 : }
150 :
151 : template <Bytecode bytecode, AccumulatorUse accum_use>
152 : V8_INLINE static BytecodeNode Create(BytecodeSourceInfo source_info) {
153 : return BytecodeNode(bytecode, 0, OperandScale::kSingle, source_info);
154 : }
155 :
156 : template <Bytecode bytecode, AccumulatorUse accum_use,
157 : OperandType operand0_type>
158 : V8_INLINE static BytecodeNode Create(BytecodeSourceInfo source_info,
159 : uint32_t operand0) {
160 : DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 0), operand0_type);
161 37367763 : OperandScale scale = OperandScale::kSingle;
162 80389822 : scale = std::max(scale, ScaleForOperand<operand0_type>(operand0));
163 : return BytecodeNode(bytecode, 1, scale, source_info, operand0);
164 : }
165 :
166 : template <Bytecode bytecode, AccumulatorUse accum_use,
167 : OperandType operand0_type, OperandType operand1_type>
168 : V8_INLINE static BytecodeNode Create(BytecodeSourceInfo source_info,
169 : uint32_t operand0, uint32_t operand1) {
170 : DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 0), operand0_type);
171 : DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 1), operand1_type);
172 14768156 : OperandScale scale = OperandScale::kSingle;
173 29273982 : scale = std::max(scale, ScaleForOperand<operand0_type>(operand0));
174 29536312 : scale = std::max(scale, ScaleForOperand<operand1_type>(operand1));
175 : return BytecodeNode(bytecode, 2, scale, source_info, operand0, operand1);
176 : }
177 :
178 : template <Bytecode bytecode, AccumulatorUse accum_use,
179 : OperandType operand0_type, OperandType operand1_type,
180 : OperandType operand2_type>
181 : V8_INLINE static BytecodeNode Create(BytecodeSourceInfo source_info,
182 : uint32_t operand0, uint32_t operand1,
183 : uint32_t operand2) {
184 : DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 0), operand0_type);
185 : DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 1), operand1_type);
186 : DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 2), operand2_type);
187 10817305 : OperandScale scale = OperandScale::kSingle;
188 20388618 : scale = std::max(scale, ScaleForOperand<operand0_type>(operand0));
189 21634610 : scale = std::max(scale, ScaleForOperand<operand1_type>(operand1));
190 21634610 : scale = std::max(scale, ScaleForOperand<operand2_type>(operand2));
191 : return BytecodeNode(bytecode, 3, scale, source_info, operand0, operand1,
192 : operand2);
193 : }
194 :
195 : template <Bytecode bytecode, AccumulatorUse accum_use,
196 : OperandType operand0_type, OperandType operand1_type,
197 : OperandType operand2_type, OperandType operand3_type>
198 : V8_INLINE static BytecodeNode Create(BytecodeSourceInfo source_info,
199 : uint32_t operand0, uint32_t operand1,
200 : uint32_t operand2, uint32_t operand3) {
201 : DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 0), operand0_type);
202 : DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 1), operand1_type);
203 : DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 2), operand2_type);
204 : DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 3), operand3_type);
205 1159912 : OperandScale scale = OperandScale::kSingle;
206 2315263 : scale = std::max(scale, ScaleForOperand<operand0_type>(operand0));
207 2319824 : scale = std::max(scale, ScaleForOperand<operand1_type>(operand1));
208 2319824 : scale = std::max(scale, ScaleForOperand<operand2_type>(operand2));
209 2319824 : scale = std::max(scale, ScaleForOperand<operand3_type>(operand3));
210 : return BytecodeNode(bytecode, 4, scale, source_info, operand0, operand1,
211 : operand2, operand3);
212 : }
213 :
214 : template <Bytecode bytecode, AccumulatorUse accum_use,
215 : OperandType operand0_type, OperandType operand1_type,
216 : OperandType operand2_type, OperandType operand3_type,
217 : OperandType operand4_type>
218 : V8_INLINE static BytecodeNode Create(BytecodeSourceInfo source_info,
219 : uint32_t operand0, uint32_t operand1,
220 : uint32_t operand2, uint32_t operand3,
221 : uint32_t operand4) {
222 : DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 0), operand0_type);
223 : DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 1), operand1_type);
224 : DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 2), operand2_type);
225 : DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 3), operand3_type);
226 : DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 4), operand4_type);
227 80112 : OperandScale scale = OperandScale::kSingle;
228 160224 : scale = std::max(scale, ScaleForOperand<operand0_type>(operand0));
229 160224 : scale = std::max(scale, ScaleForOperand<operand1_type>(operand1));
230 160224 : scale = std::max(scale, ScaleForOperand<operand2_type>(operand2));
231 160224 : scale = std::max(scale, ScaleForOperand<operand3_type>(operand3));
232 160224 : scale = std::max(scale, ScaleForOperand<operand4_type>(operand4));
233 : return BytecodeNode(bytecode, 5, scale, source_info, operand0, operand1,
234 : operand2, operand3, operand4);
235 : }
236 :
237 : template <OperandType operand_type>
238 : V8_INLINE static OperandScale ScaleForOperand(uint32_t operand) {
239 : if (BytecodeOperands::IsScalableUnsignedByte(operand_type)) {
240 : return Bytecodes::ScaleForUnsignedOperand(operand);
241 : } else if (BytecodeOperands::IsScalableSignedByte(operand_type)) {
242 : return Bytecodes::ScaleForSignedOperand(operand);
243 : } else {
244 : return OperandScale::kSingle;
245 : }
246 : }
247 :
248 : V8_INLINE void UpdateScaleForOperand(int operand_index, uint32_t operand) {
249 2074839 : if (Bytecodes::OperandIsScalableSignedByte(bytecode(), operand_index)) {
250 : operand_scale_ =
251 60 : std::max(operand_scale_, Bytecodes::ScaleForSignedOperand(operand));
252 2074791 : } else if (Bytecodes::OperandIsScalableUnsignedByte(bytecode(),
253 : operand_index)) {
254 : operand_scale_ =
255 2074792 : std::max(operand_scale_, Bytecodes::ScaleForUnsignedOperand(operand));
256 : }
257 : }
258 :
259 : V8_INLINE void SetOperand(int operand_index, uint32_t operand) {
260 2074839 : operands_[operand_index] = operand;
261 : UpdateScaleForOperand(operand_index, operand);
262 : }
263 :
264 : Bytecode bytecode_;
265 : uint32_t operands_[Bytecodes::kMaxOperands];
266 : int operand_count_;
267 : OperandScale operand_scale_;
268 : BytecodeSourceInfo source_info_;
269 : };
270 :
271 : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
272 : const BytecodeNode& node);
273 :
274 : } // namespace interpreter
275 : } // namespace internal
276 : } // namespace v8
277 :
278 : #endif // V8_INTERPRETER_BYTECODE_NODE_H_
|