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

Side by Side Diff: src/arm/stub-cache-arm.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/arm/lithium-codegen-arm.cc ('k') | src/ast.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 1553 matching lines...) Expand 10 before | Expand all | Expand 10 after
1564 index.translate(holder), Representation::Tagged()); 1564 index.translate(holder), Representation::Tagged());
1565 GenerateJumpFunction(object, r1, &miss); 1565 GenerateJumpFunction(object, r1, &miss);
1566 1566
1567 HandlerFrontendFooter(&miss); 1567 HandlerFrontendFooter(&miss);
1568 1568
1569 // Return the generated code. 1569 // Return the generated code.
1570 return GetCode(Code::FAST, name); 1570 return GetCode(Code::FAST, name);
1571 } 1571 }
1572 1572
1573 1573
1574 Handle<Code> CallStubCompiler::CompileArrayCodeCall(
1575 Handle<Object> object,
1576 Handle<JSObject> holder,
1577 Handle<Cell> cell,
1578 Handle<JSFunction> function,
1579 Handle<String> name,
1580 Code::StubType type) {
1581 Label miss;
1582
1583 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1584 if (!cell.is_null()) {
1585 ASSERT(cell->value() == *function);
1586 GenerateLoadFunctionFromCell(cell, function, &miss);
1587 }
1588
1589 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite();
1590 site->SetElementsKind(GetInitialFastElementsKind());
1591 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site);
1592 const int argc = arguments().immediate();
1593 __ mov(r0, Operand(argc));
1594 __ mov(r2, Operand(site_feedback_cell));
1595 __ mov(r1, Operand(function));
1596
1597 ArrayConstructorStub stub(isolate());
1598 __ TailCallStub(&stub);
1599
1600 HandlerFrontendFooter(&miss);
1601
1602 // Return the generated code.
1603 return GetCode(type, name);
1604 }
1605
1606
1607 Handle<Code> CallStubCompiler::CompileArrayPushCall( 1574 Handle<Code> CallStubCompiler::CompileArrayPushCall(
1608 Handle<Object> object, 1575 Handle<Object> object,
1609 Handle<JSObject> holder, 1576 Handle<JSObject> holder,
1610 Handle<Cell> cell, 1577 Handle<Cell> cell,
1611 Handle<JSFunction> function, 1578 Handle<JSFunction> function,
1612 Handle<String> name, 1579 Handle<String> name,
1613 Code::StubType type) { 1580 Code::StubType type) {
1614 // If object is not an array or is observed or sealed, bail out to regular 1581 // If object is not an array or is observed or sealed, bail out to regular
1615 // call. 1582 // call.
1616 if (!object->IsJSArray() || 1583 if (!object->IsJSArray() ||
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
1915 __ TailCallExternalReference( 1882 __ TailCallExternalReference(
1916 ExternalReference(Builtins::c_ArrayPop, isolate()), argc + 1, 1); 1883 ExternalReference(Builtins::c_ArrayPop, isolate()), argc + 1, 1);
1917 1884
1918 HandlerFrontendFooter(&miss); 1885 HandlerFrontendFooter(&miss);
1919 1886
1920 // Return the generated code. 1887 // Return the generated code.
1921 return GetCode(type, name); 1888 return GetCode(type, name);
1922 } 1889 }
1923 1890
1924 1891
1925 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
1926 Handle<Object> object,
1927 Handle<JSObject> holder,
1928 Handle<Cell> cell,
1929 Handle<JSFunction> function,
1930 Handle<String> name,
1931 Code::StubType type) {
1932 // If object is not a string, bail out to regular call.
1933 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
1934
1935 Label miss;
1936 Label name_miss;
1937 Label index_out_of_range;
1938 Label* index_out_of_range_label = &index_out_of_range;
1939
1940 if (kind_ == Code::CALL_IC &&
1941 (CallICBase::StringStubState::decode(extra_state()) ==
1942 DEFAULT_STRING_STUB)) {
1943 index_out_of_range_label = &miss;
1944 }
1945
1946 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss);
1947
1948 Register receiver = r0;
1949 Register index = r4;
1950 Register result = r1;
1951 const int argc = arguments().immediate();
1952 __ ldr(receiver, MemOperand(sp, argc * kPointerSize));
1953 if (argc > 0) {
1954 __ ldr(index, MemOperand(sp, (argc - 1) * kPointerSize));
1955 } else {
1956 __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
1957 }
1958
1959 StringCharCodeAtGenerator generator(receiver,
1960 index,
1961 result,
1962 &miss, // When not a string.
1963 &miss, // When not a number.
1964 index_out_of_range_label,
1965 STRING_INDEX_IS_NUMBER);
1966 generator.GenerateFast(masm());
1967 __ Drop(argc + 1);
1968 __ mov(r0, result);
1969 __ Ret();
1970
1971 StubRuntimeCallHelper call_helper;
1972 generator.GenerateSlow(masm(), call_helper);
1973
1974 if (index_out_of_range.is_linked()) {
1975 __ bind(&index_out_of_range);
1976 __ LoadRoot(r0, Heap::kNanValueRootIndex);
1977 __ Drop(argc + 1);
1978 __ Ret();
1979 }
1980
1981 __ bind(&miss);
1982 // Restore function name in r2.
1983 __ Move(r2, name);
1984 HandlerFrontendFooter(&name_miss);
1985
1986 // Return the generated code.
1987 return GetCode(type, name);
1988 }
1989
1990
1991 Handle<Code> CallStubCompiler::CompileStringCharAtCall(
1992 Handle<Object> object,
1993 Handle<JSObject> holder,
1994 Handle<Cell> cell,
1995 Handle<JSFunction> function,
1996 Handle<String> name,
1997 Code::StubType type) {
1998 // If object is not a string, bail out to regular call.
1999 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
2000
2001 const int argc = arguments().immediate();
2002 Label miss;
2003 Label name_miss;
2004 Label index_out_of_range;
2005 Label* index_out_of_range_label = &index_out_of_range;
2006 if (kind_ == Code::CALL_IC &&
2007 (CallICBase::StringStubState::decode(extra_state()) ==
2008 DEFAULT_STRING_STUB)) {
2009 index_out_of_range_label = &miss;
2010 }
2011
2012 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss);
2013
2014 Register receiver = r0;
2015 Register index = r4;
2016 Register scratch = r3;
2017 Register result = r1;
2018 if (argc > 0) {
2019 __ ldr(index, MemOperand(sp, (argc - 1) * kPointerSize));
2020 } else {
2021 __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
2022 }
2023
2024 StringCharAtGenerator generator(receiver,
2025 index,
2026 scratch,
2027 result,
2028 &miss, // When not a string.
2029 &miss, // When not a number.
2030 index_out_of_range_label,
2031 STRING_INDEX_IS_NUMBER);
2032 generator.GenerateFast(masm());
2033 __ Drop(argc + 1);
2034 __ mov(r0, result);
2035 __ Ret();
2036
2037 StubRuntimeCallHelper call_helper;
2038 generator.GenerateSlow(masm(), call_helper);
2039
2040 if (index_out_of_range.is_linked()) {
2041 __ bind(&index_out_of_range);
2042 __ LoadRoot(r0, Heap::kempty_stringRootIndex);
2043 __ Drop(argc + 1);
2044 __ Ret();
2045 }
2046
2047 __ bind(&miss);
2048 // Restore function name in r2.
2049 __ Move(r2, name);
2050 HandlerFrontendFooter(&name_miss);
2051
2052 // Return the generated code.
2053 return GetCode(type, name);
2054 }
2055
2056
2057 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
2058 Handle<Object> object,
2059 Handle<JSObject> holder,
2060 Handle<Cell> cell,
2061 Handle<JSFunction> function,
2062 Handle<String> name,
2063 Code::StubType type) {
2064 const int argc = arguments().immediate();
2065
2066 // If the object is not a JSObject or we got an unexpected number of
2067 // arguments, bail out to the regular call.
2068 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2069
2070 Label miss;
2071
2072 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2073 if (!cell.is_null()) {
2074 ASSERT(cell->value() == *function);
2075 GenerateLoadFunctionFromCell(cell, function, &miss);
2076 }
2077
2078 // Load the char code argument.
2079 Register code = r1;
2080 __ ldr(code, MemOperand(sp, 0 * kPointerSize));
2081
2082 // Check the code is a smi.
2083 Label slow;
2084 __ JumpIfNotSmi(code, &slow);
2085
2086 // Convert the smi code to uint16.
2087 __ and_(code, code, Operand(Smi::FromInt(0xffff)));
2088
2089 StringCharFromCodeGenerator generator(code, r0);
2090 generator.GenerateFast(masm());
2091 __ Drop(argc + 1);
2092 __ Ret();
2093
2094 StubRuntimeCallHelper call_helper;
2095 generator.GenerateSlow(masm(), call_helper);
2096
2097 __ bind(&slow);
2098 // We do not have to patch the receiver because the function makes no use of
2099 // it.
2100 GenerateJumpFunctionIgnoreReceiver(function);
2101
2102 HandlerFrontendFooter(&miss);
2103
2104 // Return the generated code.
2105 return GetCode(type, name);
2106 }
2107
2108
2109 Handle<Code> CallStubCompiler::CompileMathFloorCall(
2110 Handle<Object> object,
2111 Handle<JSObject> holder,
2112 Handle<Cell> cell,
2113 Handle<JSFunction> function,
2114 Handle<String> name,
2115 Code::StubType type) {
2116 const int argc = arguments().immediate();
2117 // If the object is not a JSObject or we got an unexpected number of
2118 // arguments, bail out to the regular call.
2119 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2120
2121 Label miss, slow;
2122
2123 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2124 if (!cell.is_null()) {
2125 ASSERT(cell->value() == *function);
2126 GenerateLoadFunctionFromCell(cell, function, &miss);
2127 }
2128
2129 // Load the (only) argument into r0.
2130 __ ldr(r0, MemOperand(sp, 0 * kPointerSize));
2131
2132 // If the argument is a smi, just return.
2133 __ SmiTst(r0);
2134 __ Drop(argc + 1, eq);
2135 __ Ret(eq);
2136
2137 __ CheckMap(r0, r1, Heap::kHeapNumberMapRootIndex, &slow, DONT_DO_SMI_CHECK);
2138
2139 Label smi_check, just_return;
2140
2141 // Load the HeapNumber value.
2142 // We will need access to the value in the core registers, so we load it
2143 // with ldrd and move it to the fpu. It also spares a sub instruction for
2144 // updating the HeapNumber value address, as vldr expects a multiple
2145 // of 4 offset.
2146 __ Ldrd(r4, r5, FieldMemOperand(r0, HeapNumber::kValueOffset));
2147 __ vmov(d1, r4, r5);
2148
2149 // Check for NaN, Infinities and -0.
2150 // They are invariant through a Math.Floor call, so just
2151 // return the original argument.
2152 __ Sbfx(r3, r5, HeapNumber::kExponentShift, HeapNumber::kExponentBits);
2153 __ cmp(r3, Operand(-1));
2154 __ b(eq, &just_return);
2155 __ eor(r3, r5, Operand(0x80000000u));
2156 __ orr(r3, r3, r4, SetCC);
2157 __ b(eq, &just_return);
2158 // Test for values that can be exactly represented as a
2159 // signed 32-bit integer.
2160 __ TryDoubleToInt32Exact(r0, d1, d2);
2161 // If exact, check smi
2162 __ b(eq, &smi_check);
2163 __ cmp(r5, Operand(0));
2164
2165 // If input is in ]+0, +inf[, the cmp has cleared overflow and negative
2166 // (V=0 and N=0), the two following instructions won't execute and
2167 // we fall through smi_check to check if the result can fit into a smi.
2168
2169 // If input is in ]-inf, -0[, sub one and, go to slow if we have
2170 // an overflow. Else we fall through smi check.
2171 // Hint: if x is a negative, non integer number,
2172 // floor(x) <=> round_to_zero(x) - 1.
2173 __ sub(r0, r0, Operand(1), SetCC, mi);
2174 __ b(vs, &slow);
2175
2176 __ bind(&smi_check);
2177 // Check if the result can fit into an smi. If we had an overflow,
2178 // the result is either 0x80000000 or 0x7FFFFFFF and won't fit into an smi.
2179 // If result doesn't fit into an smi, branch to slow.
2180 __ SmiTag(r0, SetCC);
2181 __ b(vs, &slow);
2182
2183 __ bind(&just_return);
2184 __ Drop(argc + 1);
2185 __ Ret();
2186
2187 __ bind(&slow);
2188 // We do not have to patch the receiver because the function makes no use of
2189 // it.
2190 GenerateJumpFunctionIgnoreReceiver(function);
2191
2192 HandlerFrontendFooter(&miss);
2193
2194 // Return the generated code.
2195 return GetCode(type, name);
2196 }
2197
2198
2199 Handle<Code> CallStubCompiler::CompileMathAbsCall(
2200 Handle<Object> object,
2201 Handle<JSObject> holder,
2202 Handle<Cell> cell,
2203 Handle<JSFunction> function,
2204 Handle<String> name,
2205 Code::StubType type) {
2206 const int argc = arguments().immediate();
2207 // If the object is not a JSObject or we got an unexpected number of
2208 // arguments, bail out to the regular call.
2209 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2210
2211 Label miss;
2212
2213 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2214 if (!cell.is_null()) {
2215 ASSERT(cell->value() == *function);
2216 GenerateLoadFunctionFromCell(cell, function, &miss);
2217 }
2218
2219 // Load the (only) argument into r0.
2220 __ ldr(r0, MemOperand(sp, 0 * kPointerSize));
2221
2222 // Check if the argument is a smi.
2223 Label not_smi;
2224 __ JumpIfNotSmi(r0, &not_smi);
2225
2226 // Do bitwise not or do nothing depending on the sign of the
2227 // argument.
2228 __ eor(r1, r0, Operand(r0, ASR, kBitsPerInt - 1));
2229
2230 // Add 1 or do nothing depending on the sign of the argument.
2231 __ sub(r0, r1, Operand(r0, ASR, kBitsPerInt - 1), SetCC);
2232
2233 // If the result is still negative, go to the slow case.
2234 // This only happens for the most negative smi.
2235 Label slow;
2236 __ b(mi, &slow);
2237
2238 // Smi case done.
2239 __ Drop(argc + 1);
2240 __ Ret();
2241
2242 // Check if the argument is a heap number and load its exponent and
2243 // sign.
2244 __ bind(&not_smi);
2245 __ CheckMap(r0, r1, Heap::kHeapNumberMapRootIndex, &slow, DONT_DO_SMI_CHECK);
2246 __ ldr(r1, FieldMemOperand(r0, HeapNumber::kExponentOffset));
2247
2248 // Check the sign of the argument. If the argument is positive,
2249 // just return it.
2250 Label negative_sign;
2251 __ tst(r1, Operand(HeapNumber::kSignMask));
2252 __ b(ne, &negative_sign);
2253 __ Drop(argc + 1);
2254 __ Ret();
2255
2256 // If the argument is negative, clear the sign, and return a new
2257 // number.
2258 __ bind(&negative_sign);
2259 __ eor(r1, r1, Operand(HeapNumber::kSignMask));
2260 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset));
2261 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
2262 __ AllocateHeapNumber(r0, r4, r5, r6, &slow);
2263 __ str(r1, FieldMemOperand(r0, HeapNumber::kExponentOffset));
2264 __ str(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset));
2265 __ Drop(argc + 1);
2266 __ Ret();
2267
2268 __ bind(&slow);
2269 // We do not have to patch the receiver because the function makes no use of
2270 // it.
2271 GenerateJumpFunctionIgnoreReceiver(function);
2272
2273 HandlerFrontendFooter(&miss);
2274
2275 // Return the generated code.
2276 return GetCode(type, name);
2277 }
2278
2279
2280 Handle<Code> CallStubCompiler::CompileFastApiCall( 1892 Handle<Code> CallStubCompiler::CompileFastApiCall(
2281 const CallOptimization& optimization, 1893 const CallOptimization& optimization,
2282 Handle<Object> object, 1894 Handle<Object> object,
2283 Handle<JSObject> holder, 1895 Handle<JSObject> holder,
2284 Handle<Cell> cell, 1896 Handle<Cell> cell,
2285 Handle<JSFunction> function, 1897 Handle<JSFunction> function,
2286 Handle<String> name) { 1898 Handle<String> name) {
2287 Counters* counters = isolate()->counters(); 1899 Counters* counters = isolate()->counters();
2288 1900
2289 ASSERT(optimization.is_simple_api_call()); 1901 ASSERT(optimization.is_simple_api_call());
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
2673 } 2285 }
2674 2286
2675 2287
2676 Register* KeyedStoreStubCompiler::registers() { 2288 Register* KeyedStoreStubCompiler::registers() {
2677 // receiver, name, value, scratch1, scratch2, scratch3. 2289 // receiver, name, value, scratch1, scratch2, scratch3.
2678 static Register registers[] = { r2, r1, r0, r3, r4, r5 }; 2290 static Register registers[] = { r2, r1, r0, r3, r4, r5 };
2679 return registers; 2291 return registers;
2680 } 2292 }
2681 2293
2682 2294
2683 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name,
2684 Register name_reg,
2685 Label* miss) {
2686 __ cmp(name_reg, Operand(name));
2687 __ b(ne, miss);
2688 }
2689
2690
2691 void KeyedStoreStubCompiler::GenerateNameCheck(Handle<Name> name,
2692 Register name_reg,
2693 Label* miss) {
2694 __ cmp(name_reg, Operand(name));
2695 __ b(ne, miss);
2696 }
2697
2698
2699 #undef __ 2295 #undef __
2700 #define __ ACCESS_MASM(masm) 2296 #define __ ACCESS_MASM(masm)
2701 2297
2702 2298
2703 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, 2299 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm,
2704 Register receiver, 2300 Register receiver,
2705 Handle<JSFunction> getter) { 2301 Handle<JSFunction> getter) {
2706 // ----------- S t a t e ------------- 2302 // ----------- S t a t e -------------
2707 // -- r0 : receiver 2303 // -- r0 : receiver
2708 // -- r2 : name 2304 // -- r2 : name
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2769 2365
2770 2366
2771 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC( 2367 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
2772 TypeHandleList* types, 2368 TypeHandleList* types,
2773 CodeHandleList* handlers, 2369 CodeHandleList* handlers,
2774 Handle<Name> name, 2370 Handle<Name> name,
2775 Code::StubType type, 2371 Code::StubType type,
2776 IcCheckType check) { 2372 IcCheckType check) {
2777 Label miss; 2373 Label miss;
2778 2374
2779 if (check == PROPERTY) { 2375 if (check == PROPERTY &&
2780 GenerateNameCheck(name, this->name(), &miss); 2376 (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) {
2377 __ cmp(this->name(), Operand(name));
2378 __ b(ne, &miss);
2781 } 2379 }
2782 2380
2783 Label number_case; 2381 Label number_case;
2784 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; 2382 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
2785 __ JumpIfSmi(receiver(), smi_target); 2383 __ JumpIfSmi(receiver(), smi_target);
2786 2384
2787 Register map_reg = scratch1(); 2385 Register map_reg = scratch1();
2788 2386
2789 int receiver_count = types->length(); 2387 int receiver_count = types->length();
2790 int number_of_handled_maps = 0; 2388 int number_of_handled_maps = 0;
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2890 // ----------------------------------- 2488 // -----------------------------------
2891 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 2489 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
2892 } 2490 }
2893 2491
2894 2492
2895 #undef __ 2493 #undef __
2896 2494
2897 } } // namespace v8::internal 2495 } } // namespace v8::internal
2898 2496
2899 #endif // V8_TARGET_ARCH_ARM 2497 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.cc ('k') | src/ast.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698