Chromium Code Reviews| 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 |