OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1320 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax); | 1320 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax); |
1321 __ j(not_equal, miss); | 1321 __ j(not_equal, miss); |
1322 } else { | 1322 } else { |
1323 __ Cmp(rdi, Handle<JSFunction>(function)); | 1323 __ Cmp(rdi, Handle<JSFunction>(function)); |
1324 __ j(not_equal, miss); | 1324 __ j(not_equal, miss); |
1325 } | 1325 } |
1326 } | 1326 } |
1327 | 1327 |
1328 | 1328 |
1329 MaybeObject* CallStubCompiler::GenerateMissBranch() { | 1329 MaybeObject* CallStubCompiler::GenerateMissBranch() { |
1330 MaybeObject* maybe_obj = | 1330 MaybeObject* maybe_obj = StubCache::ComputeCallMiss(arguments().immediate(), |
1331 StubCache::ComputeCallMiss(arguments().immediate(), kind_); | 1331 kind_); |
1332 Object* obj; | 1332 Object* obj; |
1333 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1333 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
1334 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); | 1334 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); |
1335 return obj; | 1335 return obj; |
1336 } | 1336 } |
1337 | 1337 |
1338 | 1338 |
1339 MaybeObject* CallStubCompiler::CompileCallField(JSObject* object, | 1339 MaybeObject* CallStubCompiler::CompileCallField(JSObject* object, |
1340 JSObject* holder, | 1340 JSObject* holder, |
1341 int index, | 1341 int index, |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1653 // -- ... | 1653 // -- ... |
1654 // -- rsp[(argc + 1) * 8] : receiver | 1654 // -- rsp[(argc + 1) * 8] : receiver |
1655 // ----------------------------------- | 1655 // ----------------------------------- |
1656 | 1656 |
1657 // If object is not a string, bail out to regular call. | 1657 // If object is not a string, bail out to regular call. |
1658 if (!object->IsString() || cell != NULL) return Heap::undefined_value(); | 1658 if (!object->IsString() || cell != NULL) return Heap::undefined_value(); |
1659 | 1659 |
1660 const int argc = arguments().immediate(); | 1660 const int argc = arguments().immediate(); |
1661 | 1661 |
1662 Label miss; | 1662 Label miss; |
| 1663 Label name_miss; |
1663 Label index_out_of_range; | 1664 Label index_out_of_range; |
| 1665 Label* index_out_of_range_label = &index_out_of_range; |
1664 | 1666 |
1665 GenerateNameCheck(name, &miss); | 1667 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) { |
| 1668 index_out_of_range_label = &miss; |
| 1669 } |
| 1670 |
| 1671 GenerateNameCheck(name, &name_miss); |
1666 | 1672 |
1667 // Check that the maps starting from the prototype haven't changed. | 1673 // Check that the maps starting from the prototype haven't changed. |
1668 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 1674 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
1669 Context::STRING_FUNCTION_INDEX, | 1675 Context::STRING_FUNCTION_INDEX, |
1670 rax, | 1676 rax, |
1671 &miss); | 1677 &miss); |
1672 ASSERT(object != holder); | 1678 ASSERT(object != holder); |
1673 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, | 1679 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, |
1674 rbx, rdx, rdi, name, &miss); | 1680 rbx, rdx, rdi, name, &miss); |
1675 | 1681 |
1676 Register receiver = rbx; | 1682 Register receiver = rbx; |
1677 Register index = rdi; | 1683 Register index = rdi; |
1678 Register scratch = rdx; | 1684 Register scratch = rdx; |
1679 Register result = rax; | 1685 Register result = rax; |
1680 __ movq(receiver, Operand(rsp, (argc + 1) * kPointerSize)); | 1686 __ movq(receiver, Operand(rsp, (argc + 1) * kPointerSize)); |
1681 if (argc > 0) { | 1687 if (argc > 0) { |
1682 __ movq(index, Operand(rsp, (argc - 0) * kPointerSize)); | 1688 __ movq(index, Operand(rsp, (argc - 0) * kPointerSize)); |
1683 } else { | 1689 } else { |
1684 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); | 1690 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); |
1685 } | 1691 } |
1686 | 1692 |
1687 StringCharCodeAtGenerator char_code_at_generator(receiver, | 1693 StringCharCodeAtGenerator char_code_at_generator(receiver, |
1688 index, | 1694 index, |
1689 scratch, | 1695 scratch, |
1690 result, | 1696 result, |
1691 &miss, // When not a string. | 1697 &miss, // When not a string. |
1692 &miss, // When not a number. | 1698 &miss, // When not a number. |
1693 &index_out_of_range, | 1699 index_out_of_range_label, |
1694 STRING_INDEX_IS_NUMBER); | 1700 STRING_INDEX_IS_NUMBER); |
1695 char_code_at_generator.GenerateFast(masm()); | 1701 char_code_at_generator.GenerateFast(masm()); |
1696 __ ret((argc + 1) * kPointerSize); | 1702 __ ret((argc + 1) * kPointerSize); |
1697 | 1703 |
1698 StubRuntimeCallHelper call_helper; | 1704 StubRuntimeCallHelper call_helper; |
1699 char_code_at_generator.GenerateSlow(masm(), call_helper); | 1705 char_code_at_generator.GenerateSlow(masm(), call_helper); |
1700 | 1706 |
1701 __ bind(&index_out_of_range); | 1707 if (index_out_of_range.is_linked()) { |
1702 __ LoadRoot(rax, Heap::kNanValueRootIndex); | 1708 __ bind(&index_out_of_range); |
1703 __ ret((argc + 1) * kPointerSize); | 1709 __ LoadRoot(rax, Heap::kNanValueRootIndex); |
| 1710 __ ret((argc + 1) * kPointerSize); |
| 1711 } |
1704 | 1712 |
1705 __ bind(&miss); | 1713 __ bind(&miss); |
| 1714 // Restore function name in rcx. |
| 1715 __ Move(rcx, Handle<String>(name)); |
| 1716 __ bind(&name_miss); |
1706 Object* obj; | 1717 Object* obj; |
1707 { MaybeObject* maybe_obj = GenerateMissBranch(); | 1718 { MaybeObject* maybe_obj = GenerateMissBranch(); |
1708 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1719 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
1709 } | 1720 } |
1710 | 1721 |
1711 // Return the generated code. | 1722 // Return the generated code. |
1712 return GetCode(function); | 1723 return GetCode(function); |
1713 } | 1724 } |
1714 | 1725 |
1715 | 1726 |
(...skipping 10 matching lines...) Expand all Loading... |
1726 // -- ... | 1737 // -- ... |
1727 // -- rsp[(argc + 1) * 8] : receiver | 1738 // -- rsp[(argc + 1) * 8] : receiver |
1728 // ----------------------------------- | 1739 // ----------------------------------- |
1729 | 1740 |
1730 // If object is not a string, bail out to regular call. | 1741 // If object is not a string, bail out to regular call. |
1731 if (!object->IsString() || cell != NULL) return Heap::undefined_value(); | 1742 if (!object->IsString() || cell != NULL) return Heap::undefined_value(); |
1732 | 1743 |
1733 const int argc = arguments().immediate(); | 1744 const int argc = arguments().immediate(); |
1734 | 1745 |
1735 Label miss; | 1746 Label miss; |
| 1747 Label name_miss; |
1736 Label index_out_of_range; | 1748 Label index_out_of_range; |
| 1749 Label* index_out_of_range_label = &index_out_of_range; |
1737 | 1750 |
1738 GenerateNameCheck(name, &miss); | 1751 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) { |
| 1752 index_out_of_range_label = &miss; |
| 1753 } |
| 1754 |
| 1755 GenerateNameCheck(name, &name_miss); |
1739 | 1756 |
1740 // Check that the maps starting from the prototype haven't changed. | 1757 // Check that the maps starting from the prototype haven't changed. |
1741 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 1758 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
1742 Context::STRING_FUNCTION_INDEX, | 1759 Context::STRING_FUNCTION_INDEX, |
1743 rax, | 1760 rax, |
1744 &miss); | 1761 &miss); |
1745 ASSERT(object != holder); | 1762 ASSERT(object != holder); |
1746 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, | 1763 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, |
1747 rbx, rdx, rdi, name, &miss); | 1764 rbx, rdx, rdi, name, &miss); |
1748 | 1765 |
1749 Register receiver = rax; | 1766 Register receiver = rax; |
1750 Register index = rdi; | 1767 Register index = rdi; |
1751 Register scratch1 = rbx; | 1768 Register scratch1 = rbx; |
1752 Register scratch2 = rdx; | 1769 Register scratch2 = rdx; |
1753 Register result = rax; | 1770 Register result = rax; |
1754 __ movq(receiver, Operand(rsp, (argc + 1) * kPointerSize)); | 1771 __ movq(receiver, Operand(rsp, (argc + 1) * kPointerSize)); |
1755 if (argc > 0) { | 1772 if (argc > 0) { |
1756 __ movq(index, Operand(rsp, (argc - 0) * kPointerSize)); | 1773 __ movq(index, Operand(rsp, (argc - 0) * kPointerSize)); |
1757 } else { | 1774 } else { |
1758 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); | 1775 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); |
1759 } | 1776 } |
1760 | 1777 |
1761 StringCharAtGenerator char_at_generator(receiver, | 1778 StringCharAtGenerator char_at_generator(receiver, |
1762 index, | 1779 index, |
1763 scratch1, | 1780 scratch1, |
1764 scratch2, | 1781 scratch2, |
1765 result, | 1782 result, |
1766 &miss, // When not a string. | 1783 &miss, // When not a string. |
1767 &miss, // When not a number. | 1784 &miss, // When not a number. |
1768 &index_out_of_range, | 1785 index_out_of_range_label, |
1769 STRING_INDEX_IS_NUMBER); | 1786 STRING_INDEX_IS_NUMBER); |
1770 char_at_generator.GenerateFast(masm()); | 1787 char_at_generator.GenerateFast(masm()); |
1771 __ ret((argc + 1) * kPointerSize); | 1788 __ ret((argc + 1) * kPointerSize); |
1772 | 1789 |
1773 StubRuntimeCallHelper call_helper; | 1790 StubRuntimeCallHelper call_helper; |
1774 char_at_generator.GenerateSlow(masm(), call_helper); | 1791 char_at_generator.GenerateSlow(masm(), call_helper); |
1775 | 1792 |
1776 __ bind(&index_out_of_range); | 1793 if (index_out_of_range.is_linked()) { |
1777 __ LoadRoot(rax, Heap::kEmptyStringRootIndex); | 1794 __ bind(&index_out_of_range); |
1778 __ ret((argc + 1) * kPointerSize); | 1795 __ LoadRoot(rax, Heap::kEmptyStringRootIndex); |
| 1796 __ ret((argc + 1) * kPointerSize); |
| 1797 } |
1779 | 1798 |
1780 __ bind(&miss); | 1799 __ bind(&miss); |
| 1800 // Restore function name in rcx. |
| 1801 __ Move(rcx, Handle<String>(name)); |
| 1802 __ bind(&name_miss); |
1781 Object* obj; | 1803 Object* obj; |
1782 { MaybeObject* maybe_obj = GenerateMissBranch(); | 1804 { MaybeObject* maybe_obj = GenerateMissBranch(); |
1783 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1805 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
1784 } | 1806 } |
1785 | 1807 |
1786 // Return the generated code. | 1808 // Return the generated code. |
1787 return GetCode(function); | 1809 return GetCode(function); |
1788 } | 1810 } |
1789 | 1811 |
1790 | 1812 |
(...skipping 1322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3113 // Return the generated code. | 3135 // Return the generated code. |
3114 return GetCode(); | 3136 return GetCode(); |
3115 } | 3137 } |
3116 | 3138 |
3117 | 3139 |
3118 #undef __ | 3140 #undef __ |
3119 | 3141 |
3120 } } // namespace v8::internal | 3142 } } // namespace v8::internal |
3121 | 3143 |
3122 #endif // V8_TARGET_ARCH_X64 | 3144 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |