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