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 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 |