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

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

Issue 83753002: Use the HandlerFrontendHeader in most call compilers. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: X64 port Created 7 years 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
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 1591 matching lines...) Expand 10 before | Expand all | Expand 10 after
1602 1602
1603 1603
1604 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { 1604 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) {
1605 if (kind_ == Code::KEYED_CALL_IC) { 1605 if (kind_ == Code::KEYED_CALL_IC) {
1606 __ cmp(ecx, Immediate(name)); 1606 __ cmp(ecx, Immediate(name));
1607 __ j(not_equal, miss); 1607 __ j(not_equal, miss);
1608 } 1608 }
1609 } 1609 }
1610 1610
1611 1611
1612 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object,
1613 Handle<JSObject> holder,
1614 Handle<Name> name,
1615 Label* miss) {
1616 ASSERT(holder->IsGlobalObject());
1617
1618 // Get the number of arguments.
1619 const int argc = arguments().immediate();
1620
1621 // Get the receiver from the stack.
1622 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1623
1624
1625 // Check that the maps haven't changed.
1626 __ JumpIfSmi(edx, miss);
1627 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder,
1628 ebx, eax, edi, name, miss);
1629 }
1630
1631
1632 void CallStubCompiler::GenerateLoadFunctionFromCell( 1612 void CallStubCompiler::GenerateLoadFunctionFromCell(
1633 Handle<Cell> cell, 1613 Handle<Cell> cell,
1634 Handle<JSFunction> function, 1614 Handle<JSFunction> function,
1635 Label* miss) { 1615 Label* miss) {
1636 // Get the value from the cell. 1616 // Get the value from the cell.
1637 if (Serializer::enabled()) { 1617 if (Serializer::enabled()) {
1638 __ mov(edi, Immediate(cell)); 1618 __ mov(edi, Immediate(cell));
1639 __ mov(edi, FieldOperand(edi, Cell::kValueOffset)); 1619 __ mov(edi, FieldOperand(edi, Cell::kValueOffset));
1640 } else { 1620 } else {
1641 __ mov(edi, Operand::ForCell(cell)); 1621 __ mov(edi, Operand::ForCell(cell));
(...skipping 26 matching lines...) Expand all
1668 kind_, 1648 kind_,
1669 extra_state_); 1649 extra_state_);
1670 __ jmp(code, RelocInfo::CODE_TARGET); 1650 __ jmp(code, RelocInfo::CODE_TARGET);
1671 } 1651 }
1672 1652
1673 1653
1674 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, 1654 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
1675 Handle<JSObject> holder, 1655 Handle<JSObject> holder,
1676 PropertyIndex index, 1656 PropertyIndex index,
1677 Handle<Name> name) { 1657 Handle<Name> name) {
1678 // ----------- S t a t e -------------
1679 // -- ecx : name
1680 // -- esp[0] : return address
1681 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1682 // -- ...
1683 // -- esp[(argc + 1) * 4] : receiver
1684 // -----------------------------------
1685 Label miss; 1658 Label miss;
1686 1659
1687 GenerateNameCheck(name, &miss); 1660 Register reg = HandlerFrontendHeader(
1688 1661 object, holder, name, RECEIVER_MAP_CHECK, &miss);
1689 // Get the receiver from the stack.
1690 const int argc = arguments().immediate();
1691 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1692
1693 // Check that the receiver isn't a smi.
1694 __ JumpIfSmi(edx, &miss);
1695
1696 // Do the right check and compute the holder register.
1697 Register reg = CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx,
1698 holder, ebx, eax, edi, name, &miss);
1699 1662
1700 GenerateFastPropertyLoad( 1663 GenerateFastPropertyLoad(
1701 masm(), edi, reg, index.is_inobject(holder), 1664 masm(), edi, reg, index.is_inobject(holder),
1702 index.translate(holder), Representation::Tagged()); 1665 index.translate(holder), Representation::Tagged());
1703 1666
1704 // Check that the function really is a function. 1667 // Check that the function really is a function.
1705 __ JumpIfSmi(edi, &miss); 1668 __ JumpIfSmi(edi, &miss);
1706 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); 1669 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx);
1707 __ j(not_equal, &miss); 1670 __ j(not_equal, &miss);
1708 1671
1709 // Patch the receiver on the stack with the global proxy if 1672 PatchGlobalProxy(object);
1710 // necessary.
1711 if (object->IsGlobalObject()) {
1712 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
1713 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
1714 }
1715 1673
1716 // Invoke the function. 1674 // Invoke the function.
1717 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 1675 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
1718 ? CALL_AS_FUNCTION 1676 ? CALL_AS_FUNCTION
1719 : CALL_AS_METHOD; 1677 : CALL_AS_METHOD;
1720 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION, 1678 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION,
1721 NullCallWrapper(), call_kind); 1679 NullCallWrapper(), call_kind);
1722 1680
1723 // Handle call cache miss. 1681 HandlerFrontendFooter(&miss);
1724 __ bind(&miss);
1725 GenerateMissBranch();
1726 1682
1727 // Return the generated code. 1683 // Return the generated code.
1728 return GetCode(Code::FAST, name); 1684 return GetCode(Code::FAST, name);
1729 } 1685 }
1730 1686
1731 1687
1732 Handle<Code> CallStubCompiler::CompileArrayCodeCall( 1688 Handle<Code> CallStubCompiler::CompileArrayCodeCall(
1733 Handle<Object> object, 1689 Handle<Object> object,
1734 Handle<JSObject> holder, 1690 Handle<JSObject> holder,
1735 Handle<Cell> cell, 1691 Handle<Cell> cell,
1736 Handle<JSFunction> function, 1692 Handle<JSFunction> function,
1737 Handle<String> name, 1693 Handle<String> name,
1738 Code::StubType type) { 1694 Code::StubType type) {
1739 Label miss; 1695 Label miss;
1740 1696
1741 // Check that function is still array 1697 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1742 const int argc = arguments().immediate(); 1698 if (!cell.is_null()) {
1743 GenerateNameCheck(name, &miss);
1744
1745 if (cell.is_null()) {
1746 // Get the receiver from the stack.
1747 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1748
1749 // Check that the receiver isn't a smi.
1750 __ JumpIfSmi(edx, &miss);
1751 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder,
1752 ebx, eax, edi, name, &miss);
1753 } else {
1754 ASSERT(cell->value() == *function); 1699 ASSERT(cell->value() == *function);
1755 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
1756 &miss);
1757 GenerateLoadFunctionFromCell(cell, function, &miss); 1700 GenerateLoadFunctionFromCell(cell, function, &miss);
1758 } 1701 }
1759 1702
1760 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); 1703 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite();
1761 site->SetElementsKind(GetInitialFastElementsKind()); 1704 site->SetElementsKind(GetInitialFastElementsKind());
1762 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); 1705 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site);
1706 const int argc = arguments().immediate();
1763 __ mov(eax, Immediate(argc)); 1707 __ mov(eax, Immediate(argc));
1764 __ mov(ebx, site_feedback_cell); 1708 __ mov(ebx, site_feedback_cell);
1765 __ mov(edi, function); 1709 __ mov(edi, function);
1766 1710
1767 ArrayConstructorStub stub(isolate()); 1711 ArrayConstructorStub stub(isolate());
1768 __ TailCallStub(&stub); 1712 __ TailCallStub(&stub);
1769 1713
1770 __ bind(&miss); 1714 HandlerFrontendFooter(&miss);
1771 GenerateMissBranch();
1772 1715
1773 // Return the generated code. 1716 // Return the generated code.
1774 return GetCode(type, name); 1717 return GetCode(type, name);
1775 } 1718 }
1776 1719
1777 1720
1778 Handle<Code> CallStubCompiler::CompileArrayPushCall( 1721 Handle<Code> CallStubCompiler::CompileArrayPushCall(
1779 Handle<Object> object, 1722 Handle<Object> object,
1780 Handle<JSObject> holder, 1723 Handle<JSObject> holder,
1781 Handle<Cell> cell, 1724 Handle<Cell> cell,
1782 Handle<JSFunction> function, 1725 Handle<JSFunction> function,
1783 Handle<String> name, 1726 Handle<String> name,
1784 Code::StubType type) { 1727 Code::StubType type) {
1785 // ----------- S t a t e -------------
1786 // -- ecx : name
1787 // -- esp[0] : return address
1788 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1789 // -- ...
1790 // -- esp[(argc + 1) * 4] : receiver
1791 // -----------------------------------
1792
1793 // If object is not an array or is observed, bail out to regular call. 1728 // If object is not an array or is observed, bail out to regular call.
1794 if (!object->IsJSArray() || 1729 if (!object->IsJSArray() ||
1795 !cell.is_null() || 1730 !cell.is_null() ||
1796 Handle<JSArray>::cast(object)->map()->is_observed()) { 1731 Handle<JSArray>::cast(object)->map()->is_observed()) {
1797 return Handle<Code>::null(); 1732 return Handle<Code>::null();
1798 } 1733 }
1799 1734
1800 Label miss; 1735 Label miss;
1801 1736
1802 GenerateNameCheck(name, &miss); 1737 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1803 1738
1804 // Get the receiver from the stack.
1805 const int argc = arguments().immediate(); 1739 const int argc = arguments().immediate();
1806 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1807
1808 // Check that the receiver isn't a smi.
1809 __ JumpIfSmi(edx, &miss);
1810
1811 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder,
1812 ebx, eax, edi, name, &miss);
1813
1814 if (argc == 0) { 1740 if (argc == 0) {
1815 // Noop, return the length. 1741 // Noop, return the length.
1816 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset)); 1742 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset));
1817 __ ret((argc + 1) * kPointerSize); 1743 __ ret((argc + 1) * kPointerSize);
1818 } else { 1744 } else {
1819 Label call_builtin; 1745 Label call_builtin;
1820 1746
1821 if (argc == 1) { // Otherwise fall through to call builtin. 1747 if (argc == 1) { // Otherwise fall through to call builtin.
1822 Label attempt_to_grow_elements, with_write_barrier, check_double; 1748 Label attempt_to_grow_elements, with_write_barrier, check_double;
1823 1749
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
2021 __ ret((argc + 1) * kPointerSize); 1947 __ ret((argc + 1) * kPointerSize);
2022 } 1948 }
2023 1949
2024 __ bind(&call_builtin); 1950 __ bind(&call_builtin);
2025 __ TailCallExternalReference( 1951 __ TailCallExternalReference(
2026 ExternalReference(Builtins::c_ArrayPush, isolate()), 1952 ExternalReference(Builtins::c_ArrayPush, isolate()),
2027 argc + 1, 1953 argc + 1,
2028 1); 1954 1);
2029 } 1955 }
2030 1956
2031 __ bind(&miss); 1957 HandlerFrontendFooter(&miss);
2032 GenerateMissBranch();
2033 1958
2034 // Return the generated code. 1959 // Return the generated code.
2035 return GetCode(type, name); 1960 return GetCode(type, name);
2036 } 1961 }
2037 1962
2038 1963
2039 Handle<Code> CallStubCompiler::CompileArrayPopCall( 1964 Handle<Code> CallStubCompiler::CompileArrayPopCall(
2040 Handle<Object> object, 1965 Handle<Object> object,
2041 Handle<JSObject> holder, 1966 Handle<JSObject> holder,
2042 Handle<Cell> cell, 1967 Handle<Cell> cell,
2043 Handle<JSFunction> function, 1968 Handle<JSFunction> function,
2044 Handle<String> name, 1969 Handle<String> name,
2045 Code::StubType type) { 1970 Code::StubType type) {
2046 // ----------- S t a t e -------------
2047 // -- ecx : name
2048 // -- esp[0] : return address
2049 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2050 // -- ...
2051 // -- esp[(argc + 1) * 4] : receiver
2052 // -----------------------------------
2053
2054 // If object is not an array or is observed, bail out to regular call. 1971 // If object is not an array or is observed, bail out to regular call.
2055 if (!object->IsJSArray() || 1972 if (!object->IsJSArray() ||
2056 !cell.is_null() || 1973 !cell.is_null() ||
2057 Handle<JSArray>::cast(object)->map()->is_observed()) { 1974 Handle<JSArray>::cast(object)->map()->is_observed()) {
2058 return Handle<Code>::null(); 1975 return Handle<Code>::null();
2059 } 1976 }
2060 1977
2061 Label miss, return_undefined, call_builtin; 1978 Label miss, return_undefined, call_builtin;
2062 1979
2063 GenerateNameCheck(name, &miss); 1980 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2064
2065 // Get the receiver from the stack.
2066 const int argc = arguments().immediate();
2067 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2068
2069 // Check that the receiver isn't a smi.
2070 __ JumpIfSmi(edx, &miss);
2071 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder,
2072 ebx, eax, edi, name, &miss);
2073 1981
2074 // Get the elements array of the object. 1982 // Get the elements array of the object.
2075 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset)); 1983 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset));
2076 1984
2077 // Check that the elements are in fast mode and writable. 1985 // Check that the elements are in fast mode and writable.
2078 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), 1986 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
2079 Immediate(factory()->fixed_array_map())); 1987 Immediate(factory()->fixed_array_map()));
2080 __ j(not_equal, &call_builtin); 1988 __ j(not_equal, &call_builtin);
2081 1989
2082 // Get the array's length into ecx and calculate new length. 1990 // Get the array's length into ecx and calculate new length.
(...skipping 11 matching lines...) Expand all
2094 __ j(equal, &call_builtin); 2002 __ j(equal, &call_builtin);
2095 2003
2096 // Set the array's length. 2004 // Set the array's length.
2097 __ mov(FieldOperand(edx, JSArray::kLengthOffset), ecx); 2005 __ mov(FieldOperand(edx, JSArray::kLengthOffset), ecx);
2098 2006
2099 // Fill with the hole. 2007 // Fill with the hole.
2100 __ mov(FieldOperand(ebx, 2008 __ mov(FieldOperand(ebx,
2101 ecx, times_half_pointer_size, 2009 ecx, times_half_pointer_size,
2102 FixedArray::kHeaderSize), 2010 FixedArray::kHeaderSize),
2103 Immediate(factory()->the_hole_value())); 2011 Immediate(factory()->the_hole_value()));
2012 const int argc = arguments().immediate();
2104 __ ret((argc + 1) * kPointerSize); 2013 __ ret((argc + 1) * kPointerSize);
2105 2014
2106 __ bind(&return_undefined); 2015 __ bind(&return_undefined);
2107 __ mov(eax, Immediate(factory()->undefined_value())); 2016 __ mov(eax, Immediate(factory()->undefined_value()));
2108 __ ret((argc + 1) * kPointerSize); 2017 __ ret((argc + 1) * kPointerSize);
2109 2018
2110 __ bind(&call_builtin); 2019 __ bind(&call_builtin);
2111 __ TailCallExternalReference( 2020 __ TailCallExternalReference(
2112 ExternalReference(Builtins::c_ArrayPop, isolate()), 2021 ExternalReference(Builtins::c_ArrayPop, isolate()),
2113 argc + 1, 2022 argc + 1,
2114 1); 2023 1);
2115 2024
2116 __ bind(&miss); 2025 HandlerFrontendFooter(&miss);
2117 GenerateMissBranch();
2118 2026
2119 // Return the generated code. 2027 // Return the generated code.
2120 return GetCode(type, name); 2028 return GetCode(type, name);
2121 } 2029 }
2122 2030
2123 2031
2124 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall( 2032 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
2125 Handle<Object> object, 2033 Handle<Object> object,
2126 Handle<JSObject> holder, 2034 Handle<JSObject> holder,
2127 Handle<Cell> cell, 2035 Handle<Cell> cell,
2128 Handle<JSFunction> function, 2036 Handle<JSFunction> function,
2129 Handle<String> name, 2037 Handle<String> name,
2130 Code::StubType type) { 2038 Code::StubType type) {
2131 // ----------- S t a t e -------------
2132 // -- ecx : function name
2133 // -- esp[0] : return address
2134 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2135 // -- ...
2136 // -- esp[(argc + 1) * 4] : receiver
2137 // -----------------------------------
2138
2139 // If object is not a string, bail out to regular call. 2039 // If object is not a string, bail out to regular call.
2140 if (!object->IsString() || !cell.is_null()) { 2040 if (!object->IsString() || !cell.is_null()) {
2141 return Handle<Code>::null(); 2041 return Handle<Code>::null();
2142 } 2042 }
2143 2043
2144 const int argc = arguments().immediate(); 2044 const int argc = arguments().immediate();
2145 2045
2146 Label miss; 2046 Label miss;
2147 Label name_miss; 2047 Label name_miss;
2148 Label index_out_of_range; 2048 Label index_out_of_range;
2149 Label* index_out_of_range_label = &index_out_of_range; 2049 Label* index_out_of_range_label = &index_out_of_range;
2150 2050
2151 if (kind_ == Code::CALL_IC && 2051 if (kind_ == Code::CALL_IC &&
2152 (CallICBase::StringStubState::decode(extra_state_) == 2052 (CallICBase::StringStubState::decode(extra_state_) ==
2153 DEFAULT_STRING_STUB)) { 2053 DEFAULT_STRING_STUB)) {
2154 index_out_of_range_label = &miss; 2054 index_out_of_range_label = &miss;
2155 } 2055 }
2156 2056
2157 GenerateNameCheck(name, &name_miss); 2057 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss);
2158
2159 // Check that the maps starting from the prototype haven't changed.
2160 GenerateDirectLoadGlobalFunctionPrototype(masm(),
2161 Context::STRING_FUNCTION_INDEX,
2162 eax,
2163 &miss);
2164 ASSERT(!object.is_identical_to(holder));
2165 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2166 CheckPrototypes(
2167 IC::CurrentTypeOf(prototype, isolate()),
2168 eax, holder, ebx, edx, edi, name, &miss);
2169 2058
2170 Register receiver = ebx; 2059 Register receiver = ebx;
2171 Register index = edi; 2060 Register index = edi;
2172 Register result = eax; 2061 Register result = eax;
2173 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize)); 2062 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize));
2174 if (argc > 0) { 2063 if (argc > 0) {
2175 __ mov(index, Operand(esp, (argc - 0) * kPointerSize)); 2064 __ mov(index, Operand(esp, (argc - 0) * kPointerSize));
2176 } else { 2065 } else {
2177 __ Set(index, Immediate(factory()->undefined_value())); 2066 __ Set(index, Immediate(factory()->undefined_value()));
2178 } 2067 }
(...skipping 28 matching lines...) Expand all
2207 } 2096 }
2208 2097
2209 2098
2210 Handle<Code> CallStubCompiler::CompileStringCharAtCall( 2099 Handle<Code> CallStubCompiler::CompileStringCharAtCall(
2211 Handle<Object> object, 2100 Handle<Object> object,
2212 Handle<JSObject> holder, 2101 Handle<JSObject> holder,
2213 Handle<Cell> cell, 2102 Handle<Cell> cell,
2214 Handle<JSFunction> function, 2103 Handle<JSFunction> function,
2215 Handle<String> name, 2104 Handle<String> name,
2216 Code::StubType type) { 2105 Code::StubType type) {
2217 // ----------- S t a t e -------------
2218 // -- ecx : function name
2219 // -- esp[0] : return address
2220 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2221 // -- ...
2222 // -- esp[(argc + 1) * 4] : receiver
2223 // -----------------------------------
2224
2225 // If object is not a string, bail out to regular call. 2106 // If object is not a string, bail out to regular call.
2226 if (!object->IsString() || !cell.is_null()) { 2107 if (!object->IsString() || !cell.is_null()) {
2227 return Handle<Code>::null(); 2108 return Handle<Code>::null();
2228 } 2109 }
2229 2110
2230 const int argc = arguments().immediate(); 2111 const int argc = arguments().immediate();
2231 2112
2232 Label miss; 2113 Label miss;
2233 Label name_miss; 2114 Label name_miss;
2234 Label index_out_of_range; 2115 Label index_out_of_range;
2235 Label* index_out_of_range_label = &index_out_of_range; 2116 Label* index_out_of_range_label = &index_out_of_range;
2236 2117
2237 if (kind_ == Code::CALL_IC && 2118 if (kind_ == Code::CALL_IC &&
2238 (CallICBase::StringStubState::decode(extra_state_) == 2119 (CallICBase::StringStubState::decode(extra_state_) ==
2239 DEFAULT_STRING_STUB)) { 2120 DEFAULT_STRING_STUB)) {
2240 index_out_of_range_label = &miss; 2121 index_out_of_range_label = &miss;
2241 } 2122 }
2242 2123
2243 GenerateNameCheck(name, &name_miss); 2124 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss);
2244
2245 // Check that the maps starting from the prototype haven't changed.
2246 GenerateDirectLoadGlobalFunctionPrototype(masm(),
2247 Context::STRING_FUNCTION_INDEX,
2248 eax,
2249 &miss);
2250 ASSERT(!object.is_identical_to(holder));
2251 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2252 CheckPrototypes(
2253 IC::CurrentTypeOf(prototype, isolate()),
2254 eax, holder, ebx, edx, edi, name, &miss);
2255 2125
2256 Register receiver = eax; 2126 Register receiver = eax;
2257 Register index = edi; 2127 Register index = edi;
2258 Register scratch = edx; 2128 Register scratch = edx;
2259 Register result = eax; 2129 Register result = eax;
2260 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize)); 2130 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize));
2261 if (argc > 0) { 2131 if (argc > 0) {
2262 __ mov(index, Operand(esp, (argc - 0) * kPointerSize)); 2132 __ mov(index, Operand(esp, (argc - 0) * kPointerSize));
2263 } else { 2133 } else {
2264 __ Set(index, Immediate(factory()->undefined_value())); 2134 __ Set(index, Immediate(factory()->undefined_value()));
(...skipping 30 matching lines...) Expand all
2295 } 2165 }
2296 2166
2297 2167
2298 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( 2168 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
2299 Handle<Object> object, 2169 Handle<Object> object,
2300 Handle<JSObject> holder, 2170 Handle<JSObject> holder,
2301 Handle<Cell> cell, 2171 Handle<Cell> cell,
2302 Handle<JSFunction> function, 2172 Handle<JSFunction> function,
2303 Handle<String> name, 2173 Handle<String> name,
2304 Code::StubType type) { 2174 Code::StubType type) {
2305 // ----------- S t a t e -------------
2306 // -- ecx : function name
2307 // -- esp[0] : return address
2308 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2309 // -- ...
2310 // -- esp[(argc + 1) * 4] : receiver
2311 // -----------------------------------
2312
2313 const int argc = arguments().immediate(); 2175 const int argc = arguments().immediate();
2314 2176
2315 // If the object is not a JSObject or we got an unexpected number of 2177 // If the object is not a JSObject or we got an unexpected number of
2316 // arguments, bail out to the regular call. 2178 // arguments, bail out to the regular call.
2317 if (!object->IsJSObject() || argc != 1) { 2179 if (!object->IsJSObject() || argc != 1) {
2318 return Handle<Code>::null(); 2180 return Handle<Code>::null();
2319 } 2181 }
2320 2182
2321 Label miss; 2183 Label miss;
2322 GenerateNameCheck(name, &miss);
2323 2184
2324 if (cell.is_null()) { 2185 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2325 __ mov(edx, Operand(esp, 2 * kPointerSize)); 2186 if (!cell.is_null()) {
2326 STATIC_ASSERT(kSmiTag == 0);
2327 __ JumpIfSmi(edx, &miss);
2328 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder,
2329 ebx, eax, edi, name, &miss);
2330 } else {
2331 ASSERT(cell->value() == *function); 2187 ASSERT(cell->value() == *function);
2332 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2333 &miss);
2334 GenerateLoadFunctionFromCell(cell, function, &miss); 2188 GenerateLoadFunctionFromCell(cell, function, &miss);
2335 } 2189 }
2336 2190
2337 // Load the char code argument. 2191 // Load the char code argument.
2338 Register code = ebx; 2192 Register code = ebx;
2339 __ mov(code, Operand(esp, 1 * kPointerSize)); 2193 __ mov(code, Operand(esp, 1 * kPointerSize));
2340 2194
2341 // Check the code is a smi. 2195 // Check the code is a smi.
2342 Label slow; 2196 Label slow;
2343 STATIC_ASSERT(kSmiTag == 0); 2197 STATIC_ASSERT(kSmiTag == 0);
(...skipping 12 matching lines...) Expand all
2356 // Tail call the full function. We do not have to patch the receiver 2210 // Tail call the full function. We do not have to patch the receiver
2357 // because the function makes no use of it. 2211 // because the function makes no use of it.
2358 __ bind(&slow); 2212 __ bind(&slow);
2359 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2213 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2360 ? CALL_AS_FUNCTION 2214 ? CALL_AS_FUNCTION
2361 : CALL_AS_METHOD; 2215 : CALL_AS_METHOD;
2362 ParameterCount expected(function); 2216 ParameterCount expected(function);
2363 __ InvokeFunction(function, expected, arguments(), 2217 __ InvokeFunction(function, expected, arguments(),
2364 JUMP_FUNCTION, NullCallWrapper(), call_kind); 2218 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2365 2219
2366 __ bind(&miss); 2220 HandlerFrontendFooter(&miss);
2367 // ecx: function name.
2368 GenerateMissBranch();
2369 2221
2370 // Return the generated code. 2222 // Return the generated code.
2371 return GetCode(type, name); 2223 return GetCode(type, name);
2372 } 2224 }
2373 2225
2374 2226
2375 Handle<Code> CallStubCompiler::CompileMathFloorCall( 2227 Handle<Code> CallStubCompiler::CompileMathFloorCall(
2376 Handle<Object> object, 2228 Handle<Object> object,
2377 Handle<JSObject> holder, 2229 Handle<JSObject> holder,
2378 Handle<Cell> cell, 2230 Handle<Cell> cell,
2379 Handle<JSFunction> function, 2231 Handle<JSFunction> function,
2380 Handle<String> name, 2232 Handle<String> name,
2381 Code::StubType type) { 2233 Code::StubType type) {
2382 // ----------- S t a t e -------------
2383 // -- ecx : name
2384 // -- esp[0] : return address
2385 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2386 // -- ...
2387 // -- esp[(argc + 1) * 4] : receiver
2388 // -----------------------------------
2389
2390 if (!CpuFeatures::IsSupported(SSE2)) { 2234 if (!CpuFeatures::IsSupported(SSE2)) {
2391 return Handle<Code>::null(); 2235 return Handle<Code>::null();
2392 } 2236 }
2393 2237
2394 CpuFeatureScope use_sse2(masm(), SSE2); 2238 CpuFeatureScope use_sse2(masm(), SSE2);
2395 2239
2396 const int argc = arguments().immediate(); 2240 const int argc = arguments().immediate();
2397 2241
2398 // If the object is not a JSObject or we got an unexpected number of 2242 // If the object is not a JSObject or we got an unexpected number of
2399 // arguments, bail out to the regular call. 2243 // arguments, bail out to the regular call.
2400 if (!object->IsJSObject() || argc != 1) { 2244 if (!object->IsJSObject() || argc != 1) {
2401 return Handle<Code>::null(); 2245 return Handle<Code>::null();
2402 } 2246 }
2403 2247
2404 Label miss; 2248 Label miss;
2405 GenerateNameCheck(name, &miss);
2406 2249
2407 if (cell.is_null()) { 2250 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2408 __ mov(edx, Operand(esp, 2 * kPointerSize)); 2251 if (!cell.is_null()) {
2409
2410 STATIC_ASSERT(kSmiTag == 0);
2411 __ JumpIfSmi(edx, &miss);
2412
2413 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder,
2414 ebx, eax, edi, name, &miss);
2415 } else {
2416 ASSERT(cell->value() == *function); 2252 ASSERT(cell->value() == *function);
2417 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2418 &miss);
2419 GenerateLoadFunctionFromCell(cell, function, &miss); 2253 GenerateLoadFunctionFromCell(cell, function, &miss);
2420 } 2254 }
2421 2255
2422 // Load the (only) argument into eax. 2256 // Load the (only) argument into eax.
2423 __ mov(eax, Operand(esp, 1 * kPointerSize)); 2257 __ mov(eax, Operand(esp, 1 * kPointerSize));
2424 2258
2425 // Check if the argument is a smi. 2259 // Check if the argument is a smi.
2426 Label smi; 2260 Label smi;
2427 STATIC_ASSERT(kSmiTag == 0); 2261 STATIC_ASSERT(kSmiTag == 0);
2428 __ JumpIfSmi(eax, &smi); 2262 __ JumpIfSmi(eax, &smi);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2488 __ mov(eax, Operand(esp, 1 * kPointerSize)); 2322 __ mov(eax, Operand(esp, 1 * kPointerSize));
2489 __ ret(2 * kPointerSize); 2323 __ ret(2 * kPointerSize);
2490 2324
2491 // Tail call the full function. We do not have to patch the receiver 2325 // Tail call the full function. We do not have to patch the receiver
2492 // because the function makes no use of it. 2326 // because the function makes no use of it.
2493 __ bind(&slow); 2327 __ bind(&slow);
2494 ParameterCount expected(function); 2328 ParameterCount expected(function);
2495 __ InvokeFunction(function, expected, arguments(), 2329 __ InvokeFunction(function, expected, arguments(),
2496 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2330 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
2497 2331
2498 __ bind(&miss); 2332 HandlerFrontendFooter(&miss);
2499 // ecx: function name.
2500 GenerateMissBranch();
2501 2333
2502 // Return the generated code. 2334 // Return the generated code.
2503 return GetCode(type, name); 2335 return GetCode(type, name);
2504 } 2336 }
2505 2337
2506 2338
2507 Handle<Code> CallStubCompiler::CompileMathAbsCall( 2339 Handle<Code> CallStubCompiler::CompileMathAbsCall(
2508 Handle<Object> object, 2340 Handle<Object> object,
2509 Handle<JSObject> holder, 2341 Handle<JSObject> holder,
2510 Handle<Cell> cell, 2342 Handle<Cell> cell,
2511 Handle<JSFunction> function, 2343 Handle<JSFunction> function,
2512 Handle<String> name, 2344 Handle<String> name,
2513 Code::StubType type) { 2345 Code::StubType type) {
2514 // ----------- S t a t e -------------
2515 // -- ecx : name
2516 // -- esp[0] : return address
2517 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2518 // -- ...
2519 // -- esp[(argc + 1) * 4] : receiver
2520 // -----------------------------------
2521
2522 const int argc = arguments().immediate(); 2346 const int argc = arguments().immediate();
2523 2347
2524 // If the object is not a JSObject or we got an unexpected number of 2348 // If the object is not a JSObject or we got an unexpected number of
2525 // arguments, bail out to the regular call. 2349 // arguments, bail out to the regular call.
2526 if (!object->IsJSObject() || argc != 1) { 2350 if (!object->IsJSObject() || argc != 1) {
2527 return Handle<Code>::null(); 2351 return Handle<Code>::null();
2528 } 2352 }
2529 2353
2530 Label miss; 2354 Label miss;
2531 GenerateNameCheck(name, &miss);
2532 2355
2533 if (cell.is_null()) { 2356 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2534 __ mov(edx, Operand(esp, 2 * kPointerSize)); 2357 if (!cell.is_null()) {
2535
2536 STATIC_ASSERT(kSmiTag == 0);
2537 __ JumpIfSmi(edx, &miss);
2538
2539 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder,
2540 ebx, eax, edi, name, &miss);
2541 } else {
2542 ASSERT(cell->value() == *function); 2358 ASSERT(cell->value() == *function);
2543 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2544 &miss);
2545 GenerateLoadFunctionFromCell(cell, function, &miss); 2359 GenerateLoadFunctionFromCell(cell, function, &miss);
2546 } 2360 }
2547 2361
2548 // Load the (only) argument into eax. 2362 // Load the (only) argument into eax.
2549 __ mov(eax, Operand(esp, 1 * kPointerSize)); 2363 __ mov(eax, Operand(esp, 1 * kPointerSize));
2550 2364
2551 // Check if the argument is a smi. 2365 // Check if the argument is a smi.
2552 Label not_smi; 2366 Label not_smi;
2553 STATIC_ASSERT(kSmiTag == 0); 2367 STATIC_ASSERT(kSmiTag == 0);
2554 __ JumpIfNotSmi(eax, &not_smi); 2368 __ JumpIfNotSmi(eax, &not_smi);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2597 __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx); 2411 __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx);
2598 __ ret(2 * kPointerSize); 2412 __ ret(2 * kPointerSize);
2599 2413
2600 // Tail call the full function. We do not have to patch the receiver 2414 // Tail call the full function. We do not have to patch the receiver
2601 // because the function makes no use of it. 2415 // because the function makes no use of it.
2602 __ bind(&slow); 2416 __ bind(&slow);
2603 ParameterCount expected(function); 2417 ParameterCount expected(function);
2604 __ InvokeFunction(function, expected, arguments(), 2418 __ InvokeFunction(function, expected, arguments(),
2605 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2419 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
2606 2420
2607 __ bind(&miss); 2421 HandlerFrontendFooter(&miss);
2608 // ecx: function name.
2609 GenerateMissBranch();
2610 2422
2611 // Return the generated code. 2423 // Return the generated code.
2612 return GetCode(type, name); 2424 return GetCode(type, name);
2613 } 2425 }
2614 2426
2615 2427
2616 Handle<Code> CallStubCompiler::CompileFastApiCall( 2428 Handle<Code> CallStubCompiler::CompileFastApiCall(
2617 const CallOptimization& optimization, 2429 const CallOptimization& optimization,
2618 Handle<Object> object, 2430 Handle<Object> object,
2619 Handle<JSObject> holder, 2431 Handle<JSObject> holder,
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2676 Label success; 2488 Label success;
2677 // Check that the object is a boolean. 2489 // Check that the object is a boolean.
2678 __ cmp(object, factory()->true_value()); 2490 __ cmp(object, factory()->true_value());
2679 __ j(equal, &success); 2491 __ j(equal, &success);
2680 __ cmp(object, factory()->false_value()); 2492 __ cmp(object, factory()->false_value());
2681 __ j(not_equal, miss); 2493 __ j(not_equal, miss);
2682 __ bind(&success); 2494 __ bind(&success);
2683 } 2495 }
2684 2496
2685 2497
2686 void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object, 2498 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) {
2687 Handle<JSObject> holder, 2499 if (object->IsGlobalObject()) {
2688 Handle<Name> name, 2500 const int argc = arguments().immediate();
2689 CheckType check) { 2501 const int receiver_offset = (argc + 1) * kPointerSize;
2690 // ----------- S t a t e ------------- 2502 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
2691 // -- ecx : name 2503 __ mov(Operand(esp, receiver_offset), edx);
2692 // -- esp[0] : return address 2504 }
2693 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 2505 }
2694 // -- ...
2695 // -- esp[(argc + 1) * 4] : receiver
2696 // -----------------------------------
2697 Label miss;
2698 GenerateNameCheck(name, &miss);
2699 2506
2700 // Get the receiver from the stack. 2507
2508 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object,
2509 Handle<JSObject> holder,
2510 Handle<Name> name,
2511 CheckType check,
2512 Label* miss) {
2513 GenerateNameCheck(name, miss);
2514
2515 Register reg = edx;
2516
2701 const int argc = arguments().immediate(); 2517 const int argc = arguments().immediate();
2702 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2518 const int receiver_offset = (argc + 1) * kPointerSize;
2519 __ mov(reg, Operand(esp, receiver_offset));
2703 2520
2704 // Check that the receiver isn't a smi. 2521 // Check that the receiver isn't a smi.
2705 if (check != NUMBER_CHECK) { 2522 if (check != NUMBER_CHECK) {
2706 __ JumpIfSmi(edx, &miss); 2523 __ JumpIfSmi(reg, miss);
2707 } 2524 }
2708 2525
2709 // Make sure that it's okay not to patch the on stack receiver 2526 // Make sure that it's okay not to patch the on stack receiver
2710 // unless we're doing a receiver map check. 2527 // unless we're doing a receiver map check.
2711 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 2528 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
2712 switch (check) { 2529 switch (check) {
2713 case RECEIVER_MAP_CHECK: 2530 case RECEIVER_MAP_CHECK:
2714 __ IncrementCounter(isolate()->counters()->call_const(), 1); 2531 __ IncrementCounter(isolate()->counters()->call_const(), 1);
2715 2532
2716 // Check that the maps haven't changed. 2533 // Check that the maps haven't changed.
2717 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder, 2534 reg = CheckPrototypes(IC::CurrentTypeOf(object, isolate()), reg, holder,
2718 ebx, eax, edi, name, &miss); 2535 ebx, eax, edi, name, miss);
2719 2536
2720 // Patch the receiver on the stack with the global proxy if
2721 // necessary.
2722 if (object->IsGlobalObject()) {
2723 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
2724 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
2725 }
2726 break; 2537 break;
2727 2538
2728 case STRING_CHECK: { 2539 case STRING_CHECK: {
2729 // Check that the object is a string. 2540 // Check that the object is a string.
2730 __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, eax); 2541 __ CmpObjectType(reg, FIRST_NONSTRING_TYPE, eax);
2731 __ j(above_equal, &miss); 2542 __ j(above_equal, miss);
2732 // Check that the maps starting from the prototype haven't changed. 2543 // Check that the maps starting from the prototype haven't changed.
2733 GenerateDirectLoadGlobalFunctionPrototype( 2544 GenerateDirectLoadGlobalFunctionPrototype(
2734 masm(), Context::STRING_FUNCTION_INDEX, eax, &miss); 2545 masm(), Context::STRING_FUNCTION_INDEX, eax, miss);
2735 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2736 CheckPrototypes(
2737 IC::CurrentTypeOf(prototype, isolate()),
2738 eax, holder, ebx, edx, edi, name, &miss);
2739 break; 2546 break;
2740 } 2547 }
2741 case SYMBOL_CHECK: { 2548 case SYMBOL_CHECK: {
2742 // Check that the object is a symbol. 2549 // Check that the object is a symbol.
2743 __ CmpObjectType(edx, SYMBOL_TYPE, eax); 2550 __ CmpObjectType(reg, SYMBOL_TYPE, eax);
2744 __ j(not_equal, &miss); 2551 __ j(not_equal, miss);
2745 // Check that the maps starting from the prototype haven't changed. 2552 // Check that the maps starting from the prototype haven't changed.
2746 GenerateDirectLoadGlobalFunctionPrototype( 2553 GenerateDirectLoadGlobalFunctionPrototype(
2747 masm(), Context::SYMBOL_FUNCTION_INDEX, eax, &miss); 2554 masm(), Context::SYMBOL_FUNCTION_INDEX, eax, miss);
2748 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2749 CheckPrototypes(
2750 IC::CurrentTypeOf(prototype, isolate()),
2751 eax, holder, ebx, edx, edi, name, &miss);
2752 break; 2555 break;
2753 } 2556 }
2754 case NUMBER_CHECK: { 2557 case NUMBER_CHECK: {
2755 Label fast; 2558 Label fast;
2756 // Check that the object is a smi or a heap number. 2559 // Check that the object is a smi or a heap number.
2757 __ JumpIfSmi(edx, &fast); 2560 __ JumpIfSmi(reg, &fast);
2758 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, eax); 2561 __ CmpObjectType(reg, HEAP_NUMBER_TYPE, eax);
2759 __ j(not_equal, &miss); 2562 __ j(not_equal, miss);
2760 __ bind(&fast); 2563 __ bind(&fast);
2761 // Check that the maps starting from the prototype haven't changed. 2564 // Check that the maps starting from the prototype haven't changed.
2762 GenerateDirectLoadGlobalFunctionPrototype( 2565 GenerateDirectLoadGlobalFunctionPrototype(
2763 masm(), Context::NUMBER_FUNCTION_INDEX, eax, &miss); 2566 masm(), Context::NUMBER_FUNCTION_INDEX, eax, miss);
2764 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2765 CheckPrototypes(
2766 IC::CurrentTypeOf(prototype, isolate()),
2767 eax, holder, ebx, edx, edi, name, &miss);
2768 break; 2567 break;
2769 } 2568 }
2770 case BOOLEAN_CHECK: { 2569 case BOOLEAN_CHECK: {
2771 GenerateBooleanCheck(edx, &miss); 2570 GenerateBooleanCheck(reg, miss);
2772 // Check that the maps starting from the prototype haven't changed. 2571 // Check that the maps starting from the prototype haven't changed.
2773 GenerateDirectLoadGlobalFunctionPrototype( 2572 GenerateDirectLoadGlobalFunctionPrototype(
2774 masm(), Context::BOOLEAN_FUNCTION_INDEX, eax, &miss); 2573 masm(), Context::BOOLEAN_FUNCTION_INDEX, eax, miss);
2775 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2776 CheckPrototypes(
2777 IC::CurrentTypeOf(prototype, isolate()),
2778 eax, holder, ebx, edx, edi, name, &miss);
2779 break; 2574 break;
2780 } 2575 }
2781 } 2576 }
2782 2577
2783 Label success; 2578 if (check != RECEIVER_MAP_CHECK) {
2784 __ jmp(&success); 2579 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2580 reg = CheckPrototypes(
2581 IC::CurrentTypeOf(prototype, isolate()),
2582 eax, holder, ebx, edx, edi, name, miss);
2583 }
2785 2584
2786 // Handle call cache miss. 2585 return reg;
2787 __ bind(&miss);
2788 GenerateMissBranch();
2789
2790 __ bind(&success);
2791 } 2586 }
2792 2587
2793 2588
2794 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { 2589 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) {
2795 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2590 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2796 ? CALL_AS_FUNCTION 2591 ? CALL_AS_FUNCTION
2797 : CALL_AS_METHOD; 2592 : CALL_AS_METHOD;
2798 ParameterCount expected(function); 2593 ParameterCount expected(function);
2799 __ InvokeFunction(function, expected, arguments(), 2594 __ InvokeFunction(function, expected, arguments(),
2800 JUMP_FUNCTION, NullCallWrapper(), call_kind); 2595 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2801 } 2596 }
2802 2597
2803 2598
2804 Handle<Code> CallStubCompiler::CompileCallConstant( 2599 Handle<Code> CallStubCompiler::CompileCallConstant(
2805 Handle<Object> object, 2600 Handle<Object> object,
2806 Handle<JSObject> holder, 2601 Handle<JSObject> holder,
2807 Handle<Name> name, 2602 Handle<Name> name,
2808 CheckType check, 2603 CheckType check,
2809 Handle<JSFunction> function) { 2604 Handle<JSFunction> function) {
2810 2605
2811 if (HasCustomCallGenerator(function)) { 2606 if (HasCustomCallGenerator(function)) {
2812 Handle<Code> code = CompileCustomCall(object, holder, 2607 Handle<Code> code = CompileCustomCall(object, holder,
2813 Handle<Cell>::null(), 2608 Handle<Cell>::null(),
2814 function, Handle<String>::cast(name), 2609 function, Handle<String>::cast(name),
2815 Code::FAST); 2610 Code::FAST);
2816 // A null handle means bail out to the regular compiler code below. 2611 // A null handle means bail out to the regular compiler code below.
2817 if (!code.is_null()) return code; 2612 if (!code.is_null()) return code;
2818 } 2613 }
2819 2614
2820 CompileHandlerFrontend(object, holder, name, check); 2615 Label miss;
2616 HandlerFrontendHeader(object, holder, name, check, &miss);
2617 PatchGlobalProxy(object);
2821 CompileHandlerBackend(function); 2618 CompileHandlerBackend(function);
2619 HandlerFrontendFooter(&miss);
2822 2620
2823 // Return the generated code. 2621 // Return the generated code.
2824 return GetCode(function); 2622 return GetCode(function);
2825 } 2623 }
2826 2624
2827 2625
2828 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, 2626 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
2829 Handle<JSObject> holder, 2627 Handle<JSObject> holder,
2830 Handle<Name> name) { 2628 Handle<Name> name) {
2831 // ----------- S t a t e -------------
2832 // -- ecx : name
2833 // -- esp[0] : return address
2834 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2835 // -- ...
2836 // -- esp[(argc + 1) * 4] : receiver
2837 // -----------------------------------
2838 Label miss; 2629 Label miss;
2839 2630
2840 GenerateNameCheck(name, &miss); 2631 GenerateNameCheck(name, &miss);
2841 2632
2842 // Get the number of arguments. 2633 // Get the number of arguments.
2843 const int argc = arguments().immediate(); 2634 const int argc = arguments().immediate();
2844 2635
2845 LookupResult lookup(isolate()); 2636 LookupResult lookup(isolate());
2846 LookupPostInterceptor(holder, name, &lookup); 2637 LookupPostInterceptor(holder, name, &lookup);
2847 2638
2848 // Get the receiver from the stack. 2639 // Get the receiver from the stack.
2849 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2640 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2850 2641
2851 CallInterceptorCompiler compiler(this, arguments(), ecx, extra_state_); 2642 CallInterceptorCompiler compiler(this, arguments(), ecx, extra_state_);
2852 compiler.Compile(masm(), object, holder, name, &lookup, edx, ebx, edi, eax, 2643 compiler.Compile(masm(), object, holder, name, &lookup, edx, ebx, edi, eax,
2853 &miss); 2644 &miss);
2854 2645
2855 // Restore receiver. 2646 // Restore receiver.
2856 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2647 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2857 2648
2858 // Check that the function really is a function. 2649 // Check that the function really is a function.
2859 __ JumpIfSmi(eax, &miss); 2650 __ JumpIfSmi(eax, &miss);
2860 __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx); 2651 __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx);
2861 __ j(not_equal, &miss); 2652 __ j(not_equal, &miss);
2862 2653
2863 // Patch the receiver on the stack with the global proxy if 2654 // Patch the receiver on the stack with the global proxy if
2864 // necessary. 2655 // necessary.
2865 if (object->IsGlobalObject()) { 2656 if (object->IsGlobalObject()) {
Igor Sheludko 2013/11/28 12:54:27 Looks like PatchGlobalProxy(object);
2866 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); 2657 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
2867 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); 2658 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
2868 } 2659 }
2869 2660
2870 // Invoke the function. 2661 // Invoke the function.
2871 __ mov(edi, eax); 2662 __ mov(edi, eax);
2872 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2663 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2873 ? CALL_AS_FUNCTION 2664 ? CALL_AS_FUNCTION
2874 : CALL_AS_METHOD; 2665 : CALL_AS_METHOD;
2875 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION, 2666 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION,
2876 NullCallWrapper(), call_kind); 2667 NullCallWrapper(), call_kind);
2877 2668
2878 // Handle load cache miss. 2669 // Handle load cache miss.
2879 __ bind(&miss); 2670 __ bind(&miss);
2880 GenerateMissBranch(); 2671 GenerateMissBranch();
2881 2672
2882 // Return the generated code. 2673 // Return the generated code.
2883 return GetCode(Code::FAST, name); 2674 return GetCode(Code::FAST, name);
2884 } 2675 }
2885 2676
2886 2677
2887 Handle<Code> CallStubCompiler::CompileCallGlobal( 2678 Handle<Code> CallStubCompiler::CompileCallGlobal(
2888 Handle<JSObject> object, 2679 Handle<JSObject> object,
2889 Handle<GlobalObject> holder, 2680 Handle<GlobalObject> holder,
2890 Handle<PropertyCell> cell, 2681 Handle<PropertyCell> cell,
2891 Handle<JSFunction> function, 2682 Handle<JSFunction> function,
2892 Handle<Name> name) { 2683 Handle<Name> name) {
2893 // ----------- S t a t e -------------
2894 // -- ecx : name
2895 // -- esp[0] : return address
2896 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2897 // -- ...
2898 // -- esp[(argc + 1) * 4] : receiver
2899 // -----------------------------------
2900
2901 if (HasCustomCallGenerator(function)) { 2684 if (HasCustomCallGenerator(function)) {
2902 Handle<Code> code = CompileCustomCall( 2685 Handle<Code> code = CompileCustomCall(
2903 object, holder, cell, function, Handle<String>::cast(name), 2686 object, holder, cell, function, Handle<String>::cast(name),
2904 Code::NORMAL); 2687 Code::NORMAL);
2905 // A null handle means bail out to the regular compiler code below. 2688 // A null handle means bail out to the regular compiler code below.
2906 if (!code.is_null()) return code; 2689 if (!code.is_null()) return code;
2907 } 2690 }
2908 2691
2909 Label miss; 2692 Label miss;
2910 GenerateNameCheck(name, &miss); 2693 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2911
2912 // Get the number of arguments.
2913 const int argc = arguments().immediate();
2914 GenerateGlobalReceiverCheck(object, holder, name, &miss);
2915 GenerateLoadFunctionFromCell(cell, function, &miss); 2694 GenerateLoadFunctionFromCell(cell, function, &miss);
2916 2695 PatchGlobalProxy(object);
2917 // Patch the receiver on the stack with the global proxy.
2918 if (object->IsGlobalObject()) {
2919 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
2920 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
2921 }
2922 2696
2923 // Set up the context (function already in edi). 2697 // Set up the context (function already in edi).
2924 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 2698 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
2925 2699
2926 // Jump to the cached code (tail call). 2700 // Jump to the cached code (tail call).
2927 Counters* counters = isolate()->counters(); 2701 Counters* counters = isolate()->counters();
2928 __ IncrementCounter(counters->call_global_inline(), 1); 2702 __ IncrementCounter(counters->call_global_inline(), 1);
2929 ParameterCount expected(function->shared()->formal_parameter_count()); 2703 ParameterCount expected(function->shared()->formal_parameter_count());
2930 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2704 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2931 ? CALL_AS_FUNCTION 2705 ? CALL_AS_FUNCTION
2932 : CALL_AS_METHOD; 2706 : CALL_AS_METHOD;
2933 // We call indirectly through the code field in the function to 2707 // We call indirectly through the code field in the function to
2934 // allow recompilation to take effect without changing any of the 2708 // allow recompilation to take effect without changing any of the
2935 // call sites. 2709 // call sites.
2936 __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), 2710 __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
2937 expected, arguments(), JUMP_FUNCTION, 2711 expected, arguments(), JUMP_FUNCTION,
2938 NullCallWrapper(), call_kind); 2712 NullCallWrapper(), call_kind);
2939 2713
2940 // Handle call cache miss. 2714 HandlerFrontendFooter(&miss);
2941 __ bind(&miss);
2942 __ IncrementCounter(counters->call_global_inline_miss(), 1);
2943 GenerateMissBranch();
2944 2715
2945 // Return the generated code. 2716 // Return the generated code.
2946 return GetCode(Code::NORMAL, name); 2717 return GetCode(Code::NORMAL, name);
2947 } 2718 }
2948 2719
2949 2720
2950 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2721 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2951 Handle<JSObject> object, 2722 Handle<JSObject> object,
2952 Handle<JSObject> holder, 2723 Handle<JSObject> holder,
2953 Handle<Name> name, 2724 Handle<Name> name,
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
3307 // ----------------------------------- 3078 // -----------------------------------
3308 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 3079 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
3309 } 3080 }
3310 3081
3311 3082
3312 #undef __ 3083 #undef __
3313 3084
3314 } } // namespace v8::internal 3085 } } // namespace v8::internal
3315 3086
3316 #endif // V8_TARGET_ARCH_IA32 3087 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698