| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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, ¬_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(¬_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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |