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...) 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...) 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 |