| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 |
| 6 | 6 |
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/base/division-by-constant.h" | 8 #include "src/base/division-by-constant.h" |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 2229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2240 } else { | 2240 } else { |
| 2241 DCHECK(SmiValuesAre31Bits()); | 2241 DCHECK(SmiValuesAre31Bits()); |
| 2242 testl(src, Immediate(source)); | 2242 testl(src, Immediate(source)); |
| 2243 } | 2243 } |
| 2244 } | 2244 } |
| 2245 | 2245 |
| 2246 | 2246 |
| 2247 // ---------------------------------------------------------------------------- | 2247 // ---------------------------------------------------------------------------- |
| 2248 | 2248 |
| 2249 | 2249 |
| 2250 void MacroAssembler::LookupNumberStringCache(Register object, | |
| 2251 Register result, | |
| 2252 Register scratch1, | |
| 2253 Register scratch2, | |
| 2254 Label* not_found) { | |
| 2255 // Use of registers. Register result is used as a temporary. | |
| 2256 Register number_string_cache = result; | |
| 2257 Register mask = scratch1; | |
| 2258 Register scratch = scratch2; | |
| 2259 | |
| 2260 // Load the number string cache. | |
| 2261 LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); | |
| 2262 | |
| 2263 // Make the hash mask from the length of the number string cache. It | |
| 2264 // contains two elements (number and string) for each cache entry. | |
| 2265 SmiToInteger32( | |
| 2266 mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset)); | |
| 2267 shrl(mask, Immediate(1)); | |
| 2268 subp(mask, Immediate(1)); // Make mask. | |
| 2269 | |
| 2270 // Calculate the entry in the number string cache. The hash value in the | |
| 2271 // number string cache for smis is just the smi value, and the hash for | |
| 2272 // doubles is the xor of the upper and lower words. See | |
| 2273 // Heap::GetNumberStringCache. | |
| 2274 Label is_smi; | |
| 2275 Label load_result_from_cache; | |
| 2276 JumpIfSmi(object, &is_smi); | |
| 2277 CheckMap(object, | |
| 2278 isolate()->factory()->heap_number_map(), | |
| 2279 not_found, | |
| 2280 DONT_DO_SMI_CHECK); | |
| 2281 | |
| 2282 STATIC_ASSERT(8 == kDoubleSize); | |
| 2283 movl(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4)); | |
| 2284 xorp(scratch, FieldOperand(object, HeapNumber::kValueOffset)); | |
| 2285 andp(scratch, mask); | |
| 2286 // Each entry in string cache consists of two pointer sized fields, | |
| 2287 // but times_twice_pointer_size (multiplication by 16) scale factor | |
| 2288 // is not supported by addrmode on x64 platform. | |
| 2289 // So we have to premultiply entry index before lookup. | |
| 2290 shlp(scratch, Immediate(kPointerSizeLog2 + 1)); | |
| 2291 | |
| 2292 Register index = scratch; | |
| 2293 Register probe = mask; | |
| 2294 movp(probe, | |
| 2295 FieldOperand(number_string_cache, | |
| 2296 index, | |
| 2297 times_1, | |
| 2298 FixedArray::kHeaderSize)); | |
| 2299 JumpIfSmi(probe, not_found); | |
| 2300 movsd(xmm0, FieldOperand(object, HeapNumber::kValueOffset)); | |
| 2301 ucomisd(xmm0, FieldOperand(probe, HeapNumber::kValueOffset)); | |
| 2302 j(parity_even, not_found); // Bail out if NaN is involved. | |
| 2303 j(not_equal, not_found); // The cache did not contain this value. | |
| 2304 jmp(&load_result_from_cache); | |
| 2305 | |
| 2306 bind(&is_smi); | |
| 2307 SmiToInteger32(scratch, object); | |
| 2308 andp(scratch, mask); | |
| 2309 // Each entry in string cache consists of two pointer sized fields, | |
| 2310 // but times_twice_pointer_size (multiplication by 16) scale factor | |
| 2311 // is not supported by addrmode on x64 platform. | |
| 2312 // So we have to premultiply entry index before lookup. | |
| 2313 shlp(scratch, Immediate(kPointerSizeLog2 + 1)); | |
| 2314 | |
| 2315 // Check if the entry is the smi we are looking for. | |
| 2316 cmpp(object, | |
| 2317 FieldOperand(number_string_cache, | |
| 2318 index, | |
| 2319 times_1, | |
| 2320 FixedArray::kHeaderSize)); | |
| 2321 j(not_equal, not_found); | |
| 2322 | |
| 2323 // Get the result from the cache. | |
| 2324 bind(&load_result_from_cache); | |
| 2325 movp(result, | |
| 2326 FieldOperand(number_string_cache, | |
| 2327 index, | |
| 2328 times_1, | |
| 2329 FixedArray::kHeaderSize + kPointerSize)); | |
| 2330 IncrementCounter(isolate()->counters()->number_to_string_native(), 1); | |
| 2331 } | |
| 2332 | |
| 2333 | |
| 2334 void MacroAssembler::JumpIfNotString(Register object, | 2250 void MacroAssembler::JumpIfNotString(Register object, |
| 2335 Register object_map, | 2251 Register object_map, |
| 2336 Label* not_string, | 2252 Label* not_string, |
| 2337 Label::Distance near_jump) { | 2253 Label::Distance near_jump) { |
| 2338 Condition is_smi = CheckSmi(object); | 2254 Condition is_smi = CheckSmi(object); |
| 2339 j(is_smi, not_string, near_jump); | 2255 j(is_smi, not_string, near_jump); |
| 2340 CmpObjectType(object, FIRST_NONSTRING_TYPE, object_map); | 2256 CmpObjectType(object, FIRST_NONSTRING_TYPE, object_map); |
| 2341 j(above_equal, not_string, near_jump); | 2257 j(above_equal, not_string, near_jump); |
| 2342 } | 2258 } |
| 2343 | 2259 |
| (...skipping 2723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5067 movl(rax, dividend); | 4983 movl(rax, dividend); |
| 5068 shrl(rax, Immediate(31)); | 4984 shrl(rax, Immediate(31)); |
| 5069 addl(rdx, rax); | 4985 addl(rdx, rax); |
| 5070 } | 4986 } |
| 5071 | 4987 |
| 5072 | 4988 |
| 5073 } // namespace internal | 4989 } // namespace internal |
| 5074 } // namespace v8 | 4990 } // namespace v8 |
| 5075 | 4991 |
| 5076 #endif // V8_TARGET_ARCH_X64 | 4992 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |