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

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

Issue 136643008: A64: Synchronize with r18256. (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/macro-assembler-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 627 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 ApiParameterOperand(1), 638 ApiParameterOperand(1),
639 argc + kFastApiCallArguments + 1, 639 argc + kFastApiCallArguments + 1,
640 return_value_operand, 640 return_value_operand,
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(CallStubCompiler* stub_compiler,
649 const ParameterCount& arguments, 649 const ParameterCount& arguments,
650 Register name, 650 Register name,
651 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) {}
656 655
657 void Compile(MacroAssembler* masm, 656 void Compile(MacroAssembler* masm,
658 Handle<JSObject> object, 657 Handle<JSObject> object,
659 Handle<JSObject> holder, 658 Handle<JSObject> holder,
660 Handle<Name> name, 659 Handle<Name> name,
661 LookupResult* lookup, 660 LookupResult* lookup,
662 Register receiver, 661 Register receiver,
663 Register scratch1, 662 Register scratch1,
664 Register scratch2, 663 Register scratch2,
665 Register scratch3, 664 Register scratch3,
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 // for API (object which is instanceof for the signature). It's 748 // for API (object which is instanceof for the signature). It's
750 // safe to omit it here, as if present, it should be fetched 749 // safe to omit it here, as if present, it should be fetched
751 // by the previous CheckPrototypes. 750 // by the previous CheckPrototypes.
752 ASSERT(depth2 == kInvalidProtoDepth); 751 ASSERT(depth2 == kInvalidProtoDepth);
753 } 752 }
754 753
755 // Invoke function. 754 // Invoke function.
756 if (can_do_fast_api_call) { 755 if (can_do_fast_api_call) {
757 GenerateFastApiCall(masm, optimization, arguments_.immediate()); 756 GenerateFastApiCall(masm, optimization, arguments_.immediate());
758 } else { 757 } else {
759 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 758 Handle<JSFunction> fun = optimization.constant_function();
760 ? CALL_AS_FUNCTION 759 stub_compiler_->GenerateJumpFunctionIgnoreReceiver(fun);
761 : CALL_AS_METHOD;
762 Handle<JSFunction> function = optimization.constant_function();
763 ParameterCount expected(function);
764 __ InvokeFunction(function, expected, arguments_,
765 JUMP_FUNCTION, NullCallWrapper(), call_kind);
766 } 760 }
767 761
768 // Deferred code for fast API call case---clean preallocated space. 762 // Deferred code for fast API call case---clean preallocated space.
769 if (can_do_fast_api_call) { 763 if (can_do_fast_api_call) {
770 __ bind(&miss_cleanup); 764 __ bind(&miss_cleanup);
771 FreeSpaceForFastApiCall(masm, scratch1); 765 FreeSpaceForFastApiCall(masm, scratch1);
772 __ jmp(miss_label); 766 __ jmp(miss_label);
773 } 767 }
774 768
775 // Invoke a regular function. 769 // Invoke a regular function.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
823 817
824 __ pop(name_); // Restore the name. 818 __ pop(name_); // Restore the name.
825 __ pop(receiver); // Restore the holder. 819 __ pop(receiver); // Restore the holder.
826 // Leave the internal frame. 820 // Leave the internal frame.
827 } 821 }
828 822
829 __ cmp(eax, masm->isolate()->factory()->no_interceptor_result_sentinel()); 823 __ cmp(eax, masm->isolate()->factory()->no_interceptor_result_sentinel());
830 __ j(not_equal, interceptor_succeeded); 824 __ j(not_equal, interceptor_succeeded);
831 } 825 }
832 826
833 StubCompiler* stub_compiler_; 827 CallStubCompiler* stub_compiler_;
834 const ParameterCount& arguments_; 828 const ParameterCount& arguments_;
835 Register name_; 829 Register name_;
836 ExtraICState extra_state_;
837 }; 830 };
838 831
839 832
840 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, 833 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
841 Label* label, 834 Label* label,
842 Handle<Name> name) { 835 Handle<Name> name) {
843 if (!label->is_unused()) { 836 if (!label->is_unused()) {
844 __ bind(label); 837 __ bind(label);
845 __ mov(this->name(), Immediate(name)); 838 __ mov(this->name(), Immediate(name));
846 } 839 }
(...skipping 748 matching lines...) Expand 10 before | Expand all | Expand 10 after
1595 1588
1596 1589
1597 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { 1590 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) {
1598 if (kind_ == Code::KEYED_CALL_IC) { 1591 if (kind_ == Code::KEYED_CALL_IC) {
1599 __ cmp(ecx, Immediate(name)); 1592 __ cmp(ecx, Immediate(name));
1600 __ j(not_equal, miss); 1593 __ j(not_equal, miss);
1601 } 1594 }
1602 } 1595 }
1603 1596
1604 1597
1598 void CallStubCompiler::GenerateFunctionCheck(Register function,
1599 Register scratch,
1600 Label* miss) {
1601 __ JumpIfSmi(function, miss);
1602 __ CmpObjectType(function, JS_FUNCTION_TYPE, scratch);
1603 __ j(not_equal, miss);
1604 }
1605
1606
1605 void CallStubCompiler::GenerateLoadFunctionFromCell( 1607 void CallStubCompiler::GenerateLoadFunctionFromCell(
1606 Handle<Cell> cell, 1608 Handle<Cell> cell,
1607 Handle<JSFunction> function, 1609 Handle<JSFunction> function,
1608 Label* miss) { 1610 Label* miss) {
1609 // Get the value from the cell. 1611 // Get the value from the cell.
1610 if (Serializer::enabled()) { 1612 if (Serializer::enabled()) {
1611 __ mov(edi, Immediate(cell)); 1613 __ mov(edi, Immediate(cell));
1612 __ mov(edi, FieldOperand(edi, Cell::kValueOffset)); 1614 __ mov(edi, FieldOperand(edi, Cell::kValueOffset));
1613 } else { 1615 } else {
1614 __ mov(edi, Operand::ForCell(cell)); 1616 __ mov(edi, Operand::ForCell(cell));
1615 } 1617 }
1616 1618
1617 // Check that the cell contains the same function. 1619 // Check that the cell contains the same function.
1618 if (isolate()->heap()->InNewSpace(*function)) { 1620 if (isolate()->heap()->InNewSpace(*function)) {
1619 // We can't embed a pointer to a function in new space so we have 1621 // We can't embed a pointer to a function in new space so we have
1620 // to verify that the shared function info is unchanged. This has 1622 // to verify that the shared function info is unchanged. This has
1621 // the nice side effect that multiple closures based on the same 1623 // the nice side effect that multiple closures based on the same
1622 // function can all use this call IC. Before we load through the 1624 // function can all use this call IC. Before we load through the
1623 // function, we have to verify that it still is a function. 1625 // function, we have to verify that it still is a function.
1624 __ JumpIfSmi(edi, miss); 1626 GenerateFunctionCheck(edi, ebx, miss);
1625 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx);
1626 __ j(not_equal, miss);
1627 1627
1628 // Check the shared function info. Make sure it hasn't changed. 1628 // Check the shared function info. Make sure it hasn't changed.
1629 __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset), 1629 __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset),
1630 Immediate(Handle<SharedFunctionInfo>(function->shared()))); 1630 Immediate(Handle<SharedFunctionInfo>(function->shared())));
1631 } else { 1631 } else {
1632 __ cmp(edi, Immediate(function)); 1632 __ cmp(edi, Immediate(function));
1633 } 1633 }
1634 __ j(not_equal, miss); 1634 __ j(not_equal, miss);
1635 } 1635 }
1636 1636
1637 1637
1638 void CallStubCompiler::GenerateMissBranch() { 1638 void CallStubCompiler::GenerateMissBranch() {
1639 Handle<Code> code = 1639 Handle<Code> code =
1640 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), 1640 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(),
1641 kind_, 1641 kind_,
1642 extra_state_); 1642 extra_state());
1643 __ jmp(code, RelocInfo::CODE_TARGET); 1643 __ jmp(code, RelocInfo::CODE_TARGET);
1644 } 1644 }
1645 1645
1646 1646
1647 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, 1647 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
1648 Handle<JSObject> holder, 1648 Handle<JSObject> holder,
1649 PropertyIndex index, 1649 PropertyIndex index,
1650 Handle<Name> name) { 1650 Handle<Name> name) {
1651 Label miss; 1651 Label miss;
1652 1652
1653 Register reg = HandlerFrontendHeader( 1653 Register reg = HandlerFrontendHeader(
1654 object, holder, name, RECEIVER_MAP_CHECK, &miss); 1654 object, holder, name, RECEIVER_MAP_CHECK, &miss);
1655 1655
1656 GenerateFastPropertyLoad( 1656 GenerateFastPropertyLoad(
1657 masm(), edi, reg, index.is_inobject(holder), 1657 masm(), edi, reg, index.is_inobject(holder),
1658 index.translate(holder), Representation::Tagged()); 1658 index.translate(holder), Representation::Tagged());
1659 1659 GenerateJumpFunction(object, edi, &miss);
1660 // Check that the function really is a function.
1661 __ JumpIfSmi(edi, &miss);
1662 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx);
1663 __ j(not_equal, &miss);
1664
1665 PatchGlobalProxy(object);
1666
1667 // Invoke the function.
1668 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
1669 ? CALL_AS_FUNCTION
1670 : CALL_AS_METHOD;
1671 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION,
1672 NullCallWrapper(), call_kind);
1673 1660
1674 HandlerFrontendFooter(&miss); 1661 HandlerFrontendFooter(&miss);
1675 1662
1676 // Return the generated code. 1663 // Return the generated code.
1677 return GetCode(Code::FAST, name); 1664 return GetCode(Code::FAST, name);
1678 } 1665 }
1679 1666
1680 1667
1681 Handle<Code> CallStubCompiler::CompileArrayCodeCall( 1668 Handle<Code> CallStubCompiler::CompileArrayCodeCall(
1682 Handle<Object> object, 1669 Handle<Object> object,
(...skipping 28 matching lines...) Expand all
1711 } 1698 }
1712 1699
1713 1700
1714 Handle<Code> CallStubCompiler::CompileArrayPushCall( 1701 Handle<Code> CallStubCompiler::CompileArrayPushCall(
1715 Handle<Object> object, 1702 Handle<Object> object,
1716 Handle<JSObject> holder, 1703 Handle<JSObject> holder,
1717 Handle<Cell> cell, 1704 Handle<Cell> cell,
1718 Handle<JSFunction> function, 1705 Handle<JSFunction> function,
1719 Handle<String> name, 1706 Handle<String> name,
1720 Code::StubType type) { 1707 Code::StubType type) {
1721 // If object is not an array or is observed, bail out to regular call. 1708 // If object is not an array or is observed or sealed, bail out to regular
1709 // call.
1722 if (!object->IsJSArray() || 1710 if (!object->IsJSArray() ||
1723 !cell.is_null() || 1711 !cell.is_null() ||
1724 Handle<JSArray>::cast(object)->map()->is_observed()) { 1712 Handle<JSArray>::cast(object)->map()->is_observed() ||
1713 !Handle<JSArray>::cast(object)->map()->is_extensible()) {
1725 return Handle<Code>::null(); 1714 return Handle<Code>::null();
1726 } 1715 }
1727 1716
1728 Label miss; 1717 Label miss;
1729 1718
1730 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 1719 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1731 1720
1732 const int argc = arguments().immediate(); 1721 const int argc = arguments().immediate();
1733 if (argc == 0) { 1722 if (argc == 0) {
1734 // Noop, return the length. 1723 // Noop, return the length.
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1954 } 1943 }
1955 1944
1956 1945
1957 Handle<Code> CallStubCompiler::CompileArrayPopCall( 1946 Handle<Code> CallStubCompiler::CompileArrayPopCall(
1958 Handle<Object> object, 1947 Handle<Object> object,
1959 Handle<JSObject> holder, 1948 Handle<JSObject> holder,
1960 Handle<Cell> cell, 1949 Handle<Cell> cell,
1961 Handle<JSFunction> function, 1950 Handle<JSFunction> function,
1962 Handle<String> name, 1951 Handle<String> name,
1963 Code::StubType type) { 1952 Code::StubType type) {
1964 // If object is not an array or is observed, bail out to regular call. 1953 // If object is not an array or is observed or sealed, bail out to regular
1954 // call.
1965 if (!object->IsJSArray() || 1955 if (!object->IsJSArray() ||
1966 !cell.is_null() || 1956 !cell.is_null() ||
1967 Handle<JSArray>::cast(object)->map()->is_observed()) { 1957 Handle<JSArray>::cast(object)->map()->is_observed() ||
1958 !Handle<JSArray>::cast(object)->map()->is_extensible()) {
1968 return Handle<Code>::null(); 1959 return Handle<Code>::null();
1969 } 1960 }
1970 1961
1971 Label miss, return_undefined, call_builtin; 1962 Label miss, return_undefined, call_builtin;
1972 1963
1973 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 1964 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1974 1965
1975 // Get the elements array of the object. 1966 // Get the elements array of the object.
1976 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset)); 1967 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset));
1977 1968
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2035 } 2026 }
2036 2027
2037 const int argc = arguments().immediate(); 2028 const int argc = arguments().immediate();
2038 2029
2039 Label miss; 2030 Label miss;
2040 Label name_miss; 2031 Label name_miss;
2041 Label index_out_of_range; 2032 Label index_out_of_range;
2042 Label* index_out_of_range_label = &index_out_of_range; 2033 Label* index_out_of_range_label = &index_out_of_range;
2043 2034
2044 if (kind_ == Code::CALL_IC && 2035 if (kind_ == Code::CALL_IC &&
2045 (CallICBase::StringStubState::decode(extra_state_) == 2036 (CallICBase::StringStubState::decode(extra_state()) ==
2046 DEFAULT_STRING_STUB)) { 2037 DEFAULT_STRING_STUB)) {
2047 index_out_of_range_label = &miss; 2038 index_out_of_range_label = &miss;
2048 } 2039 }
2049 2040
2050 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss); 2041 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss);
2051 2042
2052 Register receiver = ebx; 2043 Register receiver = ebx;
2053 Register index = edi; 2044 Register index = edi;
2054 Register result = eax; 2045 Register result = eax;
2055 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize)); 2046 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize));
(...skipping 18 matching lines...) Expand all
2074 2065
2075 if (index_out_of_range.is_linked()) { 2066 if (index_out_of_range.is_linked()) {
2076 __ bind(&index_out_of_range); 2067 __ bind(&index_out_of_range);
2077 __ Set(eax, Immediate(factory()->nan_value())); 2068 __ Set(eax, Immediate(factory()->nan_value()));
2078 __ ret((argc + 1) * kPointerSize); 2069 __ ret((argc + 1) * kPointerSize);
2079 } 2070 }
2080 2071
2081 __ bind(&miss); 2072 __ bind(&miss);
2082 // Restore function name in ecx. 2073 // Restore function name in ecx.
2083 __ Set(ecx, Immediate(name)); 2074 __ Set(ecx, Immediate(name));
2084 __ bind(&name_miss); 2075 HandlerFrontendFooter(&name_miss);
2085 GenerateMissBranch();
2086 2076
2087 // Return the generated code. 2077 // Return the generated code.
2088 return GetCode(type, name); 2078 return GetCode(type, name);
2089 } 2079 }
2090 2080
2091 2081
2092 Handle<Code> CallStubCompiler::CompileStringCharAtCall( 2082 Handle<Code> CallStubCompiler::CompileStringCharAtCall(
2093 Handle<Object> object, 2083 Handle<Object> object,
2094 Handle<JSObject> holder, 2084 Handle<JSObject> holder,
2095 Handle<Cell> cell, 2085 Handle<Cell> cell,
2096 Handle<JSFunction> function, 2086 Handle<JSFunction> function,
2097 Handle<String> name, 2087 Handle<String> name,
2098 Code::StubType type) { 2088 Code::StubType type) {
2099 // If object is not a string, bail out to regular call. 2089 // If object is not a string, bail out to regular call.
2100 if (!object->IsString() || !cell.is_null()) { 2090 if (!object->IsString() || !cell.is_null()) {
2101 return Handle<Code>::null(); 2091 return Handle<Code>::null();
2102 } 2092 }
2103 2093
2104 const int argc = arguments().immediate(); 2094 const int argc = arguments().immediate();
2105 2095
2106 Label miss; 2096 Label miss;
2107 Label name_miss; 2097 Label name_miss;
2108 Label index_out_of_range; 2098 Label index_out_of_range;
2109 Label* index_out_of_range_label = &index_out_of_range; 2099 Label* index_out_of_range_label = &index_out_of_range;
2110 2100
2111 if (kind_ == Code::CALL_IC && 2101 if (kind_ == Code::CALL_IC &&
2112 (CallICBase::StringStubState::decode(extra_state_) == 2102 (CallICBase::StringStubState::decode(extra_state()) ==
2113 DEFAULT_STRING_STUB)) { 2103 DEFAULT_STRING_STUB)) {
2114 index_out_of_range_label = &miss; 2104 index_out_of_range_label = &miss;
2115 } 2105 }
2116 2106
2117 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss); 2107 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss);
2118 2108
2119 Register receiver = eax; 2109 Register receiver = eax;
2120 Register index = edi; 2110 Register index = edi;
2121 Register scratch = edx; 2111 Register scratch = edx;
2122 Register result = eax; 2112 Register result = eax;
(...skipping 20 matching lines...) Expand all
2143 2133
2144 if (index_out_of_range.is_linked()) { 2134 if (index_out_of_range.is_linked()) {
2145 __ bind(&index_out_of_range); 2135 __ bind(&index_out_of_range);
2146 __ Set(eax, Immediate(factory()->empty_string())); 2136 __ Set(eax, Immediate(factory()->empty_string()));
2147 __ ret((argc + 1) * kPointerSize); 2137 __ ret((argc + 1) * kPointerSize);
2148 } 2138 }
2149 2139
2150 __ bind(&miss); 2140 __ bind(&miss);
2151 // Restore function name in ecx. 2141 // Restore function name in ecx.
2152 __ Set(ecx, Immediate(name)); 2142 __ Set(ecx, Immediate(name));
2153 __ bind(&name_miss); 2143 HandlerFrontendFooter(&name_miss);
2154 GenerateMissBranch();
2155 2144
2156 // Return the generated code. 2145 // Return the generated code.
2157 return GetCode(type, name); 2146 return GetCode(type, name);
2158 } 2147 }
2159 2148
2160 2149
2161 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( 2150 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
2162 Handle<Object> object, 2151 Handle<Object> object,
2163 Handle<JSObject> holder, 2152 Handle<JSObject> holder,
2164 Handle<Cell> cell, 2153 Handle<Cell> cell,
(...skipping 28 matching lines...) Expand all
2193 // Convert the smi code to uint16. 2182 // Convert the smi code to uint16.
2194 __ and_(code, Immediate(Smi::FromInt(0xffff))); 2183 __ and_(code, Immediate(Smi::FromInt(0xffff)));
2195 2184
2196 StringCharFromCodeGenerator generator(code, eax); 2185 StringCharFromCodeGenerator generator(code, eax);
2197 generator.GenerateFast(masm()); 2186 generator.GenerateFast(masm());
2198 __ ret(2 * kPointerSize); 2187 __ ret(2 * kPointerSize);
2199 2188
2200 StubRuntimeCallHelper call_helper; 2189 StubRuntimeCallHelper call_helper;
2201 generator.GenerateSlow(masm(), call_helper); 2190 generator.GenerateSlow(masm(), call_helper);
2202 2191
2203 // Tail call the full function. We do not have to patch the receiver
2204 // because the function makes no use of it.
2205 __ bind(&slow); 2192 __ bind(&slow);
2206 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2193 // We do not have to patch the receiver because the function makes no use of
2207 ? CALL_AS_FUNCTION 2194 // it.
2208 : CALL_AS_METHOD; 2195 GenerateJumpFunctionIgnoreReceiver(function);
2209 ParameterCount expected(function);
2210 __ InvokeFunction(function, expected, arguments(),
2211 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2212 2196
2213 HandlerFrontendFooter(&miss); 2197 HandlerFrontendFooter(&miss);
2214 2198
2215 // Return the generated code. 2199 // Return the generated code.
2216 return GetCode(type, name); 2200 return GetCode(type, name);
2217 } 2201 }
2218 2202
2219 2203
2220 Handle<Code> CallStubCompiler::CompileMathFloorCall( 2204 Handle<Code> CallStubCompiler::CompileMathFloorCall(
2221 Handle<Object> object, 2205 Handle<Object> object,
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
2308 // Return a new heap number. 2292 // Return a new heap number.
2309 __ AllocateHeapNumber(eax, ebx, edx, &slow); 2293 __ AllocateHeapNumber(eax, ebx, edx, &slow);
2310 __ movsd(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); 2294 __ movsd(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
2311 __ ret(2 * kPointerSize); 2295 __ ret(2 * kPointerSize);
2312 2296
2313 // Return the argument (when it's an already round heap number). 2297 // Return the argument (when it's an already round heap number).
2314 __ bind(&already_round); 2298 __ bind(&already_round);
2315 __ mov(eax, Operand(esp, 1 * kPointerSize)); 2299 __ mov(eax, Operand(esp, 1 * kPointerSize));
2316 __ ret(2 * kPointerSize); 2300 __ ret(2 * kPointerSize);
2317 2301
2318 // Tail call the full function. We do not have to patch the receiver
2319 // because the function makes no use of it.
2320 __ bind(&slow); 2302 __ bind(&slow);
2321 ParameterCount expected(function); 2303 // We do not have to patch the receiver because the function makes no use of
2322 __ InvokeFunction(function, expected, arguments(), 2304 // it.
2323 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2305 GenerateJumpFunctionIgnoreReceiver(function);
2324 2306
2325 HandlerFrontendFooter(&miss); 2307 HandlerFrontendFooter(&miss);
2326 2308
2327 // Return the generated code. 2309 // Return the generated code.
2328 return GetCode(type, name); 2310 return GetCode(type, name);
2329 } 2311 }
2330 2312
2331 2313
2332 Handle<Code> CallStubCompiler::CompileMathAbsCall( 2314 Handle<Code> CallStubCompiler::CompileMathAbsCall(
2333 Handle<Object> object, 2315 Handle<Object> object,
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2397 // If the argument is negative, clear the sign, and return a new 2379 // If the argument is negative, clear the sign, and return a new
2398 // number. 2380 // number.
2399 __ bind(&negative_sign); 2381 __ bind(&negative_sign);
2400 __ and_(ebx, ~HeapNumber::kSignMask); 2382 __ and_(ebx, ~HeapNumber::kSignMask);
2401 __ mov(ecx, FieldOperand(eax, HeapNumber::kMantissaOffset)); 2383 __ mov(ecx, FieldOperand(eax, HeapNumber::kMantissaOffset));
2402 __ AllocateHeapNumber(eax, edi, edx, &slow); 2384 __ AllocateHeapNumber(eax, edi, edx, &slow);
2403 __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), ebx); 2385 __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), ebx);
2404 __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx); 2386 __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx);
2405 __ ret(2 * kPointerSize); 2387 __ ret(2 * kPointerSize);
2406 2388
2407 // Tail call the full function. We do not have to patch the receiver
2408 // because the function makes no use of it.
2409 __ bind(&slow); 2389 __ bind(&slow);
2410 ParameterCount expected(function); 2390 // We do not have to patch the receiver because the function makes no use of
2411 __ InvokeFunction(function, expected, arguments(), 2391 // it.
2412 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2392 GenerateJumpFunctionIgnoreReceiver(function);
2413 2393
2414 HandlerFrontendFooter(&miss); 2394 HandlerFrontendFooter(&miss);
2415 2395
2416 // Return the generated code. 2396 // Return the generated code.
2417 return GetCode(type, name); 2397 return GetCode(type, name);
2418 } 2398 }
2419 2399
2420 2400
2421 Handle<Code> CallStubCompiler::CompileFastApiCall( 2401 Handle<Code> CallStubCompiler::CompileFastApiCall(
2422 const CallOptimization& optimization, 2402 const CallOptimization& optimization,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2462 __ mov(eax, Operand(esp, kFastApiCallArguments * kPointerSize)); 2442 __ mov(eax, Operand(esp, kFastApiCallArguments * kPointerSize));
2463 __ mov(Operand(esp, 0 * kPointerSize), eax); 2443 __ mov(Operand(esp, 0 * kPointerSize), eax);
2464 2444
2465 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains 2445 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains
2466 // duplicate of return address and will be overwritten. 2446 // duplicate of return address and will be overwritten.
2467 GenerateFastApiCall(masm(), optimization, argc); 2447 GenerateFastApiCall(masm(), optimization, argc);
2468 2448
2469 __ bind(&miss); 2449 __ bind(&miss);
2470 __ add(esp, Immediate(kFastApiCallArguments * kPointerSize)); 2450 __ add(esp, Immediate(kFastApiCallArguments * kPointerSize));
2471 2451
2472 __ bind(&miss_before_stack_reserved); 2452 HandlerFrontendFooter(&miss_before_stack_reserved);
2473 GenerateMissBranch();
2474 2453
2475 // Return the generated code. 2454 // Return the generated code.
2476 return GetCode(function); 2455 return GetCode(function);
2477 } 2456 }
2478 2457
2479 2458
2480 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { 2459 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
2481 Label success; 2460 Label success;
2482 // Check that the object is a boolean. 2461 // Check that the object is a boolean.
2483 __ cmp(object, factory()->true_value()); 2462 __ cmp(object, factory()->true_value());
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
2572 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); 2551 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2573 reg = CheckPrototypes( 2552 reg = CheckPrototypes(
2574 IC::CurrentTypeOf(prototype, isolate()), 2553 IC::CurrentTypeOf(prototype, isolate()),
2575 eax, holder, ebx, edx, edi, name, miss); 2554 eax, holder, ebx, edx, edi, name, miss);
2576 } 2555 }
2577 2556
2578 return reg; 2557 return reg;
2579 } 2558 }
2580 2559
2581 2560
2582 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { 2561 void CallStubCompiler::GenerateJumpFunction(Handle<Object> object,
2583 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2562 Register function,
2584 ? CALL_AS_FUNCTION 2563 Label* miss) {
2585 : CALL_AS_METHOD; 2564 // Check that the function really is a function.
2586 ParameterCount expected(function); 2565 GenerateFunctionCheck(function, ebx, miss);
2587 __ InvokeFunction(function, expected, arguments(), 2566
2588 JUMP_FUNCTION, NullCallWrapper(), call_kind); 2567 if (!function.is(edi)) __ mov(edi, function);
2568 PatchGlobalProxy(object);
2569
2570 // Invoke the function.
2571 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION,
2572 NullCallWrapper(), call_kind());
2589 } 2573 }
2590 2574
2591 2575
2592 Handle<Code> CallStubCompiler::CompileCallConstant(
2593 Handle<Object> object,
2594 Handle<JSObject> holder,
2595 Handle<Name> name,
2596 CheckType check,
2597 Handle<JSFunction> function) {
2598
2599 if (HasCustomCallGenerator(function)) {
2600 Handle<Code> code = CompileCustomCall(object, holder,
2601 Handle<Cell>::null(),
2602 function, Handle<String>::cast(name),
2603 Code::FAST);
2604 // A null handle means bail out to the regular compiler code below.
2605 if (!code.is_null()) return code;
2606 }
2607
2608 Label miss;
2609 HandlerFrontendHeader(object, holder, name, check, &miss);
2610 PatchGlobalProxy(object);
2611 CompileHandlerBackend(function);
2612 HandlerFrontendFooter(&miss);
2613
2614 // Return the generated code.
2615 return GetCode(function);
2616 }
2617
2618
2619 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, 2576 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
2620 Handle<JSObject> holder, 2577 Handle<JSObject> holder,
2621 Handle<Name> name) { 2578 Handle<Name> name) {
2622 Label miss; 2579 Label miss;
2623 2580
2624 GenerateNameCheck(name, &miss); 2581 GenerateNameCheck(name, &miss);
2625 2582
2626 // Get the number of arguments. 2583 // Get the number of arguments.
2627 const int argc = arguments().immediate(); 2584 const int argc = arguments().immediate();
2628 2585
2629 LookupResult lookup(isolate()); 2586 LookupResult lookup(isolate());
2630 LookupPostInterceptor(holder, name, &lookup); 2587 LookupPostInterceptor(holder, name, &lookup);
2631 2588
2632 // Get the receiver from the stack. 2589 // Get the receiver from the stack.
2633 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2590 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2634 2591
2635 CallInterceptorCompiler compiler(this, arguments(), ecx, extra_state_); 2592 CallInterceptorCompiler compiler(this, arguments(), ecx, extra_state());
2636 compiler.Compile(masm(), object, holder, name, &lookup, edx, ebx, edi, eax, 2593 compiler.Compile(masm(), object, holder, name, &lookup, edx, ebx, edi, eax,
2637 &miss); 2594 &miss);
2638 2595
2639 // Restore receiver. 2596 // Restore receiver.
2640 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2597 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2641 2598
2642 // Check that the function really is a function. 2599 GenerateJumpFunction(object, eax, &miss);
2643 __ JumpIfSmi(eax, &miss);
2644 __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx);
2645 __ j(not_equal, &miss);
2646 2600
2647 // Patch the receiver on the stack with the global proxy if 2601 HandlerFrontendFooter(&miss);
2648 // necessary.
2649 if (object->IsGlobalObject()) {
2650 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
2651 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
2652 }
2653
2654 // Invoke the function.
2655 __ mov(edi, eax);
2656 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2657 ? CALL_AS_FUNCTION
2658 : CALL_AS_METHOD;
2659 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION,
2660 NullCallWrapper(), call_kind);
2661
2662 // Handle load cache miss.
2663 __ bind(&miss);
2664 GenerateMissBranch();
2665 2602
2666 // Return the generated code. 2603 // Return the generated code.
2667 return GetCode(Code::FAST, name); 2604 return GetCode(Code::FAST, name);
2668 } 2605 }
2669 2606
2670 2607
2671 Handle<Code> CallStubCompiler::CompileCallGlobal( 2608 Handle<Code> CallStubCompiler::CompileCallGlobal(
2672 Handle<JSObject> object, 2609 Handle<JSObject> object,
2673 Handle<GlobalObject> holder, 2610 Handle<GlobalObject> holder,
2674 Handle<PropertyCell> cell, 2611 Handle<PropertyCell> cell,
2675 Handle<JSFunction> function, 2612 Handle<JSFunction> function,
2676 Handle<Name> name) { 2613 Handle<Name> name) {
2677 if (HasCustomCallGenerator(function)) { 2614 if (HasCustomCallGenerator(function)) {
2678 Handle<Code> code = CompileCustomCall( 2615 Handle<Code> code = CompileCustomCall(
2679 object, holder, cell, function, Handle<String>::cast(name), 2616 object, holder, cell, function, Handle<String>::cast(name),
2680 Code::NORMAL); 2617 Code::NORMAL);
2681 // A null handle means bail out to the regular compiler code below. 2618 // A null handle means bail out to the regular compiler code below.
2682 if (!code.is_null()) return code; 2619 if (!code.is_null()) return code;
2683 } 2620 }
2684 2621
2685 Label miss; 2622 Label miss;
2686 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 2623 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2624 // Potentially loads a closure that matches the shared function info of the
2625 // function, rather than function.
2687 GenerateLoadFunctionFromCell(cell, function, &miss); 2626 GenerateLoadFunctionFromCell(cell, function, &miss);
2688 PatchGlobalProxy(object); 2627 GenerateJumpFunction(object, edi, function);
2689
2690 // Set up the context (function already in edi).
2691 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
2692
2693 // Jump to the cached code (tail call).
2694 Counters* counters = isolate()->counters();
2695 __ IncrementCounter(counters->call_global_inline(), 1);
2696 ParameterCount expected(function->shared()->formal_parameter_count());
2697 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2698 ? CALL_AS_FUNCTION
2699 : CALL_AS_METHOD;
2700 // We call indirectly through the code field in the function to
2701 // allow recompilation to take effect without changing any of the
2702 // call sites.
2703 __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
2704 expected, arguments(), JUMP_FUNCTION,
2705 NullCallWrapper(), call_kind);
2706 2628
2707 HandlerFrontendFooter(&miss); 2629 HandlerFrontendFooter(&miss);
2708 2630
2709 // Return the generated code. 2631 // Return the generated code.
2710 return GetCode(Code::NORMAL, name); 2632 return GetCode(Code::NORMAL, name);
2711 } 2633 }
2712 2634
2713 2635
2714 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2636 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2715 Handle<JSObject> object, 2637 Handle<JSObject> object,
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
3070 // ----------------------------------- 2992 // -----------------------------------
3071 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 2993 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
3072 } 2994 }
3073 2995
3074 2996
3075 #undef __ 2997 #undef __
3076 2998
3077 } } // namespace v8::internal 2999 } } // namespace v8::internal
3078 3000
3079 #endif // V8_TARGET_ARCH_IA32 3001 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/macro-assembler-ia32.cc ('k') | src/ic.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698