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_BYTECODES_H_ | 5 #ifndef V8_INTERPRETER_BYTECODES_H_ |
6 #define V8_INTERPRETER_BYTECODES_H_ | 6 #define V8_INTERPRETER_BYTECODES_H_ |
7 | 7 |
8 #include <cstdint> | 8 #include <cstdint> |
9 #include <iosfwd> | 9 #include <iosfwd> |
10 #include <string> | 10 #include <string> |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
206 OperandType::kIdx, OperandType::kIdx) \ | 206 OperandType::kIdx, OperandType::kIdx) \ |
207 V(CreateFunctionContext, AccumulatorUse::kWrite, OperandType::kUImm) \ | 207 V(CreateFunctionContext, AccumulatorUse::kWrite, OperandType::kUImm) \ |
208 V(CreateWithContext, AccumulatorUse::kReadWrite, OperandType::kReg, \ | 208 V(CreateWithContext, AccumulatorUse::kReadWrite, OperandType::kReg, \ |
209 OperandType::kIdx) \ | 209 OperandType::kIdx) \ |
210 \ | 210 \ |
211 /* Arguments allocation */ \ | 211 /* Arguments allocation */ \ |
212 V(CreateMappedArguments, AccumulatorUse::kWrite) \ | 212 V(CreateMappedArguments, AccumulatorUse::kWrite) \ |
213 V(CreateUnmappedArguments, AccumulatorUse::kWrite) \ | 213 V(CreateUnmappedArguments, AccumulatorUse::kWrite) \ |
214 V(CreateRestParameter, AccumulatorUse::kWrite) \ | 214 V(CreateRestParameter, AccumulatorUse::kWrite) \ |
215 \ | 215 \ |
216 /* Control Flow */ \ | 216 /* Control Flow -- carefully ordered for efficient checks */ \ |
217 /* - [Unconditional jumps] */ \ | |
218 V(JumpLoop, AccumulatorUse::kNone, OperandType::kImm, OperandType::kImm) \ | |
219 /* - [Forward jumps] */ \ | |
217 V(Jump, AccumulatorUse::kNone, OperandType::kImm) \ | 220 V(Jump, AccumulatorUse::kNone, OperandType::kImm) \ |
221 /* - [Start constant jumps] */ \ | |
218 V(JumpConstant, AccumulatorUse::kNone, OperandType::kIdx) \ | 222 V(JumpConstant, AccumulatorUse::kNone, OperandType::kIdx) \ |
223 /* - [Conditional jumps] */ \ | |
224 /* - [Conditional constant jumps] */ \ | |
225 V(JumpIfNullConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
226 V(JumpIfUndefinedConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
227 V(JumpIfTrueConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
228 V(JumpIfFalseConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
229 V(JumpIfNotHoleConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
230 /* - [Start ToBoolean jumps] */ \ | |
231 V(JumpIfToBooleanTrueConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
232 V(JumpIfToBooleanFalseConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
233 /* - [End constant jumps] */ \ | |
234 /* - [Conditional immediate jumps] */ \ | |
235 V(JumpIfToBooleanTrue, AccumulatorUse::kRead, OperandType::kImm) \ | |
236 V(JumpIfToBooleanFalse, AccumulatorUse::kRead, OperandType::kImm) \ | |
237 /* - [End ToBoolean jumps] */ \ | |
219 V(JumpIfTrue, AccumulatorUse::kRead, OperandType::kImm) \ | 238 V(JumpIfTrue, AccumulatorUse::kRead, OperandType::kImm) \ |
220 V(JumpIfTrueConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
221 V(JumpIfFalse, AccumulatorUse::kRead, OperandType::kImm) \ | 239 V(JumpIfFalse, AccumulatorUse::kRead, OperandType::kImm) \ |
222 V(JumpIfFalseConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
223 V(JumpIfToBooleanTrue, AccumulatorUse::kRead, OperandType::kImm) \ | |
224 V(JumpIfToBooleanTrueConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
225 V(JumpIfToBooleanFalse, AccumulatorUse::kRead, OperandType::kImm) \ | |
226 V(JumpIfToBooleanFalseConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
227 V(JumpIfNull, AccumulatorUse::kRead, OperandType::kImm) \ | 240 V(JumpIfNull, AccumulatorUse::kRead, OperandType::kImm) \ |
228 V(JumpIfNullConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
229 V(JumpIfUndefined, AccumulatorUse::kRead, OperandType::kImm) \ | 241 V(JumpIfUndefined, AccumulatorUse::kRead, OperandType::kImm) \ |
230 V(JumpIfUndefinedConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
231 V(JumpIfNotHole, AccumulatorUse::kRead, OperandType::kImm) \ | 242 V(JumpIfNotHole, AccumulatorUse::kRead, OperandType::kImm) \ |
232 V(JumpIfNotHoleConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
233 V(JumpLoop, AccumulatorUse::kNone, OperandType::kImm, OperandType::kImm) \ | |
234 \ | 243 \ |
235 /* Complex flow control For..in */ \ | 244 /* Complex flow control For..in */ \ |
236 V(ForInPrepare, AccumulatorUse::kNone, OperandType::kReg, \ | 245 V(ForInPrepare, AccumulatorUse::kNone, OperandType::kReg, \ |
237 OperandType::kRegOutTriple) \ | 246 OperandType::kRegOutTriple) \ |
238 V(ForInContinue, AccumulatorUse::kWrite, OperandType::kReg, \ | 247 V(ForInContinue, AccumulatorUse::kWrite, OperandType::kReg, \ |
239 OperandType::kReg) \ | 248 OperandType::kReg) \ |
240 V(ForInNext, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg, \ | 249 V(ForInNext, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg, \ |
241 OperandType::kRegPair, OperandType::kIdx) \ | 250 OperandType::kRegPair, OperandType::kIdx) \ |
242 V(ForInStep, AccumulatorUse::kWrite, OperandType::kReg) \ | 251 V(ForInStep, AccumulatorUse::kWrite, OperandType::kReg) \ |
243 \ | 252 \ |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
293 V(DebugBreak6) | 302 V(DebugBreak6) |
294 | 303 |
295 #define DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) \ | 304 #define DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) \ |
296 V(DebugBreakWide) \ | 305 V(DebugBreakWide) \ |
297 V(DebugBreakExtraWide) | 306 V(DebugBreakExtraWide) |
298 | 307 |
299 #define DEBUG_BREAK_BYTECODE_LIST(V) \ | 308 #define DEBUG_BREAK_BYTECODE_LIST(V) \ |
300 DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \ | 309 DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \ |
301 DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) | 310 DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) |
302 | 311 |
312 // List of jump bytecodes. | |
313 #define JUMP_FORWARD_BYTECODE_LIST(V) \ | |
314 V(Jump) \ | |
315 V(JumpConstant) \ | |
316 V(JumpIfNullConstant) \ | |
317 V(JumpIfUndefinedConstant) \ | |
318 V(JumpIfTrueConstant) \ | |
319 V(JumpIfFalseConstant) \ | |
320 V(JumpIfNotHoleConstant) \ | |
321 V(JumpIfToBooleanTrueConstant) \ | |
322 V(JumpIfToBooleanFalseConstant) \ | |
323 V(JumpIfToBooleanTrue) \ | |
324 V(JumpIfToBooleanFalse) \ | |
325 V(JumpIfTrue) \ | |
326 V(JumpIfFalse) \ | |
327 V(JumpIfNull) \ | |
328 V(JumpIfUndefined) \ | |
329 V(JumpIfNotHole) | |
330 | |
331 #define JUMP_CONSTANT_BYTECODE_LIST(V) \ | |
332 V(JumpConstant) \ | |
333 V(JumpIfNullConstant) \ | |
334 V(JumpIfUndefinedConstant) \ | |
335 V(JumpIfTrueConstant) \ | |
336 V(JumpIfFalseConstant) \ | |
337 V(JumpIfNotHoleConstant) \ | |
338 V(JumpIfToBooleanTrueConstant) \ | |
339 V(JumpIfToBooleanFalseConstant) | |
340 | |
341 #define JUMP_IMMEDIATE_BYTECODE_LIST(V) \ | |
342 V(JumpLoop) \ | |
343 V(Jump) \ | |
344 V(JumpIfToBooleanTrue) \ | |
345 V(JumpIfToBooleanFalse) \ | |
346 V(JumpIfTrue) \ | |
347 V(JumpIfFalse) \ | |
348 V(JumpIfNull) \ | |
349 V(JumpIfUndefined) \ | |
350 V(JumpIfNotHole) | |
351 | |
352 #define JUMP_TO_BOOLEAN_BYTECODE_LIST(V) \ | |
353 V(JumpIfToBooleanTrueConstant) \ | |
354 V(JumpIfToBooleanFalseConstant) \ | |
355 V(JumpIfToBooleanTrue) \ | |
356 V(JumpIfToBooleanFalse) | |
357 | |
358 #define JUMP_UNCONDITIONAL_BYTECODE_LIST(V) \ | |
359 V(JumpLoop) \ | |
360 V(Jump) \ | |
361 V(JumpConstant) | |
362 | |
363 #define JUMP_CONDITIONAL_BYTECODE_LIST(V) \ | |
364 V(JumpIfNullConstant) \ | |
365 V(JumpIfUndefinedConstant) \ | |
366 V(JumpIfTrueConstant) \ | |
367 V(JumpIfFalseConstant) \ | |
368 V(JumpIfNotHoleConstant) \ | |
369 V(JumpIfToBooleanTrueConstant) \ | |
370 V(JumpIfToBooleanFalseConstant) \ | |
371 V(JumpIfToBooleanTrue) \ | |
372 V(JumpIfToBooleanFalse) \ | |
373 V(JumpIfTrue) \ | |
374 V(JumpIfFalse) \ | |
375 V(JumpIfNull) \ | |
376 V(JumpIfUndefined) \ | |
377 V(JumpIfNotHole) | |
rmcilroy
2016/12/05 14:33:40
nit - could you build these up so there aren't rep
Leszek Swirski
2016/12/05 17:53:11
Done, except for some duplication in JumpForward c
| |
378 | |
379 #define JUMP_BYTECODE_LIST(V) \ | |
380 V(JumpLoop) \ | |
381 JUMP_FORWARD_BYTECODE_LIST(V) | |
382 | |
303 // Enumeration of interpreter bytecodes. | 383 // Enumeration of interpreter bytecodes. |
304 enum class Bytecode : uint8_t { | 384 enum class Bytecode : uint8_t { |
305 #define DECLARE_BYTECODE(Name, ...) k##Name, | 385 #define DECLARE_BYTECODE(Name, ...) k##Name, |
306 BYTECODE_LIST(DECLARE_BYTECODE) | 386 BYTECODE_LIST(DECLARE_BYTECODE) |
307 #undef DECLARE_BYTECODE | 387 #undef DECLARE_BYTECODE |
308 #define COUNT_BYTECODE(x, ...) +1 | 388 #define COUNT_BYTECODE(x, ...) +1 |
309 // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will | 389 // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will |
310 // evaluate to the same value as the last real bytecode. | 390 // evaluate to the same value as the last real bytecode. |
311 kLast = -1 BYTECODE_LIST(COUNT_BYTECODE) | 391 kLast = -1 BYTECODE_LIST(COUNT_BYTECODE) |
312 #undef COUNT_BYTECODE | 392 #undef COUNT_BYTECODE |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
436 // Return true if |bytecode| is a register load without effects, | 516 // Return true if |bytecode| is a register load without effects, |
437 // e.g. Mov, Star. | 517 // e.g. Mov, Star. |
438 static CONSTEXPR bool IsRegisterLoadWithoutEffects(Bytecode bytecode) { | 518 static CONSTEXPR bool IsRegisterLoadWithoutEffects(Bytecode bytecode) { |
439 return bytecode == Bytecode::kMov || bytecode == Bytecode::kPopContext || | 519 return bytecode == Bytecode::kMov || bytecode == Bytecode::kPopContext || |
440 bytecode == Bytecode::kPushContext || bytecode == Bytecode::kStar; | 520 bytecode == Bytecode::kPushContext || bytecode == Bytecode::kStar; |
441 } | 521 } |
442 | 522 |
443 // Returns true if the bytecode is a conditional jump taking | 523 // Returns true if the bytecode is a conditional jump taking |
444 // an immediate byte operand (OperandType::kImm). | 524 // an immediate byte operand (OperandType::kImm). |
445 static CONSTEXPR bool IsConditionalJumpImmediate(Bytecode bytecode) { | 525 static CONSTEXPR bool IsConditionalJumpImmediate(Bytecode bytecode) { |
446 return bytecode == Bytecode::kJumpIfTrue || | 526 return bytecode >= Bytecode::kJumpIfToBooleanTrue && |
447 bytecode == Bytecode::kJumpIfFalse || | 527 bytecode <= Bytecode::kJumpIfNotHole; |
448 bytecode == Bytecode::kJumpIfToBooleanTrue || | |
449 bytecode == Bytecode::kJumpIfToBooleanFalse || | |
450 bytecode == Bytecode::kJumpIfNotHole || | |
451 bytecode == Bytecode::kJumpIfNull || | |
452 bytecode == Bytecode::kJumpIfUndefined; | |
453 } | 528 } |
454 | 529 |
455 // Returns true if the bytecode is a conditional jump taking | 530 // Returns true if the bytecode is a conditional jump taking |
456 // a constant pool entry (OperandType::kIdx). | 531 // a constant pool entry (OperandType::kIdx). |
457 static CONSTEXPR bool IsConditionalJumpConstant(Bytecode bytecode) { | 532 static CONSTEXPR bool IsConditionalJumpConstant(Bytecode bytecode) { |
458 return bytecode == Bytecode::kJumpIfTrueConstant || | 533 return bytecode >= Bytecode::kJumpIfNullConstant && |
459 bytecode == Bytecode::kJumpIfFalseConstant || | 534 bytecode <= Bytecode::kJumpIfToBooleanFalseConstant; |
460 bytecode == Bytecode::kJumpIfToBooleanTrueConstant || | |
461 bytecode == Bytecode::kJumpIfToBooleanFalseConstant || | |
462 bytecode == Bytecode::kJumpIfNotHoleConstant || | |
463 bytecode == Bytecode::kJumpIfNullConstant || | |
464 bytecode == Bytecode::kJumpIfUndefinedConstant; | |
465 } | 535 } |
466 | 536 |
467 // Returns true if the bytecode is a conditional jump taking | 537 // Returns true if the bytecode is a conditional jump taking |
468 // any kind of operand. | 538 // any kind of operand. |
469 static CONSTEXPR bool IsConditionalJump(Bytecode bytecode) { | 539 static CONSTEXPR bool IsConditionalJump(Bytecode bytecode) { |
470 return IsConditionalJumpImmediate(bytecode) || | 540 return bytecode >= Bytecode::kJumpIfNullConstant && |
471 IsConditionalJumpConstant(bytecode); | 541 bytecode <= Bytecode::kJumpIfNotHole; |
472 } | 542 } |
473 | 543 |
474 // Returns true if the bytecode is an unconditional jump. | 544 // Returns true if the bytecode is an unconditional jump. |
475 static CONSTEXPR bool IsUnconditionalJump(Bytecode bytecode) { | 545 static CONSTEXPR bool IsUnconditionalJump(Bytecode bytecode) { |
476 return bytecode == Bytecode::kJump || bytecode == Bytecode::kJumpConstant || | 546 return bytecode >= Bytecode::kJumpLoop && |
477 bytecode == Bytecode::kJumpLoop; | 547 bytecode <= Bytecode::kJumpConstant; |
478 } | 548 } |
479 | 549 |
480 // Returns true if the bytecode is a jump or a conditional jump taking | 550 // Returns true if the bytecode is a jump or a conditional jump taking |
481 // an immediate byte operand (OperandType::kImm). | 551 // an immediate byte operand (OperandType::kImm). |
482 static CONSTEXPR bool IsJumpImmediate(Bytecode bytecode) { | 552 static CONSTEXPR bool IsJumpImmediate(Bytecode bytecode) { |
483 return bytecode == Bytecode::kJump || bytecode == Bytecode::kJumpLoop || | 553 return bytecode == Bytecode::kJump || bytecode == Bytecode::kJumpLoop || |
484 IsConditionalJumpImmediate(bytecode); | 554 IsConditionalJumpImmediate(bytecode); |
485 } | 555 } |
486 | 556 |
487 // Returns true if the bytecode is a jump or conditional jump taking a | 557 // Returns true if the bytecode is a jump or conditional jump taking a |
488 // constant pool entry (OperandType::kIdx). | 558 // constant pool entry (OperandType::kIdx). |
489 static CONSTEXPR bool IsJumpConstant(Bytecode bytecode) { | 559 static CONSTEXPR bool IsJumpConstant(Bytecode bytecode) { |
490 return bytecode == Bytecode::kJumpConstant || | 560 return bytecode >= Bytecode::kJumpConstant && |
491 IsConditionalJumpConstant(bytecode); | 561 bytecode <= Bytecode::kJumpIfToBooleanFalseConstant; |
492 } | 562 } |
493 | 563 |
494 // Returns true if the bytecode is a jump that internally coerces the | 564 // Returns true if the bytecode is a jump that internally coerces the |
495 // accumulator to a boolean. | 565 // accumulator to a boolean. |
496 static CONSTEXPR bool IsJumpIfToBoolean(Bytecode bytecode) { | 566 static CONSTEXPR bool IsJumpIfToBoolean(Bytecode bytecode) { |
497 return bytecode == Bytecode::kJumpIfToBooleanTrue || | 567 return bytecode >= Bytecode::kJumpIfToBooleanTrueConstant && |
498 bytecode == Bytecode::kJumpIfToBooleanFalse || | 568 bytecode <= Bytecode::kJumpIfToBooleanFalse; |
499 bytecode == Bytecode::kJumpIfToBooleanTrueConstant || | |
500 bytecode == Bytecode::kJumpIfToBooleanFalseConstant; | |
501 } | 569 } |
502 | 570 |
503 // Returns true if the bytecode is a jump or conditional jump taking | 571 // Returns true if the bytecode is a jump or conditional jump taking |
504 // any kind of operand. | 572 // any kind of operand. |
505 static CONSTEXPR bool IsJump(Bytecode bytecode) { | 573 static CONSTEXPR bool IsJump(Bytecode bytecode) { |
506 return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode); | 574 return bytecode >= Bytecode::kJumpLoop && |
575 bytecode <= Bytecode::kJumpIfNotHole; | |
507 } | 576 } |
508 | 577 |
509 // Returns true if the bytecode is a forward jump or conditional jump taking | 578 // Returns true if the bytecode is a forward jump or conditional jump taking |
510 // any kind of operand. | 579 // any kind of operand. |
511 static CONSTEXPR bool IsForwardJump(Bytecode bytecode) { | 580 static CONSTEXPR bool IsForwardJump(Bytecode bytecode) { |
512 return bytecode != Bytecode::kJumpLoop && IsJump(bytecode); | 581 return bytecode >= Bytecode::kJump && bytecode <= Bytecode::kJumpIfNotHole; |
513 } | 582 } |
514 | 583 |
515 // Returns true if the bytecode is a conditional jump, a jump, or a return. | 584 // Returns true if the bytecode is a conditional jump, a jump, or a return. |
516 static CONSTEXPR bool IsJumpOrReturn(Bytecode bytecode) { | 585 static CONSTEXPR bool IsJumpOrReturn(Bytecode bytecode) { |
517 return bytecode == Bytecode::kReturn || IsJump(bytecode); | 586 return bytecode == Bytecode::kReturn || IsJump(bytecode); |
518 } | 587 } |
519 | 588 |
520 // Return true if |bytecode| is a jump without effects, | 589 // Return true if |bytecode| is a jump without effects, |
521 // e.g. any jump excluding those that include type coercion like | 590 // e.g. any jump excluding those that include type coercion like |
522 // JumpIfTrueToBoolean. | 591 // JumpIfTrueToBoolean. |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
753 #undef CONSTEXPR | 822 #undef CONSTEXPR |
754 | 823 |
755 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, | 824 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
756 const Bytecode& bytecode); | 825 const Bytecode& bytecode); |
757 | 826 |
758 } // namespace interpreter | 827 } // namespace interpreter |
759 } // namespace internal | 828 } // namespace internal |
760 } // namespace v8 | 829 } // namespace v8 |
761 | 830 |
762 #endif // V8_INTERPRETER_BYTECODES_H_ | 831 #endif // V8_INTERPRETER_BYTECODES_H_ |
OLD | NEW |