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

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

Issue 142893003: Merge bleeding_edge 18658:18677 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 11 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/lithium-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 1648 matching lines...) Expand 10 before | Expand all | Expand 10 after
1659 index.translate(holder), Representation::Tagged()); 1659 index.translate(holder), Representation::Tagged());
1660 GenerateJumpFunction(object, edi, &miss); 1660 GenerateJumpFunction(object, edi, &miss);
1661 1661
1662 HandlerFrontendFooter(&miss); 1662 HandlerFrontendFooter(&miss);
1663 1663
1664 // Return the generated code. 1664 // Return the generated code.
1665 return GetCode(Code::FAST, name); 1665 return GetCode(Code::FAST, name);
1666 } 1666 }
1667 1667
1668 1668
1669 Handle<Code> CallStubCompiler::CompileArrayCodeCall(
1670 Handle<Object> object,
1671 Handle<JSObject> holder,
1672 Handle<Cell> cell,
1673 Handle<JSFunction> function,
1674 Handle<String> name,
1675 Code::StubType type) {
1676 Label miss;
1677
1678 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1679 if (!cell.is_null()) {
1680 ASSERT(cell->value() == *function);
1681 GenerateLoadFunctionFromCell(cell, function, &miss);
1682 }
1683
1684 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite();
1685 site->SetElementsKind(GetInitialFastElementsKind());
1686 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site);
1687 const int argc = arguments().immediate();
1688 __ mov(eax, Immediate(argc));
1689 __ mov(ebx, site_feedback_cell);
1690 __ mov(edi, function);
1691
1692 ArrayConstructorStub stub(isolate());
1693 __ TailCallStub(&stub);
1694
1695 HandlerFrontendFooter(&miss);
1696
1697 // Return the generated code.
1698 return GetCode(type, name);
1699 }
1700
1701
1702 Handle<Code> CallStubCompiler::CompileArrayPushCall( 1669 Handle<Code> CallStubCompiler::CompileArrayPushCall(
1703 Handle<Object> object, 1670 Handle<Object> object,
1704 Handle<JSObject> holder, 1671 Handle<JSObject> holder,
1705 Handle<Cell> cell, 1672 Handle<Cell> cell,
1706 Handle<JSFunction> function, 1673 Handle<JSFunction> function,
1707 Handle<String> name, 1674 Handle<String> name,
1708 Code::StubType type) { 1675 Code::StubType type) {
1709 // If object is not an array or is observed or sealed, bail out to regular 1676 // If object is not an array or is observed or sealed, bail out to regular
1710 // call. 1677 // call.
1711 if (!object->IsJSArray() || 1678 if (!object->IsJSArray() ||
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
2007 argc + 1, 1974 argc + 1,
2008 1); 1975 1);
2009 1976
2010 HandlerFrontendFooter(&miss); 1977 HandlerFrontendFooter(&miss);
2011 1978
2012 // Return the generated code. 1979 // Return the generated code.
2013 return GetCode(type, name); 1980 return GetCode(type, name);
2014 } 1981 }
2015 1982
2016 1983
2017 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
2018 Handle<Object> object,
2019 Handle<JSObject> holder,
2020 Handle<Cell> cell,
2021 Handle<JSFunction> function,
2022 Handle<String> name,
2023 Code::StubType type) {
2024 // If object is not a string, bail out to regular call.
2025 if (!object->IsString() || !cell.is_null()) {
2026 return Handle<Code>::null();
2027 }
2028
2029 const int argc = arguments().immediate();
2030
2031 Label miss;
2032 Label name_miss;
2033 Label index_out_of_range;
2034 Label* index_out_of_range_label = &index_out_of_range;
2035
2036 if (kind_ == Code::CALL_IC &&
2037 (CallICBase::StringStubState::decode(extra_state()) ==
2038 DEFAULT_STRING_STUB)) {
2039 index_out_of_range_label = &miss;
2040 }
2041
2042 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss);
2043
2044 Register receiver = ebx;
2045 Register index = edi;
2046 Register result = eax;
2047 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize));
2048 if (argc > 0) {
2049 __ mov(index, Operand(esp, (argc - 0) * kPointerSize));
2050 } else {
2051 __ Set(index, Immediate(factory()->undefined_value()));
2052 }
2053
2054 StringCharCodeAtGenerator generator(receiver,
2055 index,
2056 result,
2057 &miss, // When not a string.
2058 &miss, // When not a number.
2059 index_out_of_range_label,
2060 STRING_INDEX_IS_NUMBER);
2061 generator.GenerateFast(masm());
2062 __ ret((argc + 1) * kPointerSize);
2063
2064 StubRuntimeCallHelper call_helper;
2065 generator.GenerateSlow(masm(), call_helper);
2066
2067 if (index_out_of_range.is_linked()) {
2068 __ bind(&index_out_of_range);
2069 __ Set(eax, Immediate(factory()->nan_value()));
2070 __ ret((argc + 1) * kPointerSize);
2071 }
2072
2073 __ bind(&miss);
2074 // Restore function name in ecx.
2075 __ Set(ecx, Immediate(name));
2076 HandlerFrontendFooter(&name_miss);
2077
2078 // Return the generated code.
2079 return GetCode(type, name);
2080 }
2081
2082
2083 Handle<Code> CallStubCompiler::CompileStringCharAtCall(
2084 Handle<Object> object,
2085 Handle<JSObject> holder,
2086 Handle<Cell> cell,
2087 Handle<JSFunction> function,
2088 Handle<String> name,
2089 Code::StubType type) {
2090 // If object is not a string, bail out to regular call.
2091 if (!object->IsString() || !cell.is_null()) {
2092 return Handle<Code>::null();
2093 }
2094
2095 const int argc = arguments().immediate();
2096
2097 Label miss;
2098 Label name_miss;
2099 Label index_out_of_range;
2100 Label* index_out_of_range_label = &index_out_of_range;
2101
2102 if (kind_ == Code::CALL_IC &&
2103 (CallICBase::StringStubState::decode(extra_state()) ==
2104 DEFAULT_STRING_STUB)) {
2105 index_out_of_range_label = &miss;
2106 }
2107
2108 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss);
2109
2110 Register receiver = eax;
2111 Register index = edi;
2112 Register scratch = edx;
2113 Register result = eax;
2114 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize));
2115 if (argc > 0) {
2116 __ mov(index, Operand(esp, (argc - 0) * kPointerSize));
2117 } else {
2118 __ Set(index, Immediate(factory()->undefined_value()));
2119 }
2120
2121 StringCharAtGenerator generator(receiver,
2122 index,
2123 scratch,
2124 result,
2125 &miss, // When not a string.
2126 &miss, // When not a number.
2127 index_out_of_range_label,
2128 STRING_INDEX_IS_NUMBER);
2129 generator.GenerateFast(masm());
2130 __ ret((argc + 1) * kPointerSize);
2131
2132 StubRuntimeCallHelper call_helper;
2133 generator.GenerateSlow(masm(), call_helper);
2134
2135 if (index_out_of_range.is_linked()) {
2136 __ bind(&index_out_of_range);
2137 __ Set(eax, Immediate(factory()->empty_string()));
2138 __ ret((argc + 1) * kPointerSize);
2139 }
2140
2141 __ bind(&miss);
2142 // Restore function name in ecx.
2143 __ Set(ecx, Immediate(name));
2144 HandlerFrontendFooter(&name_miss);
2145
2146 // Return the generated code.
2147 return GetCode(type, name);
2148 }
2149
2150
2151 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
2152 Handle<Object> object,
2153 Handle<JSObject> holder,
2154 Handle<Cell> cell,
2155 Handle<JSFunction> function,
2156 Handle<String> name,
2157 Code::StubType type) {
2158 const int argc = arguments().immediate();
2159
2160 // If the object is not a JSObject or we got an unexpected number of
2161 // arguments, bail out to the regular call.
2162 if (!object->IsJSObject() || argc != 1) {
2163 return Handle<Code>::null();
2164 }
2165
2166 Label miss;
2167
2168 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2169 if (!cell.is_null()) {
2170 ASSERT(cell->value() == *function);
2171 GenerateLoadFunctionFromCell(cell, function, &miss);
2172 }
2173
2174 // Load the char code argument.
2175 Register code = ebx;
2176 __ mov(code, Operand(esp, 1 * kPointerSize));
2177
2178 // Check the code is a smi.
2179 Label slow;
2180 STATIC_ASSERT(kSmiTag == 0);
2181 __ JumpIfNotSmi(code, &slow);
2182
2183 // Convert the smi code to uint16.
2184 __ and_(code, Immediate(Smi::FromInt(0xffff)));
2185
2186 StringCharFromCodeGenerator generator(code, eax);
2187 generator.GenerateFast(masm());
2188 __ ret(2 * kPointerSize);
2189
2190 StubRuntimeCallHelper call_helper;
2191 generator.GenerateSlow(masm(), call_helper);
2192
2193 __ bind(&slow);
2194 // We do not have to patch the receiver because the function makes no use of
2195 // it.
2196 GenerateJumpFunctionIgnoreReceiver(function);
2197
2198 HandlerFrontendFooter(&miss);
2199
2200 // Return the generated code.
2201 return GetCode(type, name);
2202 }
2203
2204
2205 Handle<Code> CallStubCompiler::CompileMathFloorCall(
2206 Handle<Object> object,
2207 Handle<JSObject> holder,
2208 Handle<Cell> cell,
2209 Handle<JSFunction> function,
2210 Handle<String> name,
2211 Code::StubType type) {
2212 if (!CpuFeatures::IsSupported(SSE2)) {
2213 return Handle<Code>::null();
2214 }
2215
2216 CpuFeatureScope use_sse2(masm(), SSE2);
2217
2218 const int argc = arguments().immediate();
2219
2220 // If the object is not a JSObject or we got an unexpected number of
2221 // arguments, bail out to the regular call.
2222 if (!object->IsJSObject() || argc != 1) {
2223 return Handle<Code>::null();
2224 }
2225
2226 Label miss;
2227
2228 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2229 if (!cell.is_null()) {
2230 ASSERT(cell->value() == *function);
2231 GenerateLoadFunctionFromCell(cell, function, &miss);
2232 }
2233
2234 // Load the (only) argument into eax.
2235 __ mov(eax, Operand(esp, 1 * kPointerSize));
2236
2237 // Check if the argument is a smi.
2238 Label smi;
2239 STATIC_ASSERT(kSmiTag == 0);
2240 __ JumpIfSmi(eax, &smi);
2241
2242 // Check if the argument is a heap number and load its value into xmm0.
2243 Label slow;
2244 __ CheckMap(eax, factory()->heap_number_map(), &slow, DONT_DO_SMI_CHECK);
2245 __ movsd(xmm0, FieldOperand(eax, HeapNumber::kValueOffset));
2246
2247 // Check if the argument is strictly positive. Note this also
2248 // discards NaN.
2249 __ xorpd(xmm1, xmm1);
2250 __ ucomisd(xmm0, xmm1);
2251 __ j(below_equal, &slow);
2252
2253 // Do a truncating conversion.
2254 __ cvttsd2si(eax, Operand(xmm0));
2255
2256 // Check if the result fits into a smi. Note this also checks for
2257 // 0x80000000 which signals a failed conversion.
2258 Label wont_fit_into_smi;
2259 __ test(eax, Immediate(0xc0000000));
2260 __ j(not_zero, &wont_fit_into_smi);
2261
2262 // Smi tag and return.
2263 __ SmiTag(eax);
2264 __ bind(&smi);
2265 __ ret(2 * kPointerSize);
2266
2267 // Check if the argument is < 2^kMantissaBits.
2268 Label already_round;
2269 __ bind(&wont_fit_into_smi);
2270 __ LoadPowerOf2(xmm1, ebx, HeapNumber::kMantissaBits);
2271 __ ucomisd(xmm0, xmm1);
2272 __ j(above_equal, &already_round);
2273
2274 // Save a copy of the argument.
2275 __ movaps(xmm2, xmm0);
2276
2277 // Compute (argument + 2^kMantissaBits) - 2^kMantissaBits.
2278 __ addsd(xmm0, xmm1);
2279 __ subsd(xmm0, xmm1);
2280
2281 // Compare the argument and the tentative result to get the right mask:
2282 // if xmm2 < xmm0:
2283 // xmm2 = 1...1
2284 // else:
2285 // xmm2 = 0...0
2286 __ cmpltsd(xmm2, xmm0);
2287
2288 // Subtract 1 if the argument was less than the tentative result.
2289 __ LoadPowerOf2(xmm1, ebx, 0);
2290 __ andpd(xmm1, xmm2);
2291 __ subsd(xmm0, xmm1);
2292
2293 // Return a new heap number.
2294 __ AllocateHeapNumber(eax, ebx, edx, &slow);
2295 __ movsd(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
2296 __ ret(2 * kPointerSize);
2297
2298 // Return the argument (when it's an already round heap number).
2299 __ bind(&already_round);
2300 __ mov(eax, Operand(esp, 1 * kPointerSize));
2301 __ ret(2 * kPointerSize);
2302
2303 __ bind(&slow);
2304 // We do not have to patch the receiver because the function makes no use of
2305 // it.
2306 GenerateJumpFunctionIgnoreReceiver(function);
2307
2308 HandlerFrontendFooter(&miss);
2309
2310 // Return the generated code.
2311 return GetCode(type, name);
2312 }
2313
2314
2315 Handle<Code> CallStubCompiler::CompileMathAbsCall(
2316 Handle<Object> object,
2317 Handle<JSObject> holder,
2318 Handle<Cell> cell,
2319 Handle<JSFunction> function,
2320 Handle<String> name,
2321 Code::StubType type) {
2322 const int argc = arguments().immediate();
2323
2324 // If the object is not a JSObject or we got an unexpected number of
2325 // arguments, bail out to the regular call.
2326 if (!object->IsJSObject() || argc != 1) {
2327 return Handle<Code>::null();
2328 }
2329
2330 Label miss;
2331
2332 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2333 if (!cell.is_null()) {
2334 ASSERT(cell->value() == *function);
2335 GenerateLoadFunctionFromCell(cell, function, &miss);
2336 }
2337
2338 // Load the (only) argument into eax.
2339 __ mov(eax, Operand(esp, 1 * kPointerSize));
2340
2341 // Check if the argument is a smi.
2342 Label not_smi;
2343 STATIC_ASSERT(kSmiTag == 0);
2344 __ JumpIfNotSmi(eax, &not_smi);
2345
2346 // Branchless abs implementation, refer to below:
2347 // http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs
2348 // Set ebx to 1...1 (== -1) if the argument is negative, or to 0...0
2349 // otherwise.
2350 __ mov(ebx, eax);
2351 __ sar(ebx, kBitsPerInt - 1);
2352
2353 // Do bitwise not or do nothing depending on ebx.
2354 __ xor_(eax, ebx);
2355
2356 // Add 1 or do nothing depending on ebx.
2357 __ sub(eax, ebx);
2358
2359 // If the result is still negative, go to the slow case.
2360 // This only happens for the most negative smi.
2361 Label slow;
2362 __ j(negative, &slow);
2363
2364 // Smi case done.
2365 __ ret(2 * kPointerSize);
2366
2367 // Check if the argument is a heap number and load its exponent and
2368 // sign into ebx.
2369 __ bind(&not_smi);
2370 __ CheckMap(eax, factory()->heap_number_map(), &slow, DONT_DO_SMI_CHECK);
2371 __ mov(ebx, FieldOperand(eax, HeapNumber::kExponentOffset));
2372
2373 // Check the sign of the argument. If the argument is positive,
2374 // just return it.
2375 Label negative_sign;
2376 __ test(ebx, Immediate(HeapNumber::kSignMask));
2377 __ j(not_zero, &negative_sign);
2378 __ ret(2 * kPointerSize);
2379
2380 // If the argument is negative, clear the sign, and return a new
2381 // number.
2382 __ bind(&negative_sign);
2383 __ and_(ebx, ~HeapNumber::kSignMask);
2384 __ mov(ecx, FieldOperand(eax, HeapNumber::kMantissaOffset));
2385 __ AllocateHeapNumber(eax, edi, edx, &slow);
2386 __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), ebx);
2387 __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx);
2388 __ ret(2 * kPointerSize);
2389
2390 __ bind(&slow);
2391 // We do not have to patch the receiver because the function makes no use of
2392 // it.
2393 GenerateJumpFunctionIgnoreReceiver(function);
2394
2395 HandlerFrontendFooter(&miss);
2396
2397 // Return the generated code.
2398 return GetCode(type, name);
2399 }
2400
2401
2402 Handle<Code> CallStubCompiler::CompileFastApiCall( 1984 Handle<Code> CallStubCompiler::CompileFastApiCall(
2403 const CallOptimization& optimization, 1985 const CallOptimization& optimization,
2404 Handle<Object> object, 1986 Handle<Object> object,
2405 Handle<JSObject> holder, 1987 Handle<JSObject> holder,
2406 Handle<Cell> cell, 1988 Handle<Cell> cell,
2407 Handle<JSFunction> function, 1989 Handle<JSFunction> function,
2408 Handle<String> name) { 1990 Handle<String> name) {
2409 ASSERT(optimization.is_simple_api_call()); 1991 ASSERT(optimization.is_simple_api_call());
2410 // Bail out if object is a global object as we don't want to 1992 // Bail out if object is a global object as we don't want to
2411 // repatch it to global receiver. 1993 // repatch it to global receiver.
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
2806 } 2388 }
2807 2389
2808 2390
2809 Register* KeyedStoreStubCompiler::registers() { 2391 Register* KeyedStoreStubCompiler::registers() {
2810 // receiver, name, value, scratch1, scratch2, scratch3. 2392 // receiver, name, value, scratch1, scratch2, scratch3.
2811 static Register registers[] = { edx, ecx, eax, ebx, edi, no_reg }; 2393 static Register registers[] = { edx, ecx, eax, ebx, edi, no_reg };
2812 return registers; 2394 return registers;
2813 } 2395 }
2814 2396
2815 2397
2816 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name,
2817 Register name_reg,
2818 Label* miss) {
2819 __ cmp(name_reg, Immediate(name));
2820 __ j(not_equal, miss);
2821 }
2822
2823
2824 void KeyedStoreStubCompiler::GenerateNameCheck(Handle<Name> name,
2825 Register name_reg,
2826 Label* miss) {
2827 __ cmp(name_reg, Immediate(name));
2828 __ j(not_equal, miss);
2829 }
2830
2831
2832 #undef __ 2398 #undef __
2833 #define __ ACCESS_MASM(masm) 2399 #define __ ACCESS_MASM(masm)
2834 2400
2835 2401
2836 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, 2402 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm,
2837 Register receiver, 2403 Register receiver,
2838 Handle<JSFunction> getter) { 2404 Handle<JSFunction> getter) {
2839 { 2405 {
2840 FrameScope scope(masm, StackFrame::INTERNAL); 2406 FrameScope scope(masm, StackFrame::INTERNAL);
2841 2407
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2902 2468
2903 2469
2904 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC( 2470 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
2905 TypeHandleList* types, 2471 TypeHandleList* types,
2906 CodeHandleList* handlers, 2472 CodeHandleList* handlers,
2907 Handle<Name> name, 2473 Handle<Name> name,
2908 Code::StubType type, 2474 Code::StubType type,
2909 IcCheckType check) { 2475 IcCheckType check) {
2910 Label miss; 2476 Label miss;
2911 2477
2912 if (check == PROPERTY) { 2478 if (check == PROPERTY &&
2913 GenerateNameCheck(name, this->name(), &miss); 2479 (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) {
2480 __ cmp(this->name(), Immediate(name));
2481 __ j(not_equal, &miss);
2914 } 2482 }
2915 2483
2916 Label number_case; 2484 Label number_case;
2917 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; 2485 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
2918 __ JumpIfSmi(receiver(), smi_target); 2486 __ JumpIfSmi(receiver(), smi_target);
2919 2487
2920 Register map_reg = scratch1(); 2488 Register map_reg = scratch1();
2921 __ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset)); 2489 __ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset));
2922 int receiver_count = types->length(); 2490 int receiver_count = types->length();
2923 int number_of_handled_maps = 0; 2491 int number_of_handled_maps = 0;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
2992 // ----------------------------------- 2560 // -----------------------------------
2993 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 2561 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
2994 } 2562 }
2995 2563
2996 2564
2997 #undef __ 2565 #undef __
2998 2566
2999 } } // namespace v8::internal 2567 } } // namespace v8::internal
3000 2568
3001 #endif // V8_TARGET_ARCH_IA32 2569 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/lithium-ia32.cc ('k') | src/ic.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698