| Index: src/ia32/macro-assembler-ia32.cc
 | 
| diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
 | 
| index 2ae06128a83a6ffea545668e8ce4376b65d24b9b..f8caecd67d877ac965f458dec7e5fc1a4818b4b1 100644
 | 
| --- a/src/ia32/macro-assembler-ia32.cc
 | 
| +++ b/src/ia32/macro-assembler-ia32.cc
 | 
| @@ -3023,6 +3023,88 @@ void MacroAssembler::LoadPowerOf2(XMMRegister dst,
 | 
|  }
 | 
|  
 | 
|  
 | 
| +void MacroAssembler::LookupNumberStringCache(Register object,
 | 
| +                                             Register result,
 | 
| +                                             Register scratch1,
 | 
| +                                             Register scratch2,
 | 
| +                                             Label* not_found) {
 | 
| +  // Use of registers. Register result is used as a temporary.
 | 
| +  Register number_string_cache = result;
 | 
| +  Register mask = scratch1;
 | 
| +  Register scratch = scratch2;
 | 
| +
 | 
| +  // Load the number string cache.
 | 
| +  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.
 | 
| +  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.
 | 
| +
 | 
| +  // 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
 | 
| +  // Heap::GetNumberStringCache.
 | 
| +  Label smi_hash_calculated;
 | 
| +  Label load_result_from_cache;
 | 
| +  Label not_smi;
 | 
| +  STATIC_ASSERT(kSmiTag == 0);
 | 
| +  JumpIfNotSmi(object, ¬_smi, Label::kNear);
 | 
| +  mov(scratch, object);
 | 
| +  SmiUntag(scratch);
 | 
| +  jmp(&smi_hash_calculated, Label::kNear);
 | 
| +  bind(¬_smi);
 | 
| +  cmp(FieldOperand(object, HeapObject::kMapOffset),
 | 
| +      isolate()->factory()->heap_number_map());
 | 
| +  j(not_equal, not_found);
 | 
| +  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.
 | 
| +  and_(scratch, mask);
 | 
| +  Register index = scratch;
 | 
| +  Register probe = mask;
 | 
| +  mov(probe,
 | 
| +      FieldOperand(number_string_cache,
 | 
| +                   index,
 | 
| +                   times_twice_pointer_size,
 | 
| +                   FixedArray::kHeaderSize));
 | 
| +  JumpIfSmi(probe, not_found);
 | 
| +  if (CpuFeatures::IsSupported(SSE2)) {
 | 
| +    CpuFeatureScope fscope(this, SSE2);
 | 
| +    movdbl(xmm0, FieldOperand(object, HeapNumber::kValueOffset));
 | 
| +    ucomisd(xmm0, FieldOperand(probe, HeapNumber::kValueOffset));
 | 
| +  } else {
 | 
| +    fld_d(FieldOperand(object, HeapNumber::kValueOffset));
 | 
| +    fld_d(FieldOperand(probe, HeapNumber::kValueOffset));
 | 
| +    FCmp();
 | 
| +  }
 | 
| +  j(parity_even, not_found);  // Bail out if NaN is involved.
 | 
| +  j(not_equal, not_found);  // The cache did not contain this value.
 | 
| +  jmp(&load_result_from_cache, Label::kNear);
 | 
| +
 | 
| +  bind(&smi_hash_calculated);
 | 
| +  // Object is smi and hash is now in scratch. Calculate cache index.
 | 
| +  and_(scratch, mask);
 | 
| +  // Check if the entry is the smi we are looking for.
 | 
| +  cmp(object,
 | 
| +      FieldOperand(number_string_cache,
 | 
| +                   index,
 | 
| +                   times_twice_pointer_size,
 | 
| +                   FixedArray::kHeaderSize));
 | 
| +  j(not_equal, not_found);
 | 
| +
 | 
| +  // Get the result from the cache.
 | 
| +  bind(&load_result_from_cache);
 | 
| +  mov(result,
 | 
| +      FieldOperand(number_string_cache,
 | 
| +                   index,
 | 
| +                   times_twice_pointer_size,
 | 
| +                   FixedArray::kHeaderSize + kPointerSize));
 | 
| +  IncrementCounter(isolate()->counters()->number_to_string_native(), 1);
 | 
| +}
 | 
| +
 | 
| +
 | 
|  void MacroAssembler::JumpIfInstanceTypeIsNotSequentialAscii(
 | 
|      Register instance_type,
 | 
|      Register scratch,
 | 
| 
 |