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 2246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2257 | 2257 |
2258 | 2258 |
2259 void MacroAssembler::Test(const Operand& src, Smi* source) { | 2259 void MacroAssembler::Test(const Operand& src, Smi* source) { |
2260 testl(Operand(src, kIntSize), Immediate(source->value())); | 2260 testl(Operand(src, kIntSize), Immediate(source->value())); |
2261 } | 2261 } |
2262 | 2262 |
2263 | 2263 |
2264 // ---------------------------------------------------------------------------- | 2264 // ---------------------------------------------------------------------------- |
2265 | 2265 |
2266 | 2266 |
| 2267 void MacroAssembler::LookupNumberStringCache(Register object, |
| 2268 Register result, |
| 2269 Register scratch1, |
| 2270 Register scratch2, |
| 2271 Label* not_found) { |
| 2272 // Use of registers. Register result is used as a temporary. |
| 2273 Register number_string_cache = result; |
| 2274 Register mask = scratch1; |
| 2275 Register scratch = scratch2; |
| 2276 |
| 2277 // Load the number string cache. |
| 2278 LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); |
| 2279 |
| 2280 // Make the hash mask from the length of the number string cache. It |
| 2281 // contains two elements (number and string) for each cache entry. |
| 2282 SmiToInteger32( |
| 2283 mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset)); |
| 2284 shrl(mask, Immediate(1)); |
| 2285 subq(mask, Immediate(1)); // Make mask. |
| 2286 |
| 2287 // Calculate the entry in the number string cache. The hash value in the |
| 2288 // number string cache for smis is just the smi value, and the hash for |
| 2289 // doubles is the xor of the upper and lower words. See |
| 2290 // Heap::GetNumberStringCache. |
| 2291 Label is_smi; |
| 2292 Label load_result_from_cache; |
| 2293 JumpIfSmi(object, &is_smi); |
| 2294 CheckMap(object, |
| 2295 isolate()->factory()->heap_number_map(), |
| 2296 not_found, |
| 2297 DONT_DO_SMI_CHECK); |
| 2298 |
| 2299 STATIC_ASSERT(8 == kDoubleSize); |
| 2300 movl(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4)); |
| 2301 xor_(scratch, FieldOperand(object, HeapNumber::kValueOffset)); |
| 2302 and_(scratch, mask); |
| 2303 // Each entry in string cache consists of two pointer sized fields, |
| 2304 // but times_twice_pointer_size (multiplication by 16) scale factor |
| 2305 // is not supported by addrmode on x64 platform. |
| 2306 // So we have to premultiply entry index before lookup. |
| 2307 shl(scratch, Immediate(kPointerSizeLog2 + 1)); |
| 2308 |
| 2309 Register index = scratch; |
| 2310 Register probe = mask; |
| 2311 movq(probe, |
| 2312 FieldOperand(number_string_cache, |
| 2313 index, |
| 2314 times_1, |
| 2315 FixedArray::kHeaderSize)); |
| 2316 JumpIfSmi(probe, not_found); |
| 2317 movsd(xmm0, FieldOperand(object, HeapNumber::kValueOffset)); |
| 2318 ucomisd(xmm0, FieldOperand(probe, HeapNumber::kValueOffset)); |
| 2319 j(parity_even, not_found); // Bail out if NaN is involved. |
| 2320 j(not_equal, not_found); // The cache did not contain this value. |
| 2321 jmp(&load_result_from_cache); |
| 2322 |
| 2323 bind(&is_smi); |
| 2324 SmiToInteger32(scratch, object); |
| 2325 and_(scratch, mask); |
| 2326 // Each entry in string cache consists of two pointer sized fields, |
| 2327 // but times_twice_pointer_size (multiplication by 16) scale factor |
| 2328 // is not supported by addrmode on x64 platform. |
| 2329 // So we have to premultiply entry index before lookup. |
| 2330 shl(scratch, Immediate(kPointerSizeLog2 + 1)); |
| 2331 |
| 2332 // Check if the entry is the smi we are looking for. |
| 2333 cmpq(object, |
| 2334 FieldOperand(number_string_cache, |
| 2335 index, |
| 2336 times_1, |
| 2337 FixedArray::kHeaderSize)); |
| 2338 j(not_equal, not_found); |
| 2339 |
| 2340 // Get the result from the cache. |
| 2341 bind(&load_result_from_cache); |
| 2342 movq(result, |
| 2343 FieldOperand(number_string_cache, |
| 2344 index, |
| 2345 times_1, |
| 2346 FixedArray::kHeaderSize + kPointerSize)); |
| 2347 IncrementCounter(isolate()->counters()->number_to_string_native(), 1); |
| 2348 } |
| 2349 |
| 2350 |
2267 void MacroAssembler::JumpIfNotString(Register object, | 2351 void MacroAssembler::JumpIfNotString(Register object, |
2268 Register object_map, | 2352 Register object_map, |
2269 Label* not_string, | 2353 Label* not_string, |
2270 Label::Distance near_jump) { | 2354 Label::Distance near_jump) { |
2271 Condition is_smi = CheckSmi(object); | 2355 Condition is_smi = CheckSmi(object); |
2272 j(is_smi, not_string, near_jump); | 2356 j(is_smi, not_string, near_jump); |
2273 CmpObjectType(object, FIRST_NONSTRING_TYPE, object_map); | 2357 CmpObjectType(object, FIRST_NONSTRING_TYPE, object_map); |
2274 j(above_equal, not_string, near_jump); | 2358 j(above_equal, not_string, near_jump); |
2275 } | 2359 } |
2276 | 2360 |
(...skipping 2556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4833 j(greater, &no_memento_available); | 4917 j(greater, &no_memento_available); |
4834 CompareRoot(MemOperand(scratch_reg, -AllocationMemento::kSize), | 4918 CompareRoot(MemOperand(scratch_reg, -AllocationMemento::kSize), |
4835 Heap::kAllocationMementoMapRootIndex); | 4919 Heap::kAllocationMementoMapRootIndex); |
4836 bind(&no_memento_available); | 4920 bind(&no_memento_available); |
4837 } | 4921 } |
4838 | 4922 |
4839 | 4923 |
4840 } } // namespace v8::internal | 4924 } } // namespace v8::internal |
4841 | 4925 |
4842 #endif // V8_TARGET_ARCH_X64 | 4926 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |