| Index: src/ia32/code-stubs-ia32.cc
|
| ===================================================================
|
| --- src/ia32/code-stubs-ia32.cc (revision 9686)
|
| +++ src/ia32/code-stubs-ia32.cc (working copy)
|
| @@ -3865,10 +3865,16 @@
|
| __ mov(number_string_cache,
|
| Operand::StaticArray(scratch, times_pointer_size, roots_address));
|
| // 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.
|
| __ mov(mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset));
|
| - __ shr(mask, kSmiTagSize + 1); // Untag length and divide it by two.
|
| - __ sub(mask, Immediate(1)); // Make mask.
|
| + __ lea(scratch, Operand(mask, mask, times_1, 0));
|
| + STATIC_ASSERT(Heap::kNSCSlotsPerEntry == 3);
|
| + __ and_(mask, scratch); // Multiply mask by 2/3, making it a power of 2.
|
| + // Make mask. It is 4 times the number of entries (2 times for Smi tag,
|
| + // 2 times for the size of the array * 2/3).
|
| + STATIC_ASSERT(kSmiTagSize == 1);
|
| + STATIC_ASSERT(kPointerSize == 4);
|
| + __ sub(mask, Immediate(kPointerSize - 1));
|
|
|
| // 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
|
| @@ -3877,14 +3883,16 @@
|
| Label smi_hash_calculated;
|
| Label load_result_from_cache;
|
| if (object_is_smi) {
|
| - __ mov(scratch, object);
|
| - __ SmiUntag(scratch);
|
| + STATIC_ASSERT(kPointerSizeLog2 - kSmiTagSize == 1);
|
| + STATIC_ASSERT(kSmiTag == 0);
|
| + __ lea(scratch, Operand(object, object, times_1, 0));
|
| } else {
|
| Label not_smi;
|
| STATIC_ASSERT(kSmiTag == 0);
|
| __ JumpIfNotSmi(object, ¬_smi, Label::kNear);
|
| - __ mov(scratch, object);
|
| - __ SmiUntag(scratch);
|
| + STATIC_ASSERT(kPointerSizeLog2 - kSmiTagSize == 1);
|
| + STATIC_ASSERT(kSmiTag == 0);
|
| + __ lea(scratch, Operand(object, object, times_1, 0));
|
| __ jmp(&smi_hash_calculated, Label::kNear);
|
| __ bind(¬_smi);
|
| __ cmp(FieldOperand(object, HeapObject::kMapOffset),
|
| @@ -3893,15 +3901,20 @@
|
| STATIC_ASSERT(8 == kDoubleSize);
|
| __ mov(scratch, FieldOperand(object, HeapNumber::kValueOffset));
|
| __ xor_(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4));
|
| - // Object is heap number and hash is now in scratch. Calculate cache index.
|
| + // Object is heap number and hash is now in scratch. Scale hash to pointer
|
| + // size and apply the mask.
|
| + __ shl(scratch, kPointerSizeLog2);
|
| __ and_(scratch, mask);
|
| + // Multiply by 3.
|
| + STATIC_ASSERT(Heap::kNSCSlotsPerEntry == 3);
|
| + __ lea(scratch, Operand(scratch, scratch, times_2, 0));
|
| Register index = scratch;
|
| Register probe = mask;
|
| - __ mov(probe,
|
| - FieldOperand(number_string_cache,
|
| - index,
|
| - times_twice_pointer_size,
|
| - FixedArray::kHeaderSize));
|
| + __ mov(probe, FieldOperand(
|
| + number_string_cache,
|
| + index,
|
| + times_1,
|
| + FixedArray::kHeaderSize + kPointerSizeLog2 * Heap::kNSCNumberOffset));
|
| __ JumpIfSmi(probe, not_found);
|
| if (CpuFeatures::IsSupported(SSE2)) {
|
| CpuFeatures::Scope fscope(SSE2);
|
| @@ -3921,22 +3934,28 @@
|
| __ bind(&smi_hash_calculated);
|
| // Object is smi and hash is now in scratch. Calculate cache index.
|
| __ and_(scratch, mask);
|
| + // Multiply by 3.
|
| Register index = scratch;
|
| + __ lea(index, Operand(scratch, scratch, times_2, 0));
|
| // Check if the entry is the smi we are looking for.
|
| - __ cmp(object,
|
| - FieldOperand(number_string_cache,
|
| - index,
|
| - times_twice_pointer_size,
|
| - FixedArray::kHeaderSize));
|
| + __ cmp(object, FieldOperand(
|
| + number_string_cache,
|
| + index,
|
| + times_1,
|
| + FixedArray::kHeaderSize + kPointerSizeLog2 * Heap::kNSCNumberOffset));
|
| __ j(not_equal, not_found);
|
|
|
| // Get the result from the cache.
|
| __ bind(&load_result_from_cache);
|
| + int kAgeOffset = FixedArray::kHeaderSize + kPointerSize * Heap::kNSCAgeOffset;
|
| + __ mov(FieldOperand(number_string_cache, index, times_1, kAgeOffset),
|
| + Immediate(Smi::FromInt(Heap::kNSCMinAge))); // Reset age field.
|
| __ mov(result,
|
| - FieldOperand(number_string_cache,
|
| - index,
|
| - times_twice_pointer_size,
|
| - FixedArray::kHeaderSize + kPointerSize));
|
| + FieldOperand(
|
| + number_string_cache,
|
| + index,
|
| + times_1,
|
| + FixedArray::kHeaderSize + kPointerSize * Heap::kNSCStringOffset));
|
| Counters* counters = masm->isolate()->counters();
|
| __ IncrementCounter(counters->number_to_string_native(), 1);
|
| }
|
|
|