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

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

Issue 91963003: Cleanup in the CallStubCompiler. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix check Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 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
775 static void PushInterceptorArguments(MacroAssembler* masm, 745 static void PushInterceptorArguments(MacroAssembler* masm,
776 Register receiver, 746 Register receiver,
777 Register holder, 747 Register holder,
778 Register name, 748 Register name,
779 Handle<JSObject> holder_obj) { 749 Handle<JSObject> holder_obj) {
780 STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0); 750 STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0);
781 STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1); 751 STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1);
782 STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2); 752 STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2);
783 STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3); 753 STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3);
784 STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4); 754 STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4);
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
953 ASSERT(!scratch.is(values[i])); 923 ASSERT(!scratch.is(values[i]));
954 __ str(receiver, MemOperand(sp, index-- * kPointerSize)); 924 __ str(receiver, MemOperand(sp, index-- * kPointerSize));
955 } 925 }
956 926
957 GenerateFastApiDirectCall(masm, optimization, argc, true); 927 GenerateFastApiDirectCall(masm, optimization, argc, true);
958 } 928 }
959 929
960 930
961 class CallInterceptorCompiler BASE_EMBEDDED { 931 class CallInterceptorCompiler BASE_EMBEDDED {
962 public: 932 public:
963 CallInterceptorCompiler(StubCompiler* stub_compiler, 933 CallInterceptorCompiler(CallStubCompiler* stub_compiler,
964 const ParameterCount& arguments, 934 const ParameterCount& arguments,
965 Register name, 935 Register name,
966 Code::ExtraICState extra_ic_state) 936 Code::ExtraICState extra_ic_state)
967 : stub_compiler_(stub_compiler), 937 : stub_compiler_(stub_compiler),
968 arguments_(arguments), 938 arguments_(arguments),
969 name_(name), 939 name_(name),
970 extra_ic_state_(extra_ic_state) {} 940 extra_ic_state_(extra_ic_state) {}
971 941
972 void Compile(MacroAssembler* masm, 942 void Compile(MacroAssembler* masm,
973 Handle<JSObject> object, 943 Handle<JSObject> object,
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1065 // safe to omit it here, as if present, it should be fetched 1035 // safe to omit it here, as if present, it should be fetched
1066 // by the previous CheckPrototypes. 1036 // by the previous CheckPrototypes.
1067 ASSERT(depth2 == kInvalidProtoDepth); 1037 ASSERT(depth2 == kInvalidProtoDepth);
1068 } 1038 }
1069 1039
1070 // Invoke function. 1040 // Invoke function.
1071 if (can_do_fast_api_call) { 1041 if (can_do_fast_api_call) {
1072 GenerateFastApiDirectCall( 1042 GenerateFastApiDirectCall(
1073 masm, optimization, arguments_.immediate(), false); 1043 masm, optimization, arguments_.immediate(), false);
1074 } else { 1044 } else {
1075 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
1076 ? CALL_AS_FUNCTION
1077 : CALL_AS_METHOD;
1078 Handle<JSFunction> function = optimization.constant_function(); 1045 Handle<JSFunction> function = optimization.constant_function();
1079 ParameterCount expected(function); 1046 stub_compiler_->GenerateCallFunction(object, function);
1080 __ InvokeFunction(function, expected, arguments_,
1081 JUMP_FUNCTION, NullCallWrapper(), call_kind);
1082 } 1047 }
1083 1048
1084 // Deferred code for fast API call case---clean preallocated space. 1049 // Deferred code for fast API call case---clean preallocated space.
1085 if (can_do_fast_api_call) { 1050 if (can_do_fast_api_call) {
1086 __ bind(&miss_cleanup); 1051 __ bind(&miss_cleanup);
1087 FreeSpaceForFastApiCall(masm); 1052 FreeSpaceForFastApiCall(masm);
1088 __ b(miss_label); 1053 __ b(miss_label);
1089 } 1054 }
1090 1055
1091 // Invoke a regular function. 1056 // Invoke a regular function.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1139 holder_obj); 1104 holder_obj);
1140 __ pop(name_); // Restore the name. 1105 __ pop(name_); // Restore the name.
1141 __ pop(receiver); // Restore the holder. 1106 __ pop(receiver); // Restore the holder.
1142 } 1107 }
1143 // If interceptor returns no-result sentinel, call the constant function. 1108 // If interceptor returns no-result sentinel, call the constant function.
1144 __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex); 1109 __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex);
1145 __ cmp(r0, scratch); 1110 __ cmp(r0, scratch);
1146 __ b(ne, interceptor_succeeded); 1111 __ b(ne, interceptor_succeeded);
1147 } 1112 }
1148 1113
1149 StubCompiler* stub_compiler_; 1114 CallStubCompiler* stub_compiler_;
1150 const ParameterCount& arguments_; 1115 const ParameterCount& arguments_;
1151 Register name_; 1116 Register name_;
1152 Code::ExtraICState extra_ic_state_; 1117 Code::ExtraICState extra_ic_state_;
1153 }; 1118 };
1154 1119
1155 1120
1156 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { 1121 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) {
1157 __ Jump(code, RelocInfo::CODE_TARGET); 1122 __ Jump(code, RelocInfo::CODE_TARGET);
1158 } 1123 }
1159 1124
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
1542 1507
1543 1508
1544 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { 1509 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) {
1545 if (kind_ == Code::KEYED_CALL_IC) { 1510 if (kind_ == Code::KEYED_CALL_IC) {
1546 __ cmp(r2, Operand(name)); 1511 __ cmp(r2, Operand(name));
1547 __ b(ne, miss); 1512 __ b(ne, miss);
1548 } 1513 }
1549 } 1514 }
1550 1515
1551 1516
1517 void CallStubCompiler::GenerateFunctionCheck(Register function,
1518 Register scratch,
1519 Label* miss) {
1520 __ JumpIfSmi(function, miss);
1521 __ CompareObjectType(function, scratch, scratch, JS_FUNCTION_TYPE);
1522 __ b(ne, miss);
1523 }
1524
1525
1552 void CallStubCompiler::GenerateLoadFunctionFromCell( 1526 void CallStubCompiler::GenerateLoadFunctionFromCell(
1553 Handle<Cell> cell, 1527 Handle<Cell> cell,
1554 Handle<JSFunction> function, 1528 Handle<JSFunction> function,
1555 Label* miss) { 1529 Label* miss) {
1556 // Get the value from the cell. 1530 // Get the value from the cell.
1557 __ mov(r3, Operand(cell)); 1531 __ mov(r3, Operand(cell));
1558 __ ldr(r1, FieldMemOperand(r3, Cell::kValueOffset)); 1532 __ ldr(r1, FieldMemOperand(r3, Cell::kValueOffset));
1559 1533
1560 // Check that the cell contains the same function. 1534 // Check that the cell contains the same function.
1561 if (heap()->InNewSpace(*function)) { 1535 if (heap()->InNewSpace(*function)) {
1562 // We can't embed a pointer to a function in new space so we have 1536 // We can't embed a pointer to a function in new space so we have
1563 // to verify that the shared function info is unchanged. This has 1537 // to verify that the shared function info is unchanged. This has
1564 // the nice side effect that multiple closures based on the same 1538 // the nice side effect that multiple closures based on the same
1565 // function can all use this call IC. Before we load through the 1539 // function can all use this call IC. Before we load through the
1566 // function, we have to verify that it still is a function. 1540 // function, we have to verify that it still is a function.
1567 __ JumpIfSmi(r1, miss); 1541 GenerateFunctionCheck(r1, r3, miss);
1568 __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE);
1569 __ b(ne, miss);
1570 1542
1571 // Check the shared function info. Make sure it hasn't changed. 1543 // Check the shared function info. Make sure it hasn't changed.
1572 __ Move(r3, Handle<SharedFunctionInfo>(function->shared())); 1544 __ Move(r3, Handle<SharedFunctionInfo>(function->shared()));
1573 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); 1545 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1574 __ cmp(r4, r3); 1546 __ cmp(r4, r3);
1575 } else { 1547 } else {
1576 __ cmp(r1, Operand(function)); 1548 __ cmp(r1, Operand(function));
1577 } 1549 }
1578 __ b(ne, miss); 1550 __ b(ne, miss);
1579 } 1551 }
(...skipping 11 matching lines...) Expand all
1591 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, 1563 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
1592 Handle<JSObject> holder, 1564 Handle<JSObject> holder,
1593 PropertyIndex index, 1565 PropertyIndex index,
1594 Handle<Name> name) { 1566 Handle<Name> name) {
1595 Label miss; 1567 Label miss;
1596 1568
1597 Register reg = HandlerFrontendHeader( 1569 Register reg = HandlerFrontendHeader(
1598 object, holder, name, RECEIVER_MAP_CHECK, &miss); 1570 object, holder, name, RECEIVER_MAP_CHECK, &miss);
1599 GenerateFastPropertyLoad(masm(), r1, reg, index.is_inobject(holder), 1571 GenerateFastPropertyLoad(masm(), r1, reg, index.is_inobject(holder),
1600 index.translate(holder), Representation::Tagged()); 1572 index.translate(holder), Representation::Tagged());
1601 1573 GenerateCallFunction(object, r1, &miss);
1602 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_);
1603 1574
1604 HandlerFrontendFooter(&miss); 1575 HandlerFrontendFooter(&miss);
1605 1576
1606 // Return the generated code. 1577 // Return the generated code.
1607 return GetCode(Code::FAST, name); 1578 return GetCode(Code::FAST, name);
1608 } 1579 }
1609 1580
1610 1581
1611 Handle<Code> CallStubCompiler::CompileArrayCodeCall( 1582 Handle<Code> CallStubCompiler::CompileArrayCodeCall(
1612 Handle<Object> object, 1583 Handle<Object> object,
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
2007 if (index_out_of_range.is_linked()) { 1978 if (index_out_of_range.is_linked()) {
2008 __ bind(&index_out_of_range); 1979 __ bind(&index_out_of_range);
2009 __ LoadRoot(r0, Heap::kNanValueRootIndex); 1980 __ LoadRoot(r0, Heap::kNanValueRootIndex);
2010 __ Drop(argc + 1); 1981 __ Drop(argc + 1);
2011 __ Ret(); 1982 __ Ret();
2012 } 1983 }
2013 1984
2014 __ bind(&miss); 1985 __ bind(&miss);
2015 // Restore function name in r2. 1986 // Restore function name in r2.
2016 __ Move(r2, name); 1987 __ Move(r2, name);
2017 __ bind(&name_miss); 1988 HandlerFrontendFooter(&name_miss);
2018 GenerateMissBranch();
2019 1989
2020 // Return the generated code. 1990 // Return the generated code.
2021 return GetCode(type, name); 1991 return GetCode(type, name);
2022 } 1992 }
2023 1993
2024 1994
2025 Handle<Code> CallStubCompiler::CompileStringCharAtCall( 1995 Handle<Code> CallStubCompiler::CompileStringCharAtCall(
2026 Handle<Object> object, 1996 Handle<Object> object,
2027 Handle<JSObject> holder, 1997 Handle<JSObject> holder,
2028 Handle<Cell> cell, 1998 Handle<Cell> cell,
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2074 if (index_out_of_range.is_linked()) { 2044 if (index_out_of_range.is_linked()) {
2075 __ bind(&index_out_of_range); 2045 __ bind(&index_out_of_range);
2076 __ LoadRoot(r0, Heap::kempty_stringRootIndex); 2046 __ LoadRoot(r0, Heap::kempty_stringRootIndex);
2077 __ Drop(argc + 1); 2047 __ Drop(argc + 1);
2078 __ Ret(); 2048 __ Ret();
2079 } 2049 }
2080 2050
2081 __ bind(&miss); 2051 __ bind(&miss);
2082 // Restore function name in r2. 2052 // Restore function name in r2.
2083 __ Move(r2, name); 2053 __ Move(r2, name);
2084 __ bind(&name_miss); 2054 HandlerFrontendFooter(&name_miss);
2085 GenerateMissBranch();
2086 2055
2087 // Return the generated code. 2056 // Return the generated code.
2088 return GetCode(type, name); 2057 return GetCode(type, name);
2089 } 2058 }
2090 2059
2091 2060
2092 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( 2061 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
2093 Handle<Object> object, 2062 Handle<Object> object,
2094 Handle<JSObject> holder, 2063 Handle<JSObject> holder,
2095 Handle<Cell> cell, 2064 Handle<Cell> cell,
(...skipping 26 matching lines...) Expand all
2122 __ and_(code, code, Operand(Smi::FromInt(0xffff))); 2091 __ and_(code, code, Operand(Smi::FromInt(0xffff)));
2123 2092
2124 StringCharFromCodeGenerator generator(code, r0); 2093 StringCharFromCodeGenerator generator(code, r0);
2125 generator.GenerateFast(masm()); 2094 generator.GenerateFast(masm());
2126 __ Drop(argc + 1); 2095 __ Drop(argc + 1);
2127 __ Ret(); 2096 __ Ret();
2128 2097
2129 StubRuntimeCallHelper call_helper; 2098 StubRuntimeCallHelper call_helper;
2130 generator.GenerateSlow(masm(), call_helper); 2099 generator.GenerateSlow(masm(), call_helper);
2131 2100
2132 // Tail call the full function. We do not have to patch the receiver
2133 // because the function makes no use of it.
2134 __ bind(&slow); 2101 __ bind(&slow);
2135 ParameterCount expected(function); 2102 // We do not have to patch the receiver because the function makes no use of
2136 __ InvokeFunction(function, expected, arguments(), 2103 // it.
2137 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2104 GenerateCallFunction(Handle<Object>::null(), function);
Igor Sheludko 2013/11/28 13:06:08 Consider introducing different function for such a
Toon Verwaest 2013/11/28 15:24:09 Done.
2138 2105
2139 HandlerFrontendFooter(&miss); 2106 HandlerFrontendFooter(&miss);
2140 2107
2141 // Return the generated code. 2108 // Return the generated code.
2142 return GetCode(type, name); 2109 return GetCode(type, name);
2143 } 2110 }
2144 2111
2145 2112
2146 Handle<Code> CallStubCompiler::CompileMathFloorCall( 2113 Handle<Code> CallStubCompiler::CompileMathFloorCall(
2147 Handle<Object> object, 2114 Handle<Object> object,
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
2215 // the result is either 0x80000000 or 0x7FFFFFFF and won't fit into an smi. 2182 // the result is either 0x80000000 or 0x7FFFFFFF and won't fit into an smi.
2216 // If result doesn't fit into an smi, branch to slow. 2183 // If result doesn't fit into an smi, branch to slow.
2217 __ SmiTag(r0, SetCC); 2184 __ SmiTag(r0, SetCC);
2218 __ b(vs, &slow); 2185 __ b(vs, &slow);
2219 2186
2220 __ bind(&just_return); 2187 __ bind(&just_return);
2221 __ Drop(argc + 1); 2188 __ Drop(argc + 1);
2222 __ Ret(); 2189 __ Ret();
2223 2190
2224 __ bind(&slow); 2191 __ bind(&slow);
2225 // Tail call the full function. We do not have to patch the receiver 2192 // We do not have to patch the receiver because the function makes no use of
2226 // because the function makes no use of it. 2193 // it.
2227 ParameterCount expected(function); 2194 GenerateCallFunction(Handle<Object>::null(), function);
2228 __ InvokeFunction(function, expected, arguments(),
2229 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
2230 2195
2231 HandlerFrontendFooter(&miss); 2196 HandlerFrontendFooter(&miss);
2232 2197
2233 // Return the generated code. 2198 // Return the generated code.
2234 return GetCode(type, name); 2199 return GetCode(type, name);
2235 } 2200 }
2236 2201
2237 2202
2238 Handle<Code> CallStubCompiler::CompileMathAbsCall( 2203 Handle<Code> CallStubCompiler::CompileMathAbsCall(
2239 Handle<Object> object, 2204 Handle<Object> object,
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2297 __ bind(&negative_sign); 2262 __ bind(&negative_sign);
2298 __ eor(r1, r1, Operand(HeapNumber::kSignMask)); 2263 __ eor(r1, r1, Operand(HeapNumber::kSignMask));
2299 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); 2264 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset));
2300 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); 2265 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
2301 __ AllocateHeapNumber(r0, r4, r5, r6, &slow); 2266 __ AllocateHeapNumber(r0, r4, r5, r6, &slow);
2302 __ str(r1, FieldMemOperand(r0, HeapNumber::kExponentOffset)); 2267 __ str(r1, FieldMemOperand(r0, HeapNumber::kExponentOffset));
2303 __ str(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); 2268 __ str(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset));
2304 __ Drop(argc + 1); 2269 __ Drop(argc + 1);
2305 __ Ret(); 2270 __ Ret();
2306 2271
2307 // Tail call the full function. We do not have to patch the receiver
2308 // because the function makes no use of it.
2309 __ bind(&slow); 2272 __ bind(&slow);
2310 ParameterCount expected(function); 2273 // We do not have to patch the receiver because the function makes no use of
2311 __ InvokeFunction(function, expected, arguments(), 2274 // it.
2312 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2275 GenerateCallFunction(Handle<Object>::null(), function);
2313 2276
2314 HandlerFrontendFooter(&miss); 2277 HandlerFrontendFooter(&miss);
2315 2278
2316 // Return the generated code. 2279 // Return the generated code.
2317 return GetCode(type, name); 2280 return GetCode(type, name);
2318 } 2281 }
2319 2282
2320 2283
2321 Handle<Code> CallStubCompiler::CompileFastApiCall( 2284 Handle<Code> CallStubCompiler::CompileFastApiCall(
2322 const CallOptimization& optimization, 2285 const CallOptimization& optimization,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2355 // Check that the maps haven't changed and find a Holder as a side effect. 2318 // Check that the maps haven't changed and find a Holder as a side effect.
2356 CheckPrototypes( 2319 CheckPrototypes(
2357 IC::CurrentTypeOf(object, isolate()), 2320 IC::CurrentTypeOf(object, isolate()),
2358 r1, holder, r0, r3, r4, name, depth, &miss); 2321 r1, holder, r0, r3, r4, name, depth, &miss);
2359 2322
2360 GenerateFastApiDirectCall(masm(), optimization, argc, false); 2323 GenerateFastApiDirectCall(masm(), optimization, argc, false);
2361 2324
2362 __ bind(&miss); 2325 __ bind(&miss);
2363 FreeSpaceForFastApiCall(masm()); 2326 FreeSpaceForFastApiCall(masm());
2364 2327
2365 __ bind(&miss_before_stack_reserved); 2328 HandlerFrontendFooter(&miss_before_stack_reserved);
2366 GenerateMissBranch();
2367 2329
2368 // Return the generated code. 2330 // Return the generated code.
2369 return GetCode(function); 2331 return GetCode(function);
2370 } 2332 }
2371 2333
2372 2334
2373 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { 2335 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
2374 Label success; 2336 Label success;
2375 // Check that the object is a boolean. 2337 // Check that the object is a boolean.
2376 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 2338 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
2377 __ cmp(object, ip); 2339 __ cmp(object, ip);
2378 __ b(eq, &success); 2340 __ b(eq, &success);
2379 __ LoadRoot(ip, Heap::kFalseValueRootIndex); 2341 __ LoadRoot(ip, Heap::kFalseValueRootIndex);
2380 __ cmp(object, ip); 2342 __ cmp(object, ip);
2381 __ b(ne, miss); 2343 __ b(ne, miss);
2382 __ bind(&success); 2344 __ bind(&success);
2383 } 2345 }
2384 2346
2385 2347
2386 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) { 2348 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) {
2387 if (object->IsGlobalObject()) { 2349 if (!object.is_null() && object->IsGlobalObject()) {
2388 const int argc = arguments().immediate(); 2350 const int argc = arguments().immediate();
2389 const int receiver_offset = argc * kPointerSize; 2351 const int receiver_offset = argc * kPointerSize;
2390 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); 2352 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset));
2391 __ str(r3, MemOperand(sp, receiver_offset)); 2353 __ str(r3, MemOperand(sp, receiver_offset));
2392 } 2354 }
2393 } 2355 }
2394 2356
2395 2357
2396 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object, 2358 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object,
2397 Handle<JSObject> holder, 2359 Handle<JSObject> holder,
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2473 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); 2435 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2474 reg = CheckPrototypes( 2436 reg = CheckPrototypes(
2475 IC::CurrentTypeOf(prototype, isolate()), 2437 IC::CurrentTypeOf(prototype, isolate()),
2476 r1, holder, r1, r3, r4, name, miss); 2438 r1, holder, r1, r3, r4, name, miss);
2477 } 2439 }
2478 2440
2479 return reg; 2441 return reg;
2480 } 2442 }
2481 2443
2482 2444
2483 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { 2445 void CallStubCompiler::GenerateCallFunction(Handle<Object> object,
2484 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2446 Register function,
2485 ? CALL_AS_FUNCTION 2447 Label* miss) {
2486 : CALL_AS_METHOD; 2448 ASSERT(function.is(r1));
2487 ParameterCount expected(function); 2449 // Check that the function really is a function.
2488 __ InvokeFunction(function, expected, arguments(), 2450 GenerateFunctionCheck(function, r3, miss);
2489 JUMP_FUNCTION, NullCallWrapper(), call_kind); 2451 if (!function.is(r1)) __ mov(r1, function);
2452 PatchGlobalProxy(object);
2453
2454 // Invoke the function.
2455 __ InvokeFunction(r1, arguments(), JUMP_FUNCTION,
2456 NullCallWrapper(), call_kind());
2490 } 2457 }
2491 2458
2492 2459
2493 Handle<Code> CallStubCompiler::CompileCallConstant(
2494 Handle<Object> object,
2495 Handle<JSObject> holder,
2496 Handle<Name> name,
2497 CheckType check,
2498 Handle<JSFunction> function) {
2499 if (HasCustomCallGenerator(function)) {
2500 Handle<Code> code = CompileCustomCall(object, holder,
2501 Handle<Cell>::null(),
2502 function, Handle<String>::cast(name),
2503 Code::FAST);
2504 // A null handle means bail out to the regular compiler code below.
2505 if (!code.is_null()) return code;
2506 }
2507
2508 Label miss;
2509 HandlerFrontendHeader(object, holder, name, check, &miss);
2510 PatchGlobalProxy(object);
2511 CompileHandlerBackend(function);
2512 HandlerFrontendFooter(&miss);
2513
2514 // Return the generated code.
2515 return GetCode(function);
2516 }
2517
2518
2519 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, 2460 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
2520 Handle<JSObject> holder, 2461 Handle<JSObject> holder,
2521 Handle<Name> name) { 2462 Handle<Name> name) {
2522 Label miss; 2463 Label miss;
2523 GenerateNameCheck(name, &miss); 2464 GenerateNameCheck(name, &miss);
2524 2465
2525 // Get the number of arguments. 2466 // Get the number of arguments.
2526 const int argc = arguments().immediate(); 2467 const int argc = arguments().immediate();
2527 LookupResult lookup(isolate()); 2468 LookupResult lookup(isolate());
2528 LookupPostInterceptor(holder, name, &lookup); 2469 LookupPostInterceptor(holder, name, &lookup);
2529 2470
2530 // Get the receiver from the stack. 2471 // Get the receiver from the stack.
2531 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); 2472 __ ldr(r1, MemOperand(sp, argc * kPointerSize));
2532 2473
2533 CallInterceptorCompiler compiler(this, arguments(), r2, extra_state_); 2474 CallInterceptorCompiler compiler(this, arguments(), r2, extra_state_);
2534 compiler.Compile(masm(), object, holder, name, &lookup, r1, r3, r4, r0, 2475 compiler.Compile(masm(), object, holder, name, &lookup, r1, r3, r4, r0,
2535 &miss); 2476 &miss);
2536 2477
2537 // Move returned value, the function to call, to r1. 2478 // Move returned value, the function to call, to r1.
2538 __ mov(r1, r0); 2479 __ mov(r1, r0);
2539 // Restore receiver. 2480 // Restore receiver.
2540 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); 2481 __ ldr(r0, MemOperand(sp, argc * kPointerSize));
2541 2482
2542 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); 2483 GenerateCallFunction(object, r0, &miss);
2543 2484
2544 // Handle call cache miss. 2485 HandlerFrontendFooter(&miss);
2545 __ bind(&miss);
2546 GenerateMissBranch();
2547 2486
2548 // Return the generated code. 2487 // Return the generated code.
2549 return GetCode(Code::FAST, name); 2488 return GetCode(Code::FAST, name);
2550 } 2489 }
2551 2490
2552 2491
2553 Handle<Code> CallStubCompiler::CompileCallGlobal( 2492 Handle<Code> CallStubCompiler::CompileCallGlobal(
2554 Handle<JSObject> object, 2493 Handle<JSObject> object,
2555 Handle<GlobalObject> holder, 2494 Handle<GlobalObject> holder,
2556 Handle<PropertyCell> cell, 2495 Handle<PropertyCell> cell,
2557 Handle<JSFunction> function, 2496 Handle<JSFunction> function,
2558 Handle<Name> name) { 2497 Handle<Name> name) {
2559 if (HasCustomCallGenerator(function)) { 2498 if (HasCustomCallGenerator(function)) {
2560 Handle<Code> code = CompileCustomCall( 2499 Handle<Code> code = CompileCustomCall(
2561 object, holder, cell, function, Handle<String>::cast(name), 2500 object, holder, cell, function, Handle<String>::cast(name),
2562 Code::NORMAL); 2501 Code::NORMAL);
2563 // A null handle means bail out to the regular compiler code below. 2502 // A null handle means bail out to the regular compiler code below.
2564 if (!code.is_null()) return code; 2503 if (!code.is_null()) return code;
2565 } 2504 }
2566 2505
2567 Label miss; 2506 Label miss;
2568 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 2507 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2508 // Potentially loads a closure that matches the shared function info of the
2509 // function, rather than function.
2569 GenerateLoadFunctionFromCell(cell, function, &miss); 2510 GenerateLoadFunctionFromCell(cell, function, &miss);
2570 PatchGlobalProxy(object);
2571 2511
2572 // Set up the context (function already in r1).
2573 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
2574
2575 // Jump to the cached code (tail call).
2576 Counters* counters = isolate()->counters(); 2512 Counters* counters = isolate()->counters();
2577 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4); 2513 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4);
2578 ParameterCount expected(function->shared()->formal_parameter_count()); 2514 GenerateCallFunction(object, r1, function);
2579 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2580 ? CALL_AS_FUNCTION
2581 : CALL_AS_METHOD;
2582 // We call indirectly through the code field in the function to
2583 // allow recompilation to take effect without changing any of the
2584 // call sites.
2585 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
2586 __ InvokeCode(r3, expected, arguments(), JUMP_FUNCTION,
2587 NullCallWrapper(), call_kind);
2588
2589 HandlerFrontendFooter(&miss); 2515 HandlerFrontendFooter(&miss);
2590 2516
2591 // Return the generated code. 2517 // Return the generated code.
2592 return GetCode(Code::NORMAL, name); 2518 return GetCode(Code::NORMAL, name);
2593 } 2519 }
2594 2520
2595 2521
2596 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2522 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2597 Handle<JSObject> object, 2523 Handle<JSObject> object,
2598 Handle<JSObject> holder, 2524 Handle<JSObject> holder,
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
2973 // ----------------------------------- 2899 // -----------------------------------
2974 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 2900 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
2975 } 2901 }
2976 2902
2977 2903
2978 #undef __ 2904 #undef __
2979 2905
2980 } } // namespace v8::internal 2906 } } // namespace v8::internal
2981 2907
2982 #endif // V8_TARGET_ARCH_ARM 2908 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698