Index: src/arm/codegen-arm.cc |
=================================================================== |
--- src/arm/codegen-arm.cc (revision 4474) |
+++ src/arm/codegen-arm.cc (working copy) |
@@ -6101,20 +6101,12 @@ |
Register result, |
Register scratch1, |
Register scratch2, |
+ Register scratch3, |
bool object_is_smi, |
Label* not_found) { |
- // Currently only lookup for smis. Check for smi if object is not known to be |
- // a smi. |
- if (!object_is_smi) { |
- ASSERT(kSmiTag == 0); |
- __ tst(object, Operand(kSmiTagMask)); |
- __ b(ne, not_found); |
- } |
- |
// Use of registers. Register result is used as a temporary. |
Register number_string_cache = result; |
- Register mask = scratch1; |
- Register scratch = scratch2; |
+ Register mask = scratch3; |
// Load the number string cache. |
__ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); |
@@ -6127,9 +6119,54 @@ |
__ sub(mask, mask, Operand(1)); // Make mask. |
// Calculate the entry in the number string cache. The hash value in the |
- // number string cache for smis is just the smi value. |
+ // 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 |
+ // Heap::GetNumberStringCache. |
+ Label is_smi; |
+ Label load_result_from_cache; |
+ if (!object_is_smi) { |
+ __ BranchOnSmi(object, &is_smi); |
+ if (CpuFeatures::IsSupported(VFP3)) { |
+ CpuFeatures::Scope scope(VFP3); |
+ __ CheckMap(object, |
+ scratch1, |
+ Factory::heap_number_map(), |
+ not_found, |
+ true); |
+ |
+ ASSERT_EQ(8, kDoubleSize); |
+ __ add(scratch1, |
+ object, |
+ Operand(HeapNumber::kValueOffset - kHeapObjectTag)); |
+ __ ldm(ia, scratch1, scratch1.bit() | scratch2.bit()); |
+ __ eor(scratch1, scratch1, Operand(scratch2)); |
+ __ and_(scratch1, scratch1, Operand(mask)); |
+ |
+ // Calculate address of entry in string cache: each entry consists |
+ // of two pointer sized fields. |
+ __ add(scratch1, |
+ number_string_cache, |
+ Operand(scratch1, LSL, kPointerSizeLog2 + 1)); |
+ |
+ Register probe = mask; |
+ __ ldr(probe, |
+ FieldMemOperand(scratch1, FixedArray::kHeaderSize)); |
+ __ BranchOnSmi(probe, not_found); |
+ __ sub(scratch2, object, Operand(kHeapObjectTag)); |
+ __ vldr(d0, scratch2, HeapNumber::kValueOffset); |
+ __ sub(probe, probe, Operand(kHeapObjectTag)); |
+ __ vldr(d1, probe, HeapNumber::kValueOffset); |
+ __ vcmp(d0, d1); |
+ __ b(ne, not_found); // The cache did not contain this value. |
+ __ b(&load_result_from_cache); |
+ } else { |
+ __ b(not_found); |
+ } |
+ } |
+ |
+ __ bind(&is_smi); |
+ Register scratch = scratch1; |
__ and_(scratch, mask, Operand(object, ASR, 1)); |
- |
// Calculate address of entry in string cache: each entry consists |
// of two pointer sized fields. |
__ add(scratch, |
@@ -6137,15 +6174,15 @@ |
Operand(scratch, LSL, kPointerSizeLog2 + 1)); |
// Check if the entry is the smi we are looking for. |
- Register object1 = scratch1; |
- __ ldr(object1, FieldMemOperand(scratch, FixedArray::kHeaderSize)); |
- __ cmp(object, object1); |
+ Register probe = mask; |
+ __ ldr(probe, FieldMemOperand(scratch, FixedArray::kHeaderSize)); |
+ __ cmp(object, probe); |
__ b(ne, not_found); |
// Get the result from the cache. |
+ __ bind(&load_result_from_cache); |
__ ldr(result, |
FieldMemOperand(scratch, FixedArray::kHeaderSize + kPointerSize)); |
- |
__ IncrementCounter(&Counters::number_to_string_native, |
1, |
scratch1, |
@@ -6159,13 +6196,13 @@ |
__ ldr(r1, MemOperand(sp, 0)); |
// Generate code to lookup number in the number string cache. |
- GenerateLookupNumberStringCache(masm, r1, r0, r2, r3, false, &runtime); |
+ GenerateLookupNumberStringCache(masm, r1, r0, r2, r3, r4, false, &runtime); |
__ add(sp, sp, Operand(1 * kPointerSize)); |
__ Ret(); |
__ bind(&runtime); |
// Handle number to string in the runtime system if not found in the cache. |
- __ TailCallRuntime(Runtime::kNumberToString, 1, 1); |
+ __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1); |
} |
@@ -6558,7 +6595,7 @@ |
// First argument is a string, second is a smi. Try to lookup the number |
// string for the smi in the number string cache. |
NumberToStringStub::GenerateLookupNumberStringCache( |
- masm, r0, r2, r4, r5, true, &string1); |
+ masm, r0, r2, r4, r5, r6, true, &string1); |
// Replace second argument on stack and tailcall string add stub to make |
// the result. |