Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Side by Side Diff: src/interpreter/bytecodes.h

Issue 2542903003: [Interpreter] Templatize AccumulatorUsage and OperandType for bytecode creation. (Closed)
Patch Set: Remove commented code and rebase Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/interpreter/bytecode-register-optimizer.cc ('k') | test/unittests/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 #define DECLARE_BYTECODE(Name, ...) k##Name, 384 #define DECLARE_BYTECODE(Name, ...) k##Name,
385 BYTECODE_LIST(DECLARE_BYTECODE) 385 BYTECODE_LIST(DECLARE_BYTECODE)
386 #undef DECLARE_BYTECODE 386 #undef DECLARE_BYTECODE
387 #define COUNT_BYTECODE(x, ...) +1 387 #define COUNT_BYTECODE(x, ...) +1
388 // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will 388 // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will
389 // evaluate to the same value as the last real bytecode. 389 // evaluate to the same value as the last real bytecode.
390 kLast = -1 BYTECODE_LIST(COUNT_BYTECODE) 390 kLast = -1 BYTECODE_LIST(COUNT_BYTECODE)
391 #undef COUNT_BYTECODE 391 #undef COUNT_BYTECODE
392 }; 392 };
393 393
394 // TODO(rmcilroy): Remove once we switch to MSVC 2015 which supports constexpr.
395 // See crbug.com/603131.
396 #if V8_CC_MSVC
397 #define CONSTEXPR const
398 #else
399 #define CONSTEXPR constexpr
400 #endif
401
402 class V8_EXPORT_PRIVATE Bytecodes final { 394 class V8_EXPORT_PRIVATE Bytecodes final {
403 public: 395 public:
404 // The maximum number of operands a bytecode may have. 396 // The maximum number of operands a bytecode may have.
405 static const int kMaxOperands = 4; 397 static const int kMaxOperands = 4;
406 398
407 // Returns string representation of |bytecode|. 399 // Returns string representation of |bytecode|.
408 static const char* ToString(Bytecode bytecode); 400 static const char* ToString(Bytecode bytecode);
409 401
410 // Returns string representation of |bytecode|. 402 // Returns string representation of |bytecode|.
411 static std::string ToString(Bytecode bytecode, OperandScale operand_scale); 403 static std::string ToString(Bytecode bytecode, OperandScale operand_scale);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 } 451 }
460 452
461 // Returns how accumulator is used by |bytecode|. 453 // Returns how accumulator is used by |bytecode|.
462 static AccumulatorUse GetAccumulatorUse(Bytecode bytecode) { 454 static AccumulatorUse GetAccumulatorUse(Bytecode bytecode) {
463 DCHECK(bytecode <= Bytecode::kLast); 455 DCHECK(bytecode <= Bytecode::kLast);
464 return kAccumulatorUse[static_cast<size_t>(bytecode)]; 456 return kAccumulatorUse[static_cast<size_t>(bytecode)];
465 } 457 }
466 458
467 // Returns true if |bytecode| reads the accumulator. 459 // Returns true if |bytecode| reads the accumulator.
468 static bool ReadsAccumulator(Bytecode bytecode) { 460 static bool ReadsAccumulator(Bytecode bytecode) {
469 return (GetAccumulatorUse(bytecode) & AccumulatorUse::kRead) == 461 return BytecodeOperands::ReadsAccumulator(GetAccumulatorUse(bytecode));
470 AccumulatorUse::kRead;
471 } 462 }
472 463
473 // Returns true if |bytecode| writes the accumulator. 464 // Returns true if |bytecode| writes the accumulator.
474 static bool WritesAccumulator(Bytecode bytecode) { 465 static bool WritesAccumulator(Bytecode bytecode) {
475 return (GetAccumulatorUse(bytecode) & AccumulatorUse::kWrite) == 466 return BytecodeOperands::WritesAccumulator(GetAccumulatorUse(bytecode));
476 AccumulatorUse::kWrite;
477 } 467 }
478 468
479 // Return true if |bytecode| writes the accumulator with a boolean value. 469 // Return true if |bytecode| writes the accumulator with a boolean value.
480 static bool WritesBooleanToAccumulator(Bytecode bytecode) { 470 static bool WritesBooleanToAccumulator(Bytecode bytecode) {
481 switch (bytecode) { 471 switch (bytecode) {
482 case Bytecode::kLdaTrue: 472 case Bytecode::kLdaTrue:
483 case Bytecode::kLdaFalse: 473 case Bytecode::kLdaFalse:
484 case Bytecode::kToBooleanLogicalNot: 474 case Bytecode::kToBooleanLogicalNot:
485 case Bytecode::kLogicalNot: 475 case Bytecode::kLogicalNot:
486 case Bytecode::kTestEqual: 476 case Bytecode::kTestEqual:
487 case Bytecode::kTestNotEqual: 477 case Bytecode::kTestNotEqual:
488 case Bytecode::kTestEqualStrict: 478 case Bytecode::kTestEqualStrict:
489 case Bytecode::kTestLessThan: 479 case Bytecode::kTestLessThan:
490 case Bytecode::kTestLessThanOrEqual: 480 case Bytecode::kTestLessThanOrEqual:
491 case Bytecode::kTestGreaterThan: 481 case Bytecode::kTestGreaterThan:
492 case Bytecode::kTestGreaterThanOrEqual: 482 case Bytecode::kTestGreaterThanOrEqual:
493 case Bytecode::kTestInstanceOf: 483 case Bytecode::kTestInstanceOf:
494 case Bytecode::kTestIn: 484 case Bytecode::kTestIn:
495 case Bytecode::kTestUndetectable: 485 case Bytecode::kTestUndetectable:
496 case Bytecode::kForInContinue: 486 case Bytecode::kForInContinue:
497 return true; 487 return true;
498 default: 488 default:
499 return false; 489 return false;
500 } 490 }
501 } 491 }
502 492
503 // Return true if |bytecode| is an accumulator load without effects, 493 // Return true if |bytecode| is an accumulator load without effects,
504 // e.g. LdaConstant, LdaTrue, Ldar. 494 // e.g. LdaConstant, LdaTrue, Ldar.
505 static CONSTEXPR bool IsAccumulatorLoadWithoutEffects(Bytecode bytecode) { 495 static constexpr bool IsAccumulatorLoadWithoutEffects(Bytecode bytecode) {
506 return bytecode == Bytecode::kLdar || bytecode == Bytecode::kLdaZero || 496 return bytecode == Bytecode::kLdar || bytecode == Bytecode::kLdaZero ||
507 bytecode == Bytecode::kLdaSmi || bytecode == Bytecode::kLdaNull || 497 bytecode == Bytecode::kLdaSmi || bytecode == Bytecode::kLdaNull ||
508 bytecode == Bytecode::kLdaTrue || bytecode == Bytecode::kLdaFalse || 498 bytecode == Bytecode::kLdaTrue || bytecode == Bytecode::kLdaFalse ||
509 bytecode == Bytecode::kLdaUndefined || 499 bytecode == Bytecode::kLdaUndefined ||
510 bytecode == Bytecode::kLdaTheHole || 500 bytecode == Bytecode::kLdaTheHole ||
511 bytecode == Bytecode::kLdaConstant || 501 bytecode == Bytecode::kLdaConstant ||
512 bytecode == Bytecode::kLdaContextSlot || 502 bytecode == Bytecode::kLdaContextSlot ||
513 bytecode == Bytecode::kLdaCurrentContextSlot; 503 bytecode == Bytecode::kLdaCurrentContextSlot;
514 } 504 }
515 505
516 // Return true if |bytecode| is a register load without effects, 506 // Return true if |bytecode| is a register load without effects,
517 // e.g. Mov, Star. 507 // e.g. Mov, Star.
518 static CONSTEXPR bool IsRegisterLoadWithoutEffects(Bytecode bytecode) { 508 static constexpr bool IsRegisterLoadWithoutEffects(Bytecode bytecode) {
519 return bytecode == Bytecode::kMov || bytecode == Bytecode::kPopContext || 509 return bytecode == Bytecode::kMov || bytecode == Bytecode::kPopContext ||
520 bytecode == Bytecode::kPushContext || bytecode == Bytecode::kStar; 510 bytecode == Bytecode::kPushContext || bytecode == Bytecode::kStar;
521 } 511 }
522 512
523 // Returns true if the bytecode is a conditional jump taking 513 // Returns true if the bytecode is a conditional jump taking
524 // an immediate byte operand (OperandType::kImm). 514 // an immediate byte operand (OperandType::kImm).
525 static CONSTEXPR bool IsConditionalJumpImmediate(Bytecode bytecode) { 515 static constexpr bool IsConditionalJumpImmediate(Bytecode bytecode) {
526 return bytecode >= Bytecode::kJumpIfToBooleanTrue && 516 return bytecode >= Bytecode::kJumpIfToBooleanTrue &&
527 bytecode <= Bytecode::kJumpIfNotHole; 517 bytecode <= Bytecode::kJumpIfNotHole;
528 } 518 }
529 519
530 // Returns true if the bytecode is a conditional jump taking 520 // Returns true if the bytecode is a conditional jump taking
531 // a constant pool entry (OperandType::kIdx). 521 // a constant pool entry (OperandType::kIdx).
532 static CONSTEXPR bool IsConditionalJumpConstant(Bytecode bytecode) { 522 static constexpr bool IsConditionalJumpConstant(Bytecode bytecode) {
533 return bytecode >= Bytecode::kJumpIfNullConstant && 523 return bytecode >= Bytecode::kJumpIfNullConstant &&
534 bytecode <= Bytecode::kJumpIfToBooleanFalseConstant; 524 bytecode <= Bytecode::kJumpIfToBooleanFalseConstant;
535 } 525 }
536 526
537 // Returns true if the bytecode is a conditional jump taking 527 // Returns true if the bytecode is a conditional jump taking
538 // any kind of operand. 528 // any kind of operand.
539 static CONSTEXPR bool IsConditionalJump(Bytecode bytecode) { 529 static constexpr bool IsConditionalJump(Bytecode bytecode) {
540 return bytecode >= Bytecode::kJumpIfNullConstant && 530 return bytecode >= Bytecode::kJumpIfNullConstant &&
541 bytecode <= Bytecode::kJumpIfNotHole; 531 bytecode <= Bytecode::kJumpIfNotHole;
542 } 532 }
543 533
544 // Returns true if the bytecode is an unconditional jump. 534 // Returns true if the bytecode is an unconditional jump.
545 static CONSTEXPR bool IsUnconditionalJump(Bytecode bytecode) { 535 static constexpr bool IsUnconditionalJump(Bytecode bytecode) {
546 return bytecode >= Bytecode::kJumpLoop && 536 return bytecode >= Bytecode::kJumpLoop &&
547 bytecode <= Bytecode::kJumpConstant; 537 bytecode <= Bytecode::kJumpConstant;
548 } 538 }
549 539
550 // Returns true if the bytecode is a jump or a conditional jump taking 540 // Returns true if the bytecode is a jump or a conditional jump taking
551 // an immediate byte operand (OperandType::kImm). 541 // an immediate byte operand (OperandType::kImm).
552 static CONSTEXPR bool IsJumpImmediate(Bytecode bytecode) { 542 static constexpr bool IsJumpImmediate(Bytecode bytecode) {
553 return bytecode == Bytecode::kJump || bytecode == Bytecode::kJumpLoop || 543 return bytecode == Bytecode::kJump || bytecode == Bytecode::kJumpLoop ||
554 IsConditionalJumpImmediate(bytecode); 544 IsConditionalJumpImmediate(bytecode);
555 } 545 }
556 546
557 // Returns true if the bytecode is a jump or conditional jump taking a 547 // Returns true if the bytecode is a jump or conditional jump taking a
558 // constant pool entry (OperandType::kIdx). 548 // constant pool entry (OperandType::kIdx).
559 static CONSTEXPR bool IsJumpConstant(Bytecode bytecode) { 549 static constexpr bool IsJumpConstant(Bytecode bytecode) {
560 return bytecode >= Bytecode::kJumpConstant && 550 return bytecode >= Bytecode::kJumpConstant &&
561 bytecode <= Bytecode::kJumpIfToBooleanFalseConstant; 551 bytecode <= Bytecode::kJumpIfToBooleanFalseConstant;
562 } 552 }
563 553
564 // Returns true if the bytecode is a jump that internally coerces the 554 // Returns true if the bytecode is a jump that internally coerces the
565 // accumulator to a boolean. 555 // accumulator to a boolean.
566 static CONSTEXPR bool IsJumpIfToBoolean(Bytecode bytecode) { 556 static constexpr bool IsJumpIfToBoolean(Bytecode bytecode) {
567 return bytecode >= Bytecode::kJumpIfToBooleanTrueConstant && 557 return bytecode >= Bytecode::kJumpIfToBooleanTrueConstant &&
568 bytecode <= Bytecode::kJumpIfToBooleanFalse; 558 bytecode <= Bytecode::kJumpIfToBooleanFalse;
569 } 559 }
570 560
571 // Returns true if the bytecode is a jump or conditional jump taking 561 // Returns true if the bytecode is a jump or conditional jump taking
572 // any kind of operand. 562 // any kind of operand.
573 static CONSTEXPR bool IsJump(Bytecode bytecode) { 563 static constexpr bool IsJump(Bytecode bytecode) {
574 return bytecode >= Bytecode::kJumpLoop && 564 return bytecode >= Bytecode::kJumpLoop &&
575 bytecode <= Bytecode::kJumpIfNotHole; 565 bytecode <= Bytecode::kJumpIfNotHole;
576 } 566 }
577 567
578 // Returns true if the bytecode is a forward jump or conditional jump taking 568 // Returns true if the bytecode is a forward jump or conditional jump taking
579 // any kind of operand. 569 // any kind of operand.
580 static CONSTEXPR bool IsForwardJump(Bytecode bytecode) { 570 static constexpr bool IsForwardJump(Bytecode bytecode) {
581 return bytecode >= Bytecode::kJump && bytecode <= Bytecode::kJumpIfNotHole; 571 return bytecode >= Bytecode::kJump && bytecode <= Bytecode::kJumpIfNotHole;
582 } 572 }
583 573
584 // Returns true if the bytecode is a conditional jump, a jump, or a return. 574 // Returns true if the bytecode is a conditional jump, a jump, or a return.
585 static CONSTEXPR bool IsJumpOrReturn(Bytecode bytecode) { 575 static constexpr bool IsJumpOrReturn(Bytecode bytecode) {
586 return bytecode == Bytecode::kReturn || IsJump(bytecode); 576 return bytecode == Bytecode::kReturn || IsJump(bytecode);
587 } 577 }
588 578
589 // Return true if |bytecode| is a jump without effects, 579 // Return true if |bytecode| is a jump without effects,
590 // e.g. any jump excluding those that include type coercion like 580 // e.g. any jump excluding those that include type coercion like
591 // JumpIfTrueToBoolean. 581 // JumpIfTrueToBoolean.
592 static CONSTEXPR bool IsJumpWithoutEffects(Bytecode bytecode) { 582 static constexpr bool IsJumpWithoutEffects(Bytecode bytecode) {
593 return IsJump(bytecode) && !IsJumpIfToBoolean(bytecode); 583 return IsJump(bytecode) && !IsJumpIfToBoolean(bytecode);
594 } 584 }
595 585
596 // Returns true if |bytecode| has no effects. These bytecodes only manipulate 586 // Returns true if |bytecode| has no effects. These bytecodes only manipulate
597 // interpreter frame state and will never throw. 587 // interpreter frame state and will never throw.
598 static CONSTEXPR bool IsWithoutExternalSideEffects(Bytecode bytecode) { 588 static constexpr bool IsWithoutExternalSideEffects(Bytecode bytecode) {
599 return (IsAccumulatorLoadWithoutEffects(bytecode) || 589 return (IsAccumulatorLoadWithoutEffects(bytecode) ||
600 IsRegisterLoadWithoutEffects(bytecode) || 590 IsRegisterLoadWithoutEffects(bytecode) ||
601 bytecode == Bytecode::kNop || IsJumpWithoutEffects(bytecode)); 591 bytecode == Bytecode::kNop || IsJumpWithoutEffects(bytecode));
602 } 592 }
603 593
604 // Returns true if the bytecode is Ldar or Star. 594 // Returns true if the bytecode is Ldar or Star.
605 static CONSTEXPR bool IsLdarOrStar(Bytecode bytecode) { 595 static constexpr bool IsLdarOrStar(Bytecode bytecode) {
606 return bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar; 596 return bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar;
607 } 597 }
608 598
609 // Returns true if |bytecode| puts a name in the accumulator. 599 // Returns true if |bytecode| puts a name in the accumulator.
610 static CONSTEXPR bool PutsNameInAccumulator(Bytecode bytecode) { 600 static constexpr bool PutsNameInAccumulator(Bytecode bytecode) {
611 return bytecode == Bytecode::kTypeOf; 601 return bytecode == Bytecode::kTypeOf;
612 } 602 }
613 603
614 // Returns true if the bytecode is a call or a constructor call. 604 // Returns true if the bytecode is a call or a constructor call.
615 static CONSTEXPR bool IsCallOrNew(Bytecode bytecode) { 605 static constexpr bool IsCallOrNew(Bytecode bytecode) {
616 return bytecode == Bytecode::kCall || bytecode == Bytecode::kCallProperty || 606 return bytecode == Bytecode::kCall || bytecode == Bytecode::kCallProperty ||
617 bytecode == Bytecode::kTailCall || bytecode == Bytecode::kNew; 607 bytecode == Bytecode::kTailCall || bytecode == Bytecode::kNew;
618 } 608 }
619 609
620 // Returns true if the bytecode is a call to the runtime. 610 // Returns true if the bytecode is a call to the runtime.
621 static CONSTEXPR bool IsCallRuntime(Bytecode bytecode) { 611 static constexpr bool IsCallRuntime(Bytecode bytecode) {
622 return bytecode == Bytecode::kCallRuntime || 612 return bytecode == Bytecode::kCallRuntime ||
623 bytecode == Bytecode::kCallRuntimeForPair || 613 bytecode == Bytecode::kCallRuntimeForPair ||
624 bytecode == Bytecode::kInvokeIntrinsic; 614 bytecode == Bytecode::kInvokeIntrinsic;
625 } 615 }
626 616
627 // Returns true if the bytecode is a scaling prefix bytecode. 617 // Returns true if the bytecode is a scaling prefix bytecode.
628 static CONSTEXPR bool IsPrefixScalingBytecode(Bytecode bytecode) { 618 static constexpr bool IsPrefixScalingBytecode(Bytecode bytecode) {
629 return bytecode == Bytecode::kExtraWide || bytecode == Bytecode::kWide || 619 return bytecode == Bytecode::kExtraWide || bytecode == Bytecode::kWide ||
630 bytecode == Bytecode::kDebugBreakExtraWide || 620 bytecode == Bytecode::kDebugBreakExtraWide ||
631 bytecode == Bytecode::kDebugBreakWide; 621 bytecode == Bytecode::kDebugBreakWide;
632 } 622 }
633 623
634 // Returns the number of values which |bytecode| returns. 624 // Returns the number of values which |bytecode| returns.
635 static CONSTEXPR size_t ReturnCount(Bytecode bytecode) { 625 static constexpr size_t ReturnCount(Bytecode bytecode) {
636 return bytecode == Bytecode::kReturn ? 1 : 0; 626 return bytecode == Bytecode::kReturn ? 1 : 0;
637 } 627 }
638 628
639 // Returns the number of operands expected by |bytecode|. 629 // Returns the number of operands expected by |bytecode|.
640 static int NumberOfOperands(Bytecode bytecode) { 630 static int NumberOfOperands(Bytecode bytecode) {
641 DCHECK(bytecode <= Bytecode::kLast); 631 DCHECK(bytecode <= Bytecode::kLast);
642 return kOperandCount[static_cast<size_t>(bytecode)]; 632 return kOperandCount[static_cast<size_t>(bytecode)];
643 } 633 }
644 634
645 // Returns the i-th operand of |bytecode|. 635 // Returns the i-th operand of |bytecode|.
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
810 static const OperandType* const kOperandTypes[]; 800 static const OperandType* const kOperandTypes[];
811 static const OperandTypeInfo* const kOperandTypeInfos[]; 801 static const OperandTypeInfo* const kOperandTypeInfos[];
812 static const int kOperandCount[]; 802 static const int kOperandCount[];
813 static const int kNumberOfRegisterOperands[]; 803 static const int kNumberOfRegisterOperands[];
814 static const AccumulatorUse kAccumulatorUse[]; 804 static const AccumulatorUse kAccumulatorUse[];
815 static const bool kIsScalable[]; 805 static const bool kIsScalable[];
816 static const int kBytecodeSizes[][3]; 806 static const int kBytecodeSizes[][3];
817 static const OperandSize* const kOperandSizes[][3]; 807 static const OperandSize* const kOperandSizes[][3];
818 }; 808 };
819 809
820 // TODO(rmcilroy): Remove once we switch to MSVC 2015 which supports constexpr.
821 // See crbug.com/603131.
822 #undef CONSTEXPR
823
824 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, 810 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
825 const Bytecode& bytecode); 811 const Bytecode& bytecode);
826 812
827 } // namespace interpreter 813 } // namespace interpreter
828 } // namespace internal 814 } // namespace internal
829 } // namespace v8 815 } // namespace v8
830 816
831 #endif // V8_INTERPRETER_BYTECODES_H_ 817 #endif // V8_INTERPRETER_BYTECODES_H_
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-register-optimizer.cc ('k') | test/unittests/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698