OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_INTERPRETER_BYTECODE_PIPELINE_H_ | 5 #ifndef V8_INTERPRETER_BYTECODE_PIPELINE_H_ |
6 #define V8_INTERPRETER_BYTECODE_PIPELINE_H_ | 6 #define V8_INTERPRETER_BYTECODE_PIPELINE_H_ |
7 | 7 |
8 #include "src/base/compiler-specific.h" | 8 #include "src/base/compiler-specific.h" |
9 #include "src/globals.h" | 9 #include "src/globals.h" |
10 #include "src/interpreter/bytecode-register-allocator.h" | 10 #include "src/interpreter/bytecode-register-allocator.h" |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 position_type_ = PositionType::kExpression; | 88 position_type_ = PositionType::kExpression; |
89 source_position_ = source_position; | 89 source_position_ = source_position; |
90 } | 90 } |
91 | 91 |
92 // Forces an instance into an expression position. | 92 // Forces an instance into an expression position. |
93 void ForceExpressionPosition(int source_position) { | 93 void ForceExpressionPosition(int source_position) { |
94 position_type_ = PositionType::kExpression; | 94 position_type_ = PositionType::kExpression; |
95 source_position_ = source_position; | 95 source_position_ = source_position; |
96 } | 96 } |
97 | 97 |
98 // Clones a source position. The current instance is expected to be | |
99 // invalid. | |
100 void Clone(const BytecodeSourceInfo& other) { | |
101 DCHECK(!is_valid()); | |
102 position_type_ = other.position_type_; | |
103 source_position_ = other.source_position_; | |
104 } | |
105 | |
106 int source_position() const { | 98 int source_position() const { |
107 DCHECK(is_valid()); | 99 DCHECK(is_valid()); |
108 return source_position_; | 100 return source_position_; |
109 } | 101 } |
110 | 102 |
111 bool is_statement() const { | 103 bool is_statement() const { |
112 return position_type_ == PositionType::kStatement; | 104 return position_type_ == PositionType::kStatement; |
113 } | 105 } |
114 bool is_expression() const { | 106 bool is_expression() const { |
115 return position_type_ == PositionType::kExpression; | 107 return position_type_ == PositionType::kExpression; |
(...skipping 19 matching lines...) Expand all Loading... |
135 enum class PositionType : uint8_t { kNone, kExpression, kStatement }; | 127 enum class PositionType : uint8_t { kNone, kExpression, kStatement }; |
136 | 128 |
137 PositionType position_type_; | 129 PositionType position_type_; |
138 int source_position_; | 130 int source_position_; |
139 }; | 131 }; |
140 | 132 |
141 // A container for a generated bytecode, it's operands, and source information. | 133 // A container for a generated bytecode, it's operands, and source information. |
142 // These must be allocated by a BytecodeNodeAllocator instance. | 134 // These must be allocated by a BytecodeNodeAllocator instance. |
143 class V8_EXPORT_PRIVATE BytecodeNode final : NON_EXPORTED_BASE(ZoneObject) { | 135 class V8_EXPORT_PRIVATE BytecodeNode final : NON_EXPORTED_BASE(ZoneObject) { |
144 public: | 136 public: |
145 INLINE(BytecodeNode(const Bytecode bytecode, | 137 INLINE(BytecodeNode(Bytecode bytecode, |
146 BytecodeSourceInfo* source_info = nullptr)) | 138 BytecodeSourceInfo source_info = BytecodeSourceInfo())) |
147 : bytecode_(bytecode), | 139 : bytecode_(bytecode), |
148 operand_count_(0), | 140 operand_count_(0), |
149 operand_scale_(OperandScale::kSingle) { | 141 operand_scale_(OperandScale::kSingle), |
| 142 source_info_(source_info) { |
150 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); | 143 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); |
151 AttachSourceInfo(source_info); | |
152 } | 144 } |
153 | 145 |
154 INLINE(BytecodeNode(const Bytecode bytecode, uint32_t operand0, | 146 INLINE(BytecodeNode(Bytecode bytecode, uint32_t operand0, |
155 BytecodeSourceInfo* source_info = nullptr)) | 147 BytecodeSourceInfo source_info = BytecodeSourceInfo())) |
156 : bytecode_(bytecode), | 148 : bytecode_(bytecode), |
157 operand_count_(1), | 149 operand_count_(1), |
158 operand_scale_(OperandScale::kSingle) { | 150 operand_scale_(OperandScale::kSingle), |
| 151 source_info_(source_info) { |
159 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); | 152 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); |
160 SetOperand(0, operand0); | 153 SetOperand(0, operand0); |
161 AttachSourceInfo(source_info); | |
162 } | 154 } |
163 | 155 |
164 INLINE(BytecodeNode(const Bytecode bytecode, uint32_t operand0, | 156 INLINE(BytecodeNode(Bytecode bytecode, uint32_t operand0, uint32_t operand1, |
165 uint32_t operand1, | 157 BytecodeSourceInfo source_info = BytecodeSourceInfo())) |
166 BytecodeSourceInfo* source_info = nullptr)) | |
167 : bytecode_(bytecode), | 158 : bytecode_(bytecode), |
168 operand_count_(2), | 159 operand_count_(2), |
169 operand_scale_(OperandScale::kSingle) { | 160 operand_scale_(OperandScale::kSingle), |
| 161 source_info_(source_info) { |
170 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); | 162 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); |
171 SetOperand(0, operand0); | 163 SetOperand(0, operand0); |
172 SetOperand(1, operand1); | 164 SetOperand(1, operand1); |
173 AttachSourceInfo(source_info); | |
174 } | 165 } |
175 | 166 |
176 INLINE(BytecodeNode(const Bytecode bytecode, uint32_t operand0, | 167 INLINE(BytecodeNode(Bytecode bytecode, uint32_t operand0, uint32_t operand1, |
177 uint32_t operand1, uint32_t operand2, | 168 uint32_t operand2, |
178 BytecodeSourceInfo* source_info = nullptr)) | 169 BytecodeSourceInfo source_info = BytecodeSourceInfo())) |
179 : bytecode_(bytecode), | 170 : bytecode_(bytecode), |
180 operand_count_(3), | 171 operand_count_(3), |
181 operand_scale_(OperandScale::kSingle) { | 172 operand_scale_(OperandScale::kSingle), |
| 173 source_info_(source_info) { |
182 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); | 174 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); |
183 SetOperand(0, operand0); | 175 SetOperand(0, operand0); |
184 SetOperand(1, operand1); | 176 SetOperand(1, operand1); |
185 SetOperand(2, operand2); | 177 SetOperand(2, operand2); |
186 AttachSourceInfo(source_info); | |
187 } | 178 } |
188 | 179 |
189 INLINE(BytecodeNode(const Bytecode bytecode, uint32_t operand0, | 180 INLINE(BytecodeNode(Bytecode bytecode, uint32_t operand0, uint32_t operand1, |
190 uint32_t operand1, uint32_t operand2, uint32_t operand3, | 181 uint32_t operand2, uint32_t operand3, |
191 BytecodeSourceInfo* source_info = nullptr)) | 182 BytecodeSourceInfo source_info = BytecodeSourceInfo())) |
192 : bytecode_(bytecode), | 183 : bytecode_(bytecode), |
193 operand_count_(4), | 184 operand_count_(4), |
194 operand_scale_(OperandScale::kSingle) { | 185 operand_scale_(OperandScale::kSingle), |
| 186 source_info_(source_info) { |
195 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); | 187 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); |
196 SetOperand(0, operand0); | 188 SetOperand(0, operand0); |
197 SetOperand(1, operand1); | 189 SetOperand(1, operand1); |
198 SetOperand(2, operand2); | 190 SetOperand(2, operand2); |
199 SetOperand(3, operand3); | 191 SetOperand(3, operand3); |
200 AttachSourceInfo(source_info); | |
201 } | 192 } |
202 | 193 |
203 BytecodeNode(const BytecodeNode& other); | |
204 BytecodeNode& operator=(const BytecodeNode& other); | |
205 | |
206 // Replace the bytecode of this node with |bytecode| and keep the operands. | 194 // Replace the bytecode of this node with |bytecode| and keep the operands. |
207 void replace_bytecode(Bytecode bytecode) { | 195 void replace_bytecode(Bytecode bytecode) { |
208 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode_), | 196 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode_), |
209 Bytecodes::NumberOfOperands(bytecode)); | 197 Bytecodes::NumberOfOperands(bytecode)); |
210 bytecode_ = bytecode; | 198 bytecode_ = bytecode; |
211 } | 199 } |
| 200 |
212 void set_bytecode(Bytecode bytecode) { | 201 void set_bytecode(Bytecode bytecode) { |
213 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0); | 202 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0); |
214 bytecode_ = bytecode; | 203 bytecode_ = bytecode; |
215 operand_count_ = 0; | 204 operand_count_ = 0; |
216 operand_scale_ = OperandScale::kSingle; | 205 operand_scale_ = OperandScale::kSingle; |
217 } | 206 } |
| 207 |
218 void set_bytecode(Bytecode bytecode, uint32_t operand0) { | 208 void set_bytecode(Bytecode bytecode, uint32_t operand0) { |
219 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 1); | 209 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 1); |
220 bytecode_ = bytecode; | 210 bytecode_ = bytecode; |
221 operand_count_ = 1; | 211 operand_count_ = 1; |
222 operand_scale_ = OperandScale::kSingle; | 212 operand_scale_ = OperandScale::kSingle; |
223 SetOperand(0, operand0); | 213 SetOperand(0, operand0); |
224 } | 214 } |
| 215 |
225 void set_bytecode(Bytecode bytecode, uint32_t operand0, uint32_t operand1) { | 216 void set_bytecode(Bytecode bytecode, uint32_t operand0, uint32_t operand1) { |
226 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 2); | 217 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 2); |
227 bytecode_ = bytecode; | 218 bytecode_ = bytecode; |
228 operand_count_ = 2; | 219 operand_count_ = 2; |
229 operand_scale_ = OperandScale::kSingle; | 220 operand_scale_ = OperandScale::kSingle; |
230 SetOperand(0, operand0); | 221 SetOperand(0, operand0); |
231 SetOperand(1, operand1); | 222 SetOperand(1, operand1); |
232 } | 223 } |
| 224 |
233 void set_bytecode(Bytecode bytecode, uint32_t operand0, uint32_t operand1, | 225 void set_bytecode(Bytecode bytecode, uint32_t operand0, uint32_t operand1, |
234 uint32_t operand2) { | 226 uint32_t operand2) { |
235 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 3); | 227 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 3); |
236 bytecode_ = bytecode; | 228 bytecode_ = bytecode; |
237 operand_count_ = 3; | 229 operand_count_ = 3; |
238 operand_scale_ = OperandScale::kSingle; | 230 operand_scale_ = OperandScale::kSingle; |
239 SetOperand(0, operand0); | 231 SetOperand(0, operand0); |
240 SetOperand(1, operand1); | 232 SetOperand(1, operand1); |
241 SetOperand(2, operand2); | 233 SetOperand(2, operand2); |
242 } | 234 } |
243 | 235 |
244 // Clone |other|. | |
245 void Clone(const BytecodeNode* const other); | |
246 | |
247 // Print to stream |os|. | 236 // Print to stream |os|. |
248 void Print(std::ostream& os) const; | 237 void Print(std::ostream& os) const; |
249 | 238 |
250 // Transform to a node representing |new_bytecode| which has one | 239 // Transform to a node representing |new_bytecode| which has one |
251 // operand more than the current bytecode. | 240 // operand more than the current bytecode. |
252 void Transform(Bytecode new_bytecode, uint32_t extra_operand) { | 241 void Transform(Bytecode new_bytecode, uint32_t extra_operand) { |
253 DCHECK_EQ(Bytecodes::NumberOfOperands(new_bytecode), | 242 DCHECK_EQ(Bytecodes::NumberOfOperands(new_bytecode), |
254 Bytecodes::NumberOfOperands(bytecode()) + 1); | 243 Bytecodes::NumberOfOperands(bytecode()) + 1); |
255 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 1 || | 244 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 1 || |
256 Bytecodes::GetOperandType(new_bytecode, 0) == | 245 Bytecodes::GetOperandType(new_bytecode, 0) == |
257 Bytecodes::GetOperandType(bytecode(), 0)); | 246 Bytecodes::GetOperandType(bytecode(), 0)); |
258 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 2 || | 247 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 2 || |
259 Bytecodes::GetOperandType(new_bytecode, 1) == | 248 Bytecodes::GetOperandType(new_bytecode, 1) == |
260 Bytecodes::GetOperandType(bytecode(), 1)); | 249 Bytecodes::GetOperandType(bytecode(), 1)); |
261 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 3 || | 250 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 3 || |
262 Bytecodes::GetOperandType(new_bytecode, 2) == | 251 Bytecodes::GetOperandType(new_bytecode, 2) == |
263 Bytecodes::GetOperandType(bytecode(), 2)); | 252 Bytecodes::GetOperandType(bytecode(), 2)); |
264 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 4); | 253 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 4); |
265 | 254 |
266 bytecode_ = new_bytecode; | 255 bytecode_ = new_bytecode; |
267 operand_count_++; | 256 operand_count_++; |
268 SetOperand(operand_count() - 1, extra_operand); | 257 SetOperand(operand_count() - 1, extra_operand); |
269 } | 258 } |
270 | 259 |
271 // Updates the operand at |operand_index| to |operand|. | |
272 void UpdateOperand(int operand_index, uint32_t operand) { | |
273 DCHECK_LE(operand_index, Bytecodes::NumberOfOperands(bytecode())); | |
274 operands_[operand_index] = operand; | |
275 if ((Bytecodes::OperandIsScalableSignedByte(bytecode(), operand_index) && | |
276 Bytecodes::ScaleForSignedOperand(operand) != operand_scale_) || | |
277 (Bytecodes::OperandIsScalableUnsignedByte(bytecode(), operand_index) && | |
278 Bytecodes::ScaleForUnsignedOperand(operand) != operand_scale_)) { | |
279 UpdateScale(); | |
280 } | |
281 } | |
282 | |
283 Bytecode bytecode() const { return bytecode_; } | 260 Bytecode bytecode() const { return bytecode_; } |
284 | 261 |
285 uint32_t operand(int i) const { | 262 uint32_t operand(int i) const { |
286 DCHECK_LT(i, operand_count()); | 263 DCHECK_LT(i, operand_count()); |
287 return operands_[i]; | 264 return operands_[i]; |
288 } | 265 } |
289 const uint32_t* operands() const { return operands_; } | 266 const uint32_t* operands() const { return operands_; } |
290 | 267 |
291 int operand_count() const { return operand_count_; } | 268 int operand_count() const { return operand_count_; } |
292 OperandScale operand_scale() const { return operand_scale_; } | 269 OperandScale operand_scale() const { return operand_scale_; } |
293 | 270 |
294 const BytecodeSourceInfo& source_info() const { return source_info_; } | 271 const BytecodeSourceInfo& source_info() const { return source_info_; } |
295 BytecodeSourceInfo* source_info_ptr() { return &source_info_; } | 272 void set_source_info(BytecodeSourceInfo source_info) { |
| 273 source_info_ = source_info; |
| 274 } |
296 | 275 |
297 bool operator==(const BytecodeNode& other) const; | 276 bool operator==(const BytecodeNode& other) const; |
298 bool operator!=(const BytecodeNode& other) const { return !(*this == other); } | 277 bool operator!=(const BytecodeNode& other) const { return !(*this == other); } |
299 | 278 |
300 private: | 279 private: |
301 INLINE(void AttachSourceInfo(BytecodeSourceInfo* source_info)) { | |
302 if (source_info && source_info->is_valid()) { | |
303 // Statement positions need to be emitted immediately. Expression | |
304 // positions can be pushed back until a bytecode is found that can | |
305 // throw (if expression position filtering is turned on). We only | |
306 // invalidate the existing source position information if it is used. | |
307 if (source_info->is_statement() || | |
308 !FLAG_ignition_filter_expression_positions || | |
309 !Bytecodes::IsWithoutExternalSideEffects(bytecode())) { | |
310 source_info_.Clone(*source_info); | |
311 source_info->set_invalid(); | |
312 } | |
313 } | |
314 } | |
315 | |
316 INLINE(void UpdateScaleForOperand(int operand_index, uint32_t operand)) { | 280 INLINE(void UpdateScaleForOperand(int operand_index, uint32_t operand)) { |
317 if (Bytecodes::OperandIsScalableSignedByte(bytecode(), operand_index)) { | 281 if (Bytecodes::OperandIsScalableSignedByte(bytecode(), operand_index)) { |
318 operand_scale_ = | 282 operand_scale_ = |
319 std::max(operand_scale_, Bytecodes::ScaleForSignedOperand(operand)); | 283 std::max(operand_scale_, Bytecodes::ScaleForSignedOperand(operand)); |
320 } else if (Bytecodes::OperandIsScalableUnsignedByte(bytecode(), | 284 } else if (Bytecodes::OperandIsScalableUnsignedByte(bytecode(), |
321 operand_index)) { | 285 operand_index)) { |
322 operand_scale_ = | 286 operand_scale_ = |
323 std::max(operand_scale_, Bytecodes::ScaleForUnsignedOperand(operand)); | 287 std::max(operand_scale_, Bytecodes::ScaleForUnsignedOperand(operand)); |
324 } | 288 } |
325 } | 289 } |
326 | 290 |
327 INLINE(void SetOperand(int operand_index, uint32_t operand)) { | 291 INLINE(void SetOperand(int operand_index, uint32_t operand)) { |
328 operands_[operand_index] = operand; | 292 operands_[operand_index] = operand; |
329 UpdateScaleForOperand(operand_index, operand); | 293 UpdateScaleForOperand(operand_index, operand); |
330 } | 294 } |
331 | 295 |
332 void UpdateScale() { | |
333 operand_scale_ = OperandScale::kSingle; | |
334 for (int i = 0; i < operand_count(); i++) { | |
335 UpdateScaleForOperand(i, operands_[i]); | |
336 } | |
337 } | |
338 | |
339 Bytecode bytecode_; | 296 Bytecode bytecode_; |
340 uint32_t operands_[Bytecodes::kMaxOperands]; | 297 uint32_t operands_[Bytecodes::kMaxOperands]; |
341 int operand_count_; | 298 int operand_count_; |
342 OperandScale operand_scale_; | 299 OperandScale operand_scale_; |
343 BytecodeSourceInfo source_info_; | 300 BytecodeSourceInfo source_info_; |
344 }; | 301 }; |
345 | 302 |
346 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, | 303 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
347 const BytecodeSourceInfo& info); | 304 const BytecodeSourceInfo& info); |
348 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, | 305 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
349 const BytecodeNode& node); | 306 const BytecodeNode& node); |
350 | 307 |
351 } // namespace interpreter | 308 } // namespace interpreter |
352 } // namespace internal | 309 } // namespace internal |
353 } // namespace v8 | 310 } // namespace v8 |
354 | 311 |
355 #endif // V8_INTERPRETER_BYTECODE_PIPELINE_H_ | 312 #endif // V8_INTERPRETER_BYTECODE_PIPELINE_H_ |
OLD | NEW |