| Index: src/x64/code-stubs-x64.cc
|
| ===================================================================
|
| --- src/x64/code-stubs-x64.cc (revision 9686)
|
| +++ src/x64/code-stubs-x64.cc (working copy)
|
| @@ -2930,12 +2930,16 @@
|
| __ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex);
|
|
|
| // Make the hash mask from the length of the number string cache. It
|
| - // contains two elements (number and string) for each cache entry.
|
| + // contains three elements (number, string and age) for each cache entry.
|
| __ SmiToInteger32(
|
| - mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset));
|
| - __ shrl(mask, Immediate(1));
|
| - __ subq(mask, Immediate(1)); // Make mask.
|
| + scratch, FieldOperand(number_string_cache, FixedArray::kLengthOffset));
|
|
|
| + STATIC_ASSERT(Heap::kNSCSlotsPerEntry == 3);
|
| + // mask = scratch / 3 - 1, making it one less than a power of 2.
|
| + __ lea(mask, Operand(scratch, -1));
|
| + __ and_(scratch, mask);
|
| + __ xor_(mask, scratch);
|
| +
|
| // Calculate the entry in the number string cache. The hash value in the
|
| // number string cache for smis is just the smi value, and the hash for
|
| // doubles is the xor of the upper and lower words. See
|
| @@ -2957,11 +2961,11 @@
|
|
|
| Register index = scratch;
|
| Register probe = mask;
|
| - __ movq(probe,
|
| - FieldOperand(number_string_cache,
|
| - index,
|
| - times_1,
|
| - FixedArray::kHeaderSize));
|
| + __ movq(probe, FieldOperand(
|
| + number_string_cache,
|
| + index,
|
| + times_pointer_size,
|
| + FixedArray::kHeaderSize + kPointerSize * Heap::kNSCNumberOffset));
|
| __ JumpIfSmi(probe, not_found);
|
| __ movsd(xmm0, FieldOperand(object, HeapNumber::kValueOffset));
|
| __ movsd(xmm1, FieldOperand(probe, HeapNumber::kValueOffset));
|
| @@ -2977,20 +2981,26 @@
|
|
|
| Register index = scratch;
|
| // Check if the entry is the smi we are looking for.
|
| - __ cmpq(object,
|
| - FieldOperand(number_string_cache,
|
| - index,
|
| - times_1,
|
| - FixedArray::kHeaderSize));
|
| + __ cmpq(object, FieldOperand(
|
| + number_string_cache,
|
| + index,
|
| + times_pointer_size,
|
| + FixedArray::kHeaderSize + kPointerSize * Heap::kNSCNumberOffset));
|
| __ j(not_equal, not_found);
|
|
|
| // Get the result from the cache.
|
| __ bind(&load_result_from_cache);
|
| - __ movq(result,
|
| - FieldOperand(number_string_cache,
|
| + int kAgeOffset = FixedArray::kHeaderSize + kPointerSize * Heap::kNSCAgeOffset;
|
| + __ Move(FieldOperand(number_string_cache,
|
| index,
|
| - times_1,
|
| - FixedArray::kHeaderSize + kPointerSize));
|
| + times_pointer_size,
|
| + kAgeOffset),
|
| + Smi::FromInt(Heap::kNSCMinAge)); // Reset age field.
|
| + __ movq(result, FieldOperand(
|
| + number_string_cache,
|
| + index,
|
| + times_pointer_size,
|
| + FixedArray::kHeaderSize + kPointerSize * Heap::kNSCStringOffset));
|
| Counters* counters = masm->isolate()->counters();
|
| __ IncrementCounter(counters->number_to_string_native(), 1);
|
| }
|
| @@ -3000,11 +3010,9 @@
|
| Register hash,
|
| Register mask) {
|
| __ and_(hash, mask);
|
| - // Each entry in string cache consists of two pointer sized fields,
|
| - // but times_twice_pointer_size (multiplication by 16) scale factor
|
| - // is not supported by addrmode on x64 platform.
|
| - // So we have to premultiply entry index before lookup.
|
| - __ shl(hash, Immediate(kPointerSizeLog2 + 1));
|
| + // Each entry in string cache consists of three pointer sized fields,
|
| + // so we multiply by 3 and we will use times_pointer_size scaling.
|
| + __ lea(hash, Operand(hash, hash, times_2, 0));
|
| }
|
|
|
|
|
|
|