Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 750 // ----------- S t a t e ------------- | 750 // ----------- S t a t e ------------- |
| 751 // -- r0: receiver | 751 // -- r0: receiver |
| 752 // -- r1: function to call | 752 // -- r1: function to call |
| 753 // ----------------------------------- | 753 // ----------------------------------- |
| 754 | 754 |
| 755 // Check that the function really is a function. | 755 // Check that the function really is a function. |
| 756 __ JumpIfSmi(r1, miss); | 756 __ JumpIfSmi(r1, miss); |
| 757 __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE); | 757 __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE); |
| 758 __ b(ne, miss); | 758 __ b(ne, miss); |
| 759 | 759 |
| 760 // Patch the receiver on the stack with the global proxy if | |
| 761 // necessary. | |
| 762 if (object->IsGlobalObject()) { | |
| 763 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); | |
| 764 __ str(r3, MemOperand(sp, arguments.immediate() * kPointerSize)); | |
| 765 } | |
| 766 | |
|
Igor Sheludko
2013/11/25 16:31:53
Non-equivalent modification for one of the Generat
Toon Verwaest
2013/11/27 15:16:55
Done.
| |
| 767 // Invoke the function. | 760 // Invoke the function. |
| 768 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state) | 761 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state) |
| 769 ? CALL_AS_FUNCTION | 762 ? CALL_AS_FUNCTION |
| 770 : CALL_AS_METHOD; | 763 : CALL_AS_METHOD; |
| 771 __ InvokeFunction(r1, arguments, JUMP_FUNCTION, NullCallWrapper(), call_kind); | 764 __ InvokeFunction(r1, arguments, JUMP_FUNCTION, NullCallWrapper(), call_kind); |
| 772 } | 765 } |
| 773 | 766 |
| 774 | 767 |
| 775 static void PushInterceptorArguments(MacroAssembler* masm, | 768 static void PushInterceptorArguments(MacroAssembler* masm, |
| 776 Register receiver, | 769 Register receiver, |
| (...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1542 | 1535 |
| 1543 | 1536 |
| 1544 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { | 1537 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { |
| 1545 if (kind_ == Code::KEYED_CALL_IC) { | 1538 if (kind_ == Code::KEYED_CALL_IC) { |
| 1546 __ cmp(r2, Operand(name)); | 1539 __ cmp(r2, Operand(name)); |
| 1547 __ b(ne, miss); | 1540 __ b(ne, miss); |
| 1548 } | 1541 } |
| 1549 } | 1542 } |
| 1550 | 1543 |
| 1551 | 1544 |
| 1552 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object, | |
| 1553 Handle<JSObject> holder, | |
| 1554 Handle<Name> name, | |
| 1555 Label* miss) { | |
| 1556 ASSERT(holder->IsGlobalObject()); | |
| 1557 | |
| 1558 // Get the number of arguments. | |
| 1559 const int argc = arguments().immediate(); | |
| 1560 | |
| 1561 // Get the receiver from the stack. | |
| 1562 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | |
| 1563 | |
| 1564 // Check that the maps haven't changed. | |
| 1565 __ JumpIfSmi(r0, miss); | |
| 1566 CheckPrototypes( | |
| 1567 IC::CurrentTypeOf(object, isolate()), r0, holder, r3, r1, r4, name, miss); | |
| 1568 } | |
| 1569 | |
| 1570 | |
| 1571 void CallStubCompiler::GenerateLoadFunctionFromCell( | 1545 void CallStubCompiler::GenerateLoadFunctionFromCell( |
| 1572 Handle<Cell> cell, | 1546 Handle<Cell> cell, |
| 1573 Handle<JSFunction> function, | 1547 Handle<JSFunction> function, |
| 1574 Label* miss) { | 1548 Label* miss) { |
| 1575 // Get the value from the cell. | 1549 // Get the value from the cell. |
| 1576 __ mov(r3, Operand(cell)); | 1550 __ mov(r3, Operand(cell)); |
| 1577 __ ldr(r1, FieldMemOperand(r3, Cell::kValueOffset)); | 1551 __ ldr(r1, FieldMemOperand(r3, Cell::kValueOffset)); |
| 1578 | 1552 |
| 1579 // Check that the cell contains the same function. | 1553 // Check that the cell contains the same function. |
| 1580 if (heap()->InNewSpace(*function)) { | 1554 if (heap()->InNewSpace(*function)) { |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 1604 kind_, | 1578 kind_, |
| 1605 extra_state_); | 1579 extra_state_); |
| 1606 __ Jump(code, RelocInfo::CODE_TARGET); | 1580 __ Jump(code, RelocInfo::CODE_TARGET); |
| 1607 } | 1581 } |
| 1608 | 1582 |
| 1609 | 1583 |
| 1610 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, | 1584 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, |
| 1611 Handle<JSObject> holder, | 1585 Handle<JSObject> holder, |
| 1612 PropertyIndex index, | 1586 PropertyIndex index, |
| 1613 Handle<Name> name) { | 1587 Handle<Name> name) { |
| 1614 // ----------- S t a t e ------------- | |
| 1615 // -- r2 : name | |
| 1616 // -- lr : return address | |
| 1617 // ----------------------------------- | |
|
Igor Sheludko
2013/11/25 16:31:53
Are these (and similar) comments really useless he
Toon Verwaest
2013/11/27 15:16:55
Yes they are. Look at Load/Store, that's what I wa
| |
| 1618 Label miss; | 1588 Label miss; |
| 1619 | 1589 |
| 1620 GenerateNameCheck(name, &miss); | 1590 Register reg = HandlerFrontendHeader( |
| 1621 | 1591 object, holder, name, RECEIVER_MAP_CHECK, &miss); |
| 1622 const int argc = arguments().immediate(); | |
| 1623 | |
| 1624 // Get the receiver of the function from the stack into r0. | |
| 1625 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | |
| 1626 // Check that the receiver isn't a smi. | |
| 1627 __ JumpIfSmi(r0, &miss); | |
| 1628 | |
| 1629 // Do the right check and compute the holder register. | |
| 1630 Register reg = CheckPrototypes( | |
| 1631 IC::CurrentTypeOf(object, isolate()), | |
| 1632 r0, holder, r1, r3, r4, name, &miss); | |
| 1633 GenerateFastPropertyLoad(masm(), r1, reg, index.is_inobject(holder), | 1592 GenerateFastPropertyLoad(masm(), r1, reg, index.is_inobject(holder), |
| 1634 index.translate(holder), Representation::Tagged()); | 1593 index.translate(holder), Representation::Tagged()); |
| 1635 | 1594 |
| 1636 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); | 1595 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); |
| 1637 | 1596 |
| 1638 // Handle call cache miss. | 1597 HandlerFrontendFooter(&miss); |
| 1639 __ bind(&miss); | |
| 1640 GenerateMissBranch(); | |
| 1641 | 1598 |
| 1642 // Return the generated code. | 1599 // Return the generated code. |
| 1643 return GetCode(Code::FAST, name); | 1600 return GetCode(Code::FAST, name); |
| 1644 } | 1601 } |
| 1645 | 1602 |
| 1646 | 1603 |
| 1647 Handle<Code> CallStubCompiler::CompileArrayCodeCall( | 1604 Handle<Code> CallStubCompiler::CompileArrayCodeCall( |
| 1648 Handle<Object> object, | 1605 Handle<Object> object, |
| 1649 Handle<JSObject> holder, | 1606 Handle<JSObject> holder, |
| 1650 Handle<Cell> cell, | 1607 Handle<Cell> cell, |
| 1651 Handle<JSFunction> function, | 1608 Handle<JSFunction> function, |
| 1652 Handle<String> name, | 1609 Handle<String> name, |
| 1653 Code::StubType type) { | 1610 Code::StubType type) { |
| 1654 Label miss; | 1611 Label miss; |
| 1655 | 1612 |
| 1656 // Check that function is still array | 1613 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); |
|
Igor Sheludko
2013/11/25 16:31:53
Eagle's eye!
| |
| 1657 const int argc = arguments().immediate(); | 1614 if (!cell.is_null()) { |
| 1658 GenerateNameCheck(name, &miss); | |
| 1659 Register receiver = r1; | |
| 1660 | |
| 1661 if (cell.is_null()) { | |
| 1662 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); | |
| 1663 | |
| 1664 // Check that the receiver isn't a smi. | |
| 1665 __ JumpIfSmi(receiver, &miss); | |
| 1666 | |
| 1667 // Check that the maps haven't changed. | |
| 1668 CheckPrototypes( | |
| 1669 IC::CurrentTypeOf(object, isolate()), receiver, holder, | |
| 1670 r3, r0, r4, name, &miss); | |
| 1671 } else { | |
| 1672 ASSERT(cell->value() == *function); | 1615 ASSERT(cell->value() == *function); |
| 1673 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | |
| 1674 &miss); | |
| 1675 GenerateLoadFunctionFromCell(cell, function, &miss); | 1616 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 1676 } | 1617 } |
| 1677 | 1618 |
| 1678 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); | 1619 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); |
| 1679 site->SetElementsKind(GetInitialFastElementsKind()); | 1620 site->SetElementsKind(GetInitialFastElementsKind()); |
| 1680 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); | 1621 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); |
| 1622 const int argc = arguments().immediate(); | |
| 1681 __ mov(r0, Operand(argc)); | 1623 __ mov(r0, Operand(argc)); |
| 1682 __ mov(r2, Operand(site_feedback_cell)); | 1624 __ mov(r2, Operand(site_feedback_cell)); |
| 1683 __ mov(r1, Operand(function)); | 1625 __ mov(r1, Operand(function)); |
| 1684 | 1626 |
| 1685 ArrayConstructorStub stub(isolate()); | 1627 ArrayConstructorStub stub(isolate()); |
| 1686 __ TailCallStub(&stub); | 1628 __ TailCallStub(&stub); |
| 1687 | 1629 |
| 1688 __ bind(&miss); | 1630 HandlerFrontendFooter(&miss); |
| 1689 GenerateMissBranch(); | |
| 1690 | 1631 |
| 1691 // Return the generated code. | 1632 // Return the generated code. |
| 1692 return GetCode(type, name); | 1633 return GetCode(type, name); |
| 1693 } | 1634 } |
| 1694 | 1635 |
| 1695 | 1636 |
| 1696 Handle<Code> CallStubCompiler::CompileArrayPushCall( | 1637 Handle<Code> CallStubCompiler::CompileArrayPushCall( |
| 1697 Handle<Object> object, | 1638 Handle<Object> object, |
| 1698 Handle<JSObject> holder, | 1639 Handle<JSObject> holder, |
| 1699 Handle<Cell> cell, | 1640 Handle<Cell> cell, |
| 1700 Handle<JSFunction> function, | 1641 Handle<JSFunction> function, |
| 1701 Handle<String> name, | 1642 Handle<String> name, |
| 1702 Code::StubType type) { | 1643 Code::StubType type) { |
| 1703 // ----------- S t a t e ------------- | |
| 1704 // -- r2 : name | |
| 1705 // -- lr : return address | |
| 1706 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | |
| 1707 // -- ... | |
| 1708 // -- sp[argc * 4] : receiver | |
| 1709 // ----------------------------------- | |
| 1710 | |
| 1711 // If object is not an array or is observed, bail out to regular call. | 1644 // If object is not an array or is observed, bail out to regular call. |
| 1712 if (!object->IsJSArray() || | 1645 if (!object->IsJSArray() || |
| 1713 !cell.is_null() || | 1646 !cell.is_null() || |
| 1714 Handle<JSArray>::cast(object)->map()->is_observed()) { | 1647 Handle<JSArray>::cast(object)->map()->is_observed()) { |
| 1715 return Handle<Code>::null(); | 1648 return Handle<Code>::null(); |
| 1716 } | 1649 } |
| 1717 | 1650 |
| 1718 Label miss; | 1651 Label miss; |
| 1719 GenerateNameCheck(name, &miss); | |
| 1720 | 1652 |
| 1653 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); | |
| 1721 Register receiver = r1; | 1654 Register receiver = r1; |
| 1722 // Get the receiver from the stack | 1655 |
| 1723 const int argc = arguments().immediate(); | 1656 const int argc = arguments().immediate(); |
| 1724 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); | |
| 1725 | |
| 1726 // Check that the receiver isn't a smi. | |
| 1727 __ JumpIfSmi(receiver, &miss); | |
| 1728 | |
| 1729 // Check that the maps haven't changed. | |
| 1730 CheckPrototypes( | |
| 1731 IC::CurrentTypeOf(object, isolate()), receiver, holder, | |
| 1732 r3, r0, r4, name, &miss); | |
| 1733 | |
| 1734 if (argc == 0) { | 1657 if (argc == 0) { |
| 1735 // Nothing to do, just return the length. | 1658 // Nothing to do, just return the length. |
| 1736 __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1659 __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
| 1737 __ Drop(argc + 1); | 1660 __ Drop(argc + 1); |
| 1738 __ Ret(); | 1661 __ Ret(); |
| 1739 } else { | 1662 } else { |
| 1740 Label call_builtin; | 1663 Label call_builtin; |
| 1741 | 1664 |
| 1742 if (argc == 1) { // Otherwise fall through to call the builtin. | 1665 if (argc == 1) { // Otherwise fall through to call the builtin. |
| 1743 Label attempt_to_grow_elements, with_write_barrier, check_double; | 1666 Label attempt_to_grow_elements, with_write_barrier, check_double; |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1936 | 1859 |
| 1937 // Elements are in new space, so write barrier is not required. | 1860 // Elements are in new space, so write barrier is not required. |
| 1938 __ Drop(argc + 1); | 1861 __ Drop(argc + 1); |
| 1939 __ Ret(); | 1862 __ Ret(); |
| 1940 } | 1863 } |
| 1941 __ bind(&call_builtin); | 1864 __ bind(&call_builtin); |
| 1942 __ TailCallExternalReference( | 1865 __ TailCallExternalReference( |
| 1943 ExternalReference(Builtins::c_ArrayPush, isolate()), argc + 1, 1); | 1866 ExternalReference(Builtins::c_ArrayPush, isolate()), argc + 1, 1); |
| 1944 } | 1867 } |
| 1945 | 1868 |
| 1946 // Handle call cache miss. | 1869 HandlerFrontendFooter(&miss); |
| 1947 __ bind(&miss); | |
| 1948 GenerateMissBranch(); | |
| 1949 | 1870 |
| 1950 // Return the generated code. | 1871 // Return the generated code. |
| 1951 return GetCode(type, name); | 1872 return GetCode(type, name); |
| 1952 } | 1873 } |
| 1953 | 1874 |
| 1954 | 1875 |
| 1955 Handle<Code> CallStubCompiler::CompileArrayPopCall( | 1876 Handle<Code> CallStubCompiler::CompileArrayPopCall( |
| 1956 Handle<Object> object, | 1877 Handle<Object> object, |
| 1957 Handle<JSObject> holder, | 1878 Handle<JSObject> holder, |
| 1958 Handle<Cell> cell, | 1879 Handle<Cell> cell, |
| 1959 Handle<JSFunction> function, | 1880 Handle<JSFunction> function, |
| 1960 Handle<String> name, | 1881 Handle<String> name, |
| 1961 Code::StubType type) { | 1882 Code::StubType type) { |
| 1962 // ----------- S t a t e ------------- | |
| 1963 // -- r2 : name | |
| 1964 // -- lr : return address | |
| 1965 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | |
| 1966 // -- ... | |
| 1967 // -- sp[argc * 4] : receiver | |
| 1968 // ----------------------------------- | |
| 1969 | |
| 1970 // If object is not an array or is observed, bail out to regular call. | 1883 // If object is not an array or is observed, bail out to regular call. |
| 1971 if (!object->IsJSArray() || | 1884 if (!object->IsJSArray() || |
| 1972 !cell.is_null() || | 1885 !cell.is_null() || |
| 1973 Handle<JSArray>::cast(object)->map()->is_observed()) { | 1886 Handle<JSArray>::cast(object)->map()->is_observed()) { |
| 1974 return Handle<Code>::null(); | 1887 return Handle<Code>::null(); |
| 1975 } | 1888 } |
| 1976 | 1889 |
| 1977 Label miss, return_undefined, call_builtin; | 1890 Label miss, return_undefined, call_builtin; |
| 1978 Register receiver = r1; | 1891 Register receiver = r1; |
| 1979 Register elements = r3; | 1892 Register elements = r3; |
| 1980 GenerateNameCheck(name, &miss); | |
| 1981 | 1893 |
| 1982 // Get the receiver from the stack | 1894 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); |
| 1983 const int argc = arguments().immediate(); | |
| 1984 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); | |
| 1985 // Check that the receiver isn't a smi. | |
| 1986 __ JumpIfSmi(receiver, &miss); | |
| 1987 | |
| 1988 // Check that the maps haven't changed. | |
| 1989 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), receiver, holder, | |
| 1990 elements, r4, r0, name, &miss); | |
| 1991 | 1895 |
| 1992 // Get the elements array of the object. | 1896 // Get the elements array of the object. |
| 1993 __ ldr(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); | 1897 __ ldr(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); |
| 1994 | 1898 |
| 1995 // Check that the elements are in fast mode and writable. | 1899 // Check that the elements are in fast mode and writable. |
| 1996 __ CheckMap(elements, | 1900 __ CheckMap(elements, |
| 1997 r0, | 1901 r0, |
| 1998 Heap::kFixedArrayMapRootIndex, | 1902 Heap::kFixedArrayMapRootIndex, |
| 1999 &call_builtin, | 1903 &call_builtin, |
| 2000 DONT_DO_SMI_CHECK); | 1904 DONT_DO_SMI_CHECK); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 2011 __ add(elements, elements, Operand::PointerOffsetFromSmiKey(r4)); | 1915 __ add(elements, elements, Operand::PointerOffsetFromSmiKey(r4)); |
| 2012 __ ldr(r0, FieldMemOperand(elements, FixedArray::kHeaderSize)); | 1916 __ ldr(r0, FieldMemOperand(elements, FixedArray::kHeaderSize)); |
| 2013 __ cmp(r0, r6); | 1917 __ cmp(r0, r6); |
| 2014 __ b(eq, &call_builtin); | 1918 __ b(eq, &call_builtin); |
| 2015 | 1919 |
| 2016 // Set the array's length. | 1920 // Set the array's length. |
| 2017 __ str(r4, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1921 __ str(r4, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
| 2018 | 1922 |
| 2019 // Fill with the hole. | 1923 // Fill with the hole. |
| 2020 __ str(r6, FieldMemOperand(elements, FixedArray::kHeaderSize)); | 1924 __ str(r6, FieldMemOperand(elements, FixedArray::kHeaderSize)); |
| 1925 const int argc = arguments().immediate(); | |
| 2021 __ Drop(argc + 1); | 1926 __ Drop(argc + 1); |
| 2022 __ Ret(); | 1927 __ Ret(); |
| 2023 | 1928 |
| 2024 __ bind(&return_undefined); | 1929 __ bind(&return_undefined); |
| 2025 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); | 1930 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); |
| 2026 __ Drop(argc + 1); | 1931 __ Drop(argc + 1); |
| 2027 __ Ret(); | 1932 __ Ret(); |
| 2028 | 1933 |
| 2029 __ bind(&call_builtin); | 1934 __ bind(&call_builtin); |
| 2030 __ TailCallExternalReference( | 1935 __ TailCallExternalReference( |
| 2031 ExternalReference(Builtins::c_ArrayPop, isolate()), argc + 1, 1); | 1936 ExternalReference(Builtins::c_ArrayPop, isolate()), argc + 1, 1); |
| 2032 | 1937 |
| 2033 // Handle call cache miss. | 1938 HandlerFrontendFooter(&miss); |
| 2034 __ bind(&miss); | |
| 2035 GenerateMissBranch(); | |
| 2036 | 1939 |
| 2037 // Return the generated code. | 1940 // Return the generated code. |
| 2038 return GetCode(type, name); | 1941 return GetCode(type, name); |
| 2039 } | 1942 } |
| 2040 | 1943 |
| 2041 | 1944 |
| 2042 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall( | 1945 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall( |
| 2043 Handle<Object> object, | 1946 Handle<Object> object, |
| 2044 Handle<JSObject> holder, | 1947 Handle<JSObject> holder, |
| 2045 Handle<Cell> cell, | 1948 Handle<Cell> cell, |
| 2046 Handle<JSFunction> function, | 1949 Handle<JSFunction> function, |
| 2047 Handle<String> name, | 1950 Handle<String> name, |
| 2048 Code::StubType type) { | 1951 Code::StubType type) { |
| 2049 // ----------- S t a t e ------------- | |
| 2050 // -- r2 : function name | |
| 2051 // -- lr : return address | |
| 2052 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | |
| 2053 // -- ... | |
| 2054 // -- sp[argc * 4] : receiver | |
| 2055 // ----------------------------------- | |
| 2056 | |
| 2057 // If object is not a string, bail out to regular call. | 1952 // If object is not a string, bail out to regular call. |
| 2058 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); | 1953 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); |
| 2059 | 1954 |
| 2060 const int argc = arguments().immediate(); | |
| 2061 Label miss; | 1955 Label miss; |
| 2062 Label name_miss; | 1956 Label name_miss; |
| 2063 Label index_out_of_range; | 1957 Label index_out_of_range; |
| 2064 Label* index_out_of_range_label = &index_out_of_range; | 1958 Label* index_out_of_range_label = &index_out_of_range; |
| 2065 | 1959 |
| 2066 if (kind_ == Code::CALL_IC && | 1960 if (kind_ == Code::CALL_IC && |
| 2067 (CallICBase::StringStubState::decode(extra_state_) == | 1961 (CallICBase::StringStubState::decode(extra_state_) == |
| 2068 DEFAULT_STRING_STUB)) { | 1962 DEFAULT_STRING_STUB)) { |
| 2069 index_out_of_range_label = &miss; | 1963 index_out_of_range_label = &miss; |
| 2070 } | 1964 } |
| 2071 GenerateNameCheck(name, &name_miss); | |
| 2072 | 1965 |
| 2073 // Check that the maps starting from the prototype haven't changed. | 1966 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss); |
| 2074 GenerateDirectLoadGlobalFunctionPrototype(masm(), | |
| 2075 Context::STRING_FUNCTION_INDEX, | |
| 2076 r0, | |
| 2077 &miss); | |
| 2078 ASSERT(!object.is_identical_to(holder)); | |
| 2079 Handle<JSObject> prototype(JSObject::cast(object->GetPrototype(isolate()))); | |
| 2080 CheckPrototypes( | |
| 2081 IC::CurrentTypeOf(prototype, isolate()), | |
| 2082 r0, holder, r1, r3, r4, name, &miss); | |
| 2083 | 1967 |
| 2084 Register receiver = r1; | 1968 Register receiver = r1; |
| 2085 Register index = r4; | 1969 Register index = r4; |
| 2086 Register result = r0; | 1970 Register result = r0; |
| 1971 const int argc = arguments().immediate(); | |
| 2087 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); | 1972 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); |
| 2088 if (argc > 0) { | 1973 if (argc > 0) { |
| 2089 __ ldr(index, MemOperand(sp, (argc - 1) * kPointerSize)); | 1974 __ ldr(index, MemOperand(sp, (argc - 1) * kPointerSize)); |
| 2090 } else { | 1975 } else { |
| 2091 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); | 1976 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); |
| 2092 } | 1977 } |
| 2093 | 1978 |
| 2094 StringCharCodeAtGenerator generator(receiver, | 1979 StringCharCodeAtGenerator generator(receiver, |
| 2095 index, | 1980 index, |
| 2096 result, | 1981 result, |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 2123 } | 2008 } |
| 2124 | 2009 |
| 2125 | 2010 |
| 2126 Handle<Code> CallStubCompiler::CompileStringCharAtCall( | 2011 Handle<Code> CallStubCompiler::CompileStringCharAtCall( |
| 2127 Handle<Object> object, | 2012 Handle<Object> object, |
| 2128 Handle<JSObject> holder, | 2013 Handle<JSObject> holder, |
| 2129 Handle<Cell> cell, | 2014 Handle<Cell> cell, |
| 2130 Handle<JSFunction> function, | 2015 Handle<JSFunction> function, |
| 2131 Handle<String> name, | 2016 Handle<String> name, |
| 2132 Code::StubType type) { | 2017 Code::StubType type) { |
| 2133 // ----------- S t a t e ------------- | |
| 2134 // -- r2 : function name | |
| 2135 // -- lr : return address | |
| 2136 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | |
| 2137 // -- ... | |
| 2138 // -- sp[argc * 4] : receiver | |
| 2139 // ----------------------------------- | |
| 2140 | |
| 2141 // If object is not a string, bail out to regular call. | 2018 // If object is not a string, bail out to regular call. |
| 2142 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); | 2019 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); |
| 2143 | 2020 |
| 2144 const int argc = arguments().immediate(); | 2021 const int argc = arguments().immediate(); |
| 2145 Label miss; | 2022 Label miss; |
| 2146 Label name_miss; | 2023 Label name_miss; |
| 2147 Label index_out_of_range; | 2024 Label index_out_of_range; |
| 2148 Label* index_out_of_range_label = &index_out_of_range; | 2025 Label* index_out_of_range_label = &index_out_of_range; |
| 2149 if (kind_ == Code::CALL_IC && | 2026 if (kind_ == Code::CALL_IC && |
| 2150 (CallICBase::StringStubState::decode(extra_state_) == | 2027 (CallICBase::StringStubState::decode(extra_state_) == |
| 2151 DEFAULT_STRING_STUB)) { | 2028 DEFAULT_STRING_STUB)) { |
| 2152 index_out_of_range_label = &miss; | 2029 index_out_of_range_label = &miss; |
| 2153 } | 2030 } |
| 2154 GenerateNameCheck(name, &name_miss); | |
| 2155 | 2031 |
| 2156 // Check that the maps starting from the prototype haven't changed. | 2032 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss); |
| 2157 GenerateDirectLoadGlobalFunctionPrototype(masm(), | |
| 2158 Context::STRING_FUNCTION_INDEX, | |
| 2159 r0, | |
| 2160 &miss); | |
| 2161 ASSERT(!object.is_identical_to(holder)); | |
| 2162 Handle<JSObject> prototype(JSObject::cast(object->GetPrototype(isolate()))); | |
| 2163 CheckPrototypes( | |
| 2164 IC::CurrentTypeOf(prototype, isolate()), | |
| 2165 r0, holder, r1, r3, r4, name, &miss); | |
| 2166 | 2033 |
| 2167 Register receiver = r0; | 2034 Register receiver = r0; |
| 2168 Register index = r4; | 2035 Register index = r4; |
| 2169 Register scratch = r3; | 2036 Register scratch = r3; |
| 2170 Register result = r0; | 2037 Register result = r0; |
| 2171 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); | 2038 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); |
| 2172 if (argc > 0) { | 2039 if (argc > 0) { |
| 2173 __ ldr(index, MemOperand(sp, (argc - 1) * kPointerSize)); | 2040 __ ldr(index, MemOperand(sp, (argc - 1) * kPointerSize)); |
| 2174 } else { | 2041 } else { |
| 2175 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); | 2042 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2208 } | 2075 } |
| 2209 | 2076 |
| 2210 | 2077 |
| 2211 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( | 2078 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( |
| 2212 Handle<Object> object, | 2079 Handle<Object> object, |
| 2213 Handle<JSObject> holder, | 2080 Handle<JSObject> holder, |
| 2214 Handle<Cell> cell, | 2081 Handle<Cell> cell, |
| 2215 Handle<JSFunction> function, | 2082 Handle<JSFunction> function, |
| 2216 Handle<String> name, | 2083 Handle<String> name, |
| 2217 Code::StubType type) { | 2084 Code::StubType type) { |
| 2218 // ----------- S t a t e ------------- | |
| 2219 // -- r2 : function name | |
| 2220 // -- lr : return address | |
| 2221 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | |
| 2222 // -- ... | |
| 2223 // -- sp[argc * 4] : receiver | |
| 2224 // ----------------------------------- | |
| 2225 | |
| 2226 const int argc = arguments().immediate(); | 2085 const int argc = arguments().immediate(); |
| 2227 | 2086 |
| 2228 // If the object is not a JSObject or we got an unexpected number of | 2087 // If the object is not a JSObject or we got an unexpected number of |
| 2229 // arguments, bail out to the regular call. | 2088 // arguments, bail out to the regular call. |
| 2230 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); | 2089 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); |
| 2231 | 2090 |
| 2232 Label miss; | 2091 Label miss; |
| 2233 GenerateNameCheck(name, &miss); | |
| 2234 | 2092 |
| 2235 if (cell.is_null()) { | 2093 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); |
| 2236 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); | 2094 if (!cell.is_null()) { |
| 2237 | |
| 2238 __ JumpIfSmi(r1, &miss); | |
| 2239 | |
| 2240 CheckPrototypes( | |
| 2241 IC::CurrentTypeOf(object, isolate()), | |
| 2242 r1, holder, r0, r3, r4, name, &miss); | |
| 2243 } else { | |
| 2244 ASSERT(cell->value() == *function); | 2095 ASSERT(cell->value() == *function); |
| 2245 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | |
| 2246 &miss); | |
| 2247 GenerateLoadFunctionFromCell(cell, function, &miss); | 2096 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 2248 } | 2097 } |
| 2249 | 2098 |
| 2250 // Load the char code argument. | 2099 // Load the char code argument. |
| 2251 Register code = r1; | 2100 Register code = r1; |
| 2252 __ ldr(code, MemOperand(sp, 0 * kPointerSize)); | 2101 __ ldr(code, MemOperand(sp, 0 * kPointerSize)); |
| 2253 | 2102 |
| 2254 // Check the code is a smi. | 2103 // Check the code is a smi. |
| 2255 Label slow; | 2104 Label slow; |
| 2256 __ JumpIfNotSmi(code, &slow); | 2105 __ JumpIfNotSmi(code, &slow); |
| 2257 | 2106 |
| 2258 // Convert the smi code to uint16. | 2107 // Convert the smi code to uint16. |
| 2259 __ and_(code, code, Operand(Smi::FromInt(0xffff))); | 2108 __ and_(code, code, Operand(Smi::FromInt(0xffff))); |
| 2260 | 2109 |
| 2261 StringCharFromCodeGenerator generator(code, r0); | 2110 StringCharFromCodeGenerator generator(code, r0); |
| 2262 generator.GenerateFast(masm()); | 2111 generator.GenerateFast(masm()); |
| 2263 __ Drop(argc + 1); | 2112 __ Drop(argc + 1); |
| 2264 __ Ret(); | 2113 __ Ret(); |
| 2265 | 2114 |
| 2266 StubRuntimeCallHelper call_helper; | 2115 StubRuntimeCallHelper call_helper; |
| 2267 generator.GenerateSlow(masm(), call_helper); | 2116 generator.GenerateSlow(masm(), call_helper); |
| 2268 | 2117 |
| 2269 // Tail call the full function. We do not have to patch the receiver | 2118 // Tail call the full function. We do not have to patch the receiver |
| 2270 // because the function makes no use of it. | 2119 // because the function makes no use of it. |
| 2271 __ bind(&slow); | 2120 __ bind(&slow); |
| 2272 ParameterCount expected(function); | 2121 ParameterCount expected(function); |
| 2273 __ InvokeFunction(function, expected, arguments(), | 2122 __ InvokeFunction(function, expected, arguments(), |
| 2274 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 2123 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); |
| 2275 | 2124 |
| 2276 __ bind(&miss); | 2125 HandlerFrontendFooter(&miss); |
| 2277 // r2: function name. | |
| 2278 GenerateMissBranch(); | |
| 2279 | 2126 |
| 2280 // Return the generated code. | 2127 // Return the generated code. |
| 2281 return GetCode(type, name); | 2128 return GetCode(type, name); |
| 2282 } | 2129 } |
| 2283 | 2130 |
| 2284 | 2131 |
| 2285 Handle<Code> CallStubCompiler::CompileMathFloorCall( | 2132 Handle<Code> CallStubCompiler::CompileMathFloorCall( |
| 2286 Handle<Object> object, | 2133 Handle<Object> object, |
| 2287 Handle<JSObject> holder, | 2134 Handle<JSObject> holder, |
| 2288 Handle<Cell> cell, | 2135 Handle<Cell> cell, |
| 2289 Handle<JSFunction> function, | 2136 Handle<JSFunction> function, |
| 2290 Handle<String> name, | 2137 Handle<String> name, |
| 2291 Code::StubType type) { | 2138 Code::StubType type) { |
| 2292 // ----------- S t a t e ------------- | |
| 2293 // -- r2 : function name | |
| 2294 // -- lr : return address | |
| 2295 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | |
| 2296 // -- ... | |
| 2297 // -- sp[argc * 4] : receiver | |
| 2298 // ----------------------------------- | |
| 2299 | |
| 2300 const int argc = arguments().immediate(); | 2139 const int argc = arguments().immediate(); |
| 2301 // If the object is not a JSObject or we got an unexpected number of | 2140 // If the object is not a JSObject or we got an unexpected number of |
| 2302 // arguments, bail out to the regular call. | 2141 // arguments, bail out to the regular call. |
| 2303 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); | 2142 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); |
| 2304 | 2143 |
| 2305 Label miss, slow; | 2144 Label miss, slow; |
| 2306 GenerateNameCheck(name, &miss); | |
| 2307 | 2145 |
| 2308 if (cell.is_null()) { | 2146 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); |
| 2309 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); | 2147 if (!cell.is_null()) { |
| 2310 __ JumpIfSmi(r1, &miss); | |
| 2311 CheckPrototypes( | |
| 2312 IC::CurrentTypeOf(object, isolate()), | |
| 2313 r1, holder, r0, r3, r4, name, &miss); | |
| 2314 } else { | |
| 2315 ASSERT(cell->value() == *function); | 2148 ASSERT(cell->value() == *function); |
| 2316 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | |
| 2317 &miss); | |
| 2318 GenerateLoadFunctionFromCell(cell, function, &miss); | 2149 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 2319 } | 2150 } |
| 2320 | 2151 |
| 2321 // Load the (only) argument into r0. | 2152 // Load the (only) argument into r0. |
| 2322 __ ldr(r0, MemOperand(sp, 0 * kPointerSize)); | 2153 __ ldr(r0, MemOperand(sp, 0 * kPointerSize)); |
| 2323 | 2154 |
| 2324 // If the argument is a smi, just return. | 2155 // If the argument is a smi, just return. |
| 2325 __ SmiTst(r0); | 2156 __ SmiTst(r0); |
| 2326 __ Drop(argc + 1, eq); | 2157 __ Drop(argc + 1, eq); |
| 2327 __ Ret(eq); | 2158 __ Ret(eq); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2376 __ Drop(argc + 1); | 2207 __ Drop(argc + 1); |
| 2377 __ Ret(); | 2208 __ Ret(); |
| 2378 | 2209 |
| 2379 __ bind(&slow); | 2210 __ bind(&slow); |
| 2380 // Tail call the full function. We do not have to patch the receiver | 2211 // Tail call the full function. We do not have to patch the receiver |
| 2381 // because the function makes no use of it. | 2212 // because the function makes no use of it. |
| 2382 ParameterCount expected(function); | 2213 ParameterCount expected(function); |
| 2383 __ InvokeFunction(function, expected, arguments(), | 2214 __ InvokeFunction(function, expected, arguments(), |
| 2384 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 2215 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); |
| 2385 | 2216 |
| 2386 __ bind(&miss); | 2217 HandlerFrontendFooter(&miss); |
| 2387 // r2: function name. | |
| 2388 GenerateMissBranch(); | |
| 2389 | 2218 |
| 2390 // Return the generated code. | 2219 // Return the generated code. |
| 2391 return GetCode(type, name); | 2220 return GetCode(type, name); |
| 2392 } | 2221 } |
| 2393 | 2222 |
| 2394 | 2223 |
| 2395 Handle<Code> CallStubCompiler::CompileMathAbsCall( | 2224 Handle<Code> CallStubCompiler::CompileMathAbsCall( |
| 2396 Handle<Object> object, | 2225 Handle<Object> object, |
| 2397 Handle<JSObject> holder, | 2226 Handle<JSObject> holder, |
| 2398 Handle<Cell> cell, | 2227 Handle<Cell> cell, |
| 2399 Handle<JSFunction> function, | 2228 Handle<JSFunction> function, |
| 2400 Handle<String> name, | 2229 Handle<String> name, |
| 2401 Code::StubType type) { | 2230 Code::StubType type) { |
| 2402 // ----------- S t a t e ------------- | |
| 2403 // -- r2 : function name | |
| 2404 // -- lr : return address | |
| 2405 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | |
| 2406 // -- ... | |
| 2407 // -- sp[argc * 4] : receiver | |
| 2408 // ----------------------------------- | |
| 2409 | |
| 2410 const int argc = arguments().immediate(); | 2231 const int argc = arguments().immediate(); |
| 2411 // If the object is not a JSObject or we got an unexpected number of | 2232 // If the object is not a JSObject or we got an unexpected number of |
| 2412 // arguments, bail out to the regular call. | 2233 // arguments, bail out to the regular call. |
| 2413 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); | 2234 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); |
| 2414 | 2235 |
| 2415 Label miss; | 2236 Label miss; |
| 2416 GenerateNameCheck(name, &miss); | 2237 |
| 2417 if (cell.is_null()) { | 2238 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); |
| 2418 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); | 2239 if (!cell.is_null()) { |
| 2419 __ JumpIfSmi(r1, &miss); | |
| 2420 CheckPrototypes( | |
| 2421 IC::CurrentTypeOf(object, isolate()), | |
| 2422 r1, holder, r0, r3, r4, name, &miss); | |
| 2423 } else { | |
| 2424 ASSERT(cell->value() == *function); | 2240 ASSERT(cell->value() == *function); |
| 2425 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | |
| 2426 &miss); | |
| 2427 GenerateLoadFunctionFromCell(cell, function, &miss); | 2241 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 2428 } | 2242 } |
| 2429 | 2243 |
| 2430 // Load the (only) argument into r0. | 2244 // Load the (only) argument into r0. |
| 2431 __ ldr(r0, MemOperand(sp, 0 * kPointerSize)); | 2245 __ ldr(r0, MemOperand(sp, 0 * kPointerSize)); |
| 2432 | 2246 |
| 2433 // Check if the argument is a smi. | 2247 // Check if the argument is a smi. |
| 2434 Label not_smi; | 2248 Label not_smi; |
| 2435 __ JumpIfNotSmi(r0, ¬_smi); | 2249 __ JumpIfNotSmi(r0, ¬_smi); |
| 2436 | 2250 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2476 __ Drop(argc + 1); | 2290 __ Drop(argc + 1); |
| 2477 __ Ret(); | 2291 __ Ret(); |
| 2478 | 2292 |
| 2479 // Tail call the full function. We do not have to patch the receiver | 2293 // Tail call the full function. We do not have to patch the receiver |
| 2480 // because the function makes no use of it. | 2294 // because the function makes no use of it. |
| 2481 __ bind(&slow); | 2295 __ bind(&slow); |
| 2482 ParameterCount expected(function); | 2296 ParameterCount expected(function); |
| 2483 __ InvokeFunction(function, expected, arguments(), | 2297 __ InvokeFunction(function, expected, arguments(), |
| 2484 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 2298 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); |
| 2485 | 2299 |
| 2486 __ bind(&miss); | 2300 HandlerFrontendFooter(&miss); |
| 2487 // r2: function name. | |
| 2488 GenerateMissBranch(); | |
| 2489 | 2301 |
| 2490 // Return the generated code. | 2302 // Return the generated code. |
| 2491 return GetCode(type, name); | 2303 return GetCode(type, name); |
| 2492 } | 2304 } |
| 2493 | 2305 |
| 2494 | 2306 |
| 2495 Handle<Code> CallStubCompiler::CompileFastApiCall( | 2307 Handle<Code> CallStubCompiler::CompileFastApiCall( |
| 2496 const CallOptimization& optimization, | 2308 const CallOptimization& optimization, |
| 2497 Handle<Object> object, | 2309 Handle<Object> object, |
| 2498 Handle<JSObject> holder, | 2310 Handle<JSObject> holder, |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2550 __ LoadRoot(ip, Heap::kTrueValueRootIndex); | 2362 __ LoadRoot(ip, Heap::kTrueValueRootIndex); |
| 2551 __ cmp(object, ip); | 2363 __ cmp(object, ip); |
| 2552 __ b(eq, &success); | 2364 __ b(eq, &success); |
| 2553 __ LoadRoot(ip, Heap::kFalseValueRootIndex); | 2365 __ LoadRoot(ip, Heap::kFalseValueRootIndex); |
| 2554 __ cmp(object, ip); | 2366 __ cmp(object, ip); |
| 2555 __ b(ne, miss); | 2367 __ b(ne, miss); |
| 2556 __ bind(&success); | 2368 __ bind(&success); |
| 2557 } | 2369 } |
| 2558 | 2370 |
| 2559 | 2371 |
| 2560 void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object, | 2372 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object, |
| 2561 Handle<JSObject> holder, | 2373 Handle<JSObject> holder, |
| 2562 Handle<Name> name, | 2374 Handle<Name> name, |
| 2563 CheckType check) { | 2375 CheckType check, |
| 2376 Label* miss) { | |
| 2564 // ----------- S t a t e ------------- | 2377 // ----------- S t a t e ------------- |
| 2565 // -- r2 : name | 2378 // -- r2 : name |
| 2566 // -- lr : return address | 2379 // -- lr : return address |
| 2567 // ----------------------------------- | 2380 // ----------------------------------- |
|
Igor Sheludko
2013/11/25 16:31:53
What do you think about putting these comments her
Toon Verwaest
2013/11/27 15:16:55
I removed the comment altogether. I prefer to add
| |
| 2568 Label miss; | 2381 GenerateNameCheck(name, miss); |
| 2569 GenerateNameCheck(name, &miss); | 2382 |
| 2383 Register reg = r1; | |
|
Igor Sheludko
2013/11/25 16:31:53
It looks like the other usages of "r1" below shoul
Toon Verwaest
2013/11/27 15:16:55
Done.
| |
| 2570 | 2384 |
| 2571 // Get the receiver from the stack | 2385 // Get the receiver from the stack |
| 2572 const int argc = arguments().immediate(); | 2386 const int argc = arguments().immediate(); |
| 2573 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 2387 const int receiver_offset = argc * kPointerSize; |
| 2388 __ ldr(r1, MemOperand(sp, receiver_offset)); | |
| 2574 | 2389 |
| 2575 // Check that the receiver isn't a smi. | 2390 // Check that the receiver isn't a smi. |
| 2576 if (check != NUMBER_CHECK) { | 2391 if (check != NUMBER_CHECK) { |
| 2577 __ JumpIfSmi(r1, &miss); | 2392 __ JumpIfSmi(r1, miss); |
| 2578 } | 2393 } |
| 2579 | 2394 |
| 2580 // Make sure that it's okay not to patch the on stack receiver | 2395 // Make sure that it's okay not to patch the on stack receiver |
| 2581 // unless we're doing a receiver map check. | 2396 // unless we're doing a receiver map check. |
| 2582 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); | 2397 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); |
| 2583 switch (check) { | 2398 switch (check) { |
| 2584 case RECEIVER_MAP_CHECK: | 2399 case RECEIVER_MAP_CHECK: |
| 2585 __ IncrementCounter(isolate()->counters()->call_const(), 1, r0, r3); | 2400 __ IncrementCounter(isolate()->counters()->call_const(), 1, r0, r3); |
| 2586 | 2401 |
| 2587 // Check that the maps haven't changed. | 2402 // Check that the maps haven't changed. |
| 2588 CheckPrototypes( | 2403 reg = CheckPrototypes( |
| 2589 IC::CurrentTypeOf(object, isolate()), | 2404 IC::CurrentTypeOf(object, isolate()), |
| 2590 r1, holder, r0, r3, r4, name, &miss); | 2405 r1, holder, r0, r3, r4, name, miss); |
| 2591 | 2406 |
| 2592 // Patch the receiver on the stack with the global proxy if | 2407 // Patch the receiver on the stack with the global proxy if |
| 2593 // necessary. | 2408 // necessary. |
| 2594 if (object->IsGlobalObject()) { | 2409 if (object->IsGlobalObject()) { |
| 2595 __ ldr(r3, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 2410 __ ldr(r3, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
| 2596 __ str(r3, MemOperand(sp, argc * kPointerSize)); | 2411 __ str(r3, MemOperand(sp, receiver_offset)); |
| 2597 } | 2412 } |
| 2598 break; | 2413 break; |
| 2599 | 2414 |
| 2600 case STRING_CHECK: { | 2415 case STRING_CHECK: { |
| 2601 // Check that the object is a string. | 2416 // Check that the object is a string. |
| 2602 __ CompareObjectType(r1, r3, r3, FIRST_NONSTRING_TYPE); | 2417 __ CompareObjectType(r1, r3, r3, FIRST_NONSTRING_TYPE); |
| 2603 __ b(ge, &miss); | 2418 __ b(ge, miss); |
| 2604 // Check that the maps starting from the prototype haven't changed. | 2419 // Check that the maps starting from the prototype haven't changed. |
| 2605 GenerateDirectLoadGlobalFunctionPrototype( | 2420 GenerateDirectLoadGlobalFunctionPrototype( |
| 2606 masm(), Context::STRING_FUNCTION_INDEX, r0, &miss); | 2421 masm(), Context::STRING_FUNCTION_INDEX, r0, miss); |
| 2607 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); | |
| 2608 CheckPrototypes( | |
| 2609 IC::CurrentTypeOf(prototype, isolate()), | |
| 2610 r0, holder, r3, r1, r4, name, &miss); | |
| 2611 break; | 2422 break; |
| 2612 } | 2423 } |
| 2613 case SYMBOL_CHECK: { | 2424 case SYMBOL_CHECK: { |
| 2614 // Check that the object is a symbol. | 2425 // Check that the object is a symbol. |
| 2615 __ CompareObjectType(r1, r1, r3, SYMBOL_TYPE); | 2426 __ CompareObjectType(r1, r1, r3, SYMBOL_TYPE); |
| 2616 __ b(ne, &miss); | 2427 __ b(ne, miss); |
| 2617 // Check that the maps starting from the prototype haven't changed. | 2428 // Check that the maps starting from the prototype haven't changed. |
| 2618 GenerateDirectLoadGlobalFunctionPrototype( | 2429 GenerateDirectLoadGlobalFunctionPrototype( |
| 2619 masm(), Context::SYMBOL_FUNCTION_INDEX, r0, &miss); | 2430 masm(), Context::SYMBOL_FUNCTION_INDEX, r0, miss); |
| 2620 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); | |
| 2621 CheckPrototypes( | |
| 2622 IC::CurrentTypeOf(prototype, isolate()), | |
| 2623 r0, holder, r3, r1, r4, name, &miss); | |
| 2624 break; | 2431 break; |
| 2625 } | 2432 } |
| 2626 case NUMBER_CHECK: { | 2433 case NUMBER_CHECK: { |
| 2627 Label fast; | 2434 Label fast; |
| 2628 // Check that the object is a smi or a heap number. | 2435 // Check that the object is a smi or a heap number. |
| 2629 __ JumpIfSmi(r1, &fast); | 2436 __ JumpIfSmi(r1, &fast); |
| 2630 __ CompareObjectType(r1, r0, r0, HEAP_NUMBER_TYPE); | 2437 __ CompareObjectType(r1, r0, r0, HEAP_NUMBER_TYPE); |
| 2631 __ b(ne, &miss); | 2438 __ b(ne, miss); |
| 2632 __ bind(&fast); | 2439 __ bind(&fast); |
| 2633 // Check that the maps starting from the prototype haven't changed. | 2440 // Check that the maps starting from the prototype haven't changed. |
| 2634 GenerateDirectLoadGlobalFunctionPrototype( | 2441 GenerateDirectLoadGlobalFunctionPrototype( |
| 2635 masm(), Context::NUMBER_FUNCTION_INDEX, r0, &miss); | 2442 masm(), Context::NUMBER_FUNCTION_INDEX, r0, miss); |
| 2636 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); | |
| 2637 CheckPrototypes( | |
| 2638 IC::CurrentTypeOf(prototype, isolate()), | |
| 2639 r0, holder, r3, r1, r4, name, &miss); | |
| 2640 break; | 2443 break; |
| 2641 } | 2444 } |
| 2642 case BOOLEAN_CHECK: { | 2445 case BOOLEAN_CHECK: { |
| 2643 GenerateBooleanCheck(r1, &miss); | 2446 GenerateBooleanCheck(r1, miss); |
| 2644 | 2447 |
| 2645 // Check that the maps starting from the prototype haven't changed. | 2448 // Check that the maps starting from the prototype haven't changed. |
| 2646 GenerateDirectLoadGlobalFunctionPrototype( | 2449 GenerateDirectLoadGlobalFunctionPrototype( |
| 2647 masm(), Context::BOOLEAN_FUNCTION_INDEX, r0, &miss); | 2450 masm(), Context::BOOLEAN_FUNCTION_INDEX, r0, miss); |
| 2648 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); | |
| 2649 CheckPrototypes( | |
| 2650 IC::CurrentTypeOf(prototype, isolate()), | |
| 2651 r0, holder, r3, r1, r4, name, &miss); | |
| 2652 break; | 2451 break; |
| 2653 } | 2452 } |
| 2654 } | 2453 } |
| 2655 | 2454 |
| 2656 Label success; | 2455 if (check != RECEIVER_MAP_CHECK) { |
| 2657 __ b(&success); | 2456 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
| 2457 reg = CheckPrototypes( | |
| 2458 IC::CurrentTypeOf(prototype, isolate()), | |
| 2459 r0, holder, r3, r1, r4, name, miss); | |
| 2460 } | |
| 2658 | 2461 |
| 2659 // Handle call cache miss. | 2462 return reg; |
| 2660 __ bind(&miss); | |
| 2661 GenerateMissBranch(); | |
| 2662 | |
| 2663 __ bind(&success); | |
| 2664 } | 2463 } |
| 2665 | 2464 |
| 2666 | 2465 |
| 2667 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { | 2466 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { |
| 2668 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2467 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
| 2669 ? CALL_AS_FUNCTION | 2468 ? CALL_AS_FUNCTION |
| 2670 : CALL_AS_METHOD; | 2469 : CALL_AS_METHOD; |
| 2671 ParameterCount expected(function); | 2470 ParameterCount expected(function); |
| 2672 __ InvokeFunction(function, expected, arguments(), | 2471 __ InvokeFunction(function, expected, arguments(), |
| 2673 JUMP_FUNCTION, NullCallWrapper(), call_kind); | 2472 JUMP_FUNCTION, NullCallWrapper(), call_kind); |
| 2674 } | 2473 } |
| 2675 | 2474 |
| 2676 | 2475 |
| 2677 Handle<Code> CallStubCompiler::CompileCallConstant( | 2476 Handle<Code> CallStubCompiler::CompileCallConstant( |
| 2678 Handle<Object> object, | 2477 Handle<Object> object, |
| 2679 Handle<JSObject> holder, | 2478 Handle<JSObject> holder, |
| 2680 Handle<Name> name, | 2479 Handle<Name> name, |
| 2681 CheckType check, | 2480 CheckType check, |
| 2682 Handle<JSFunction> function) { | 2481 Handle<JSFunction> function) { |
| 2683 if (HasCustomCallGenerator(function)) { | 2482 if (HasCustomCallGenerator(function)) { |
| 2684 Handle<Code> code = CompileCustomCall(object, holder, | 2483 Handle<Code> code = CompileCustomCall(object, holder, |
| 2685 Handle<Cell>::null(), | 2484 Handle<Cell>::null(), |
| 2686 function, Handle<String>::cast(name), | 2485 function, Handle<String>::cast(name), |
| 2687 Code::FAST); | 2486 Code::FAST); |
| 2688 // A null handle means bail out to the regular compiler code below. | 2487 // A null handle means bail out to the regular compiler code below. |
| 2689 if (!code.is_null()) return code; | 2488 if (!code.is_null()) return code; |
| 2690 } | 2489 } |
| 2691 | 2490 |
| 2692 CompileHandlerFrontend(object, holder, name, check); | 2491 Label miss; |
| 2492 HandlerFrontendHeader(object, holder, name, check, &miss); | |
| 2693 CompileHandlerBackend(function); | 2493 CompileHandlerBackend(function); |
| 2494 HandlerFrontendFooter(&miss); | |
| 2694 | 2495 |
| 2695 // Return the generated code. | 2496 // Return the generated code. |
| 2696 return GetCode(function); | 2497 return GetCode(function); |
| 2697 } | 2498 } |
| 2698 | 2499 |
| 2699 | 2500 |
| 2700 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, | 2501 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, |
| 2701 Handle<JSObject> holder, | 2502 Handle<JSObject> holder, |
| 2702 Handle<Name> name) { | 2503 Handle<Name> name) { |
| 2703 // ----------- S t a t e ------------- | |
| 2704 // -- r2 : name | |
| 2705 // -- lr : return address | |
| 2706 // ----------------------------------- | |
| 2707 Label miss; | 2504 Label miss; |
| 2708 GenerateNameCheck(name, &miss); | 2505 GenerateNameCheck(name, &miss); |
| 2709 | 2506 |
| 2710 // Get the number of arguments. | 2507 // Get the number of arguments. |
| 2711 const int argc = arguments().immediate(); | 2508 const int argc = arguments().immediate(); |
| 2712 LookupResult lookup(isolate()); | 2509 LookupResult lookup(isolate()); |
| 2713 LookupPostInterceptor(holder, name, &lookup); | 2510 LookupPostInterceptor(holder, name, &lookup); |
| 2714 | 2511 |
| 2715 // Get the receiver from the stack. | 2512 // Get the receiver from the stack. |
| 2716 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 2513 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
| 2717 | 2514 |
| 2718 CallInterceptorCompiler compiler(this, arguments(), r2, extra_state_); | 2515 CallInterceptorCompiler compiler(this, arguments(), r2, extra_state_); |
| 2719 compiler.Compile(masm(), object, holder, name, &lookup, r1, r3, r4, r0, | 2516 compiler.Compile(masm(), object, holder, name, &lookup, r1, r3, r4, r0, |
| 2720 &miss); | 2517 &miss); |
| 2721 | 2518 |
| 2722 // Move returned value, the function to call, to r1. | 2519 // Move returned value, the function to call, to r1. |
| 2723 __ mov(r1, r0); | 2520 __ mov(r1, r0); |
| 2724 // Restore receiver. | 2521 // Restore receiver. |
| 2725 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | 2522 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); |
| 2726 | 2523 |
| 2727 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); | 2524 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); |
|
Igor Sheludko
2013/11/25 16:31:53
Modified GenerateCallFunction() is no longer patch
Toon Verwaest
2013/11/27 15:16:55
Done.
| |
| 2728 | 2525 |
| 2729 // Handle call cache miss. | 2526 // Handle call cache miss. |
| 2730 __ bind(&miss); | 2527 __ bind(&miss); |
| 2731 GenerateMissBranch(); | 2528 GenerateMissBranch(); |
| 2732 | 2529 |
| 2733 // Return the generated code. | 2530 // Return the generated code. |
| 2734 return GetCode(Code::FAST, name); | 2531 return GetCode(Code::FAST, name); |
| 2735 } | 2532 } |
| 2736 | 2533 |
| 2737 | 2534 |
| 2738 Handle<Code> CallStubCompiler::CompileCallGlobal( | 2535 Handle<Code> CallStubCompiler::CompileCallGlobal( |
| 2739 Handle<JSObject> object, | 2536 Handle<JSObject> object, |
| 2740 Handle<GlobalObject> holder, | 2537 Handle<GlobalObject> holder, |
| 2741 Handle<PropertyCell> cell, | 2538 Handle<PropertyCell> cell, |
| 2742 Handle<JSFunction> function, | 2539 Handle<JSFunction> function, |
| 2743 Handle<Name> name) { | 2540 Handle<Name> name) { |
| 2744 // ----------- S t a t e ------------- | |
| 2745 // -- r2 : name | |
| 2746 // -- lr : return address | |
| 2747 // ----------------------------------- | |
| 2748 if (HasCustomCallGenerator(function)) { | 2541 if (HasCustomCallGenerator(function)) { |
| 2749 Handle<Code> code = CompileCustomCall( | 2542 Handle<Code> code = CompileCustomCall( |
| 2750 object, holder, cell, function, Handle<String>::cast(name), | 2543 object, holder, cell, function, Handle<String>::cast(name), |
| 2751 Code::NORMAL); | 2544 Code::NORMAL); |
| 2752 // A null handle means bail out to the regular compiler code below. | 2545 // A null handle means bail out to the regular compiler code below. |
| 2753 if (!code.is_null()) return code; | 2546 if (!code.is_null()) return code; |
| 2754 } | 2547 } |
| 2755 | 2548 |
| 2756 Label miss; | 2549 Label miss; |
| 2757 GenerateNameCheck(name, &miss); | 2550 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); |
| 2758 | |
| 2759 // Get the number of arguments. | |
| 2760 const int argc = arguments().immediate(); | |
| 2761 GenerateGlobalReceiverCheck(object, holder, name, &miss); | |
| 2762 GenerateLoadFunctionFromCell(cell, function, &miss); | 2551 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 2763 | 2552 |
| 2764 // Patch the receiver on the stack with the global proxy if | |
| 2765 // necessary. | |
| 2766 if (object->IsGlobalObject()) { | |
| 2767 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); | |
| 2768 __ str(r3, MemOperand(sp, argc * kPointerSize)); | |
| 2769 } | |
| 2770 | |
| 2771 // Set up the context (function already in r1). | 2553 // Set up the context (function already in r1). |
| 2772 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | 2554 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
| 2773 | 2555 |
| 2774 // Jump to the cached code (tail call). | 2556 // Jump to the cached code (tail call). |
| 2775 Counters* counters = isolate()->counters(); | 2557 Counters* counters = isolate()->counters(); |
| 2776 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4); | 2558 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4); |
| 2777 ParameterCount expected(function->shared()->formal_parameter_count()); | 2559 ParameterCount expected(function->shared()->formal_parameter_count()); |
| 2778 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2560 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
| 2779 ? CALL_AS_FUNCTION | 2561 ? CALL_AS_FUNCTION |
| 2780 : CALL_AS_METHOD; | 2562 : CALL_AS_METHOD; |
| 2781 // We call indirectly through the code field in the function to | 2563 // We call indirectly through the code field in the function to |
| 2782 // allow recompilation to take effect without changing any of the | 2564 // allow recompilation to take effect without changing any of the |
| 2783 // call sites. | 2565 // call sites. |
| 2784 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); | 2566 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); |
| 2785 __ InvokeCode(r3, expected, arguments(), JUMP_FUNCTION, | 2567 __ InvokeCode(r3, expected, arguments(), JUMP_FUNCTION, |
| 2786 NullCallWrapper(), call_kind); | 2568 NullCallWrapper(), call_kind); |
| 2787 | 2569 |
| 2788 // Handle call cache miss. | 2570 HandlerFrontendFooter(&miss); |
| 2789 __ bind(&miss); | |
| 2790 __ IncrementCounter(counters->call_global_inline_miss(), 1, r1, r3); | |
| 2791 GenerateMissBranch(); | |
| 2792 | 2571 |
| 2793 // Return the generated code. | 2572 // Return the generated code. |
| 2794 return GetCode(Code::NORMAL, name); | 2573 return GetCode(Code::NORMAL, name); |
| 2795 } | 2574 } |
| 2796 | 2575 |
| 2797 | 2576 |
| 2798 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 2577 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
| 2799 Handle<JSObject> object, | 2578 Handle<JSObject> object, |
| 2800 Handle<JSObject> holder, | 2579 Handle<JSObject> holder, |
| 2801 Handle<Name> name, | 2580 Handle<Name> name, |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3175 // ----------------------------------- | 2954 // ----------------------------------- |
| 3176 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 2955 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
| 3177 } | 2956 } |
| 3178 | 2957 |
| 3179 | 2958 |
| 3180 #undef __ | 2959 #undef __ |
| 3181 | 2960 |
| 3182 } } // namespace v8::internal | 2961 } } // namespace v8::internal |
| 3183 | 2962 |
| 3184 #endif // V8_TARGET_ARCH_ARM | 2963 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |