Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(113)

Side by Side Diff: src/mips/stub-cache-mips.cc

Issue 143633007: A64: Synchronize with r18764. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/mips/macro-assembler-mips.cc ('k') | src/objects.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 1089 matching lines...) Expand 10 before | Expand all | Expand 10 after
1100 1100
1101 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { 1101 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) {
1102 __ Jump(code, RelocInfo::CODE_TARGET); 1102 __ Jump(code, RelocInfo::CODE_TARGET);
1103 } 1103 }
1104 1104
1105 1105
1106 #undef __ 1106 #undef __
1107 #define __ ACCESS_MASM(masm()) 1107 #define __ ACCESS_MASM(masm())
1108 1108
1109 1109
1110 Register StubCompiler::CheckPrototypes(Handle<Type> type, 1110 Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
1111 Register object_reg, 1111 Register object_reg,
1112 Handle<JSObject> holder, 1112 Handle<JSObject> holder,
1113 Register holder_reg, 1113 Register holder_reg,
1114 Register scratch1, 1114 Register scratch1,
1115 Register scratch2, 1115 Register scratch2,
1116 Handle<Name> name, 1116 Handle<Name> name,
1117 int save_at_depth, 1117 int save_at_depth,
1118 Label* miss, 1118 Label* miss,
1119 PrototypeCheckType check) { 1119 PrototypeCheckType check) {
1120 Handle<Map> receiver_map(IC::TypeToMap(*type, isolate())); 1120 Handle<Map> receiver_map(IC::TypeToMap(*type, isolate()));
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1246 Label success; 1246 Label success;
1247 __ Branch(&success); 1247 __ Branch(&success);
1248 GenerateRestoreName(masm(), miss, name); 1248 GenerateRestoreName(masm(), miss, name);
1249 TailCallBuiltin(masm(), MissBuiltin(kind())); 1249 TailCallBuiltin(masm(), MissBuiltin(kind()));
1250 __ bind(&success); 1250 __ bind(&success);
1251 } 1251 }
1252 } 1252 }
1253 1253
1254 1254
1255 Register LoadStubCompiler::CallbackHandlerFrontend( 1255 Register LoadStubCompiler::CallbackHandlerFrontend(
1256 Handle<Type> type, 1256 Handle<HeapType> type,
1257 Register object_reg, 1257 Register object_reg,
1258 Handle<JSObject> holder, 1258 Handle<JSObject> holder,
1259 Handle<Name> name, 1259 Handle<Name> name,
1260 Handle<Object> callback) { 1260 Handle<Object> callback) {
1261 Label miss; 1261 Label miss;
1262 1262
1263 Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss); 1263 Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss);
1264 1264
1265 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { 1265 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
1266 ASSERT(!reg.is(scratch2())); 1266 ASSERT(!reg.is(scratch2()));
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
1549 index.translate(holder), Representation::Tagged()); 1549 index.translate(holder), Representation::Tagged());
1550 GenerateJumpFunction(object, a1, &miss); 1550 GenerateJumpFunction(object, a1, &miss);
1551 1551
1552 HandlerFrontendFooter(&miss); 1552 HandlerFrontendFooter(&miss);
1553 1553
1554 // Return the generated code. 1554 // Return the generated code.
1555 return GetCode(Code::FAST, name); 1555 return GetCode(Code::FAST, name);
1556 } 1556 }
1557 1557
1558 1558
1559 Handle<Code> CallStubCompiler::CompileArrayCodeCall(
1560 Handle<Object> object,
1561 Handle<JSObject> holder,
1562 Handle<Cell> cell,
1563 Handle<JSFunction> function,
1564 Handle<String> name,
1565 Code::StubType type) {
1566 Label miss;
1567
1568 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1569 if (!cell.is_null()) {
1570 ASSERT(cell->value() == *function);
1571 GenerateLoadFunctionFromCell(cell, function, &miss);
1572 }
1573
1574 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite();
1575 site->SetElementsKind(GetInitialFastElementsKind());
1576 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site);
1577 const int argc = arguments().immediate();
1578 __ li(a0, Operand(argc));
1579 __ li(a2, Operand(site_feedback_cell));
1580 __ li(a1, Operand(function));
1581
1582 ArrayConstructorStub stub(isolate());
1583 __ TailCallStub(&stub);
1584
1585 HandlerFrontendFooter(&miss);
1586
1587 // Return the generated code.
1588 return GetCode(type, name);
1589 }
1590
1591
1592 Handle<Code> CallStubCompiler::CompileArrayPushCall(
1593 Handle<Object> object,
1594 Handle<JSObject> holder,
1595 Handle<Cell> cell,
1596 Handle<JSFunction> function,
1597 Handle<String> name,
1598 Code::StubType type) {
1599 // If object is not an array or is observed or sealed, bail out to regular
1600 // call.
1601 if (!object->IsJSArray() ||
1602 !cell.is_null() ||
1603 Handle<JSArray>::cast(object)->map()->is_observed() ||
1604 !Handle<JSArray>::cast(object)->map()->is_extensible()) {
1605 return Handle<Code>::null();
1606 }
1607
1608 Label miss;
1609 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1610 Register receiver = a0;
1611 Register scratch = a1;
1612
1613 const int argc = arguments().immediate();
1614
1615 if (argc == 0) {
1616 // Nothing to do, just return the length.
1617 __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset));
1618 __ DropAndRet(argc + 1);
1619 } else {
1620 Label call_builtin;
1621 if (argc == 1) { // Otherwise fall through to call the builtin.
1622 Label attempt_to_grow_elements, with_write_barrier, check_double;
1623
1624 Register elements = t2;
1625 Register end_elements = t1;
1626 // Get the elements array of the object.
1627 __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset));
1628
1629 // Check that the elements are in fast mode and writable.
1630 __ CheckMap(elements,
1631 scratch,
1632 Heap::kFixedArrayMapRootIndex,
1633 &check_double,
1634 DONT_DO_SMI_CHECK);
1635
1636 // Get the array's length into scratch and calculate new length.
1637 __ lw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
1638 STATIC_ASSERT(kSmiTagSize == 1);
1639 STATIC_ASSERT(kSmiTag == 0);
1640 __ Addu(scratch, scratch, Operand(Smi::FromInt(argc)));
1641
1642 // Get the elements' length.
1643 __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset));
1644
1645 // Check if we could survive without allocation.
1646 __ Branch(&attempt_to_grow_elements, gt, scratch, Operand(t0));
1647
1648 // Check if value is a smi.
1649 __ lw(t0, MemOperand(sp, (argc - 1) * kPointerSize));
1650 __ JumpIfNotSmi(t0, &with_write_barrier);
1651
1652 // Save new length.
1653 __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
1654
1655 // Store the value.
1656 // We may need a register containing the address end_elements below,
1657 // so write back the value in end_elements.
1658 __ sll(end_elements, scratch, kPointerSizeLog2 - kSmiTagSize);
1659 __ Addu(end_elements, elements, end_elements);
1660 const int kEndElementsOffset =
1661 FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize;
1662 __ Addu(end_elements, end_elements, kEndElementsOffset);
1663 __ sw(t0, MemOperand(end_elements));
1664
1665 // Check for a smi.
1666 __ mov(v0, scratch);
1667 __ DropAndRet(argc + 1);
1668
1669 __ bind(&check_double);
1670
1671 // Check that the elements are in fast mode and writable.
1672 __ CheckMap(elements,
1673 scratch,
1674 Heap::kFixedDoubleArrayMapRootIndex,
1675 &call_builtin,
1676 DONT_DO_SMI_CHECK);
1677
1678 // Get the array's length into scratch and calculate new length.
1679 __ lw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
1680 STATIC_ASSERT(kSmiTagSize == 1);
1681 STATIC_ASSERT(kSmiTag == 0);
1682 __ Addu(scratch, scratch, Operand(Smi::FromInt(argc)));
1683
1684 // Get the elements' length.
1685 __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset));
1686
1687 // Check if we could survive without allocation.
1688 __ Branch(&call_builtin, gt, scratch, Operand(t0));
1689
1690 __ lw(t0, MemOperand(sp, (argc - 1) * kPointerSize));
1691 __ StoreNumberToDoubleElements(
1692 t0, scratch, elements, a3, t1, a2,
1693 &call_builtin, argc * kDoubleSize);
1694
1695 // Save new length.
1696 __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
1697
1698 __ mov(v0, scratch);
1699 __ DropAndRet(argc + 1);
1700
1701 __ bind(&with_write_barrier);
1702
1703 __ lw(a3, FieldMemOperand(receiver, HeapObject::kMapOffset));
1704
1705 if (FLAG_smi_only_arrays && !FLAG_trace_elements_transitions) {
1706 Label fast_object, not_fast_object;
1707 __ CheckFastObjectElements(a3, t3, &not_fast_object);
1708 __ jmp(&fast_object);
1709 // In case of fast smi-only, convert to fast object, otherwise bail out.
1710 __ bind(&not_fast_object);
1711 __ CheckFastSmiElements(a3, t3, &call_builtin);
1712
1713 __ lw(t3, FieldMemOperand(t0, HeapObject::kMapOffset));
1714 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
1715 __ Branch(&call_builtin, eq, t3, Operand(at));
1716 // edx: receiver
1717 // a3: map
1718 Label try_holey_map;
1719 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
1720 FAST_ELEMENTS,
1721 a3,
1722 t3,
1723 &try_holey_map);
1724 __ mov(a2, receiver);
1725 ElementsTransitionGenerator::
1726 GenerateMapChangeElementsTransition(masm(),
1727 DONT_TRACK_ALLOCATION_SITE,
1728 NULL);
1729 __ jmp(&fast_object);
1730
1731 __ bind(&try_holey_map);
1732 __ LoadTransitionedArrayMapConditional(FAST_HOLEY_SMI_ELEMENTS,
1733 FAST_HOLEY_ELEMENTS,
1734 a3,
1735 t3,
1736 &call_builtin);
1737 __ mov(a2, receiver);
1738 ElementsTransitionGenerator::
1739 GenerateMapChangeElementsTransition(masm(),
1740 DONT_TRACK_ALLOCATION_SITE,
1741 NULL);
1742 __ bind(&fast_object);
1743 } else {
1744 __ CheckFastObjectElements(a3, a3, &call_builtin);
1745 }
1746
1747 // Save new length.
1748 __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
1749
1750 // Store the value.
1751 // We may need a register containing the address end_elements below,
1752 // so write back the value in end_elements.
1753 __ sll(end_elements, scratch, kPointerSizeLog2 - kSmiTagSize);
1754 __ Addu(end_elements, elements, end_elements);
1755 __ Addu(end_elements, end_elements, kEndElementsOffset);
1756 __ sw(t0, MemOperand(end_elements));
1757
1758 __ RecordWrite(elements,
1759 end_elements,
1760 t0,
1761 kRAHasNotBeenSaved,
1762 kDontSaveFPRegs,
1763 EMIT_REMEMBERED_SET,
1764 OMIT_SMI_CHECK);
1765 __ mov(v0, scratch);
1766 __ DropAndRet(argc + 1);
1767
1768 __ bind(&attempt_to_grow_elements);
1769 // scratch: array's length + 1.
1770 // t0: elements' length.
1771
1772 if (!FLAG_inline_new) {
1773 __ Branch(&call_builtin);
1774 }
1775
1776 __ lw(a2, MemOperand(sp, (argc - 1) * kPointerSize));
1777 // Growing elements that are SMI-only requires special handling in case
1778 // the new element is non-Smi. For now, delegate to the builtin.
1779 Label no_fast_elements_check;
1780 __ JumpIfSmi(a2, &no_fast_elements_check);
1781 __ lw(t3, FieldMemOperand(receiver, HeapObject::kMapOffset));
1782 __ CheckFastObjectElements(t3, t3, &call_builtin);
1783 __ bind(&no_fast_elements_check);
1784
1785 ExternalReference new_space_allocation_top =
1786 ExternalReference::new_space_allocation_top_address(isolate());
1787 ExternalReference new_space_allocation_limit =
1788 ExternalReference::new_space_allocation_limit_address(isolate());
1789
1790 const int kAllocationDelta = 4;
1791 // Load top and check if it is the end of elements.
1792 __ sll(end_elements, scratch, kPointerSizeLog2 - kSmiTagSize);
1793 __ Addu(end_elements, elements, end_elements);
1794 __ Addu(end_elements, end_elements, Operand(kEndElementsOffset));
1795 __ li(t3, Operand(new_space_allocation_top));
1796 __ lw(a3, MemOperand(t3));
1797 __ Branch(&call_builtin, ne, end_elements, Operand(a3));
1798
1799 __ li(t5, Operand(new_space_allocation_limit));
1800 __ lw(t5, MemOperand(t5));
1801 __ Addu(a3, a3, Operand(kAllocationDelta * kPointerSize));
1802 __ Branch(&call_builtin, hi, a3, Operand(t5));
1803
1804 // We fit and could grow elements.
1805 // Update new_space_allocation_top.
1806 __ sw(a3, MemOperand(t3));
1807 // Push the argument.
1808 __ sw(a2, MemOperand(end_elements));
1809 // Fill the rest with holes.
1810 __ LoadRoot(a3, Heap::kTheHoleValueRootIndex);
1811 for (int i = 1; i < kAllocationDelta; i++) {
1812 __ sw(a3, MemOperand(end_elements, i * kPointerSize));
1813 }
1814
1815 // Update elements' and array's sizes.
1816 __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
1817 __ Addu(t0, t0, Operand(Smi::FromInt(kAllocationDelta)));
1818 __ sw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset));
1819
1820 // Elements are in new space, so write barrier is not required.
1821 __ mov(v0, scratch);
1822 __ DropAndRet(argc + 1);
1823 }
1824 __ bind(&call_builtin);
1825 __ TailCallExternalReference(
1826 ExternalReference(Builtins::c_ArrayPush, isolate()), argc + 1, 1);
1827 }
1828
1829 HandlerFrontendFooter(&miss);
1830
1831 // Return the generated code.
1832 return GetCode(type, name);
1833 }
1834
1835
1836 Handle<Code> CallStubCompiler::CompileArrayPopCall(
1837 Handle<Object> object,
1838 Handle<JSObject> holder,
1839 Handle<Cell> cell,
1840 Handle<JSFunction> function,
1841 Handle<String> name,
1842 Code::StubType type) {
1843 // If object is not an array or is observed or sealed, bail out to regular
1844 // call.
1845 if (!object->IsJSArray() ||
1846 !cell.is_null() ||
1847 Handle<JSArray>::cast(object)->map()->is_observed() ||
1848 !Handle<JSArray>::cast(object)->map()->is_extensible()) {
1849 return Handle<Code>::null();
1850 }
1851
1852 Label miss, return_undefined, call_builtin;
1853 Register receiver = a0;
1854 Register scratch = a1;
1855 Register elements = a3;
1856 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1857
1858 // Get the elements array of the object.
1859 __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset));
1860
1861 // Check that the elements are in fast mode and writable.
1862 __ CheckMap(elements,
1863 scratch,
1864 Heap::kFixedArrayMapRootIndex,
1865 &call_builtin,
1866 DONT_DO_SMI_CHECK);
1867
1868 // Get the array's length into t0 and calculate new length.
1869 __ lw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset));
1870 __ Subu(t0, t0, Operand(Smi::FromInt(1)));
1871 __ Branch(&return_undefined, lt, t0, Operand(zero_reg));
1872
1873 // Get the last element.
1874 __ LoadRoot(t2, Heap::kTheHoleValueRootIndex);
1875 STATIC_ASSERT(kSmiTagSize == 1);
1876 STATIC_ASSERT(kSmiTag == 0);
1877 // We can't address the last element in one operation. Compute the more
1878 // expensive shift first, and use an offset later on.
1879 __ sll(t1, t0, kPointerSizeLog2 - kSmiTagSize);
1880 __ Addu(elements, elements, t1);
1881 __ lw(scratch, FieldMemOperand(elements, FixedArray::kHeaderSize));
1882 __ Branch(&call_builtin, eq, scratch, Operand(t2));
1883
1884 // Set the array's length.
1885 __ sw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset));
1886
1887 // Fill with the hole.
1888 __ sw(t2, FieldMemOperand(elements, FixedArray::kHeaderSize));
1889 const int argc = arguments().immediate();
1890 __ mov(v0, scratch);
1891 __ DropAndRet(argc + 1);
1892
1893 __ bind(&return_undefined);
1894 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
1895 __ DropAndRet(argc + 1);
1896
1897 __ bind(&call_builtin);
1898 __ TailCallExternalReference(
1899 ExternalReference(Builtins::c_ArrayPop, isolate()), argc + 1, 1);
1900
1901 HandlerFrontendFooter(&miss);
1902
1903 // Return the generated code.
1904 return GetCode(type, name);
1905 }
1906
1907
1908 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
1909 Handle<Object> object,
1910 Handle<JSObject> holder,
1911 Handle<Cell> cell,
1912 Handle<JSFunction> function,
1913 Handle<String> name,
1914 Code::StubType type) {
1915 // If object is not a string, bail out to regular call.
1916 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
1917
1918 Label miss;
1919 Label name_miss;
1920 Label index_out_of_range;
1921
1922 Label* index_out_of_range_label = &index_out_of_range;
1923
1924 if (kind_ == Code::CALL_IC &&
1925 (CallICBase::StringStubState::decode(extra_state()) ==
1926 DEFAULT_STRING_STUB)) {
1927 index_out_of_range_label = &miss;
1928 }
1929
1930 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss);
1931
1932 Register receiver = a0;
1933 Register index = t1;
1934 Register result = a1;
1935 const int argc = arguments().immediate();
1936 __ lw(receiver, MemOperand(sp, argc * kPointerSize));
1937 if (argc > 0) {
1938 __ lw(index, MemOperand(sp, (argc - 1) * kPointerSize));
1939 } else {
1940 __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
1941 }
1942
1943 StringCharCodeAtGenerator generator(receiver,
1944 index,
1945 result,
1946 &miss, // When not a string.
1947 &miss, // When not a number.
1948 index_out_of_range_label,
1949 STRING_INDEX_IS_NUMBER);
1950 generator.GenerateFast(masm());
1951 __ mov(v0, result);
1952 __ DropAndRet(argc + 1);
1953
1954 StubRuntimeCallHelper call_helper;
1955 generator.GenerateSlow(masm(), call_helper);
1956
1957 if (index_out_of_range.is_linked()) {
1958 __ bind(&index_out_of_range);
1959 __ LoadRoot(v0, Heap::kNanValueRootIndex);
1960 __ DropAndRet(argc + 1);
1961 }
1962
1963 __ bind(&miss);
1964 // Restore function name in a2.
1965 __ li(a2, name);
1966 HandlerFrontendFooter(&name_miss);
1967
1968 // Return the generated code.
1969 return GetCode(type, name);
1970 }
1971
1972
1973 Handle<Code> CallStubCompiler::CompileStringCharAtCall(
1974 Handle<Object> object,
1975 Handle<JSObject> holder,
1976 Handle<Cell> cell,
1977 Handle<JSFunction> function,
1978 Handle<String> name,
1979 Code::StubType type) {
1980 // If object is not a string, bail out to regular call.
1981 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
1982
1983 const int argc = arguments().immediate();
1984 Label miss;
1985 Label name_miss;
1986 Label index_out_of_range;
1987 Label* index_out_of_range_label = &index_out_of_range;
1988 if (kind_ == Code::CALL_IC &&
1989 (CallICBase::StringStubState::decode(extra_state()) ==
1990 DEFAULT_STRING_STUB)) {
1991 index_out_of_range_label = &miss;
1992 }
1993
1994 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss);
1995
1996 Register receiver = a0;
1997 Register index = t1;
1998 Register scratch = a3;
1999 Register result = a1;
2000 if (argc > 0) {
2001 __ lw(index, MemOperand(sp, (argc - 1) * kPointerSize));
2002 } else {
2003 __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
2004 }
2005
2006 StringCharAtGenerator generator(receiver,
2007 index,
2008 scratch,
2009 result,
2010 &miss, // When not a string.
2011 &miss, // When not a number.
2012 index_out_of_range_label,
2013 STRING_INDEX_IS_NUMBER);
2014 generator.GenerateFast(masm());
2015 __ mov(v0, result);
2016 __ DropAndRet(argc + 1);
2017
2018 StubRuntimeCallHelper call_helper;
2019 generator.GenerateSlow(masm(), call_helper);
2020
2021 if (index_out_of_range.is_linked()) {
2022 __ bind(&index_out_of_range);
2023 __ LoadRoot(v0, Heap::kempty_stringRootIndex);
2024 __ DropAndRet(argc + 1);
2025 }
2026
2027 __ bind(&miss);
2028 // Restore function name in a2.
2029 __ li(a2, name);
2030 HandlerFrontendFooter(&name_miss);
2031
2032 // Return the generated code.
2033 return GetCode(type, name);
2034 }
2035
2036
2037 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
2038 Handle<Object> object,
2039 Handle<JSObject> holder,
2040 Handle<Cell> cell,
2041 Handle<JSFunction> function,
2042 Handle<String> name,
2043 Code::StubType type) {
2044 const int argc = arguments().immediate();
2045
2046 // If the object is not a JSObject or we got an unexpected number of
2047 // arguments, bail out to the regular call.
2048 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2049
2050 Label miss;
2051 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2052 if (!cell.is_null()) {
2053 ASSERT(cell->value() == *function);
2054 GenerateLoadFunctionFromCell(cell, function, &miss);
2055 }
2056
2057 // Load the char code argument.
2058 Register code = a1;
2059 __ lw(code, MemOperand(sp, 0 * kPointerSize));
2060
2061 // Check the code is a smi.
2062 Label slow;
2063 STATIC_ASSERT(kSmiTag == 0);
2064 __ JumpIfNotSmi(code, &slow);
2065
2066 // Convert the smi code to uint16.
2067 __ And(code, code, Operand(Smi::FromInt(0xffff)));
2068
2069 StringCharFromCodeGenerator generator(code, v0);
2070 generator.GenerateFast(masm());
2071 __ DropAndRet(argc + 1);
2072
2073 StubRuntimeCallHelper call_helper;
2074 generator.GenerateSlow(masm(), call_helper);
2075
2076 __ bind(&slow);
2077 // We do not have to patch the receiver because the function makes no use of
2078 // it.
2079 GenerateJumpFunctionIgnoreReceiver(function);
2080
2081 HandlerFrontendFooter(&miss);
2082
2083 // Return the generated code.
2084 return GetCode(type, name);
2085 }
2086
2087
2088 Handle<Code> CallStubCompiler::CompileMathFloorCall(
2089 Handle<Object> object,
2090 Handle<JSObject> holder,
2091 Handle<Cell> cell,
2092 Handle<JSFunction> function,
2093 Handle<String> name,
2094 Code::StubType type) {
2095 const int argc = arguments().immediate();
2096 // If the object is not a JSObject or we got an unexpected number of
2097 // arguments, bail out to the regular call.
2098 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2099
2100 Label miss, slow;
2101 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2102 if (!cell.is_null()) {
2103 ASSERT(cell->value() == *function);
2104 GenerateLoadFunctionFromCell(cell, function, &miss);
2105 }
2106
2107 // Load the (only) argument into v0.
2108 __ lw(v0, MemOperand(sp, 0 * kPointerSize));
2109
2110 // If the argument is a smi, just return.
2111 STATIC_ASSERT(kSmiTag == 0);
2112 __ SmiTst(v0, t0);
2113 __ DropAndRet(argc + 1, eq, t0, Operand(zero_reg));
2114
2115 __ CheckMap(v0, a1, Heap::kHeapNumberMapRootIndex, &slow, DONT_DO_SMI_CHECK);
2116
2117 Label wont_fit_smi, no_fpu_error, restore_fcsr_and_return;
2118
2119 // If fpu is enabled, we use the floor instruction.
2120
2121 // Load the HeapNumber value.
2122 __ ldc1(f0, FieldMemOperand(v0, HeapNumber::kValueOffset));
2123
2124 // Backup FCSR.
2125 __ cfc1(a3, FCSR);
2126 // Clearing FCSR clears the exception mask with no side-effects.
2127 __ ctc1(zero_reg, FCSR);
2128 // Convert the argument to an integer.
2129 __ floor_w_d(f0, f0);
2130
2131 // Start checking for special cases.
2132 // Get the argument exponent and clear the sign bit.
2133 __ lw(t1, FieldMemOperand(v0, HeapNumber::kValueOffset + kPointerSize));
2134 __ And(t2, t1, Operand(~HeapNumber::kSignMask));
2135 __ srl(t2, t2, HeapNumber::kMantissaBitsInTopWord);
2136
2137 // Retrieve FCSR and check for fpu errors.
2138 __ cfc1(t5, FCSR);
2139 __ And(t5, t5, Operand(kFCSRExceptionFlagMask));
2140 __ Branch(&no_fpu_error, eq, t5, Operand(zero_reg));
2141
2142 // Check for NaN, Infinity, and -Infinity.
2143 // They are invariant through a Math.Floor call, so just
2144 // return the original argument.
2145 __ Subu(t3, t2, Operand(HeapNumber::kExponentMask
2146 >> HeapNumber::kMantissaBitsInTopWord));
2147 __ Branch(&restore_fcsr_and_return, eq, t3, Operand(zero_reg));
2148 // We had an overflow or underflow in the conversion. Check if we
2149 // have a big exponent.
2150 // If greater or equal, the argument is already round and in v0.
2151 __ Branch(&restore_fcsr_and_return, ge, t3,
2152 Operand(HeapNumber::kMantissaBits));
2153 __ Branch(&wont_fit_smi);
2154
2155 __ bind(&no_fpu_error);
2156 // Move the result back to v0.
2157 __ mfc1(v0, f0);
2158 // Check if the result fits into a smi.
2159 __ Addu(a1, v0, Operand(0x40000000));
2160 __ Branch(&wont_fit_smi, lt, a1, Operand(zero_reg));
2161 // Tag the result.
2162 STATIC_ASSERT(kSmiTag == 0);
2163 __ sll(v0, v0, kSmiTagSize);
2164
2165 // Check for -0.
2166 __ Branch(&restore_fcsr_and_return, ne, v0, Operand(zero_reg));
2167 // t1 already holds the HeapNumber exponent.
2168 __ And(t0, t1, Operand(HeapNumber::kSignMask));
2169 // If our HeapNumber is negative it was -0, so load its address and return.
2170 // Else v0 is loaded with 0, so we can also just return.
2171 __ Branch(&restore_fcsr_and_return, eq, t0, Operand(zero_reg));
2172 __ lw(v0, MemOperand(sp, 0 * kPointerSize));
2173
2174 __ bind(&restore_fcsr_and_return);
2175 // Restore FCSR and return.
2176 __ ctc1(a3, FCSR);
2177
2178 __ DropAndRet(argc + 1);
2179
2180 __ bind(&wont_fit_smi);
2181 // Restore FCSR and fall to slow case.
2182 __ ctc1(a3, FCSR);
2183
2184 __ bind(&slow);
2185 // We do not have to patch the receiver because the function makes no use of
2186 // it.
2187 GenerateJumpFunctionIgnoreReceiver(function);
2188
2189 HandlerFrontendFooter(&miss);
2190
2191 // Return the generated code.
2192 return GetCode(type, name);
2193 }
2194
2195
2196 Handle<Code> CallStubCompiler::CompileMathAbsCall(
2197 Handle<Object> object,
2198 Handle<JSObject> holder,
2199 Handle<Cell> cell,
2200 Handle<JSFunction> function,
2201 Handle<String> name,
2202 Code::StubType type) {
2203 const int argc = arguments().immediate();
2204 // If the object is not a JSObject or we got an unexpected number of
2205 // arguments, bail out to the regular call.
2206 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2207
2208 Label miss;
2209
2210 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2211 if (!cell.is_null()) {
2212 ASSERT(cell->value() == *function);
2213 GenerateLoadFunctionFromCell(cell, function, &miss);
2214 }
2215
2216 // Load the (only) argument into v0.
2217 __ lw(v0, MemOperand(sp, 0 * kPointerSize));
2218
2219 // Check if the argument is a smi.
2220 Label not_smi;
2221 STATIC_ASSERT(kSmiTag == 0);
2222 __ JumpIfNotSmi(v0, &not_smi);
2223
2224 // Do bitwise not or do nothing depending on the sign of the
2225 // argument.
2226 __ sra(t0, v0, kBitsPerInt - 1);
2227 __ Xor(a1, v0, t0);
2228
2229 // Add 1 or do nothing depending on the sign of the argument.
2230 __ Subu(v0, a1, t0);
2231
2232 // If the result is still negative, go to the slow case.
2233 // This only happens for the most negative smi.
2234 Label slow;
2235 __ Branch(&slow, lt, v0, Operand(zero_reg));
2236
2237 // Smi case done.
2238 __ DropAndRet(argc + 1);
2239
2240 // Check if the argument is a heap number and load its exponent and
2241 // sign.
2242 __ bind(&not_smi);
2243 __ CheckMap(v0, a1, Heap::kHeapNumberMapRootIndex, &slow, DONT_DO_SMI_CHECK);
2244 __ lw(a1, FieldMemOperand(v0, HeapNumber::kExponentOffset));
2245
2246 // Check the sign of the argument. If the argument is positive,
2247 // just return it.
2248 Label negative_sign;
2249 __ And(t0, a1, Operand(HeapNumber::kSignMask));
2250 __ Branch(&negative_sign, ne, t0, Operand(zero_reg));
2251 __ DropAndRet(argc + 1);
2252
2253 // If the argument is negative, clear the sign, and return a new
2254 // number.
2255 __ bind(&negative_sign);
2256 __ Xor(a1, a1, Operand(HeapNumber::kSignMask));
2257 __ lw(a3, FieldMemOperand(v0, HeapNumber::kMantissaOffset));
2258 __ LoadRoot(t2, Heap::kHeapNumberMapRootIndex);
2259 __ AllocateHeapNumber(v0, t0, t1, t2, &slow);
2260 __ sw(a1, FieldMemOperand(v0, HeapNumber::kExponentOffset));
2261 __ sw(a3, FieldMemOperand(v0, HeapNumber::kMantissaOffset));
2262 __ DropAndRet(argc + 1);
2263
2264 __ bind(&slow);
2265 // We do not have to patch the receiver because the function makes no use of
2266 // it.
2267 GenerateJumpFunctionIgnoreReceiver(function);
2268
2269 HandlerFrontendFooter(&miss);
2270
2271 // Return the generated code.
2272 return GetCode(type, name);
2273 }
2274
2275
2276 Handle<Code> CallStubCompiler::CompileFastApiCall( 1559 Handle<Code> CallStubCompiler::CompileFastApiCall(
2277 const CallOptimization& optimization, 1560 const CallOptimization& optimization,
2278 Handle<Object> object, 1561 Handle<Object> object,
2279 Handle<JSObject> holder, 1562 Handle<JSObject> holder,
2280 Handle<Cell> cell, 1563 Handle<Cell> cell,
2281 Handle<JSFunction> function, 1564 Handle<JSFunction> function,
2282 Handle<String> name) { 1565 Handle<String> name) {
2283 1566
2284 Counters* counters = isolate()->counters(); 1567 Counters* counters = isolate()->counters();
2285 1568
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
2507 // Return the generated code. 1790 // Return the generated code.
2508 return GetCode(Code::NORMAL, name); 1791 return GetCode(Code::NORMAL, name);
2509 } 1792 }
2510 1793
2511 1794
2512 Handle<Code> StoreStubCompiler::CompileStoreCallback( 1795 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2513 Handle<JSObject> object, 1796 Handle<JSObject> object,
2514 Handle<JSObject> holder, 1797 Handle<JSObject> holder,
2515 Handle<Name> name, 1798 Handle<Name> name,
2516 Handle<ExecutableAccessorInfo> callback) { 1799 Handle<ExecutableAccessorInfo> callback) {
2517 HandlerFrontend(IC::CurrentTypeOf(object, isolate()), 1800 Register holder_reg = HandlerFrontend(
2518 receiver(), holder, name); 1801 IC::CurrentTypeOf(object, isolate()), receiver(), holder, name);
2519 1802
2520 // Stub never generated for non-global objects that require access 1803 // Stub never generated for non-global objects that require access
2521 // checks. 1804 // checks.
2522 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); 1805 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
2523 1806
2524 __ push(receiver()); // Receiver. 1807 __ push(receiver()); // Receiver.
1808 __ push(holder_reg);
2525 __ li(at, Operand(callback)); // Callback info. 1809 __ li(at, Operand(callback)); // Callback info.
2526 __ push(at); 1810 __ push(at);
2527 __ li(at, Operand(name)); 1811 __ li(at, Operand(name));
2528 __ Push(at, value()); 1812 __ Push(at, value());
2529 1813
2530 // Do tail-call to the runtime system. 1814 // Do tail-call to the runtime system.
2531 ExternalReference store_callback_property = 1815 ExternalReference store_callback_property =
2532 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 1816 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
2533 __ TailCallExternalReference(store_callback_property, 4, 1); 1817 __ TailCallExternalReference(store_callback_property, 5, 1);
2534 1818
2535 // Return the generated code. 1819 // Return the generated code.
2536 return GetCode(kind(), Code::FAST, name); 1820 return GetCode(kind(), Code::FAST, name);
2537 } 1821 }
2538 1822
2539 1823
2540 Handle<Code> StoreStubCompiler::CompileStoreCallback( 1824 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2541 Handle<JSObject> object, 1825 Handle<JSObject> object,
2542 Handle<JSObject> holder, 1826 Handle<JSObject> holder,
2543 Handle<Name> name, 1827 Handle<Name> name,
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
2628 1912
2629 // Handle store cache miss. 1913 // Handle store cache miss.
2630 __ bind(&miss); 1914 __ bind(&miss);
2631 TailCallBuiltin(masm(), MissBuiltin(kind())); 1915 TailCallBuiltin(masm(), MissBuiltin(kind()));
2632 1916
2633 // Return the generated code. 1917 // Return the generated code.
2634 return GetCode(kind(), Code::FAST, name); 1918 return GetCode(kind(), Code::FAST, name);
2635 } 1919 }
2636 1920
2637 1921
2638 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<Type> type, 1922 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<HeapType> type,
2639 Handle<JSObject> last, 1923 Handle<JSObject> last,
2640 Handle<Name> name) { 1924 Handle<Name> name) {
2641 NonexistentHandlerFrontend(type, last, name); 1925 NonexistentHandlerFrontend(type, last, name);
2642 1926
2643 // Return undefined if maps of the full prototype chain is still the same. 1927 // Return undefined if maps of the full prototype chain is still the same.
2644 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); 1928 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
2645 __ Ret(); 1929 __ Ret();
2646 1930
2647 // Return the generated code. 1931 // Return the generated code.
2648 return GetCode(kind(), Code::FAST, name); 1932 return GetCode(kind(), Code::FAST, name);
(...skipping 21 matching lines...) Expand all
2670 } 1954 }
2671 1955
2672 1956
2673 Register* KeyedStoreStubCompiler::registers() { 1957 Register* KeyedStoreStubCompiler::registers() {
2674 // receiver, name, value, scratch1, scratch2, scratch3. 1958 // receiver, name, value, scratch1, scratch2, scratch3.
2675 static Register registers[] = { a2, a1, a0, a3, t0, t1 }; 1959 static Register registers[] = { a2, a1, a0, a3, t0, t1 };
2676 return registers; 1960 return registers;
2677 } 1961 }
2678 1962
2679 1963
2680 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name,
2681 Register name_reg,
2682 Label* miss) {
2683 __ Branch(miss, ne, name_reg, Operand(name));
2684 }
2685
2686
2687 void KeyedStoreStubCompiler::GenerateNameCheck(Handle<Name> name,
2688 Register name_reg,
2689 Label* miss) {
2690 __ Branch(miss, ne, name_reg, Operand(name));
2691 }
2692
2693
2694 #undef __ 1964 #undef __
2695 #define __ ACCESS_MASM(masm) 1965 #define __ ACCESS_MASM(masm)
2696 1966
2697 1967
2698 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, 1968 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm,
2699 Register receiver, 1969 Register receiver,
2700 Handle<JSFunction> getter) { 1970 Handle<JSFunction> getter) {
2701 // ----------- S t a t e ------------- 1971 // ----------- S t a t e -------------
2702 // -- a0 : receiver 1972 // -- a0 : receiver
2703 // -- a2 : name 1973 // -- a2 : name
(...skipping 20 matching lines...) Expand all
2724 } 1994 }
2725 __ Ret(); 1995 __ Ret();
2726 } 1996 }
2727 1997
2728 1998
2729 #undef __ 1999 #undef __
2730 #define __ ACCESS_MASM(masm()) 2000 #define __ ACCESS_MASM(masm())
2731 2001
2732 2002
2733 Handle<Code> LoadStubCompiler::CompileLoadGlobal( 2003 Handle<Code> LoadStubCompiler::CompileLoadGlobal(
2734 Handle<Type> type, 2004 Handle<HeapType> type,
2735 Handle<GlobalObject> global, 2005 Handle<GlobalObject> global,
2736 Handle<PropertyCell> cell, 2006 Handle<PropertyCell> cell,
2737 Handle<Name> name, 2007 Handle<Name> name,
2738 bool is_dont_delete) { 2008 bool is_dont_delete) {
2739 Label miss; 2009 Label miss;
2740 2010
2741 HandlerFrontendHeader(type, receiver(), global, name, &miss); 2011 HandlerFrontendHeader(type, receiver(), global, name, &miss);
2742 2012
2743 // Get the value from the cell. 2013 // Get the value from the cell.
2744 __ li(a3, Operand(cell)); 2014 __ li(a3, Operand(cell));
(...skipping 18 matching lines...) Expand all
2763 2033
2764 2034
2765 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC( 2035 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
2766 TypeHandleList* types, 2036 TypeHandleList* types,
2767 CodeHandleList* handlers, 2037 CodeHandleList* handlers,
2768 Handle<Name> name, 2038 Handle<Name> name,
2769 Code::StubType type, 2039 Code::StubType type,
2770 IcCheckType check) { 2040 IcCheckType check) {
2771 Label miss; 2041 Label miss;
2772 2042
2773 if (check == PROPERTY) { 2043 if (check == PROPERTY &&
2774 GenerateNameCheck(name, this->name(), &miss); 2044 (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) {
2045 __ Branch(&miss, ne, this->name(), Operand(name));
2775 } 2046 }
2776 2047
2777 Label number_case; 2048 Label number_case;
2778 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; 2049 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
2779 __ JumpIfSmi(receiver(), smi_target); 2050 __ JumpIfSmi(receiver(), smi_target);
2780 2051
2781 Register map_reg = scratch1(); 2052 Register map_reg = scratch1();
2782 2053
2783 int receiver_count = types->length(); 2054 int receiver_count = types->length();
2784 int number_of_handled_maps = 0; 2055 int number_of_handled_maps = 0;
2785 __ lw(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset)); 2056 __ lw(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
2786 for (int current = 0; current < receiver_count; ++current) { 2057 for (int current = 0; current < receiver_count; ++current) {
2787 Handle<Type> type = types->at(current); 2058 Handle<HeapType> type = types->at(current);
2788 Handle<Map> map = IC::TypeToMap(*type, isolate()); 2059 Handle<Map> map = IC::TypeToMap(*type, isolate());
2789 if (!map->is_deprecated()) { 2060 if (!map->is_deprecated()) {
2790 number_of_handled_maps++; 2061 number_of_handled_maps++;
2791 if (type->Is(Type::Number())) { 2062 if (type->Is(HeapType::Number())) {
2792 ASSERT(!number_case.is_unused()); 2063 ASSERT(!number_case.is_unused());
2793 __ bind(&number_case); 2064 __ bind(&number_case);
2794 } 2065 }
2795 __ Jump(handlers->at(current), RelocInfo::CODE_TARGET, 2066 __ Jump(handlers->at(current), RelocInfo::CODE_TARGET,
2796 eq, map_reg, Operand(map)); 2067 eq, map_reg, Operand(map));
2797 } 2068 }
2798 } 2069 }
2799 ASSERT(number_of_handled_maps != 0); 2070 ASSERT(number_of_handled_maps != 0);
2800 2071
2801 __ bind(&miss); 2072 __ bind(&miss);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
2884 // ----------------------------------- 2155 // -----------------------------------
2885 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 2156 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
2886 } 2157 }
2887 2158
2888 2159
2889 #undef __ 2160 #undef __
2890 2161
2891 } } // namespace v8::internal 2162 } } // namespace v8::internal
2892 2163
2893 #endif // V8_TARGET_ARCH_MIPS 2164 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/macro-assembler-mips.cc ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698