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

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

Issue 96573002: Revert r18131 and r18139 "Clean up in the CallStubCompiler". (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: 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
« no previous file with comments | « src/arm/macro-assembler-arm.cc ('k') | src/ia32/macro-assembler-ia32.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 724 matching lines...) Expand 10 before | Expand all | Expand 10 after
735 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, 735 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
736 Label* label, 736 Label* label,
737 Handle<Name> name) { 737 Handle<Name> name) {
738 if (!label->is_unused()) { 738 if (!label->is_unused()) {
739 __ bind(label); 739 __ bind(label);
740 __ mov(this->name(), Operand(name)); 740 __ mov(this->name(), Operand(name));
741 } 741 }
742 } 742 }
743 743
744 744
745 static void GenerateCallFunction(MacroAssembler* masm,
746 Handle<Object> object,
747 const ParameterCount& arguments,
748 Label* miss,
749 Code::ExtraICState extra_ic_state) {
750 // ----------- S t a t e -------------
751 // -- r0: receiver
752 // -- r1: function to call
753 // -----------------------------------
754
755 // Check that the function really is a function.
756 __ JumpIfSmi(r1, miss);
757 __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE);
758 __ b(ne, miss);
759
760 if (object->IsGlobalObject()) {
761 const int argc = arguments.immediate();
762 const int receiver_offset = argc * kPointerSize;
763 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset));
764 __ str(r3, MemOperand(sp, receiver_offset));
765 }
766
767 // Invoke the function.
768 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state)
769 ? CALL_AS_FUNCTION
770 : CALL_AS_METHOD;
771 __ InvokeFunction(r1, arguments, JUMP_FUNCTION, NullCallWrapper(), call_kind);
772 }
773
774
745 static void PushInterceptorArguments(MacroAssembler* masm, 775 static void PushInterceptorArguments(MacroAssembler* masm,
746 Register receiver, 776 Register receiver,
747 Register holder, 777 Register holder,
748 Register name, 778 Register name,
749 Handle<JSObject> holder_obj) { 779 Handle<JSObject> holder_obj) {
750 STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0); 780 STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0);
751 STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1); 781 STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1);
752 STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2); 782 STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2);
753 STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3); 783 STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3);
754 STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4); 784 STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4);
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
918 ASSERT(!scratch.is(values[i])); 948 ASSERT(!scratch.is(values[i]));
919 __ str(receiver, MemOperand(sp, index-- * kPointerSize)); 949 __ str(receiver, MemOperand(sp, index-- * kPointerSize));
920 } 950 }
921 951
922 GenerateFastApiDirectCall(masm, optimization, argc, true); 952 GenerateFastApiDirectCall(masm, optimization, argc, true);
923 } 953 }
924 954
925 955
926 class CallInterceptorCompiler BASE_EMBEDDED { 956 class CallInterceptorCompiler BASE_EMBEDDED {
927 public: 957 public:
928 CallInterceptorCompiler(CallStubCompiler* stub_compiler, 958 CallInterceptorCompiler(StubCompiler* stub_compiler,
929 const ParameterCount& arguments, 959 const ParameterCount& arguments,
930 Register name, 960 Register name,
931 ExtraICState extra_ic_state) 961 ExtraICState extra_ic_state)
932 : stub_compiler_(stub_compiler), 962 : stub_compiler_(stub_compiler),
933 arguments_(arguments), 963 arguments_(arguments),
934 name_(name), 964 name_(name),
935 extra_ic_state_(extra_ic_state) {} 965 extra_ic_state_(extra_ic_state) {}
936 966
937 void Compile(MacroAssembler* masm, 967 void Compile(MacroAssembler* masm,
938 Handle<JSObject> object, 968 Handle<JSObject> object,
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1030 // safe to omit it here, as if present, it should be fetched 1060 // safe to omit it here, as if present, it should be fetched
1031 // by the previous CheckPrototypes. 1061 // by the previous CheckPrototypes.
1032 ASSERT(depth2 == kInvalidProtoDepth); 1062 ASSERT(depth2 == kInvalidProtoDepth);
1033 } 1063 }
1034 1064
1035 // Invoke function. 1065 // Invoke function.
1036 if (can_do_fast_api_call) { 1066 if (can_do_fast_api_call) {
1037 GenerateFastApiDirectCall( 1067 GenerateFastApiDirectCall(
1038 masm, optimization, arguments_.immediate(), false); 1068 masm, optimization, arguments_.immediate(), false);
1039 } else { 1069 } else {
1070 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
1071 ? CALL_AS_FUNCTION
1072 : CALL_AS_METHOD;
1040 Handle<JSFunction> function = optimization.constant_function(); 1073 Handle<JSFunction> function = optimization.constant_function();
1041 stub_compiler_->GenerateJumpFunction(object, function); 1074 ParameterCount expected(function);
1075 __ InvokeFunction(function, expected, arguments_,
1076 JUMP_FUNCTION, NullCallWrapper(), call_kind);
1042 } 1077 }
1043 1078
1044 // Deferred code for fast API call case---clean preallocated space. 1079 // Deferred code for fast API call case---clean preallocated space.
1045 if (can_do_fast_api_call) { 1080 if (can_do_fast_api_call) {
1046 __ bind(&miss_cleanup); 1081 __ bind(&miss_cleanup);
1047 FreeSpaceForFastApiCall(masm); 1082 FreeSpaceForFastApiCall(masm);
1048 __ b(miss_label); 1083 __ b(miss_label);
1049 } 1084 }
1050 1085
1051 // Invoke a regular function. 1086 // Invoke a regular function.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1097 IC::kLoadPropertyWithInterceptorOnly); 1132 IC::kLoadPropertyWithInterceptorOnly);
1098 __ pop(name_); // Restore the name. 1133 __ pop(name_); // Restore the name.
1099 __ pop(receiver); // Restore the holder. 1134 __ pop(receiver); // Restore the holder.
1100 } 1135 }
1101 // If interceptor returns no-result sentinel, call the constant function. 1136 // If interceptor returns no-result sentinel, call the constant function.
1102 __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex); 1137 __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex);
1103 __ cmp(r0, scratch); 1138 __ cmp(r0, scratch);
1104 __ b(ne, interceptor_succeeded); 1139 __ b(ne, interceptor_succeeded);
1105 } 1140 }
1106 1141
1107 CallStubCompiler* stub_compiler_; 1142 StubCompiler* stub_compiler_;
1108 const ParameterCount& arguments_; 1143 const ParameterCount& arguments_;
1109 Register name_; 1144 Register name_;
1110 ExtraICState extra_ic_state_; 1145 ExtraICState extra_ic_state_;
1111 }; 1146 };
1112 1147
1113 1148
1114 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { 1149 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) {
1115 __ Jump(code, RelocInfo::CODE_TARGET); 1150 __ Jump(code, RelocInfo::CODE_TARGET);
1116 } 1151 }
1117 1152
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
1499 1534
1500 1535
1501 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { 1536 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) {
1502 if (kind_ == Code::KEYED_CALL_IC) { 1537 if (kind_ == Code::KEYED_CALL_IC) {
1503 __ cmp(r2, Operand(name)); 1538 __ cmp(r2, Operand(name));
1504 __ b(ne, miss); 1539 __ b(ne, miss);
1505 } 1540 }
1506 } 1541 }
1507 1542
1508 1543
1509 void CallStubCompiler::GenerateFunctionCheck(Register function,
1510 Register scratch,
1511 Label* miss) {
1512 __ JumpIfSmi(function, miss);
1513 __ CompareObjectType(function, scratch, scratch, JS_FUNCTION_TYPE);
1514 __ b(ne, miss);
1515 }
1516
1517
1518 void CallStubCompiler::GenerateLoadFunctionFromCell( 1544 void CallStubCompiler::GenerateLoadFunctionFromCell(
1519 Handle<Cell> cell, 1545 Handle<Cell> cell,
1520 Handle<JSFunction> function, 1546 Handle<JSFunction> function,
1521 Label* miss) { 1547 Label* miss) {
1522 // Get the value from the cell. 1548 // Get the value from the cell.
1523 __ mov(r3, Operand(cell)); 1549 __ mov(r3, Operand(cell));
1524 __ ldr(r1, FieldMemOperand(r3, Cell::kValueOffset)); 1550 __ ldr(r1, FieldMemOperand(r3, Cell::kValueOffset));
1525 1551
1526 // Check that the cell contains the same function. 1552 // Check that the cell contains the same function.
1527 if (heap()->InNewSpace(*function)) { 1553 if (heap()->InNewSpace(*function)) {
1528 // We can't embed a pointer to a function in new space so we have 1554 // We can't embed a pointer to a function in new space so we have
1529 // to verify that the shared function info is unchanged. This has 1555 // to verify that the shared function info is unchanged. This has
1530 // the nice side effect that multiple closures based on the same 1556 // the nice side effect that multiple closures based on the same
1531 // function can all use this call IC. Before we load through the 1557 // function can all use this call IC. Before we load through the
1532 // function, we have to verify that it still is a function. 1558 // function, we have to verify that it still is a function.
1533 GenerateFunctionCheck(r1, r3, miss); 1559 __ JumpIfSmi(r1, miss);
1560 __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE);
1561 __ b(ne, miss);
1534 1562
1535 // Check the shared function info. Make sure it hasn't changed. 1563 // Check the shared function info. Make sure it hasn't changed.
1536 __ Move(r3, Handle<SharedFunctionInfo>(function->shared())); 1564 __ Move(r3, Handle<SharedFunctionInfo>(function->shared()));
1537 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); 1565 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1538 __ cmp(r4, r3); 1566 __ cmp(r4, r3);
1539 } else { 1567 } else {
1540 __ cmp(r1, Operand(function)); 1568 __ cmp(r1, Operand(function));
1541 } 1569 }
1542 __ b(ne, miss); 1570 __ b(ne, miss);
1543 } 1571 }
(...skipping 11 matching lines...) Expand all
1555 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, 1583 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
1556 Handle<JSObject> holder, 1584 Handle<JSObject> holder,
1557 PropertyIndex index, 1585 PropertyIndex index,
1558 Handle<Name> name) { 1586 Handle<Name> name) {
1559 Label miss; 1587 Label miss;
1560 1588
1561 Register reg = HandlerFrontendHeader( 1589 Register reg = HandlerFrontendHeader(
1562 object, holder, name, RECEIVER_MAP_CHECK, &miss); 1590 object, holder, name, RECEIVER_MAP_CHECK, &miss);
1563 GenerateFastPropertyLoad(masm(), r1, reg, index.is_inobject(holder), 1591 GenerateFastPropertyLoad(masm(), r1, reg, index.is_inobject(holder),
1564 index.translate(holder), Representation::Tagged()); 1592 index.translate(holder), Representation::Tagged());
1565 GenerateJumpFunction(object, r1, &miss); 1593
1594 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_);
1566 1595
1567 HandlerFrontendFooter(&miss); 1596 HandlerFrontendFooter(&miss);
1568 1597
1569 // Return the generated code. 1598 // Return the generated code.
1570 return GetCode(Code::FAST, name); 1599 return GetCode(Code::FAST, name);
1571 } 1600 }
1572 1601
1573 1602
1574 Handle<Code> CallStubCompiler::CompileArrayCodeCall( 1603 Handle<Code> CallStubCompiler::CompileArrayCodeCall(
1575 Handle<Object> object, 1604 Handle<Object> object,
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
1970 if (index_out_of_range.is_linked()) { 1999 if (index_out_of_range.is_linked()) {
1971 __ bind(&index_out_of_range); 2000 __ bind(&index_out_of_range);
1972 __ LoadRoot(r0, Heap::kNanValueRootIndex); 2001 __ LoadRoot(r0, Heap::kNanValueRootIndex);
1973 __ Drop(argc + 1); 2002 __ Drop(argc + 1);
1974 __ Ret(); 2003 __ Ret();
1975 } 2004 }
1976 2005
1977 __ bind(&miss); 2006 __ bind(&miss);
1978 // Restore function name in r2. 2007 // Restore function name in r2.
1979 __ Move(r2, name); 2008 __ Move(r2, name);
1980 HandlerFrontendFooter(&name_miss); 2009 __ bind(&name_miss);
2010 GenerateMissBranch();
1981 2011
1982 // Return the generated code. 2012 // Return the generated code.
1983 return GetCode(type, name); 2013 return GetCode(type, name);
1984 } 2014 }
1985 2015
1986 2016
1987 Handle<Code> CallStubCompiler::CompileStringCharAtCall( 2017 Handle<Code> CallStubCompiler::CompileStringCharAtCall(
1988 Handle<Object> object, 2018 Handle<Object> object,
1989 Handle<JSObject> holder, 2019 Handle<JSObject> holder,
1990 Handle<Cell> cell, 2020 Handle<Cell> cell,
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2036 if (index_out_of_range.is_linked()) { 2066 if (index_out_of_range.is_linked()) {
2037 __ bind(&index_out_of_range); 2067 __ bind(&index_out_of_range);
2038 __ LoadRoot(r0, Heap::kempty_stringRootIndex); 2068 __ LoadRoot(r0, Heap::kempty_stringRootIndex);
2039 __ Drop(argc + 1); 2069 __ Drop(argc + 1);
2040 __ Ret(); 2070 __ Ret();
2041 } 2071 }
2042 2072
2043 __ bind(&miss); 2073 __ bind(&miss);
2044 // Restore function name in r2. 2074 // Restore function name in r2.
2045 __ Move(r2, name); 2075 __ Move(r2, name);
2046 HandlerFrontendFooter(&name_miss); 2076 __ bind(&name_miss);
2077 GenerateMissBranch();
2047 2078
2048 // Return the generated code. 2079 // Return the generated code.
2049 return GetCode(type, name); 2080 return GetCode(type, name);
2050 } 2081 }
2051 2082
2052 2083
2053 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( 2084 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
2054 Handle<Object> object, 2085 Handle<Object> object,
2055 Handle<JSObject> holder, 2086 Handle<JSObject> holder,
2056 Handle<Cell> cell, 2087 Handle<Cell> cell,
(...skipping 26 matching lines...) Expand all
2083 __ and_(code, code, Operand(Smi::FromInt(0xffff))); 2114 __ and_(code, code, Operand(Smi::FromInt(0xffff)));
2084 2115
2085 StringCharFromCodeGenerator generator(code, r0); 2116 StringCharFromCodeGenerator generator(code, r0);
2086 generator.GenerateFast(masm()); 2117 generator.GenerateFast(masm());
2087 __ Drop(argc + 1); 2118 __ Drop(argc + 1);
2088 __ Ret(); 2119 __ Ret();
2089 2120
2090 StubRuntimeCallHelper call_helper; 2121 StubRuntimeCallHelper call_helper;
2091 generator.GenerateSlow(masm(), call_helper); 2122 generator.GenerateSlow(masm(), call_helper);
2092 2123
2124 // Tail call the full function. We do not have to patch the receiver
2125 // because the function makes no use of it.
2093 __ bind(&slow); 2126 __ bind(&slow);
2094 // We do not have to patch the receiver because the function makes no use of 2127 ParameterCount expected(function);
2095 // it. 2128 __ InvokeFunction(function, expected, arguments(),
2096 GenerateJumpFunctionIgnoreReceiver(function); 2129 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
2097 2130
2098 HandlerFrontendFooter(&miss); 2131 HandlerFrontendFooter(&miss);
2099 2132
2100 // Return the generated code. 2133 // Return the generated code.
2101 return GetCode(type, name); 2134 return GetCode(type, name);
2102 } 2135 }
2103 2136
2104 2137
2105 Handle<Code> CallStubCompiler::CompileMathFloorCall( 2138 Handle<Code> CallStubCompiler::CompileMathFloorCall(
2106 Handle<Object> object, 2139 Handle<Object> object,
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
2174 // the result is either 0x80000000 or 0x7FFFFFFF and won't fit into an smi. 2207 // the result is either 0x80000000 or 0x7FFFFFFF and won't fit into an smi.
2175 // If result doesn't fit into an smi, branch to slow. 2208 // If result doesn't fit into an smi, branch to slow.
2176 __ SmiTag(r0, SetCC); 2209 __ SmiTag(r0, SetCC);
2177 __ b(vs, &slow); 2210 __ b(vs, &slow);
2178 2211
2179 __ bind(&just_return); 2212 __ bind(&just_return);
2180 __ Drop(argc + 1); 2213 __ Drop(argc + 1);
2181 __ Ret(); 2214 __ Ret();
2182 2215
2183 __ bind(&slow); 2216 __ bind(&slow);
2184 // We do not have to patch the receiver because the function makes no use of 2217 // Tail call the full function. We do not have to patch the receiver
2185 // it. 2218 // because the function makes no use of it.
2186 GenerateJumpFunctionIgnoreReceiver(function); 2219 ParameterCount expected(function);
2220 __ InvokeFunction(function, expected, arguments(),
2221 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
2187 2222
2188 HandlerFrontendFooter(&miss); 2223 HandlerFrontendFooter(&miss);
2189 2224
2190 // Return the generated code. 2225 // Return the generated code.
2191 return GetCode(type, name); 2226 return GetCode(type, name);
2192 } 2227 }
2193 2228
2194 2229
2195 Handle<Code> CallStubCompiler::CompileMathAbsCall( 2230 Handle<Code> CallStubCompiler::CompileMathAbsCall(
2196 Handle<Object> object, 2231 Handle<Object> object,
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2254 __ bind(&negative_sign); 2289 __ bind(&negative_sign);
2255 __ eor(r1, r1, Operand(HeapNumber::kSignMask)); 2290 __ eor(r1, r1, Operand(HeapNumber::kSignMask));
2256 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); 2291 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset));
2257 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); 2292 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
2258 __ AllocateHeapNumber(r0, r4, r5, r6, &slow); 2293 __ AllocateHeapNumber(r0, r4, r5, r6, &slow);
2259 __ str(r1, FieldMemOperand(r0, HeapNumber::kExponentOffset)); 2294 __ str(r1, FieldMemOperand(r0, HeapNumber::kExponentOffset));
2260 __ str(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); 2295 __ str(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset));
2261 __ Drop(argc + 1); 2296 __ Drop(argc + 1);
2262 __ Ret(); 2297 __ Ret();
2263 2298
2299 // Tail call the full function. We do not have to patch the receiver
2300 // because the function makes no use of it.
2264 __ bind(&slow); 2301 __ bind(&slow);
2265 // We do not have to patch the receiver because the function makes no use of 2302 ParameterCount expected(function);
2266 // it. 2303 __ InvokeFunction(function, expected, arguments(),
2267 GenerateJumpFunctionIgnoreReceiver(function); 2304 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
2268 2305
2269 HandlerFrontendFooter(&miss); 2306 HandlerFrontendFooter(&miss);
2270 2307
2271 // Return the generated code. 2308 // Return the generated code.
2272 return GetCode(type, name); 2309 return GetCode(type, name);
2273 } 2310 }
2274 2311
2275 2312
2276 Handle<Code> CallStubCompiler::CompileFastApiCall( 2313 Handle<Code> CallStubCompiler::CompileFastApiCall(
2277 const CallOptimization& optimization, 2314 const CallOptimization& optimization,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2310 // Check that the maps haven't changed and find a Holder as a side effect. 2347 // Check that the maps haven't changed and find a Holder as a side effect.
2311 CheckPrototypes( 2348 CheckPrototypes(
2312 IC::CurrentTypeOf(object, isolate()), 2349 IC::CurrentTypeOf(object, isolate()),
2313 r1, holder, r0, r3, r4, name, depth, &miss); 2350 r1, holder, r0, r3, r4, name, depth, &miss);
2314 2351
2315 GenerateFastApiDirectCall(masm(), optimization, argc, false); 2352 GenerateFastApiDirectCall(masm(), optimization, argc, false);
2316 2353
2317 __ bind(&miss); 2354 __ bind(&miss);
2318 FreeSpaceForFastApiCall(masm()); 2355 FreeSpaceForFastApiCall(masm());
2319 2356
2320 HandlerFrontendFooter(&miss_before_stack_reserved); 2357 __ bind(&miss_before_stack_reserved);
2358 GenerateMissBranch();
2321 2359
2322 // Return the generated code. 2360 // Return the generated code.
2323 return GetCode(function); 2361 return GetCode(function);
2324 } 2362 }
2325 2363
2326 2364
2327 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { 2365 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
2328 Label success; 2366 Label success;
2329 // Check that the object is a boolean. 2367 // Check that the object is a boolean.
2330 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 2368 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
2331 __ cmp(object, ip); 2369 __ cmp(object, ip);
2332 __ b(eq, &success); 2370 __ b(eq, &success);
2333 __ LoadRoot(ip, Heap::kFalseValueRootIndex); 2371 __ LoadRoot(ip, Heap::kFalseValueRootIndex);
2334 __ cmp(object, ip); 2372 __ cmp(object, ip);
2335 __ b(ne, miss); 2373 __ b(ne, miss);
2336 __ bind(&success); 2374 __ bind(&success);
2337 } 2375 }
2338 2376
2339 2377
2340 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) { 2378 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) {
2341 if (!object.is_null() && object->IsGlobalObject()) { 2379 if (object->IsGlobalObject()) {
2342 const int argc = arguments().immediate(); 2380 const int argc = arguments().immediate();
2343 const int receiver_offset = argc * kPointerSize; 2381 const int receiver_offset = argc * kPointerSize;
2344 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); 2382 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset));
2345 __ str(r3, MemOperand(sp, receiver_offset)); 2383 __ str(r3, MemOperand(sp, receiver_offset));
2346 } 2384 }
2347 } 2385 }
2348 2386
2349 2387
2350 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object, 2388 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object,
2351 Handle<JSObject> holder, 2389 Handle<JSObject> holder,
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2427 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); 2465 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2428 reg = CheckPrototypes( 2466 reg = CheckPrototypes(
2429 IC::CurrentTypeOf(prototype, isolate()), 2467 IC::CurrentTypeOf(prototype, isolate()),
2430 r1, holder, r1, r3, r4, name, miss); 2468 r1, holder, r1, r3, r4, name, miss);
2431 } 2469 }
2432 2470
2433 return reg; 2471 return reg;
2434 } 2472 }
2435 2473
2436 2474
2437 void CallStubCompiler::GenerateJumpFunction(Handle<Object> object, 2475 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) {
2438 Register function, 2476 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2439 Label* miss) { 2477 ? CALL_AS_FUNCTION
2440 ASSERT(function.is(r1)); 2478 : CALL_AS_METHOD;
2441 // Check that the function really is a function. 2479 ParameterCount expected(function);
2442 GenerateFunctionCheck(function, r3, miss); 2480 __ InvokeFunction(function, expected, arguments(),
2443 if (!function.is(r1)) __ mov(r1, function); 2481 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2444 PatchGlobalProxy(object);
2445
2446 // Invoke the function.
2447 __ InvokeFunction(r1, arguments(), JUMP_FUNCTION,
2448 NullCallWrapper(), call_kind());
2449 } 2482 }
2450 2483
2451 2484
2485 Handle<Code> CallStubCompiler::CompileCallConstant(
2486 Handle<Object> object,
2487 Handle<JSObject> holder,
2488 Handle<Name> name,
2489 CheckType check,
2490 Handle<JSFunction> function) {
2491 if (HasCustomCallGenerator(function)) {
2492 Handle<Code> code = CompileCustomCall(object, holder,
2493 Handle<Cell>::null(),
2494 function, Handle<String>::cast(name),
2495 Code::FAST);
2496 // A null handle means bail out to the regular compiler code below.
2497 if (!code.is_null()) return code;
2498 }
2499
2500 Label miss;
2501 HandlerFrontendHeader(object, holder, name, check, &miss);
2502 PatchGlobalProxy(object);
2503 CompileHandlerBackend(function);
2504 HandlerFrontendFooter(&miss);
2505
2506 // Return the generated code.
2507 return GetCode(function);
2508 }
2509
2510
2452 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, 2511 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
2453 Handle<JSObject> holder, 2512 Handle<JSObject> holder,
2454 Handle<Name> name) { 2513 Handle<Name> name) {
2455 Label miss; 2514 Label miss;
2456 GenerateNameCheck(name, &miss); 2515 GenerateNameCheck(name, &miss);
2457 2516
2458 // Get the number of arguments. 2517 // Get the number of arguments.
2459 const int argc = arguments().immediate(); 2518 const int argc = arguments().immediate();
2460 LookupResult lookup(isolate()); 2519 LookupResult lookup(isolate());
2461 LookupPostInterceptor(holder, name, &lookup); 2520 LookupPostInterceptor(holder, name, &lookup);
2462 2521
2463 // Get the receiver from the stack. 2522 // Get the receiver from the stack.
2464 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); 2523 __ ldr(r1, MemOperand(sp, argc * kPointerSize));
2465 2524
2466 CallInterceptorCompiler compiler(this, arguments(), r2, extra_state_); 2525 CallInterceptorCompiler compiler(this, arguments(), r2, extra_state_);
2467 compiler.Compile(masm(), object, holder, name, &lookup, r1, r3, r4, r0, 2526 compiler.Compile(masm(), object, holder, name, &lookup, r1, r3, r4, r0,
2468 &miss); 2527 &miss);
2469 2528
2470 // Move returned value, the function to call, to r1. 2529 // Move returned value, the function to call, to r1.
2471 __ mov(r1, r0); 2530 __ mov(r1, r0);
2472 // Restore receiver. 2531 // Restore receiver.
2473 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); 2532 __ ldr(r0, MemOperand(sp, argc * kPointerSize));
2474 2533
2475 GenerateJumpFunction(object, r1, &miss); 2534 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_);
2476 2535
2477 HandlerFrontendFooter(&miss); 2536 // Handle call cache miss.
2537 __ bind(&miss);
2538 GenerateMissBranch();
2478 2539
2479 // Return the generated code. 2540 // Return the generated code.
2480 return GetCode(Code::FAST, name); 2541 return GetCode(Code::FAST, name);
2481 } 2542 }
2482 2543
2483 2544
2484 Handle<Code> CallStubCompiler::CompileCallGlobal( 2545 Handle<Code> CallStubCompiler::CompileCallGlobal(
2485 Handle<JSObject> object, 2546 Handle<JSObject> object,
2486 Handle<GlobalObject> holder, 2547 Handle<GlobalObject> holder,
2487 Handle<PropertyCell> cell, 2548 Handle<PropertyCell> cell,
2488 Handle<JSFunction> function, 2549 Handle<JSFunction> function,
2489 Handle<Name> name) { 2550 Handle<Name> name) {
2490 if (HasCustomCallGenerator(function)) { 2551 if (HasCustomCallGenerator(function)) {
2491 Handle<Code> code = CompileCustomCall( 2552 Handle<Code> code = CompileCustomCall(
2492 object, holder, cell, function, Handle<String>::cast(name), 2553 object, holder, cell, function, Handle<String>::cast(name),
2493 Code::NORMAL); 2554 Code::NORMAL);
2494 // A null handle means bail out to the regular compiler code below. 2555 // A null handle means bail out to the regular compiler code below.
2495 if (!code.is_null()) return code; 2556 if (!code.is_null()) return code;
2496 } 2557 }
2497 2558
2498 Label miss; 2559 Label miss;
2499 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 2560 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2500 // Potentially loads a closure that matches the shared function info of the
2501 // function, rather than function.
2502 GenerateLoadFunctionFromCell(cell, function, &miss); 2561 GenerateLoadFunctionFromCell(cell, function, &miss);
2562 PatchGlobalProxy(object);
2503 2563
2564 // Set up the context (function already in r1).
2565 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
2566
2567 // Jump to the cached code (tail call).
2504 Counters* counters = isolate()->counters(); 2568 Counters* counters = isolate()->counters();
2505 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4); 2569 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4);
2506 GenerateJumpFunction(object, r1, function); 2570 ParameterCount expected(function->shared()->formal_parameter_count());
2571 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2572 ? CALL_AS_FUNCTION
2573 : CALL_AS_METHOD;
2574 // We call indirectly through the code field in the function to
2575 // allow recompilation to take effect without changing any of the
2576 // call sites.
2577 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
2578 __ InvokeCode(r3, expected, arguments(), JUMP_FUNCTION,
2579 NullCallWrapper(), call_kind);
2580
2507 HandlerFrontendFooter(&miss); 2581 HandlerFrontendFooter(&miss);
2508 2582
2509 // Return the generated code. 2583 // Return the generated code.
2510 return GetCode(Code::NORMAL, name); 2584 return GetCode(Code::NORMAL, name);
2511 } 2585 }
2512 2586
2513 2587
2514 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2588 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2515 Handle<JSObject> object, 2589 Handle<JSObject> object,
2516 Handle<JSObject> holder, 2590 Handle<JSObject> holder,
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
2888 // ----------------------------------- 2962 // -----------------------------------
2889 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 2963 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
2890 } 2964 }
2891 2965
2892 2966
2893 #undef __ 2967 #undef __
2894 2968
2895 } } // namespace v8::internal 2969 } } // namespace v8::internal
2896 2970
2897 #endif // V8_TARGET_ARCH_ARM 2971 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/macro-assembler-arm.cc ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698