OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 1314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1325 __ cmp(r4, r3); | 1325 __ cmp(r4, r3); |
1326 __ b(ne, miss); | 1326 __ b(ne, miss); |
1327 } else { | 1327 } else { |
1328 __ cmp(r1, Operand(Handle<JSFunction>(function))); | 1328 __ cmp(r1, Operand(Handle<JSFunction>(function))); |
1329 __ b(ne, miss); | 1329 __ b(ne, miss); |
1330 } | 1330 } |
1331 } | 1331 } |
1332 | 1332 |
1333 | 1333 |
1334 MaybeObject* CallStubCompiler::GenerateMissBranch() { | 1334 MaybeObject* CallStubCompiler::GenerateMissBranch() { |
| 1335 MaybeObject* maybe_obj = StubCache::ComputeCallMiss(arguments().immediate(), |
| 1336 kind_); |
1335 Object* obj; | 1337 Object* obj; |
1336 { MaybeObject* maybe_obj = | 1338 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
1337 StubCache::ComputeCallMiss(arguments().immediate(), kind_); | |
1338 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
1339 } | |
1340 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); | 1339 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); |
1341 return obj; | 1340 return obj; |
1342 } | 1341 } |
1343 | 1342 |
1344 | 1343 |
1345 MaybeObject* CallStubCompiler::CompileCallField(JSObject* object, | 1344 MaybeObject* CallStubCompiler::CompileCallField(JSObject* object, |
1346 JSObject* holder, | 1345 JSObject* holder, |
1347 int index, | 1346 int index, |
1348 String* name) { | 1347 String* name) { |
1349 // ----------- S t a t e ------------- | 1348 // ----------- S t a t e ------------- |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1639 // -- ... | 1638 // -- ... |
1640 // -- sp[argc * 4] : receiver | 1639 // -- sp[argc * 4] : receiver |
1641 // ----------------------------------- | 1640 // ----------------------------------- |
1642 | 1641 |
1643 // If object is not a string, bail out to regular call. | 1642 // If object is not a string, bail out to regular call. |
1644 if (!object->IsString() || cell != NULL) return Heap::undefined_value(); | 1643 if (!object->IsString() || cell != NULL) return Heap::undefined_value(); |
1645 | 1644 |
1646 const int argc = arguments().immediate(); | 1645 const int argc = arguments().immediate(); |
1647 | 1646 |
1648 Label miss; | 1647 Label miss; |
| 1648 Label name_miss; |
1649 Label index_out_of_range; | 1649 Label index_out_of_range; |
1650 GenerateNameCheck(name, &miss); | 1650 Label* index_out_of_range_label = &index_out_of_range; |
| 1651 |
| 1652 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) { |
| 1653 index_out_of_range_label = &miss; |
| 1654 } |
| 1655 |
| 1656 GenerateNameCheck(name, &name_miss); |
1651 | 1657 |
1652 // Check that the maps starting from the prototype haven't changed. | 1658 // Check that the maps starting from the prototype haven't changed. |
1653 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 1659 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
1654 Context::STRING_FUNCTION_INDEX, | 1660 Context::STRING_FUNCTION_INDEX, |
1655 r0, | 1661 r0, |
1656 &miss); | 1662 &miss); |
1657 ASSERT(object != holder); | 1663 ASSERT(object != holder); |
1658 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, | 1664 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, |
1659 r1, r3, r4, name, &miss); | 1665 r1, r3, r4, name, &miss); |
1660 | 1666 |
1661 Register receiver = r1; | 1667 Register receiver = r1; |
1662 Register index = r4; | 1668 Register index = r4; |
1663 Register scratch = r3; | 1669 Register scratch = r3; |
1664 Register result = r0; | 1670 Register result = r0; |
1665 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); | 1671 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); |
1666 if (argc > 0) { | 1672 if (argc > 0) { |
1667 __ ldr(index, MemOperand(sp, (argc - 1) * kPointerSize)); | 1673 __ ldr(index, MemOperand(sp, (argc - 1) * kPointerSize)); |
1668 } else { | 1674 } else { |
1669 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); | 1675 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); |
1670 } | 1676 } |
1671 | 1677 |
1672 StringCharCodeAtGenerator char_code_at_generator(receiver, | 1678 StringCharCodeAtGenerator char_code_at_generator(receiver, |
1673 index, | 1679 index, |
1674 scratch, | 1680 scratch, |
1675 result, | 1681 result, |
1676 &miss, // When not a string. | 1682 &miss, // When not a string. |
1677 &miss, // When not a number. | 1683 &miss, // When not a number. |
1678 &index_out_of_range, | 1684 index_out_of_range_label, |
1679 STRING_INDEX_IS_NUMBER); | 1685 STRING_INDEX_IS_NUMBER); |
1680 char_code_at_generator.GenerateFast(masm()); | 1686 char_code_at_generator.GenerateFast(masm()); |
1681 __ Drop(argc + 1); | 1687 __ Drop(argc + 1); |
1682 __ Ret(); | 1688 __ Ret(); |
1683 | 1689 |
1684 StubRuntimeCallHelper call_helper; | 1690 StubRuntimeCallHelper call_helper; |
1685 char_code_at_generator.GenerateSlow(masm(), call_helper); | 1691 char_code_at_generator.GenerateSlow(masm(), call_helper); |
1686 | 1692 |
1687 __ bind(&index_out_of_range); | 1693 if (index_out_of_range.is_linked()) { |
1688 __ LoadRoot(r0, Heap::kNanValueRootIndex); | 1694 __ bind(&index_out_of_range); |
1689 __ Drop(argc + 1); | 1695 __ LoadRoot(r0, Heap::kNanValueRootIndex); |
1690 __ Ret(); | 1696 __ Drop(argc + 1); |
| 1697 __ Ret(); |
| 1698 } |
1691 | 1699 |
1692 __ bind(&miss); | 1700 __ bind(&miss); |
| 1701 // Restore function name in r2. |
| 1702 __ Move(r2, Handle<String>(name)); |
| 1703 __ bind(&name_miss); |
1693 Object* obj; | 1704 Object* obj; |
1694 { MaybeObject* maybe_obj = GenerateMissBranch(); | 1705 { MaybeObject* maybe_obj = GenerateMissBranch(); |
1695 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1706 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
1696 } | 1707 } |
1697 | 1708 |
1698 // Return the generated code. | 1709 // Return the generated code. |
1699 return GetCode(function); | 1710 return GetCode(function); |
1700 } | 1711 } |
1701 | 1712 |
1702 | 1713 |
(...skipping 10 matching lines...) Expand all Loading... |
1713 // -- ... | 1724 // -- ... |
1714 // -- sp[argc * 4] : receiver | 1725 // -- sp[argc * 4] : receiver |
1715 // ----------------------------------- | 1726 // ----------------------------------- |
1716 | 1727 |
1717 // If object is not a string, bail out to regular call. | 1728 // If object is not a string, bail out to regular call. |
1718 if (!object->IsString() || cell != NULL) return Heap::undefined_value(); | 1729 if (!object->IsString() || cell != NULL) return Heap::undefined_value(); |
1719 | 1730 |
1720 const int argc = arguments().immediate(); | 1731 const int argc = arguments().immediate(); |
1721 | 1732 |
1722 Label miss; | 1733 Label miss; |
| 1734 Label name_miss; |
1723 Label index_out_of_range; | 1735 Label index_out_of_range; |
| 1736 Label* index_out_of_range_label = &index_out_of_range; |
1724 | 1737 |
1725 GenerateNameCheck(name, &miss); | 1738 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) { |
| 1739 index_out_of_range_label = &miss; |
| 1740 } |
| 1741 |
| 1742 GenerateNameCheck(name, &name_miss); |
1726 | 1743 |
1727 // Check that the maps starting from the prototype haven't changed. | 1744 // Check that the maps starting from the prototype haven't changed. |
1728 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 1745 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
1729 Context::STRING_FUNCTION_INDEX, | 1746 Context::STRING_FUNCTION_INDEX, |
1730 r0, | 1747 r0, |
1731 &miss); | 1748 &miss); |
1732 ASSERT(object != holder); | 1749 ASSERT(object != holder); |
1733 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, | 1750 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, |
1734 r1, r3, r4, name, &miss); | 1751 r1, r3, r4, name, &miss); |
1735 | 1752 |
1736 Register receiver = r0; | 1753 Register receiver = r0; |
1737 Register index = r4; | 1754 Register index = r4; |
1738 Register scratch1 = r1; | 1755 Register scratch1 = r1; |
1739 Register scratch2 = r3; | 1756 Register scratch2 = r3; |
1740 Register result = r0; | 1757 Register result = r0; |
1741 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); | 1758 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); |
1742 if (argc > 0) { | 1759 if (argc > 0) { |
1743 __ ldr(index, MemOperand(sp, (argc - 1) * kPointerSize)); | 1760 __ ldr(index, MemOperand(sp, (argc - 1) * kPointerSize)); |
1744 } else { | 1761 } else { |
1745 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); | 1762 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); |
1746 } | 1763 } |
1747 | 1764 |
1748 StringCharAtGenerator char_at_generator(receiver, | 1765 StringCharAtGenerator char_at_generator(receiver, |
1749 index, | 1766 index, |
1750 scratch1, | 1767 scratch1, |
1751 scratch2, | 1768 scratch2, |
1752 result, | 1769 result, |
1753 &miss, // When not a string. | 1770 &miss, // When not a string. |
1754 &miss, // When not a number. | 1771 &miss, // When not a number. |
1755 &index_out_of_range, | 1772 index_out_of_range_label, |
1756 STRING_INDEX_IS_NUMBER); | 1773 STRING_INDEX_IS_NUMBER); |
1757 char_at_generator.GenerateFast(masm()); | 1774 char_at_generator.GenerateFast(masm()); |
1758 __ Drop(argc + 1); | 1775 __ Drop(argc + 1); |
1759 __ Ret(); | 1776 __ Ret(); |
1760 | 1777 |
1761 StubRuntimeCallHelper call_helper; | 1778 StubRuntimeCallHelper call_helper; |
1762 char_at_generator.GenerateSlow(masm(), call_helper); | 1779 char_at_generator.GenerateSlow(masm(), call_helper); |
1763 | 1780 |
1764 __ bind(&index_out_of_range); | 1781 if (index_out_of_range.is_linked()) { |
1765 __ LoadRoot(r0, Heap::kEmptyStringRootIndex); | 1782 __ bind(&index_out_of_range); |
1766 __ Drop(argc + 1); | 1783 __ LoadRoot(r0, Heap::kEmptyStringRootIndex); |
1767 __ Ret(); | 1784 __ Drop(argc + 1); |
| 1785 __ Ret(); |
| 1786 } |
1768 | 1787 |
1769 __ bind(&miss); | 1788 __ bind(&miss); |
| 1789 // Restore function name in r2. |
| 1790 __ Move(r2, Handle<String>(name)); |
| 1791 __ bind(&name_miss); |
1770 Object* obj; | 1792 Object* obj; |
1771 { MaybeObject* maybe_obj = GenerateMissBranch(); | 1793 { MaybeObject* maybe_obj = GenerateMissBranch(); |
1772 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1794 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
1773 } | 1795 } |
1774 | 1796 |
1775 // Return the generated code. | 1797 // Return the generated code. |
1776 return GetCode(function); | 1798 return GetCode(function); |
1777 } | 1799 } |
1778 | 1800 |
1779 | 1801 |
(...skipping 1420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3200 // Return the generated code. | 3222 // Return the generated code. |
3201 return GetCode(); | 3223 return GetCode(); |
3202 } | 3224 } |
3203 | 3225 |
3204 | 3226 |
3205 #undef __ | 3227 #undef __ |
3206 | 3228 |
3207 } } // namespace v8::internal | 3229 } } // namespace v8::internal |
3208 | 3230 |
3209 #endif // V8_TARGET_ARCH_ARM | 3231 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |