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

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

Issue 2149093002: Reland "[interpreter] Reduce dependencies in bytecodes.{h,cc}" (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 5 months 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/bytecodes.h ('k') | src/interpreter/handler-table-builder.h » ('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 #include "src/interpreter/bytecodes.h" 5 #include "src/interpreter/bytecodes.h"
6 6
7 #include <iomanip> 7 #include <iomanip>
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/code-stubs.h" 10 #include "src/globals.h"
11 #include "src/frames.h"
12 #include "src/interpreter/bytecode-traits.h" 11 #include "src/interpreter/bytecode-traits.h"
13 #include "src/interpreter/interpreter.h"
14 12
15 namespace v8 { 13 namespace v8 {
16 namespace internal { 14 namespace internal {
17 namespace interpreter { 15 namespace interpreter {
18 16
19 STATIC_CONST_MEMBER_DEFINITION const int Bytecodes::kMaxOperands; 17 STATIC_CONST_MEMBER_DEFINITION const int Bytecodes::kMaxOperands;
20 18
21 // static 19 // static
22 const char* Bytecodes::ToString(Bytecode bytecode) { 20 const char* Bytecodes::ToString(Bytecode bytecode) {
23 switch (bytecode) { 21 switch (bytecode) {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 case OperandSize::kShort: 95 case OperandSize::kShort:
98 return "Short"; 96 return "Short";
99 case OperandSize::kQuad: 97 case OperandSize::kQuad:
100 return "Quad"; 98 return "Quad";
101 } 99 }
102 UNREACHABLE(); 100 UNREACHABLE();
103 return ""; 101 return "";
104 } 102 }
105 103
106 // static 104 // static
105 uint8_t Bytecodes::ToByte(Bytecode bytecode) {
106 DCHECK_LE(bytecode, Bytecode::kLast);
107 return static_cast<uint8_t>(bytecode);
108 }
109
110 // static
107 Bytecode Bytecodes::FromByte(uint8_t value) { 111 Bytecode Bytecodes::FromByte(uint8_t value) {
108 Bytecode bytecode = static_cast<Bytecode>(value); 112 Bytecode bytecode = static_cast<Bytecode>(value);
109 DCHECK(bytecode <= Bytecode::kLast); 113 DCHECK(bytecode <= Bytecode::kLast);
110 return bytecode; 114 return bytecode;
111 } 115 }
112 116
113 // static 117 // static
114 Bytecode Bytecodes::GetDebugBreak(Bytecode bytecode) { 118 Bytecode Bytecodes::GetDebugBreak(Bytecode bytecode) {
115 DCHECK(!IsDebugBreak(bytecode)); 119 DCHECK(!IsDebugBreak(bytecode));
116 if (bytecode == Bytecode::kWide) { 120 if (bytecode == Bytecode::kWide) {
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 bool Bytecodes::IsConditionalJumpImmediate(Bytecode bytecode) { 377 bool Bytecodes::IsConditionalJumpImmediate(Bytecode bytecode) {
374 return bytecode == Bytecode::kJumpIfTrue || 378 return bytecode == Bytecode::kJumpIfTrue ||
375 bytecode == Bytecode::kJumpIfFalse || 379 bytecode == Bytecode::kJumpIfFalse ||
376 bytecode == Bytecode::kJumpIfToBooleanTrue || 380 bytecode == Bytecode::kJumpIfToBooleanTrue ||
377 bytecode == Bytecode::kJumpIfToBooleanFalse || 381 bytecode == Bytecode::kJumpIfToBooleanFalse ||
378 bytecode == Bytecode::kJumpIfNotHole || 382 bytecode == Bytecode::kJumpIfNotHole ||
379 bytecode == Bytecode::kJumpIfNull || 383 bytecode == Bytecode::kJumpIfNull ||
380 bytecode == Bytecode::kJumpIfUndefined; 384 bytecode == Bytecode::kJumpIfUndefined;
381 } 385 }
382 386
383
384 // static 387 // static
385 bool Bytecodes::IsConditionalJumpConstant(Bytecode bytecode) { 388 bool Bytecodes::IsConditionalJumpConstant(Bytecode bytecode) {
386 return bytecode == Bytecode::kJumpIfTrueConstant || 389 return bytecode == Bytecode::kJumpIfTrueConstant ||
387 bytecode == Bytecode::kJumpIfFalseConstant || 390 bytecode == Bytecode::kJumpIfFalseConstant ||
388 bytecode == Bytecode::kJumpIfToBooleanTrueConstant || 391 bytecode == Bytecode::kJumpIfToBooleanTrueConstant ||
389 bytecode == Bytecode::kJumpIfToBooleanFalseConstant || 392 bytecode == Bytecode::kJumpIfToBooleanFalseConstant ||
390 bytecode == Bytecode::kJumpIfNotHoleConstant || 393 bytecode == Bytecode::kJumpIfNotHoleConstant ||
391 bytecode == Bytecode::kJumpIfNullConstant || 394 bytecode == Bytecode::kJumpIfNullConstant ||
392 bytecode == Bytecode::kJumpIfUndefinedConstant; 395 bytecode == Bytecode::kJumpIfUndefinedConstant;
393 } 396 }
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 if (value <= kMaxUInt8) { 618 if (value <= kMaxUInt8) {
616 return OperandSize::kByte; 619 return OperandSize::kByte;
617 } else if (value <= kMaxUInt16) { 620 } else if (value <= kMaxUInt16) {
618 return OperandSize::kShort; 621 return OperandSize::kShort;
619 } else { 622 } else {
620 return OperandSize::kQuad; 623 return OperandSize::kQuad;
621 } 624 }
622 } 625 }
623 626
624 // static 627 // static
625 Register Bytecodes::DecodeRegisterOperand(const uint8_t* operand_start,
626 OperandType operand_type,
627 OperandScale operand_scale) {
628 DCHECK(Bytecodes::IsRegisterOperandType(operand_type));
629 int32_t operand =
630 DecodeSignedOperand(operand_start, operand_type, operand_scale);
631 return Register::FromOperand(operand);
632 }
633
634 // static
635 int32_t Bytecodes::DecodeSignedOperand(const uint8_t* operand_start,
636 OperandType operand_type,
637 OperandScale operand_scale) {
638 DCHECK(!Bytecodes::IsUnsignedOperandType(operand_type));
639 switch (Bytecodes::SizeOfOperand(operand_type, operand_scale)) {
640 case OperandSize::kByte:
641 return static_cast<int8_t>(*operand_start);
642 case OperandSize::kShort:
643 return static_cast<int16_t>(ReadUnalignedUInt16(operand_start));
644 case OperandSize::kQuad:
645 return static_cast<int32_t>(ReadUnalignedUInt32(operand_start));
646 case OperandSize::kNone:
647 UNREACHABLE();
648 }
649 return 0;
650 }
651
652 // static
653 uint32_t Bytecodes::DecodeUnsignedOperand(const uint8_t* operand_start,
654 OperandType operand_type,
655 OperandScale operand_scale) {
656 DCHECK(Bytecodes::IsUnsignedOperandType(operand_type));
657 switch (Bytecodes::SizeOfOperand(operand_type, operand_scale)) {
658 case OperandSize::kByte:
659 return *operand_start;
660 case OperandSize::kShort:
661 return ReadUnalignedUInt16(operand_start);
662 case OperandSize::kQuad:
663 return ReadUnalignedUInt32(operand_start);
664 case OperandSize::kNone:
665 UNREACHABLE();
666 }
667 return 0;
668 }
669
670 // static
671 std::ostream& Bytecodes::Decode(std::ostream& os, const uint8_t* bytecode_start,
672 int parameter_count) {
673 Bytecode bytecode = Bytecodes::FromByte(bytecode_start[0]);
674 int prefix_offset = 0;
675 OperandScale operand_scale = OperandScale::kSingle;
676 if (IsPrefixScalingBytecode(bytecode)) {
677 prefix_offset = 1;
678 operand_scale = Bytecodes::PrefixBytecodeToOperandScale(bytecode);
679 bytecode = Bytecodes::FromByte(bytecode_start[1]);
680 }
681
682 // Prepare to print bytecode and operands as hex digits.
683 std::ios saved_format(nullptr);
684 saved_format.copyfmt(saved_format);
685 os.fill('0');
686 os.flags(std::ios::hex);
687
688 int bytecode_size = Bytecodes::Size(bytecode, operand_scale);
689 for (int i = 0; i < prefix_offset + bytecode_size; i++) {
690 os << std::setw(2) << static_cast<uint32_t>(bytecode_start[i]) << ' ';
691 }
692 os.copyfmt(saved_format);
693
694 const int kBytecodeColumnSize = 6;
695 for (int i = prefix_offset + bytecode_size; i < kBytecodeColumnSize; i++) {
696 os << " ";
697 }
698
699 os << Bytecodes::ToString(bytecode, operand_scale) << " ";
700
701 // Operands for the debug break are from the original instruction.
702 if (IsDebugBreak(bytecode)) return os;
703
704 int number_of_operands = NumberOfOperands(bytecode);
705 int range = 0;
706 for (int i = 0; i < number_of_operands; i++) {
707 OperandType op_type = GetOperandType(bytecode, i);
708 const uint8_t* operand_start =
709 &bytecode_start[prefix_offset +
710 GetOperandOffset(bytecode, i, operand_scale)];
711 switch (op_type) {
712 case interpreter::OperandType::kRegCount:
713 os << "#"
714 << DecodeUnsignedOperand(operand_start, op_type, operand_scale);
715 break;
716 case interpreter::OperandType::kIdx:
717 case interpreter::OperandType::kRuntimeId:
718 case interpreter::OperandType::kIntrinsicId:
719 os << "["
720 << DecodeUnsignedOperand(operand_start, op_type, operand_scale)
721 << "]";
722 break;
723 case interpreter::OperandType::kImm:
724 os << "[" << DecodeSignedOperand(operand_start, op_type, operand_scale)
725 << "]";
726 break;
727 case interpreter::OperandType::kFlag8:
728 os << "#"
729 << DecodeUnsignedOperand(operand_start, op_type, operand_scale);
730 break;
731 case interpreter::OperandType::kMaybeReg:
732 case interpreter::OperandType::kReg:
733 case interpreter::OperandType::kRegOut: {
734 Register reg =
735 DecodeRegisterOperand(operand_start, op_type, operand_scale);
736 os << reg.ToString(parameter_count);
737 break;
738 }
739 case interpreter::OperandType::kRegOutTriple:
740 range += 1;
741 case interpreter::OperandType::kRegOutPair:
742 case interpreter::OperandType::kRegPair: {
743 range += 1;
744 Register first_reg =
745 DecodeRegisterOperand(operand_start, op_type, operand_scale);
746 Register last_reg = Register(first_reg.index() + range);
747 os << first_reg.ToString(parameter_count) << "-"
748 << last_reg.ToString(parameter_count);
749 break;
750 }
751 case interpreter::OperandType::kNone:
752 UNREACHABLE();
753 break;
754 }
755 if (i != number_of_operands - 1) {
756 os << ", ";
757 }
758 }
759 return os;
760 }
761
762 // static
763 bool Bytecodes::BytecodeHasHandler(Bytecode bytecode, 628 bool Bytecodes::BytecodeHasHandler(Bytecode bytecode,
764 OperandScale operand_scale) { 629 OperandScale operand_scale) {
765 return operand_scale == OperandScale::kSingle || 630 return operand_scale == OperandScale::kSingle ||
766 Bytecodes::IsBytecodeWithScalableOperands(bytecode); 631 Bytecodes::IsBytecodeWithScalableOperands(bytecode);
767 } 632 }
768 633
769 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode) { 634 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode) {
770 return os << Bytecodes::ToString(bytecode); 635 return os << Bytecodes::ToString(bytecode);
771 } 636 }
772 637
773 std::ostream& operator<<(std::ostream& os, const AccumulatorUse& use) { 638 std::ostream& operator<<(std::ostream& os, const AccumulatorUse& use) {
774 return os << Bytecodes::AccumulatorUseToString(use); 639 return os << Bytecodes::AccumulatorUseToString(use);
775 } 640 }
776 641
777 std::ostream& operator<<(std::ostream& os, const OperandSize& operand_size) { 642 std::ostream& operator<<(std::ostream& os, const OperandSize& operand_size) {
778 return os << Bytecodes::OperandSizeToString(operand_size); 643 return os << Bytecodes::OperandSizeToString(operand_size);
779 } 644 }
780 645
781 std::ostream& operator<<(std::ostream& os, const OperandScale& operand_scale) { 646 std::ostream& operator<<(std::ostream& os, const OperandScale& operand_scale) {
782 return os << Bytecodes::OperandScaleToString(operand_scale); 647 return os << Bytecodes::OperandScaleToString(operand_scale);
783 } 648 }
784 649
785 std::ostream& operator<<(std::ostream& os, const OperandType& operand_type) { 650 std::ostream& operator<<(std::ostream& os, const OperandType& operand_type) {
786 return os << Bytecodes::OperandTypeToString(operand_type); 651 return os << Bytecodes::OperandTypeToString(operand_type);
787 } 652 }
788 653
789 static const int kLastParamRegisterIndex =
790 (InterpreterFrameConstants::kRegisterFileFromFp -
791 InterpreterFrameConstants::kLastParamFromFp) /
792 kPointerSize;
793 static const int kFunctionClosureRegisterIndex =
794 (InterpreterFrameConstants::kRegisterFileFromFp -
795 StandardFrameConstants::kFunctionOffset) /
796 kPointerSize;
797 static const int kCurrentContextRegisterIndex =
798 (InterpreterFrameConstants::kRegisterFileFromFp -
799 StandardFrameConstants::kContextOffset) /
800 kPointerSize;
801 static const int kNewTargetRegisterIndex =
802 (InterpreterFrameConstants::kRegisterFileFromFp -
803 InterpreterFrameConstants::kNewTargetFromFp) /
804 kPointerSize;
805 static const int kBytecodeArrayRegisterIndex =
806 (InterpreterFrameConstants::kRegisterFileFromFp -
807 InterpreterFrameConstants::kBytecodeArrayFromFp) /
808 kPointerSize;
809 static const int kBytecodeOffsetRegisterIndex =
810 (InterpreterFrameConstants::kRegisterFileFromFp -
811 InterpreterFrameConstants::kBytecodeOffsetFromFp) /
812 kPointerSize;
813 static const int kCallerPCOffsetRegisterIndex =
814 (InterpreterFrameConstants::kRegisterFileFromFp -
815 InterpreterFrameConstants::kCallerPCOffsetFromFp) /
816 kPointerSize;
817
818 Register Register::FromParameterIndex(int index, int parameter_count) {
819 DCHECK_GE(index, 0);
820 DCHECK_LT(index, parameter_count);
821 int register_index = kLastParamRegisterIndex - parameter_count + index + 1;
822 DCHECK_LT(register_index, 0);
823 return Register(register_index);
824 }
825
826 int Register::ToParameterIndex(int parameter_count) const {
827 DCHECK(is_parameter());
828 return index() - kLastParamRegisterIndex + parameter_count - 1;
829 }
830
831 Register Register::function_closure() {
832 return Register(kFunctionClosureRegisterIndex);
833 }
834
835 bool Register::is_function_closure() const {
836 return index() == kFunctionClosureRegisterIndex;
837 }
838
839 Register Register::current_context() {
840 return Register(kCurrentContextRegisterIndex);
841 }
842
843 bool Register::is_current_context() const {
844 return index() == kCurrentContextRegisterIndex;
845 }
846
847 Register Register::new_target() { return Register(kNewTargetRegisterIndex); }
848
849 bool Register::is_new_target() const {
850 return index() == kNewTargetRegisterIndex;
851 }
852
853 Register Register::bytecode_array() {
854 return Register(kBytecodeArrayRegisterIndex);
855 }
856
857 bool Register::is_bytecode_array() const {
858 return index() == kBytecodeArrayRegisterIndex;
859 }
860
861 Register Register::bytecode_offset() {
862 return Register(kBytecodeOffsetRegisterIndex);
863 }
864
865 bool Register::is_bytecode_offset() const {
866 return index() == kBytecodeOffsetRegisterIndex;
867 }
868
869 // static
870 Register Register::virtual_accumulator() {
871 return Register(kCallerPCOffsetRegisterIndex);
872 }
873
874 OperandSize Register::SizeOfOperand() const {
875 int32_t operand = ToOperand();
876 if (operand >= kMinInt8 && operand <= kMaxInt8) {
877 return OperandSize::kByte;
878 } else if (operand >= kMinInt16 && operand <= kMaxInt16) {
879 return OperandSize::kShort;
880 } else {
881 return OperandSize::kQuad;
882 }
883 }
884
885 bool Register::AreContiguous(Register reg1, Register reg2, Register reg3,
886 Register reg4, Register reg5) {
887 if (reg1.index() + 1 != reg2.index()) {
888 return false;
889 }
890 if (reg3.is_valid() && reg2.index() + 1 != reg3.index()) {
891 return false;
892 }
893 if (reg4.is_valid() && reg3.index() + 1 != reg4.index()) {
894 return false;
895 }
896 if (reg5.is_valid() && reg4.index() + 1 != reg5.index()) {
897 return false;
898 }
899 return true;
900 }
901
902 std::string Register::ToString(int parameter_count) {
903 if (is_current_context()) {
904 return std::string("<context>");
905 } else if (is_function_closure()) {
906 return std::string("<closure>");
907 } else if (is_new_target()) {
908 return std::string("<new.target>");
909 } else if (is_parameter()) {
910 int parameter_index = ToParameterIndex(parameter_count);
911 if (parameter_index == 0) {
912 return std::string("<this>");
913 } else {
914 std::ostringstream s;
915 s << "a" << parameter_index - 1;
916 return s.str();
917 }
918 } else {
919 std::ostringstream s;
920 s << "r" << index();
921 return s.str();
922 }
923 }
924
925 // static
926 uint8_t CreateObjectLiteralFlags::Encode(bool fast_clone_supported,
927 int properties_count,
928 int runtime_flags) {
929 uint8_t result = FlagsBits::encode(runtime_flags);
930 if (fast_clone_supported) {
931 STATIC_ASSERT(
932 FastCloneShallowObjectStub::kMaximumClonedProperties <=
933 1 << CreateObjectLiteralFlags::FastClonePropertiesCountBits::kShift);
934 DCHECK_LE(properties_count,
935 FastCloneShallowObjectStub::kMaximumClonedProperties);
936 result |= CreateObjectLiteralFlags::FastClonePropertiesCountBits::encode(
937 properties_count);
938 }
939 return result;
940 }
941
942 // static
943 uint8_t CreateClosureFlags::Encode(bool pretenure, bool is_function_scope) {
944 uint8_t result = PretenuredBit::encode(pretenure);
945 if (!FLAG_always_opt && !FLAG_prepare_always_opt &&
946 pretenure == NOT_TENURED && is_function_scope) {
947 result |= FastNewClosureBit::encode(true);
948 }
949 return result;
950 }
951
952 } // namespace interpreter 654 } // namespace interpreter
953 } // namespace internal 655 } // namespace internal
954 } // namespace v8 656 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecodes.h ('k') | src/interpreter/handler-table-builder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698