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

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

Issue 148343005: A64: Synchronize with r18147. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/ic-ia32.cc ('k') | src/ic.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 restore_context ? 641 restore_context ?
642 &context_restore_operand : NULL); 642 &context_restore_operand : NULL);
643 } 643 }
644 644
645 645
646 class CallInterceptorCompiler BASE_EMBEDDED { 646 class CallInterceptorCompiler BASE_EMBEDDED {
647 public: 647 public:
648 CallInterceptorCompiler(StubCompiler* stub_compiler, 648 CallInterceptorCompiler(StubCompiler* stub_compiler,
649 const ParameterCount& arguments, 649 const ParameterCount& arguments,
650 Register name, 650 Register name,
651 Code::ExtraICState extra_state) 651 ExtraICState extra_state)
652 : stub_compiler_(stub_compiler), 652 : stub_compiler_(stub_compiler),
653 arguments_(arguments), 653 arguments_(arguments),
654 name_(name), 654 name_(name),
655 extra_state_(extra_state) {} 655 extra_state_(extra_state) {}
656 656
657 void Compile(MacroAssembler* masm, 657 void Compile(MacroAssembler* masm,
658 Handle<JSObject> object, 658 Handle<JSObject> object,
659 Handle<JSObject> holder, 659 Handle<JSObject> holder,
660 Handle<Name> name, 660 Handle<Name> name,
661 LookupResult* lookup, 661 LookupResult* lookup,
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 // Leave the internal frame. 826 // Leave the internal frame.
827 } 827 }
828 828
829 __ cmp(eax, masm->isolate()->factory()->no_interceptor_result_sentinel()); 829 __ cmp(eax, masm->isolate()->factory()->no_interceptor_result_sentinel());
830 __ j(not_equal, interceptor_succeeded); 830 __ j(not_equal, interceptor_succeeded);
831 } 831 }
832 832
833 StubCompiler* stub_compiler_; 833 StubCompiler* stub_compiler_;
834 const ParameterCount& arguments_; 834 const ParameterCount& arguments_;
835 Register name_; 835 Register name_;
836 Code::ExtraICState extra_state_; 836 ExtraICState extra_state_;
837 }; 837 };
838 838
839 839
840 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, 840 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
841 Label* label, 841 Label* label,
842 Handle<Name> name) { 842 Handle<Name> name) {
843 if (!label->is_unused()) { 843 if (!label->is_unused()) {
844 __ bind(label); 844 __ bind(label);
845 __ mov(this->name(), Immediate(name)); 845 __ mov(this->name(), Immediate(name));
846 } 846 }
(...skipping 748 matching lines...) Expand 10 before | Expand all | Expand 10 after
1595 1595
1596 1596
1597 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { 1597 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) {
1598 if (kind_ == Code::KEYED_CALL_IC) { 1598 if (kind_ == Code::KEYED_CALL_IC) {
1599 __ cmp(ecx, Immediate(name)); 1599 __ cmp(ecx, Immediate(name));
1600 __ j(not_equal, miss); 1600 __ j(not_equal, miss);
1601 } 1601 }
1602 } 1602 }
1603 1603
1604 1604
1605 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object,
1606 Handle<JSObject> holder,
1607 Handle<Name> name,
1608 Label* miss) {
1609 ASSERT(holder->IsGlobalObject());
1610
1611 // Get the number of arguments.
1612 const int argc = arguments().immediate();
1613
1614 // Get the receiver from the stack.
1615 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1616
1617
1618 // Check that the maps haven't changed.
1619 __ JumpIfSmi(edx, miss);
1620 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder,
1621 ebx, eax, edi, name, miss);
1622 }
1623
1624
1625 void CallStubCompiler::GenerateLoadFunctionFromCell( 1605 void CallStubCompiler::GenerateLoadFunctionFromCell(
1626 Handle<Cell> cell, 1606 Handle<Cell> cell,
1627 Handle<JSFunction> function, 1607 Handle<JSFunction> function,
1628 Label* miss) { 1608 Label* miss) {
1629 // Get the value from the cell. 1609 // Get the value from the cell.
1630 if (Serializer::enabled()) { 1610 if (Serializer::enabled()) {
1631 __ mov(edi, Immediate(cell)); 1611 __ mov(edi, Immediate(cell));
1632 __ mov(edi, FieldOperand(edi, Cell::kValueOffset)); 1612 __ mov(edi, FieldOperand(edi, Cell::kValueOffset));
1633 } else { 1613 } else {
1634 __ mov(edi, Operand::ForCell(cell)); 1614 __ mov(edi, Operand::ForCell(cell));
(...skipping 26 matching lines...) Expand all
1661 kind_, 1641 kind_,
1662 extra_state_); 1642 extra_state_);
1663 __ jmp(code, RelocInfo::CODE_TARGET); 1643 __ jmp(code, RelocInfo::CODE_TARGET);
1664 } 1644 }
1665 1645
1666 1646
1667 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, 1647 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
1668 Handle<JSObject> holder, 1648 Handle<JSObject> holder,
1669 PropertyIndex index, 1649 PropertyIndex index,
1670 Handle<Name> name) { 1650 Handle<Name> name) {
1671 // ----------- S t a t e -------------
1672 // -- ecx : name
1673 // -- esp[0] : return address
1674 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1675 // -- ...
1676 // -- esp[(argc + 1) * 4] : receiver
1677 // -----------------------------------
1678 Label miss; 1651 Label miss;
1679 1652
1680 GenerateNameCheck(name, &miss); 1653 Register reg = HandlerFrontendHeader(
1681 1654 object, holder, name, RECEIVER_MAP_CHECK, &miss);
1682 // Get the receiver from the stack.
1683 const int argc = arguments().immediate();
1684 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1685
1686 // Check that the receiver isn't a smi.
1687 __ JumpIfSmi(edx, &miss);
1688
1689 // Do the right check and compute the holder register.
1690 Register reg = CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx,
1691 holder, ebx, eax, edi, name, &miss);
1692 1655
1693 GenerateFastPropertyLoad( 1656 GenerateFastPropertyLoad(
1694 masm(), edi, reg, index.is_inobject(holder), 1657 masm(), edi, reg, index.is_inobject(holder),
1695 index.translate(holder), Representation::Tagged()); 1658 index.translate(holder), Representation::Tagged());
1696 1659
1697 // Check that the function really is a function. 1660 // Check that the function really is a function.
1698 __ JumpIfSmi(edi, &miss); 1661 __ JumpIfSmi(edi, &miss);
1699 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); 1662 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx);
1700 __ j(not_equal, &miss); 1663 __ j(not_equal, &miss);
1701 1664
1702 // Patch the receiver on the stack with the global proxy if 1665 PatchGlobalProxy(object);
1703 // necessary.
1704 if (object->IsGlobalObject()) {
1705 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
1706 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
1707 }
1708 1666
1709 // Invoke the function. 1667 // Invoke the function.
1710 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 1668 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
1711 ? CALL_AS_FUNCTION 1669 ? CALL_AS_FUNCTION
1712 : CALL_AS_METHOD; 1670 : CALL_AS_METHOD;
1713 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION, 1671 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION,
1714 NullCallWrapper(), call_kind); 1672 NullCallWrapper(), call_kind);
1715 1673
1716 // Handle call cache miss. 1674 HandlerFrontendFooter(&miss);
1717 __ bind(&miss);
1718 GenerateMissBranch();
1719 1675
1720 // Return the generated code. 1676 // Return the generated code.
1721 return GetCode(Code::FAST, name); 1677 return GetCode(Code::FAST, name);
1722 } 1678 }
1723 1679
1724 1680
1725 Handle<Code> CallStubCompiler::CompileArrayCodeCall( 1681 Handle<Code> CallStubCompiler::CompileArrayCodeCall(
1726 Handle<Object> object, 1682 Handle<Object> object,
1727 Handle<JSObject> holder, 1683 Handle<JSObject> holder,
1728 Handle<Cell> cell, 1684 Handle<Cell> cell,
1729 Handle<JSFunction> function, 1685 Handle<JSFunction> function,
1730 Handle<String> name, 1686 Handle<String> name,
1731 Code::StubType type) { 1687 Code::StubType type) {
1732 Label miss; 1688 Label miss;
1733 1689
1734 // Check that function is still array 1690 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1735 const int argc = arguments().immediate(); 1691 if (!cell.is_null()) {
1736 GenerateNameCheck(name, &miss);
1737
1738 if (cell.is_null()) {
1739 // Get the receiver from the stack.
1740 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1741
1742 // Check that the receiver isn't a smi.
1743 __ JumpIfSmi(edx, &miss);
1744 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder,
1745 ebx, eax, edi, name, &miss);
1746 } else {
1747 ASSERT(cell->value() == *function); 1692 ASSERT(cell->value() == *function);
1748 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
1749 &miss);
1750 GenerateLoadFunctionFromCell(cell, function, &miss); 1693 GenerateLoadFunctionFromCell(cell, function, &miss);
1751 } 1694 }
1752 1695
1753 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); 1696 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite();
1754 site->SetElementsKind(GetInitialFastElementsKind()); 1697 site->SetElementsKind(GetInitialFastElementsKind());
1755 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); 1698 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site);
1699 const int argc = arguments().immediate();
1756 __ mov(eax, Immediate(argc)); 1700 __ mov(eax, Immediate(argc));
1757 __ mov(ebx, site_feedback_cell); 1701 __ mov(ebx, site_feedback_cell);
1758 __ mov(edi, function); 1702 __ mov(edi, function);
1759 1703
1760 ArrayConstructorStub stub(isolate()); 1704 ArrayConstructorStub stub(isolate());
1761 __ TailCallStub(&stub); 1705 __ TailCallStub(&stub);
1762 1706
1763 __ bind(&miss); 1707 HandlerFrontendFooter(&miss);
1764 GenerateMissBranch();
1765 1708
1766 // Return the generated code. 1709 // Return the generated code.
1767 return GetCode(type, name); 1710 return GetCode(type, name);
1768 } 1711 }
1769 1712
1770 1713
1771 Handle<Code> CallStubCompiler::CompileArrayPushCall( 1714 Handle<Code> CallStubCompiler::CompileArrayPushCall(
1772 Handle<Object> object, 1715 Handle<Object> object,
1773 Handle<JSObject> holder, 1716 Handle<JSObject> holder,
1774 Handle<Cell> cell, 1717 Handle<Cell> cell,
1775 Handle<JSFunction> function, 1718 Handle<JSFunction> function,
1776 Handle<String> name, 1719 Handle<String> name,
1777 Code::StubType type) { 1720 Code::StubType type) {
1778 // ----------- S t a t e -------------
1779 // -- ecx : name
1780 // -- esp[0] : return address
1781 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1782 // -- ...
1783 // -- esp[(argc + 1) * 4] : receiver
1784 // -----------------------------------
1785
1786 // If object is not an array or is observed, bail out to regular call. 1721 // If object is not an array or is observed, bail out to regular call.
1787 if (!object->IsJSArray() || 1722 if (!object->IsJSArray() ||
1788 !cell.is_null() || 1723 !cell.is_null() ||
1789 Handle<JSArray>::cast(object)->map()->is_observed()) { 1724 Handle<JSArray>::cast(object)->map()->is_observed()) {
1790 return Handle<Code>::null(); 1725 return Handle<Code>::null();
1791 } 1726 }
1792 1727
1793 Label miss; 1728 Label miss;
1794 1729
1795 GenerateNameCheck(name, &miss); 1730 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1796 1731
1797 // Get the receiver from the stack.
1798 const int argc = arguments().immediate(); 1732 const int argc = arguments().immediate();
1799 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1800
1801 // Check that the receiver isn't a smi.
1802 __ JumpIfSmi(edx, &miss);
1803
1804 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder,
1805 ebx, eax, edi, name, &miss);
1806
1807 if (argc == 0) { 1733 if (argc == 0) {
1808 // Noop, return the length. 1734 // Noop, return the length.
1809 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset)); 1735 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset));
1810 __ ret((argc + 1) * kPointerSize); 1736 __ ret((argc + 1) * kPointerSize);
1811 } else { 1737 } else {
1812 Label call_builtin; 1738 Label call_builtin;
1813 1739
1814 if (argc == 1) { // Otherwise fall through to call builtin. 1740 if (argc == 1) { // Otherwise fall through to call builtin.
1815 Label attempt_to_grow_elements, with_write_barrier, check_double; 1741 Label attempt_to_grow_elements, with_write_barrier, check_double;
1816 1742
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
2014 __ ret((argc + 1) * kPointerSize); 1940 __ ret((argc + 1) * kPointerSize);
2015 } 1941 }
2016 1942
2017 __ bind(&call_builtin); 1943 __ bind(&call_builtin);
2018 __ TailCallExternalReference( 1944 __ TailCallExternalReference(
2019 ExternalReference(Builtins::c_ArrayPush, isolate()), 1945 ExternalReference(Builtins::c_ArrayPush, isolate()),
2020 argc + 1, 1946 argc + 1,
2021 1); 1947 1);
2022 } 1948 }
2023 1949
2024 __ bind(&miss); 1950 HandlerFrontendFooter(&miss);
2025 GenerateMissBranch();
2026 1951
2027 // Return the generated code. 1952 // Return the generated code.
2028 return GetCode(type, name); 1953 return GetCode(type, name);
2029 } 1954 }
2030 1955
2031 1956
2032 Handle<Code> CallStubCompiler::CompileArrayPopCall( 1957 Handle<Code> CallStubCompiler::CompileArrayPopCall(
2033 Handle<Object> object, 1958 Handle<Object> object,
2034 Handle<JSObject> holder, 1959 Handle<JSObject> holder,
2035 Handle<Cell> cell, 1960 Handle<Cell> cell,
2036 Handle<JSFunction> function, 1961 Handle<JSFunction> function,
2037 Handle<String> name, 1962 Handle<String> name,
2038 Code::StubType type) { 1963 Code::StubType type) {
2039 // ----------- S t a t e -------------
2040 // -- ecx : name
2041 // -- esp[0] : return address
2042 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2043 // -- ...
2044 // -- esp[(argc + 1) * 4] : receiver
2045 // -----------------------------------
2046
2047 // If object is not an array or is observed, bail out to regular call. 1964 // If object is not an array or is observed, bail out to regular call.
2048 if (!object->IsJSArray() || 1965 if (!object->IsJSArray() ||
2049 !cell.is_null() || 1966 !cell.is_null() ||
2050 Handle<JSArray>::cast(object)->map()->is_observed()) { 1967 Handle<JSArray>::cast(object)->map()->is_observed()) {
2051 return Handle<Code>::null(); 1968 return Handle<Code>::null();
2052 } 1969 }
2053 1970
2054 Label miss, return_undefined, call_builtin; 1971 Label miss, return_undefined, call_builtin;
2055 1972
2056 GenerateNameCheck(name, &miss); 1973 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2057
2058 // Get the receiver from the stack.
2059 const int argc = arguments().immediate();
2060 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2061
2062 // Check that the receiver isn't a smi.
2063 __ JumpIfSmi(edx, &miss);
2064 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder,
2065 ebx, eax, edi, name, &miss);
2066 1974
2067 // Get the elements array of the object. 1975 // Get the elements array of the object.
2068 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset)); 1976 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset));
2069 1977
2070 // Check that the elements are in fast mode and writable. 1978 // Check that the elements are in fast mode and writable.
2071 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), 1979 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
2072 Immediate(factory()->fixed_array_map())); 1980 Immediate(factory()->fixed_array_map()));
2073 __ j(not_equal, &call_builtin); 1981 __ j(not_equal, &call_builtin);
2074 1982
2075 // Get the array's length into ecx and calculate new length. 1983 // Get the array's length into ecx and calculate new length.
(...skipping 11 matching lines...) Expand all
2087 __ j(equal, &call_builtin); 1995 __ j(equal, &call_builtin);
2088 1996
2089 // Set the array's length. 1997 // Set the array's length.
2090 __ mov(FieldOperand(edx, JSArray::kLengthOffset), ecx); 1998 __ mov(FieldOperand(edx, JSArray::kLengthOffset), ecx);
2091 1999
2092 // Fill with the hole. 2000 // Fill with the hole.
2093 __ mov(FieldOperand(ebx, 2001 __ mov(FieldOperand(ebx,
2094 ecx, times_half_pointer_size, 2002 ecx, times_half_pointer_size,
2095 FixedArray::kHeaderSize), 2003 FixedArray::kHeaderSize),
2096 Immediate(factory()->the_hole_value())); 2004 Immediate(factory()->the_hole_value()));
2005 const int argc = arguments().immediate();
2097 __ ret((argc + 1) * kPointerSize); 2006 __ ret((argc + 1) * kPointerSize);
2098 2007
2099 __ bind(&return_undefined); 2008 __ bind(&return_undefined);
2100 __ mov(eax, Immediate(factory()->undefined_value())); 2009 __ mov(eax, Immediate(factory()->undefined_value()));
2101 __ ret((argc + 1) * kPointerSize); 2010 __ ret((argc + 1) * kPointerSize);
2102 2011
2103 __ bind(&call_builtin); 2012 __ bind(&call_builtin);
2104 __ TailCallExternalReference( 2013 __ TailCallExternalReference(
2105 ExternalReference(Builtins::c_ArrayPop, isolate()), 2014 ExternalReference(Builtins::c_ArrayPop, isolate()),
2106 argc + 1, 2015 argc + 1,
2107 1); 2016 1);
2108 2017
2109 __ bind(&miss); 2018 HandlerFrontendFooter(&miss);
2110 GenerateMissBranch();
2111 2019
2112 // Return the generated code. 2020 // Return the generated code.
2113 return GetCode(type, name); 2021 return GetCode(type, name);
2114 } 2022 }
2115 2023
2116 2024
2117 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall( 2025 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
2118 Handle<Object> object, 2026 Handle<Object> object,
2119 Handle<JSObject> holder, 2027 Handle<JSObject> holder,
2120 Handle<Cell> cell, 2028 Handle<Cell> cell,
2121 Handle<JSFunction> function, 2029 Handle<JSFunction> function,
2122 Handle<String> name, 2030 Handle<String> name,
2123 Code::StubType type) { 2031 Code::StubType type) {
2124 // ----------- S t a t e -------------
2125 // -- ecx : function name
2126 // -- esp[0] : return address
2127 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2128 // -- ...
2129 // -- esp[(argc + 1) * 4] : receiver
2130 // -----------------------------------
2131
2132 // If object is not a string, bail out to regular call. 2032 // If object is not a string, bail out to regular call.
2133 if (!object->IsString() || !cell.is_null()) { 2033 if (!object->IsString() || !cell.is_null()) {
2134 return Handle<Code>::null(); 2034 return Handle<Code>::null();
2135 } 2035 }
2136 2036
2137 const int argc = arguments().immediate(); 2037 const int argc = arguments().immediate();
2138 2038
2139 Label miss; 2039 Label miss;
2140 Label name_miss; 2040 Label name_miss;
2141 Label index_out_of_range; 2041 Label index_out_of_range;
2142 Label* index_out_of_range_label = &index_out_of_range; 2042 Label* index_out_of_range_label = &index_out_of_range;
2143 2043
2144 if (kind_ == Code::CALL_IC && 2044 if (kind_ == Code::CALL_IC &&
2145 (CallICBase::StringStubState::decode(extra_state_) == 2045 (CallICBase::StringStubState::decode(extra_state_) ==
2146 DEFAULT_STRING_STUB)) { 2046 DEFAULT_STRING_STUB)) {
2147 index_out_of_range_label = &miss; 2047 index_out_of_range_label = &miss;
2148 } 2048 }
2149 2049
2150 GenerateNameCheck(name, &name_miss); 2050 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss);
2151
2152 // Check that the maps starting from the prototype haven't changed.
2153 GenerateDirectLoadGlobalFunctionPrototype(masm(),
2154 Context::STRING_FUNCTION_INDEX,
2155 eax,
2156 &miss);
2157 ASSERT(!object.is_identical_to(holder));
2158 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2159 CheckPrototypes(
2160 IC::CurrentTypeOf(prototype, isolate()),
2161 eax, holder, ebx, edx, edi, name, &miss);
2162 2051
2163 Register receiver = ebx; 2052 Register receiver = ebx;
2164 Register index = edi; 2053 Register index = edi;
2165 Register result = eax; 2054 Register result = eax;
2166 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize)); 2055 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize));
2167 if (argc > 0) { 2056 if (argc > 0) {
2168 __ mov(index, Operand(esp, (argc - 0) * kPointerSize)); 2057 __ mov(index, Operand(esp, (argc - 0) * kPointerSize));
2169 } else { 2058 } else {
2170 __ Set(index, Immediate(factory()->undefined_value())); 2059 __ Set(index, Immediate(factory()->undefined_value()));
2171 } 2060 }
(...skipping 28 matching lines...) Expand all
2200 } 2089 }
2201 2090
2202 2091
2203 Handle<Code> CallStubCompiler::CompileStringCharAtCall( 2092 Handle<Code> CallStubCompiler::CompileStringCharAtCall(
2204 Handle<Object> object, 2093 Handle<Object> object,
2205 Handle<JSObject> holder, 2094 Handle<JSObject> holder,
2206 Handle<Cell> cell, 2095 Handle<Cell> cell,
2207 Handle<JSFunction> function, 2096 Handle<JSFunction> function,
2208 Handle<String> name, 2097 Handle<String> name,
2209 Code::StubType type) { 2098 Code::StubType type) {
2210 // ----------- S t a t e -------------
2211 // -- ecx : function name
2212 // -- esp[0] : return address
2213 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2214 // -- ...
2215 // -- esp[(argc + 1) * 4] : receiver
2216 // -----------------------------------
2217
2218 // If object is not a string, bail out to regular call. 2099 // If object is not a string, bail out to regular call.
2219 if (!object->IsString() || !cell.is_null()) { 2100 if (!object->IsString() || !cell.is_null()) {
2220 return Handle<Code>::null(); 2101 return Handle<Code>::null();
2221 } 2102 }
2222 2103
2223 const int argc = arguments().immediate(); 2104 const int argc = arguments().immediate();
2224 2105
2225 Label miss; 2106 Label miss;
2226 Label name_miss; 2107 Label name_miss;
2227 Label index_out_of_range; 2108 Label index_out_of_range;
2228 Label* index_out_of_range_label = &index_out_of_range; 2109 Label* index_out_of_range_label = &index_out_of_range;
2229 2110
2230 if (kind_ == Code::CALL_IC && 2111 if (kind_ == Code::CALL_IC &&
2231 (CallICBase::StringStubState::decode(extra_state_) == 2112 (CallICBase::StringStubState::decode(extra_state_) ==
2232 DEFAULT_STRING_STUB)) { 2113 DEFAULT_STRING_STUB)) {
2233 index_out_of_range_label = &miss; 2114 index_out_of_range_label = &miss;
2234 } 2115 }
2235 2116
2236 GenerateNameCheck(name, &name_miss); 2117 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss);
2237
2238 // Check that the maps starting from the prototype haven't changed.
2239 GenerateDirectLoadGlobalFunctionPrototype(masm(),
2240 Context::STRING_FUNCTION_INDEX,
2241 eax,
2242 &miss);
2243 ASSERT(!object.is_identical_to(holder));
2244 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2245 CheckPrototypes(
2246 IC::CurrentTypeOf(prototype, isolate()),
2247 eax, holder, ebx, edx, edi, name, &miss);
2248 2118
2249 Register receiver = eax; 2119 Register receiver = eax;
2250 Register index = edi; 2120 Register index = edi;
2251 Register scratch = edx; 2121 Register scratch = edx;
2252 Register result = eax; 2122 Register result = eax;
2253 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize)); 2123 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize));
2254 if (argc > 0) { 2124 if (argc > 0) {
2255 __ mov(index, Operand(esp, (argc - 0) * kPointerSize)); 2125 __ mov(index, Operand(esp, (argc - 0) * kPointerSize));
2256 } else { 2126 } else {
2257 __ Set(index, Immediate(factory()->undefined_value())); 2127 __ Set(index, Immediate(factory()->undefined_value()));
(...skipping 30 matching lines...) Expand all
2288 } 2158 }
2289 2159
2290 2160
2291 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( 2161 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
2292 Handle<Object> object, 2162 Handle<Object> object,
2293 Handle<JSObject> holder, 2163 Handle<JSObject> holder,
2294 Handle<Cell> cell, 2164 Handle<Cell> cell,
2295 Handle<JSFunction> function, 2165 Handle<JSFunction> function,
2296 Handle<String> name, 2166 Handle<String> name,
2297 Code::StubType type) { 2167 Code::StubType type) {
2298 // ----------- S t a t e -------------
2299 // -- ecx : function name
2300 // -- esp[0] : return address
2301 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2302 // -- ...
2303 // -- esp[(argc + 1) * 4] : receiver
2304 // -----------------------------------
2305
2306 const int argc = arguments().immediate(); 2168 const int argc = arguments().immediate();
2307 2169
2308 // If the object is not a JSObject or we got an unexpected number of 2170 // If the object is not a JSObject or we got an unexpected number of
2309 // arguments, bail out to the regular call. 2171 // arguments, bail out to the regular call.
2310 if (!object->IsJSObject() || argc != 1) { 2172 if (!object->IsJSObject() || argc != 1) {
2311 return Handle<Code>::null(); 2173 return Handle<Code>::null();
2312 } 2174 }
2313 2175
2314 Label miss; 2176 Label miss;
2315 GenerateNameCheck(name, &miss);
2316 2177
2317 if (cell.is_null()) { 2178 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2318 __ mov(edx, Operand(esp, 2 * kPointerSize)); 2179 if (!cell.is_null()) {
2319 STATIC_ASSERT(kSmiTag == 0);
2320 __ JumpIfSmi(edx, &miss);
2321 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder,
2322 ebx, eax, edi, name, &miss);
2323 } else {
2324 ASSERT(cell->value() == *function); 2180 ASSERT(cell->value() == *function);
2325 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2326 &miss);
2327 GenerateLoadFunctionFromCell(cell, function, &miss); 2181 GenerateLoadFunctionFromCell(cell, function, &miss);
2328 } 2182 }
2329 2183
2330 // Load the char code argument. 2184 // Load the char code argument.
2331 Register code = ebx; 2185 Register code = ebx;
2332 __ mov(code, Operand(esp, 1 * kPointerSize)); 2186 __ mov(code, Operand(esp, 1 * kPointerSize));
2333 2187
2334 // Check the code is a smi. 2188 // Check the code is a smi.
2335 Label slow; 2189 Label slow;
2336 STATIC_ASSERT(kSmiTag == 0); 2190 STATIC_ASSERT(kSmiTag == 0);
(...skipping 12 matching lines...) Expand all
2349 // Tail call the full function. We do not have to patch the receiver 2203 // Tail call the full function. We do not have to patch the receiver
2350 // because the function makes no use of it. 2204 // because the function makes no use of it.
2351 __ bind(&slow); 2205 __ bind(&slow);
2352 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2206 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2353 ? CALL_AS_FUNCTION 2207 ? CALL_AS_FUNCTION
2354 : CALL_AS_METHOD; 2208 : CALL_AS_METHOD;
2355 ParameterCount expected(function); 2209 ParameterCount expected(function);
2356 __ InvokeFunction(function, expected, arguments(), 2210 __ InvokeFunction(function, expected, arguments(),
2357 JUMP_FUNCTION, NullCallWrapper(), call_kind); 2211 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2358 2212
2359 __ bind(&miss); 2213 HandlerFrontendFooter(&miss);
2360 // ecx: function name.
2361 GenerateMissBranch();
2362 2214
2363 // Return the generated code. 2215 // Return the generated code.
2364 return GetCode(type, name); 2216 return GetCode(type, name);
2365 } 2217 }
2366 2218
2367 2219
2368 Handle<Code> CallStubCompiler::CompileMathFloorCall( 2220 Handle<Code> CallStubCompiler::CompileMathFloorCall(
2369 Handle<Object> object, 2221 Handle<Object> object,
2370 Handle<JSObject> holder, 2222 Handle<JSObject> holder,
2371 Handle<Cell> cell, 2223 Handle<Cell> cell,
2372 Handle<JSFunction> function, 2224 Handle<JSFunction> function,
2373 Handle<String> name, 2225 Handle<String> name,
2374 Code::StubType type) { 2226 Code::StubType type) {
2375 // ----------- S t a t e -------------
2376 // -- ecx : name
2377 // -- esp[0] : return address
2378 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2379 // -- ...
2380 // -- esp[(argc + 1) * 4] : receiver
2381 // -----------------------------------
2382
2383 if (!CpuFeatures::IsSupported(SSE2)) { 2227 if (!CpuFeatures::IsSupported(SSE2)) {
2384 return Handle<Code>::null(); 2228 return Handle<Code>::null();
2385 } 2229 }
2386 2230
2387 CpuFeatureScope use_sse2(masm(), SSE2); 2231 CpuFeatureScope use_sse2(masm(), SSE2);
2388 2232
2389 const int argc = arguments().immediate(); 2233 const int argc = arguments().immediate();
2390 2234
2391 // If the object is not a JSObject or we got an unexpected number of 2235 // If the object is not a JSObject or we got an unexpected number of
2392 // arguments, bail out to the regular call. 2236 // arguments, bail out to the regular call.
2393 if (!object->IsJSObject() || argc != 1) { 2237 if (!object->IsJSObject() || argc != 1) {
2394 return Handle<Code>::null(); 2238 return Handle<Code>::null();
2395 } 2239 }
2396 2240
2397 Label miss; 2241 Label miss;
2398 GenerateNameCheck(name, &miss);
2399 2242
2400 if (cell.is_null()) { 2243 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2401 __ mov(edx, Operand(esp, 2 * kPointerSize)); 2244 if (!cell.is_null()) {
2402
2403 STATIC_ASSERT(kSmiTag == 0);
2404 __ JumpIfSmi(edx, &miss);
2405
2406 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder,
2407 ebx, eax, edi, name, &miss);
2408 } else {
2409 ASSERT(cell->value() == *function); 2245 ASSERT(cell->value() == *function);
2410 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2411 &miss);
2412 GenerateLoadFunctionFromCell(cell, function, &miss); 2246 GenerateLoadFunctionFromCell(cell, function, &miss);
2413 } 2247 }
2414 2248
2415 // Load the (only) argument into eax. 2249 // Load the (only) argument into eax.
2416 __ mov(eax, Operand(esp, 1 * kPointerSize)); 2250 __ mov(eax, Operand(esp, 1 * kPointerSize));
2417 2251
2418 // Check if the argument is a smi. 2252 // Check if the argument is a smi.
2419 Label smi; 2253 Label smi;
2420 STATIC_ASSERT(kSmiTag == 0); 2254 STATIC_ASSERT(kSmiTag == 0);
2421 __ JumpIfSmi(eax, &smi); 2255 __ JumpIfSmi(eax, &smi);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2481 __ mov(eax, Operand(esp, 1 * kPointerSize)); 2315 __ mov(eax, Operand(esp, 1 * kPointerSize));
2482 __ ret(2 * kPointerSize); 2316 __ ret(2 * kPointerSize);
2483 2317
2484 // Tail call the full function. We do not have to patch the receiver 2318 // Tail call the full function. We do not have to patch the receiver
2485 // because the function makes no use of it. 2319 // because the function makes no use of it.
2486 __ bind(&slow); 2320 __ bind(&slow);
2487 ParameterCount expected(function); 2321 ParameterCount expected(function);
2488 __ InvokeFunction(function, expected, arguments(), 2322 __ InvokeFunction(function, expected, arguments(),
2489 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2323 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
2490 2324
2491 __ bind(&miss); 2325 HandlerFrontendFooter(&miss);
2492 // ecx: function name.
2493 GenerateMissBranch();
2494 2326
2495 // Return the generated code. 2327 // Return the generated code.
2496 return GetCode(type, name); 2328 return GetCode(type, name);
2497 } 2329 }
2498 2330
2499 2331
2500 Handle<Code> CallStubCompiler::CompileMathAbsCall( 2332 Handle<Code> CallStubCompiler::CompileMathAbsCall(
2501 Handle<Object> object, 2333 Handle<Object> object,
2502 Handle<JSObject> holder, 2334 Handle<JSObject> holder,
2503 Handle<Cell> cell, 2335 Handle<Cell> cell,
2504 Handle<JSFunction> function, 2336 Handle<JSFunction> function,
2505 Handle<String> name, 2337 Handle<String> name,
2506 Code::StubType type) { 2338 Code::StubType type) {
2507 // ----------- S t a t e -------------
2508 // -- ecx : name
2509 // -- esp[0] : return address
2510 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2511 // -- ...
2512 // -- esp[(argc + 1) * 4] : receiver
2513 // -----------------------------------
2514
2515 const int argc = arguments().immediate(); 2339 const int argc = arguments().immediate();
2516 2340
2517 // If the object is not a JSObject or we got an unexpected number of 2341 // If the object is not a JSObject or we got an unexpected number of
2518 // arguments, bail out to the regular call. 2342 // arguments, bail out to the regular call.
2519 if (!object->IsJSObject() || argc != 1) { 2343 if (!object->IsJSObject() || argc != 1) {
2520 return Handle<Code>::null(); 2344 return Handle<Code>::null();
2521 } 2345 }
2522 2346
2523 Label miss; 2347 Label miss;
2524 GenerateNameCheck(name, &miss);
2525 2348
2526 if (cell.is_null()) { 2349 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2527 __ mov(edx, Operand(esp, 2 * kPointerSize)); 2350 if (!cell.is_null()) {
2528
2529 STATIC_ASSERT(kSmiTag == 0);
2530 __ JumpIfSmi(edx, &miss);
2531
2532 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder,
2533 ebx, eax, edi, name, &miss);
2534 } else {
2535 ASSERT(cell->value() == *function); 2351 ASSERT(cell->value() == *function);
2536 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2537 &miss);
2538 GenerateLoadFunctionFromCell(cell, function, &miss); 2352 GenerateLoadFunctionFromCell(cell, function, &miss);
2539 } 2353 }
2540 2354
2541 // Load the (only) argument into eax. 2355 // Load the (only) argument into eax.
2542 __ mov(eax, Operand(esp, 1 * kPointerSize)); 2356 __ mov(eax, Operand(esp, 1 * kPointerSize));
2543 2357
2544 // Check if the argument is a smi. 2358 // Check if the argument is a smi.
2545 Label not_smi; 2359 Label not_smi;
2546 STATIC_ASSERT(kSmiTag == 0); 2360 STATIC_ASSERT(kSmiTag == 0);
2547 __ JumpIfNotSmi(eax, &not_smi); 2361 __ JumpIfNotSmi(eax, &not_smi);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2590 __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx); 2404 __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx);
2591 __ ret(2 * kPointerSize); 2405 __ ret(2 * kPointerSize);
2592 2406
2593 // Tail call the full function. We do not have to patch the receiver 2407 // Tail call the full function. We do not have to patch the receiver
2594 // because the function makes no use of it. 2408 // because the function makes no use of it.
2595 __ bind(&slow); 2409 __ bind(&slow);
2596 ParameterCount expected(function); 2410 ParameterCount expected(function);
2597 __ InvokeFunction(function, expected, arguments(), 2411 __ InvokeFunction(function, expected, arguments(),
2598 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2412 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
2599 2413
2600 __ bind(&miss); 2414 HandlerFrontendFooter(&miss);
2601 // ecx: function name.
2602 GenerateMissBranch();
2603 2415
2604 // Return the generated code. 2416 // Return the generated code.
2605 return GetCode(type, name); 2417 return GetCode(type, name);
2606 } 2418 }
2607 2419
2608 2420
2609 Handle<Code> CallStubCompiler::CompileFastApiCall( 2421 Handle<Code> CallStubCompiler::CompileFastApiCall(
2610 const CallOptimization& optimization, 2422 const CallOptimization& optimization,
2611 Handle<Object> object, 2423 Handle<Object> object,
2612 Handle<JSObject> holder, 2424 Handle<JSObject> holder,
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2669 Label success; 2481 Label success;
2670 // Check that the object is a boolean. 2482 // Check that the object is a boolean.
2671 __ cmp(object, factory()->true_value()); 2483 __ cmp(object, factory()->true_value());
2672 __ j(equal, &success); 2484 __ j(equal, &success);
2673 __ cmp(object, factory()->false_value()); 2485 __ cmp(object, factory()->false_value());
2674 __ j(not_equal, miss); 2486 __ j(not_equal, miss);
2675 __ bind(&success); 2487 __ bind(&success);
2676 } 2488 }
2677 2489
2678 2490
2679 void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object, 2491 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) {
2680 Handle<JSObject> holder, 2492 if (object->IsGlobalObject()) {
2681 Handle<Name> name, 2493 const int argc = arguments().immediate();
2682 CheckType check) { 2494 const int receiver_offset = (argc + 1) * kPointerSize;
2683 // ----------- S t a t e ------------- 2495 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
2684 // -- ecx : name 2496 __ mov(Operand(esp, receiver_offset), edx);
2685 // -- esp[0] : return address 2497 }
2686 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 2498 }
2687 // -- ...
2688 // -- esp[(argc + 1) * 4] : receiver
2689 // -----------------------------------
2690 Label miss;
2691 GenerateNameCheck(name, &miss);
2692 2499
2693 // Get the receiver from the stack. 2500
2501 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object,
2502 Handle<JSObject> holder,
2503 Handle<Name> name,
2504 CheckType check,
2505 Label* miss) {
2506 GenerateNameCheck(name, miss);
2507
2508 Register reg = edx;
2509
2694 const int argc = arguments().immediate(); 2510 const int argc = arguments().immediate();
2695 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2511 const int receiver_offset = (argc + 1) * kPointerSize;
2512 __ mov(reg, Operand(esp, receiver_offset));
2696 2513
2697 // Check that the receiver isn't a smi. 2514 // Check that the receiver isn't a smi.
2698 if (check != NUMBER_CHECK) { 2515 if (check != NUMBER_CHECK) {
2699 __ JumpIfSmi(edx, &miss); 2516 __ JumpIfSmi(reg, miss);
2700 } 2517 }
2701 2518
2702 // Make sure that it's okay not to patch the on stack receiver 2519 // Make sure that it's okay not to patch the on stack receiver
2703 // unless we're doing a receiver map check. 2520 // unless we're doing a receiver map check.
2704 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 2521 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
2705 switch (check) { 2522 switch (check) {
2706 case RECEIVER_MAP_CHECK: 2523 case RECEIVER_MAP_CHECK:
2707 __ IncrementCounter(isolate()->counters()->call_const(), 1); 2524 __ IncrementCounter(isolate()->counters()->call_const(), 1);
2708 2525
2709 // Check that the maps haven't changed. 2526 // Check that the maps haven't changed.
2710 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder, 2527 reg = CheckPrototypes(IC::CurrentTypeOf(object, isolate()), reg, holder,
2711 ebx, eax, edi, name, &miss); 2528 ebx, eax, edi, name, miss);
2712 2529
2713 // Patch the receiver on the stack with the global proxy if
2714 // necessary.
2715 if (object->IsGlobalObject()) {
2716 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
2717 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
2718 }
2719 break; 2530 break;
2720 2531
2721 case STRING_CHECK: { 2532 case STRING_CHECK: {
2722 // Check that the object is a string. 2533 // Check that the object is a string.
2723 __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, eax); 2534 __ CmpObjectType(reg, FIRST_NONSTRING_TYPE, eax);
2724 __ j(above_equal, &miss); 2535 __ j(above_equal, miss);
2725 // Check that the maps starting from the prototype haven't changed. 2536 // Check that the maps starting from the prototype haven't changed.
2726 GenerateDirectLoadGlobalFunctionPrototype( 2537 GenerateDirectLoadGlobalFunctionPrototype(
2727 masm(), Context::STRING_FUNCTION_INDEX, eax, &miss); 2538 masm(), Context::STRING_FUNCTION_INDEX, eax, miss);
2728 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2729 CheckPrototypes(
2730 IC::CurrentTypeOf(prototype, isolate()),
2731 eax, holder, ebx, edx, edi, name, &miss);
2732 break; 2539 break;
2733 } 2540 }
2734 case SYMBOL_CHECK: { 2541 case SYMBOL_CHECK: {
2735 // Check that the object is a symbol. 2542 // Check that the object is a symbol.
2736 __ CmpObjectType(edx, SYMBOL_TYPE, eax); 2543 __ CmpObjectType(reg, SYMBOL_TYPE, eax);
2737 __ j(not_equal, &miss); 2544 __ j(not_equal, miss);
2738 // Check that the maps starting from the prototype haven't changed. 2545 // Check that the maps starting from the prototype haven't changed.
2739 GenerateDirectLoadGlobalFunctionPrototype( 2546 GenerateDirectLoadGlobalFunctionPrototype(
2740 masm(), Context::SYMBOL_FUNCTION_INDEX, eax, &miss); 2547 masm(), Context::SYMBOL_FUNCTION_INDEX, eax, miss);
2741 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2742 CheckPrototypes(
2743 IC::CurrentTypeOf(prototype, isolate()),
2744 eax, holder, ebx, edx, edi, name, &miss);
2745 break; 2548 break;
2746 } 2549 }
2747 case NUMBER_CHECK: { 2550 case NUMBER_CHECK: {
2748 Label fast; 2551 Label fast;
2749 // Check that the object is a smi or a heap number. 2552 // Check that the object is a smi or a heap number.
2750 __ JumpIfSmi(edx, &fast); 2553 __ JumpIfSmi(reg, &fast);
2751 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, eax); 2554 __ CmpObjectType(reg, HEAP_NUMBER_TYPE, eax);
2752 __ j(not_equal, &miss); 2555 __ j(not_equal, miss);
2753 __ bind(&fast); 2556 __ bind(&fast);
2754 // Check that the maps starting from the prototype haven't changed. 2557 // Check that the maps starting from the prototype haven't changed.
2755 GenerateDirectLoadGlobalFunctionPrototype( 2558 GenerateDirectLoadGlobalFunctionPrototype(
2756 masm(), Context::NUMBER_FUNCTION_INDEX, eax, &miss); 2559 masm(), Context::NUMBER_FUNCTION_INDEX, eax, miss);
2757 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2758 CheckPrototypes(
2759 IC::CurrentTypeOf(prototype, isolate()),
2760 eax, holder, ebx, edx, edi, name, &miss);
2761 break; 2560 break;
2762 } 2561 }
2763 case BOOLEAN_CHECK: { 2562 case BOOLEAN_CHECK: {
2764 GenerateBooleanCheck(edx, &miss); 2563 GenerateBooleanCheck(reg, miss);
2765 // Check that the maps starting from the prototype haven't changed. 2564 // Check that the maps starting from the prototype haven't changed.
2766 GenerateDirectLoadGlobalFunctionPrototype( 2565 GenerateDirectLoadGlobalFunctionPrototype(
2767 masm(), Context::BOOLEAN_FUNCTION_INDEX, eax, &miss); 2566 masm(), Context::BOOLEAN_FUNCTION_INDEX, eax, miss);
2768 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2769 CheckPrototypes(
2770 IC::CurrentTypeOf(prototype, isolate()),
2771 eax, holder, ebx, edx, edi, name, &miss);
2772 break; 2567 break;
2773 } 2568 }
2774 } 2569 }
2775 2570
2776 Label success; 2571 if (check != RECEIVER_MAP_CHECK) {
2777 __ jmp(&success); 2572 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2573 reg = CheckPrototypes(
2574 IC::CurrentTypeOf(prototype, isolate()),
2575 eax, holder, ebx, edx, edi, name, miss);
2576 }
2778 2577
2779 // Handle call cache miss. 2578 return reg;
2780 __ bind(&miss);
2781 GenerateMissBranch();
2782
2783 __ bind(&success);
2784 } 2579 }
2785 2580
2786 2581
2787 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { 2582 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) {
2788 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2583 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2789 ? CALL_AS_FUNCTION 2584 ? CALL_AS_FUNCTION
2790 : CALL_AS_METHOD; 2585 : CALL_AS_METHOD;
2791 ParameterCount expected(function); 2586 ParameterCount expected(function);
2792 __ InvokeFunction(function, expected, arguments(), 2587 __ InvokeFunction(function, expected, arguments(),
2793 JUMP_FUNCTION, NullCallWrapper(), call_kind); 2588 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2794 } 2589 }
2795 2590
2796 2591
2797 Handle<Code> CallStubCompiler::CompileCallConstant( 2592 Handle<Code> CallStubCompiler::CompileCallConstant(
2798 Handle<Object> object, 2593 Handle<Object> object,
2799 Handle<JSObject> holder, 2594 Handle<JSObject> holder,
2800 Handle<Name> name, 2595 Handle<Name> name,
2801 CheckType check, 2596 CheckType check,
2802 Handle<JSFunction> function) { 2597 Handle<JSFunction> function) {
2803 2598
2804 if (HasCustomCallGenerator(function)) { 2599 if (HasCustomCallGenerator(function)) {
2805 Handle<Code> code = CompileCustomCall(object, holder, 2600 Handle<Code> code = CompileCustomCall(object, holder,
2806 Handle<Cell>::null(), 2601 Handle<Cell>::null(),
2807 function, Handle<String>::cast(name), 2602 function, Handle<String>::cast(name),
2808 Code::FAST); 2603 Code::FAST);
2809 // A null handle means bail out to the regular compiler code below. 2604 // A null handle means bail out to the regular compiler code below.
2810 if (!code.is_null()) return code; 2605 if (!code.is_null()) return code;
2811 } 2606 }
2812 2607
2813 CompileHandlerFrontend(object, holder, name, check); 2608 Label miss;
2609 HandlerFrontendHeader(object, holder, name, check, &miss);
2610 PatchGlobalProxy(object);
2814 CompileHandlerBackend(function); 2611 CompileHandlerBackend(function);
2612 HandlerFrontendFooter(&miss);
2815 2613
2816 // Return the generated code. 2614 // Return the generated code.
2817 return GetCode(function); 2615 return GetCode(function);
2818 } 2616 }
2819 2617
2820 2618
2821 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, 2619 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
2822 Handle<JSObject> holder, 2620 Handle<JSObject> holder,
2823 Handle<Name> name) { 2621 Handle<Name> name) {
2824 // ----------- S t a t e -------------
2825 // -- ecx : name
2826 // -- esp[0] : return address
2827 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2828 // -- ...
2829 // -- esp[(argc + 1) * 4] : receiver
2830 // -----------------------------------
2831 Label miss; 2622 Label miss;
2832 2623
2833 GenerateNameCheck(name, &miss); 2624 GenerateNameCheck(name, &miss);
2834 2625
2835 // Get the number of arguments. 2626 // Get the number of arguments.
2836 const int argc = arguments().immediate(); 2627 const int argc = arguments().immediate();
2837 2628
2838 LookupResult lookup(isolate()); 2629 LookupResult lookup(isolate());
2839 LookupPostInterceptor(holder, name, &lookup); 2630 LookupPostInterceptor(holder, name, &lookup);
2840 2631
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2876 return GetCode(Code::FAST, name); 2667 return GetCode(Code::FAST, name);
2877 } 2668 }
2878 2669
2879 2670
2880 Handle<Code> CallStubCompiler::CompileCallGlobal( 2671 Handle<Code> CallStubCompiler::CompileCallGlobal(
2881 Handle<JSObject> object, 2672 Handle<JSObject> object,
2882 Handle<GlobalObject> holder, 2673 Handle<GlobalObject> holder,
2883 Handle<PropertyCell> cell, 2674 Handle<PropertyCell> cell,
2884 Handle<JSFunction> function, 2675 Handle<JSFunction> function,
2885 Handle<Name> name) { 2676 Handle<Name> name) {
2886 // ----------- S t a t e -------------
2887 // -- ecx : name
2888 // -- esp[0] : return address
2889 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2890 // -- ...
2891 // -- esp[(argc + 1) * 4] : receiver
2892 // -----------------------------------
2893
2894 if (HasCustomCallGenerator(function)) { 2677 if (HasCustomCallGenerator(function)) {
2895 Handle<Code> code = CompileCustomCall( 2678 Handle<Code> code = CompileCustomCall(
2896 object, holder, cell, function, Handle<String>::cast(name), 2679 object, holder, cell, function, Handle<String>::cast(name),
2897 Code::NORMAL); 2680 Code::NORMAL);
2898 // A null handle means bail out to the regular compiler code below. 2681 // A null handle means bail out to the regular compiler code below.
2899 if (!code.is_null()) return code; 2682 if (!code.is_null()) return code;
2900 } 2683 }
2901 2684
2902 Label miss; 2685 Label miss;
2903 GenerateNameCheck(name, &miss); 2686 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2904
2905 // Get the number of arguments.
2906 const int argc = arguments().immediate();
2907 GenerateGlobalReceiverCheck(object, holder, name, &miss);
2908 GenerateLoadFunctionFromCell(cell, function, &miss); 2687 GenerateLoadFunctionFromCell(cell, function, &miss);
2909 2688 PatchGlobalProxy(object);
2910 // Patch the receiver on the stack with the global proxy.
2911 if (object->IsGlobalObject()) {
2912 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
2913 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
2914 }
2915 2689
2916 // Set up the context (function already in edi). 2690 // Set up the context (function already in edi).
2917 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 2691 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
2918 2692
2919 // Jump to the cached code (tail call). 2693 // Jump to the cached code (tail call).
2920 Counters* counters = isolate()->counters(); 2694 Counters* counters = isolate()->counters();
2921 __ IncrementCounter(counters->call_global_inline(), 1); 2695 __ IncrementCounter(counters->call_global_inline(), 1);
2922 ParameterCount expected(function->shared()->formal_parameter_count()); 2696 ParameterCount expected(function->shared()->formal_parameter_count());
2923 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2697 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2924 ? CALL_AS_FUNCTION 2698 ? CALL_AS_FUNCTION
2925 : CALL_AS_METHOD; 2699 : CALL_AS_METHOD;
2926 // We call indirectly through the code field in the function to 2700 // We call indirectly through the code field in the function to
2927 // allow recompilation to take effect without changing any of the 2701 // allow recompilation to take effect without changing any of the
2928 // call sites. 2702 // call sites.
2929 __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), 2703 __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
2930 expected, arguments(), JUMP_FUNCTION, 2704 expected, arguments(), JUMP_FUNCTION,
2931 NullCallWrapper(), call_kind); 2705 NullCallWrapper(), call_kind);
2932 2706
2933 // Handle call cache miss. 2707 HandlerFrontendFooter(&miss);
2934 __ bind(&miss);
2935 __ IncrementCounter(counters->call_global_inline_miss(), 1);
2936 GenerateMissBranch();
2937 2708
2938 // Return the generated code. 2709 // Return the generated code.
2939 return GetCode(Code::NORMAL, name); 2710 return GetCode(Code::NORMAL, name);
2940 } 2711 }
2941 2712
2942 2713
2943 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2714 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2944 Handle<JSObject> object, 2715 Handle<JSObject> object,
2945 Handle<JSObject> holder, 2716 Handle<JSObject> holder,
2946 Handle<Name> name, 2717 Handle<Name> name,
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
3030 #define __ ACCESS_MASM(masm()) 2801 #define __ ACCESS_MASM(masm())
3031 2802
3032 2803
3033 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( 2804 Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
3034 Handle<JSObject> object, 2805 Handle<JSObject> object,
3035 Handle<Name> name) { 2806 Handle<Name> name) {
3036 __ pop(scratch1()); // remove the return address 2807 __ pop(scratch1()); // remove the return address
3037 __ push(receiver()); 2808 __ push(receiver());
3038 __ push(this->name()); 2809 __ push(this->name());
3039 __ push(value()); 2810 __ push(value());
3040 __ push(Immediate(Smi::FromInt(strict_mode())));
3041 __ push(scratch1()); // restore return address 2811 __ push(scratch1()); // restore return address
3042 2812
3043 // Do tail-call to the runtime system. 2813 // Do tail-call to the runtime system.
3044 ExternalReference store_ic_property = 2814 ExternalReference store_ic_property =
3045 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); 2815 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate());
3046 __ TailCallExternalReference(store_ic_property, 4, 1); 2816 __ TailCallExternalReference(store_ic_property, 3, 1);
3047 2817
3048 // Return the generated code. 2818 // Return the generated code.
3049 return GetCode(kind(), Code::FAST, name); 2819 return GetCode(kind(), Code::FAST, name);
3050 } 2820 }
3051 2821
3052 2822
3053 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( 2823 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
3054 MapHandleList* receiver_maps, 2824 MapHandleList* receiver_maps,
3055 CodeHandleList* handler_stubs, 2825 CodeHandleList* handler_stubs,
3056 MapHandleList* transitioned_maps) { 2826 MapHandleList* transitioned_maps) {
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
3300 // ----------------------------------- 3070 // -----------------------------------
3301 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 3071 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
3302 } 3072 }
3303 3073
3304 3074
3305 #undef __ 3075 #undef __
3306 3076
3307 } } // namespace v8::internal 3077 } } // namespace v8::internal
3308 3078
3309 #endif // V8_TARGET_ARCH_IA32 3079 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/ic-ia32.cc ('k') | src/ic.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698