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 913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
924 Node* context = __ GetContext(); | 924 Node* context = __ GetContext(); |
925 Node* slot_index = __ BytecodeOperandIdx(1); | 925 Node* slot_index = __ BytecodeOperandIdx(1); |
926 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 926 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
927 Node* result = Generator::Generate(assembler, lhs, rhs, slot_index, | 927 Node* result = Generator::Generate(assembler, lhs, rhs, slot_index, |
928 type_feedback_vector, context); | 928 type_feedback_vector, context); |
929 __ SetAccumulator(result); | 929 __ SetAccumulator(result); |
930 __ Dispatch(); | 930 __ Dispatch(); |
931 } | 931 } |
932 | 932 |
933 template <class Generator> | 933 template <class Generator> |
934 void Interpreter::DoCompareOpWithFeedback(InterpreterAssembler* assembler) { | 934 void Interpreter::DoCompareOpWithFeedback(InterpreterAssembler* assembler, |
935 Generator generator) { | |
935 Node* reg_index = __ BytecodeOperandReg(0); | 936 Node* reg_index = __ BytecodeOperandReg(0); |
936 Node* lhs = __ LoadRegister(reg_index); | 937 Node* lhs = __ LoadRegister(reg_index); |
937 Node* rhs = __ GetAccumulator(); | 938 Node* rhs = __ GetAccumulator(); |
938 Node* context = __ GetContext(); | 939 Node* context = __ GetContext(); |
939 Node* slot_index = __ BytecodeOperandIdx(1); | 940 Node* slot_index = __ BytecodeOperandIdx(1); |
940 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 941 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
941 | 942 |
942 // TODO(interpreter): the only reason this check is here is because we | 943 // TODO(interpreter): the only reason this check is here is because we |
943 // sometimes emit comparisons that shouldn't collect feedback (e.g. | 944 // sometimes emit comparisons that shouldn't collect feedback (e.g. |
944 // try-finally blocks and generators), and we could get rid of this by | 945 // 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))); | 993 __ Int32Constant(CompareOperationFeedback::kSignedSmall))); |
993 __ Goto(&do_compare); | 994 __ Goto(&do_compare); |
994 } | 995 } |
995 | 996 |
996 __ Bind(&do_compare); | 997 __ Bind(&do_compare); |
997 __ UpdateFeedback(var_type_feedback.value(), type_feedback_vector, | 998 __ UpdateFeedback(var_type_feedback.value(), type_feedback_vector, |
998 slot_index); | 999 slot_index); |
999 __ Goto(&skip_feedback_update); | 1000 __ Goto(&skip_feedback_update); |
1000 | 1001 |
1001 __ Bind(&skip_feedback_update); | 1002 __ Bind(&skip_feedback_update); |
1002 Node* result = Generator::Generate(assembler, lhs, rhs, context); | 1003 Node* result = generator(assembler, lhs, rhs, context); |
1003 __ SetAccumulator(result); | 1004 __ SetAccumulator(result); |
1004 __ Dispatch(); | 1005 __ Dispatch(); |
1005 } | 1006 } |
1006 | 1007 |
1007 // Add <src> | 1008 // Add <src> |
1008 // | 1009 // |
1009 // Add register <src> to accumulator. | 1010 // Add register <src> to accumulator. |
1010 void Interpreter::DoAdd(InterpreterAssembler* assembler) { | 1011 void Interpreter::DoAdd(InterpreterAssembler* assembler) { |
1011 DoBinaryOpWithFeedback<AddWithFeedbackStub>(assembler); | 1012 DoBinaryOpWithFeedback<AddWithFeedbackStub>(assembler); |
1012 } | 1013 } |
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1513 __ Bind(&end); | 1514 __ Bind(&end); |
1514 __ SetAccumulator(result.value()); | 1515 __ SetAccumulator(result.value()); |
1515 __ Dispatch(); | 1516 __ Dispatch(); |
1516 } | 1517 } |
1517 | 1518 |
1518 // TypeOf | 1519 // TypeOf |
1519 // | 1520 // |
1520 // Load the accumulator with the string representating type of the | 1521 // Load the accumulator with the string representating type of the |
1521 // object in the accumulator. | 1522 // object in the accumulator. |
1522 void Interpreter::DoTypeOf(InterpreterAssembler* assembler) { | 1523 void Interpreter::DoTypeOf(InterpreterAssembler* assembler) { |
1523 DoUnaryOp<TypeofStub>(assembler); | 1524 struct Generator { |
1525 static Node* Generate(InterpreterAssembler* assembler, Node* value, | |
1526 Node* context) { | |
1527 return assembler->Typeof(value, context); | |
1528 } | |
1529 }; | |
1530 DoUnaryOp<Generator>(assembler); | |
1524 } | 1531 } |
1525 | 1532 |
1526 void Interpreter::DoDelete(Runtime::FunctionId function_id, | 1533 void Interpreter::DoDelete(Runtime::FunctionId function_id, |
1527 InterpreterAssembler* assembler) { | 1534 InterpreterAssembler* assembler) { |
1528 Node* reg_index = __ BytecodeOperandReg(0); | 1535 Node* reg_index = __ BytecodeOperandReg(0); |
1529 Node* object = __ LoadRegister(reg_index); | 1536 Node* object = __ LoadRegister(reg_index); |
1530 Node* key = __ GetAccumulator(); | 1537 Node* key = __ GetAccumulator(); |
1531 Node* context = __ GetContext(); | 1538 Node* context = __ GetContext(); |
1532 Node* result = __ CallRuntime(function_id, context, object, key); | 1539 Node* result = __ CallRuntime(function_id, context, object, key); |
1533 __ SetAccumulator(result); | 1540 __ 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, | 1698 Node* result = __ CallConstruct(constructor, context, new_target, first_arg, |
1692 args_count, slot_id, type_feedback_vector); | 1699 args_count, slot_id, type_feedback_vector); |
1693 __ SetAccumulator(result); | 1700 __ SetAccumulator(result); |
1694 __ Dispatch(); | 1701 __ Dispatch(); |
1695 } | 1702 } |
1696 | 1703 |
1697 // TestEqual <src> | 1704 // TestEqual <src> |
1698 // | 1705 // |
1699 // Test if the value in the <src> register equals the accumulator. | 1706 // Test if the value in the <src> register equals the accumulator. |
1700 void Interpreter::DoTestEqual(InterpreterAssembler* assembler) { | 1707 void Interpreter::DoTestEqual(InterpreterAssembler* assembler) { |
1701 DoCompareOpWithFeedback<EqualStub>(assembler); | 1708 DoCompareOpWithFeedback(assembler, [](CodeStubAssembler* assembler, Node* lhs, |
1709 Node* rhs, Node* context) { | |
1710 return assembler->Equal(CodeStubAssembler::kDontNegateResult, lhs, rhs, | |
1711 context); | |
rmcilroy
2016/10/05 17:20:52
I'm not keen on this approach of building a genera
| |
1712 }); | |
1702 } | 1713 } |
1703 | 1714 |
1704 // TestNotEqual <src> | 1715 // TestNotEqual <src> |
1705 // | 1716 // |
1706 // Test if the value in the <src> register is not equal to the accumulator. | 1717 // Test if the value in the <src> register is not equal to the accumulator. |
1707 void Interpreter::DoTestNotEqual(InterpreterAssembler* assembler) { | 1718 void Interpreter::DoTestNotEqual(InterpreterAssembler* assembler) { |
1708 DoCompareOpWithFeedback<NotEqualStub>(assembler); | 1719 DoCompareOpWithFeedback(assembler, [](CodeStubAssembler* assembler, Node* lhs, |
1720 Node* rhs, Node* context) { | |
1721 return assembler->Equal(CodeStubAssembler::kNegateResult, lhs, rhs, | |
1722 context); | |
1723 }); | |
1709 } | 1724 } |
1710 | 1725 |
1711 // TestEqualStrict <src> | 1726 // TestEqualStrict <src> |
1712 // | 1727 // |
1713 // Test if the value in the <src> register is strictly equal to the accumulator. | 1728 // Test if the value in the <src> register is strictly equal to the accumulator. |
1714 void Interpreter::DoTestEqualStrict(InterpreterAssembler* assembler) { | 1729 void Interpreter::DoTestEqualStrict(InterpreterAssembler* assembler) { |
1715 DoCompareOpWithFeedback<StrictEqualStub>(assembler); | 1730 DoCompareOpWithFeedback(assembler, [](CodeStubAssembler* assembler, Node* lhs, |
1731 Node* rhs, Node* context) { | |
1732 return assembler->StrictEqual(CodeStubAssembler::kDontNegateResult, lhs, | |
1733 rhs, context); | |
1734 }); | |
1716 } | 1735 } |
1717 | 1736 |
1718 // TestLessThan <src> | 1737 // TestLessThan <src> |
1719 // | 1738 // |
1720 // Test if the value in the <src> register is less than the accumulator. | 1739 // Test if the value in the <src> register is less than the accumulator. |
1721 void Interpreter::DoTestLessThan(InterpreterAssembler* assembler) { | 1740 void Interpreter::DoTestLessThan(InterpreterAssembler* assembler) { |
1722 DoCompareOpWithFeedback<LessThanStub>(assembler); | 1741 DoCompareOpWithFeedback(assembler, [](CodeStubAssembler* assembler, Node* lhs, |
1742 Node* rhs, Node* context) { | |
1743 return assembler->RelationalComparison(CodeStubAssembler::kLessThan, lhs, | |
1744 rhs, context); | |
1745 }); | |
1723 } | 1746 } |
1724 | 1747 |
1725 // TestGreaterThan <src> | 1748 // TestGreaterThan <src> |
1726 // | 1749 // |
1727 // Test if the value in the <src> register is greater than the accumulator. | 1750 // Test if the value in the <src> register is greater than the accumulator. |
1728 void Interpreter::DoTestGreaterThan(InterpreterAssembler* assembler) { | 1751 void Interpreter::DoTestGreaterThan(InterpreterAssembler* assembler) { |
1729 DoCompareOpWithFeedback<GreaterThanStub>(assembler); | 1752 DoCompareOpWithFeedback(assembler, [](CodeStubAssembler* assembler, Node* lhs, |
1753 Node* rhs, Node* context) { | |
1754 return assembler->RelationalComparison(CodeStubAssembler::kGreaterThan, lhs, | |
1755 rhs, context); | |
1756 }); | |
1730 } | 1757 } |
1731 | 1758 |
1732 // TestLessThanOrEqual <src> | 1759 // TestLessThanOrEqual <src> |
1733 // | 1760 // |
1734 // Test if the value in the <src> register is less than or equal to the | 1761 // Test if the value in the <src> register is less than or equal to the |
1735 // accumulator. | 1762 // accumulator. |
1736 void Interpreter::DoTestLessThanOrEqual(InterpreterAssembler* assembler) { | 1763 void Interpreter::DoTestLessThanOrEqual(InterpreterAssembler* assembler) { |
1737 DoCompareOpWithFeedback<LessThanOrEqualStub>(assembler); | 1764 DoCompareOpWithFeedback(assembler, [](CodeStubAssembler* assembler, Node* lhs, |
1765 Node* rhs, Node* context) { | |
1766 return assembler->RelationalComparison(CodeStubAssembler::kLessThanOrEqual, | |
1767 lhs, rhs, context); | |
1768 }); | |
1738 } | 1769 } |
1739 | 1770 |
1740 // TestGreaterThanOrEqual <src> | 1771 // TestGreaterThanOrEqual <src> |
1741 // | 1772 // |
1742 // Test if the value in the <src> register is greater than or equal to the | 1773 // Test if the value in the <src> register is greater than or equal to the |
1743 // accumulator. | 1774 // accumulator. |
1744 void Interpreter::DoTestGreaterThanOrEqual(InterpreterAssembler* assembler) { | 1775 void Interpreter::DoTestGreaterThanOrEqual(InterpreterAssembler* assembler) { |
1745 DoCompareOpWithFeedback<GreaterThanOrEqualStub>(assembler); | 1776 DoCompareOpWithFeedback(assembler, [](CodeStubAssembler* assembler, Node* lhs, |
1777 Node* rhs, Node* context) { | |
1778 return assembler->RelationalComparison( | |
1779 CodeStubAssembler::kGreaterThanOrEqual, lhs, rhs, context); | |
1780 }); | |
1746 } | 1781 } |
1747 | 1782 |
1748 // TestIn <src> | 1783 // TestIn <src> |
1749 // | 1784 // |
1750 // Test if the object referenced by the register operand is a property of the | 1785 // Test if the object referenced by the register operand is a property of the |
1751 // object referenced by the accumulator. | 1786 // object referenced by the accumulator. |
1752 void Interpreter::DoTestIn(InterpreterAssembler* assembler) { | 1787 void Interpreter::DoTestIn(InterpreterAssembler* assembler) { |
1753 DoBinaryOp<HasPropertyStub>(assembler); | 1788 struct Generator { |
1789 static Node* Generate(InterpreterAssembler* assembler, compiler::Node* key, | |
1790 compiler::Node* object, compiler::Node* context) { | |
1791 return assembler->HasProperty(object, key, context, | |
1792 Runtime::kHasProperty); | |
1793 } | |
1794 }; | |
1795 DoBinaryOp<Generator>(assembler); | |
rmcilroy
2016/10/05 17:20:52
Ditto for DoBinaryOp (maybe these should be callin
| |
1754 } | 1796 } |
1755 | 1797 |
1756 // TestInstanceOf <src> | 1798 // TestInstanceOf <src> |
1757 // | 1799 // |
1758 // Test if the object referenced by the <src> register is an an instance of type | 1800 // Test if the object referenced by the <src> register is an an instance of type |
1759 // referenced by the accumulator. | 1801 // referenced by the accumulator. |
1760 void Interpreter::DoTestInstanceOf(InterpreterAssembler* assembler) { | 1802 void Interpreter::DoTestInstanceOf(InterpreterAssembler* assembler) { |
1761 DoBinaryOp<InstanceOfStub>(assembler); | 1803 struct Generator { |
1804 static Node* Generate(InterpreterAssembler* assembler, | |
1805 compiler::Node* object, compiler::Node* callable, | |
1806 compiler::Node* context) { | |
1807 return assembler->InstanceOf(object, callable, context); | |
1808 } | |
1809 }; | |
1810 DoBinaryOp<Generator>(assembler); | |
1762 } | 1811 } |
1763 | 1812 |
1764 // Jump <imm> | 1813 // Jump <imm> |
1765 // | 1814 // |
1766 // Jump by number of bytes represented by the immediate operand |imm|. | 1815 // Jump by number of bytes represented by the immediate operand |imm|. |
1767 void Interpreter::DoJump(InterpreterAssembler* assembler) { | 1816 void Interpreter::DoJump(InterpreterAssembler* assembler) { |
1768 Node* relative_jump = __ BytecodeOperandImm(0); | 1817 Node* relative_jump = __ BytecodeOperandImm(0); |
1769 __ Jump(relative_jump); | 1818 __ Jump(relative_jump); |
1770 } | 1819 } |
1771 | 1820 |
(...skipping 826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2598 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, | 2647 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, |
2599 __ SmiTag(new_state)); | 2648 __ SmiTag(new_state)); |
2600 __ SetAccumulator(old_state); | 2649 __ SetAccumulator(old_state); |
2601 | 2650 |
2602 __ Dispatch(); | 2651 __ Dispatch(); |
2603 } | 2652 } |
2604 | 2653 |
2605 } // namespace interpreter | 2654 } // namespace interpreter |
2606 } // namespace internal | 2655 } // namespace internal |
2607 } // namespace v8 | 2656 } // namespace v8 |
OLD | NEW |