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 #include "src/interpreter/interpreter.h" | 5 #include "src/interpreter/interpreter.h" |
6 | 6 |
7 #include <fstream> | 7 #include <fstream> |
8 #include <memory> | 8 #include <memory> |
9 | 9 |
10 #include "src/ast/prettyprinter.h" | 10 #include "src/ast/prettyprinter.h" |
(...skipping 886 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
897 // PopContext <context> | 897 // PopContext <context> |
898 // | 898 // |
899 // Pops the current context and sets <context> as the new context. | 899 // Pops the current context and sets <context> as the new context. |
900 void Interpreter::DoPopContext(InterpreterAssembler* assembler) { | 900 void Interpreter::DoPopContext(InterpreterAssembler* assembler) { |
901 Node* reg_index = __ BytecodeOperandReg(0); | 901 Node* reg_index = __ BytecodeOperandReg(0); |
902 Node* context = __ LoadRegister(reg_index); | 902 Node* context = __ LoadRegister(reg_index); |
903 __ SetContext(context); | 903 __ SetContext(context); |
904 __ Dispatch(); | 904 __ Dispatch(); |
905 } | 905 } |
906 | 906 |
907 // TODO(mythria): Remove this function once all BinaryOps record type feedback. | 907 // TODO(mythria): Remove this function once all BinaryOps record type feedback. |
rmcilroy
2016/10/06 15:00:13
Please update this comment (BinaryOps -> CompareOp
| |
908 template <class Generator> | 908 void Interpreter::DoCompareOp(Token::Value compare_op, |
909 void Interpreter::DoBinaryOp(InterpreterAssembler* assembler) { | 909 InterpreterAssembler* assembler) { |
910 Node* reg_index = __ BytecodeOperandReg(0); | 910 Node* reg_index = __ BytecodeOperandReg(0); |
911 Node* lhs = __ LoadRegister(reg_index); | 911 Node* lhs = __ LoadRegister(reg_index); |
912 Node* rhs = __ GetAccumulator(); | 912 Node* rhs = __ GetAccumulator(); |
913 Node* context = __ GetContext(); | 913 Node* context = __ GetContext(); |
914 Node* result = Generator::Generate(assembler, lhs, rhs, context); | 914 Node* result; |
915 switch (compare_op) { | |
916 case Token::IN: | |
917 result = assembler->HasProperty(rhs, lhs, context); | |
918 break; | |
919 case Token::INSTANCEOF: | |
920 result = assembler->InstanceOf(lhs, rhs, context); | |
921 break; | |
922 default: | |
923 UNREACHABLE(); | |
924 } | |
915 __ SetAccumulator(result); | 925 __ SetAccumulator(result); |
916 __ Dispatch(); | 926 __ Dispatch(); |
917 } | 927 } |
918 | 928 |
919 template <class Generator> | 929 template <class Generator> |
920 void Interpreter::DoBinaryOpWithFeedback(InterpreterAssembler* assembler) { | 930 void Interpreter::DoBinaryOpWithFeedback(InterpreterAssembler* assembler) { |
921 Node* reg_index = __ BytecodeOperandReg(0); | 931 Node* reg_index = __ BytecodeOperandReg(0); |
922 Node* lhs = __ LoadRegister(reg_index); | 932 Node* lhs = __ LoadRegister(reg_index); |
923 Node* rhs = __ GetAccumulator(); | 933 Node* rhs = __ GetAccumulator(); |
924 Node* context = __ GetContext(); | 934 Node* context = __ GetContext(); |
925 Node* slot_index = __ BytecodeOperandIdx(1); | 935 Node* slot_index = __ BytecodeOperandIdx(1); |
926 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 936 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
927 Node* result = Generator::Generate(assembler, lhs, rhs, slot_index, | 937 Node* result = Generator::Generate(assembler, lhs, rhs, slot_index, |
928 type_feedback_vector, context); | 938 type_feedback_vector, context); |
929 __ SetAccumulator(result); | 939 __ SetAccumulator(result); |
930 __ Dispatch(); | 940 __ Dispatch(); |
931 } | 941 } |
932 | 942 |
933 template <class Generator> | 943 void Interpreter::DoCompareOpWithFeedback(Token::Value compare_op, |
934 void Interpreter::DoCompareOpWithFeedback(InterpreterAssembler* assembler) { | 944 InterpreterAssembler* assembler) { |
935 Node* reg_index = __ BytecodeOperandReg(0); | 945 Node* reg_index = __ BytecodeOperandReg(0); |
936 Node* lhs = __ LoadRegister(reg_index); | 946 Node* lhs = __ LoadRegister(reg_index); |
937 Node* rhs = __ GetAccumulator(); | 947 Node* rhs = __ GetAccumulator(); |
938 Node* context = __ GetContext(); | 948 Node* context = __ GetContext(); |
939 Node* slot_index = __ BytecodeOperandIdx(1); | 949 Node* slot_index = __ BytecodeOperandIdx(1); |
940 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 950 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
941 | 951 |
942 // TODO(interpreter): the only reason this check is here is because we | 952 // TODO(interpreter): the only reason this check is here is because we |
943 // sometimes emit comparisons that shouldn't collect feedback (e.g. | 953 // sometimes emit comparisons that shouldn't collect feedback (e.g. |
944 // try-finally blocks and generators), and we could get rid of this by | 954 // try-finally blocks and generators), and we could get rid of this by |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
992 __ Int32Constant(CompareOperationFeedback::kSignedSmall))); | 1002 __ Int32Constant(CompareOperationFeedback::kSignedSmall))); |
993 __ Goto(&do_compare); | 1003 __ Goto(&do_compare); |
994 } | 1004 } |
995 | 1005 |
996 __ Bind(&do_compare); | 1006 __ Bind(&do_compare); |
997 __ UpdateFeedback(var_type_feedback.value(), type_feedback_vector, | 1007 __ UpdateFeedback(var_type_feedback.value(), type_feedback_vector, |
998 slot_index); | 1008 slot_index); |
999 __ Goto(&skip_feedback_update); | 1009 __ Goto(&skip_feedback_update); |
1000 | 1010 |
1001 __ Bind(&skip_feedback_update); | 1011 __ Bind(&skip_feedback_update); |
1002 Node* result = Generator::Generate(assembler, lhs, rhs, context); | 1012 Node* result; |
1013 switch (compare_op) { | |
1014 case Token::EQ: | |
1015 result = assembler->Equal(CodeStubAssembler::kDontNegateResult, lhs, rhs, | |
1016 context); | |
1017 break; | |
1018 case Token::NE: | |
1019 result = | |
1020 assembler->Equal(CodeStubAssembler::kNegateResult, lhs, rhs, context); | |
1021 break; | |
1022 case Token::EQ_STRICT: | |
1023 result = assembler->StrictEqual(CodeStubAssembler::kDontNegateResult, lhs, | |
1024 rhs, context); | |
1025 break; | |
1026 case Token::LT: | |
1027 result = assembler->RelationalComparison(CodeStubAssembler::kLessThan, | |
1028 lhs, rhs, context); | |
1029 break; | |
1030 case Token::GT: | |
1031 result = assembler->RelationalComparison(CodeStubAssembler::kGreaterThan, | |
1032 lhs, rhs, context); | |
1033 break; | |
1034 case Token::LTE: | |
1035 result = assembler->RelationalComparison( | |
1036 CodeStubAssembler::kLessThanOrEqual, lhs, rhs, context); | |
1037 break; | |
1038 case Token::GTE: | |
1039 result = assembler->RelationalComparison( | |
1040 CodeStubAssembler::kGreaterThanOrEqual, lhs, rhs, context); | |
1041 break; | |
1042 default: | |
1043 UNREACHABLE(); | |
1044 } | |
1003 __ SetAccumulator(result); | 1045 __ SetAccumulator(result); |
1004 __ Dispatch(); | 1046 __ Dispatch(); |
1005 } | 1047 } |
1006 | 1048 |
1007 // Add <src> | 1049 // Add <src> |
1008 // | 1050 // |
1009 // Add register <src> to accumulator. | 1051 // Add register <src> to accumulator. |
1010 void Interpreter::DoAdd(InterpreterAssembler* assembler) { | 1052 void Interpreter::DoAdd(InterpreterAssembler* assembler) { |
1011 DoBinaryOpWithFeedback<AddWithFeedbackStub>(assembler); | 1053 DoBinaryOpWithFeedback<AddWithFeedbackStub>(assembler); |
1012 } | 1054 } |
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1513 __ Bind(&end); | 1555 __ Bind(&end); |
1514 __ SetAccumulator(result.value()); | 1556 __ SetAccumulator(result.value()); |
1515 __ Dispatch(); | 1557 __ Dispatch(); |
1516 } | 1558 } |
1517 | 1559 |
1518 // TypeOf | 1560 // TypeOf |
1519 // | 1561 // |
1520 // Load the accumulator with the string representating type of the | 1562 // Load the accumulator with the string representating type of the |
1521 // object in the accumulator. | 1563 // object in the accumulator. |
1522 void Interpreter::DoTypeOf(InterpreterAssembler* assembler) { | 1564 void Interpreter::DoTypeOf(InterpreterAssembler* assembler) { |
1523 DoUnaryOp<TypeofStub>(assembler); | 1565 struct Generator { |
1566 static Node* Generate(InterpreterAssembler* assembler, Node* value, | |
1567 Node* context) { | |
1568 return assembler->Typeof(value, context); | |
1569 } | |
1570 }; | |
rmcilroy
2016/10/06 15:00:13
TypeOf is the only non-feedback unary op, please j
| |
1571 DoUnaryOp<Generator>(assembler); | |
1524 } | 1572 } |
1525 | 1573 |
1526 void Interpreter::DoDelete(Runtime::FunctionId function_id, | 1574 void Interpreter::DoDelete(Runtime::FunctionId function_id, |
1527 InterpreterAssembler* assembler) { | 1575 InterpreterAssembler* assembler) { |
1528 Node* reg_index = __ BytecodeOperandReg(0); | 1576 Node* reg_index = __ BytecodeOperandReg(0); |
1529 Node* object = __ LoadRegister(reg_index); | 1577 Node* object = __ LoadRegister(reg_index); |
1530 Node* key = __ GetAccumulator(); | 1578 Node* key = __ GetAccumulator(); |
1531 Node* context = __ GetContext(); | 1579 Node* context = __ GetContext(); |
1532 Node* result = __ CallRuntime(function_id, context, object, key); | 1580 Node* result = __ CallRuntime(function_id, context, object, key); |
1533 __ SetAccumulator(result); | 1581 __ SetAccumulator(result); |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1691 Node* result = __ CallConstruct(constructor, context, new_target, first_arg, | 1739 Node* result = __ CallConstruct(constructor, context, new_target, first_arg, |
1692 args_count, slot_id, type_feedback_vector); | 1740 args_count, slot_id, type_feedback_vector); |
1693 __ SetAccumulator(result); | 1741 __ SetAccumulator(result); |
1694 __ Dispatch(); | 1742 __ Dispatch(); |
1695 } | 1743 } |
1696 | 1744 |
1697 // TestEqual <src> | 1745 // TestEqual <src> |
1698 // | 1746 // |
1699 // Test if the value in the <src> register equals the accumulator. | 1747 // Test if the value in the <src> register equals the accumulator. |
1700 void Interpreter::DoTestEqual(InterpreterAssembler* assembler) { | 1748 void Interpreter::DoTestEqual(InterpreterAssembler* assembler) { |
1701 DoCompareOpWithFeedback<EqualStub>(assembler); | 1749 DoCompareOpWithFeedback(Token::Value::EQ, assembler); |
1702 } | 1750 } |
1703 | 1751 |
1704 // TestNotEqual <src> | 1752 // TestNotEqual <src> |
1705 // | 1753 // |
1706 // Test if the value in the <src> register is not equal to the accumulator. | 1754 // Test if the value in the <src> register is not equal to the accumulator. |
1707 void Interpreter::DoTestNotEqual(InterpreterAssembler* assembler) { | 1755 void Interpreter::DoTestNotEqual(InterpreterAssembler* assembler) { |
1708 DoCompareOpWithFeedback<NotEqualStub>(assembler); | 1756 DoCompareOpWithFeedback(Token::Value::NE, assembler); |
1709 } | 1757 } |
1710 | 1758 |
1711 // TestEqualStrict <src> | 1759 // TestEqualStrict <src> |
1712 // | 1760 // |
1713 // Test if the value in the <src> register is strictly equal to the accumulator. | 1761 // Test if the value in the <src> register is strictly equal to the accumulator. |
1714 void Interpreter::DoTestEqualStrict(InterpreterAssembler* assembler) { | 1762 void Interpreter::DoTestEqualStrict(InterpreterAssembler* assembler) { |
1715 DoCompareOpWithFeedback<StrictEqualStub>(assembler); | 1763 DoCompareOpWithFeedback(Token::Value::EQ_STRICT, assembler); |
1716 } | 1764 } |
1717 | 1765 |
1718 // TestLessThan <src> | 1766 // TestLessThan <src> |
1719 // | 1767 // |
1720 // Test if the value in the <src> register is less than the accumulator. | 1768 // Test if the value in the <src> register is less than the accumulator. |
1721 void Interpreter::DoTestLessThan(InterpreterAssembler* assembler) { | 1769 void Interpreter::DoTestLessThan(InterpreterAssembler* assembler) { |
1722 DoCompareOpWithFeedback<LessThanStub>(assembler); | 1770 DoCompareOpWithFeedback(Token::Value::LT, assembler); |
1723 } | 1771 } |
1724 | 1772 |
1725 // TestGreaterThan <src> | 1773 // TestGreaterThan <src> |
1726 // | 1774 // |
1727 // Test if the value in the <src> register is greater than the accumulator. | 1775 // Test if the value in the <src> register is greater than the accumulator. |
1728 void Interpreter::DoTestGreaterThan(InterpreterAssembler* assembler) { | 1776 void Interpreter::DoTestGreaterThan(InterpreterAssembler* assembler) { |
1729 DoCompareOpWithFeedback<GreaterThanStub>(assembler); | 1777 DoCompareOpWithFeedback(Token::Value::GT, assembler); |
1730 } | 1778 } |
1731 | 1779 |
1732 // TestLessThanOrEqual <src> | 1780 // TestLessThanOrEqual <src> |
1733 // | 1781 // |
1734 // Test if the value in the <src> register is less than or equal to the | 1782 // Test if the value in the <src> register is less than or equal to the |
1735 // accumulator. | 1783 // accumulator. |
1736 void Interpreter::DoTestLessThanOrEqual(InterpreterAssembler* assembler) { | 1784 void Interpreter::DoTestLessThanOrEqual(InterpreterAssembler* assembler) { |
1737 DoCompareOpWithFeedback<LessThanOrEqualStub>(assembler); | 1785 DoCompareOpWithFeedback(Token::Value::LTE, assembler); |
1738 } | 1786 } |
1739 | 1787 |
1740 // TestGreaterThanOrEqual <src> | 1788 // TestGreaterThanOrEqual <src> |
1741 // | 1789 // |
1742 // Test if the value in the <src> register is greater than or equal to the | 1790 // Test if the value in the <src> register is greater than or equal to the |
1743 // accumulator. | 1791 // accumulator. |
1744 void Interpreter::DoTestGreaterThanOrEqual(InterpreterAssembler* assembler) { | 1792 void Interpreter::DoTestGreaterThanOrEqual(InterpreterAssembler* assembler) { |
1745 DoCompareOpWithFeedback<GreaterThanOrEqualStub>(assembler); | 1793 DoCompareOpWithFeedback(Token::Value::GTE, assembler); |
1746 } | 1794 } |
1747 | 1795 |
1748 // TestIn <src> | 1796 // TestIn <src> |
1749 // | 1797 // |
1750 // Test if the object referenced by the register operand is a property of the | 1798 // Test if the object referenced by the register operand is a property of the |
1751 // object referenced by the accumulator. | 1799 // object referenced by the accumulator. |
1752 void Interpreter::DoTestIn(InterpreterAssembler* assembler) { | 1800 void Interpreter::DoTestIn(InterpreterAssembler* assembler) { |
1753 DoBinaryOp<HasPropertyStub>(assembler); | 1801 DoCompareOp(Token::IN, assembler); |
1754 } | 1802 } |
1755 | 1803 |
1756 // TestInstanceOf <src> | 1804 // TestInstanceOf <src> |
1757 // | 1805 // |
1758 // Test if the object referenced by the <src> register is an an instance of type | 1806 // Test if the object referenced by the <src> register is an an instance of type |
1759 // referenced by the accumulator. | 1807 // referenced by the accumulator. |
1760 void Interpreter::DoTestInstanceOf(InterpreterAssembler* assembler) { | 1808 void Interpreter::DoTestInstanceOf(InterpreterAssembler* assembler) { |
1761 DoBinaryOp<InstanceOfStub>(assembler); | 1809 DoCompareOp(Token::INSTANCEOF, assembler); |
1762 } | 1810 } |
1763 | 1811 |
1764 // Jump <imm> | 1812 // Jump <imm> |
1765 // | 1813 // |
1766 // Jump by number of bytes represented by the immediate operand |imm|. | 1814 // Jump by number of bytes represented by the immediate operand |imm|. |
1767 void Interpreter::DoJump(InterpreterAssembler* assembler) { | 1815 void Interpreter::DoJump(InterpreterAssembler* assembler) { |
1768 Node* relative_jump = __ BytecodeOperandImm(0); | 1816 Node* relative_jump = __ BytecodeOperandImm(0); |
1769 __ Jump(relative_jump); | 1817 __ Jump(relative_jump); |
1770 } | 1818 } |
1771 | 1819 |
(...skipping 826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2598 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, | 2646 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, |
2599 __ SmiTag(new_state)); | 2647 __ SmiTag(new_state)); |
2600 __ SetAccumulator(old_state); | 2648 __ SetAccumulator(old_state); |
2601 | 2649 |
2602 __ Dispatch(); | 2650 __ Dispatch(); |
2603 } | 2651 } |
2604 | 2652 |
2605 } // namespace interpreter | 2653 } // namespace interpreter |
2606 } // namespace internal | 2654 } // namespace internal |
2607 } // namespace v8 | 2655 } // namespace v8 |
OLD | NEW |