| Index: src/x64/macro-assembler-x64.cc | 
| =================================================================== | 
| --- src/x64/macro-assembler-x64.cc	(revision 10379) | 
| +++ src/x64/macro-assembler-x64.cc	(working copy) | 
| @@ -3210,6 +3210,42 @@ | 
| } | 
|  | 
|  | 
| +void MacroAssembler::GetNumberHash(Register r0, Register scratch) { | 
| +  // First of all we assign the hash seed to scratch. | 
| +  LoadRoot(scratch, Heap::kHashSeedRootIndex); | 
| +  SmiToInteger32(scratch, scratch); | 
| + | 
| +  // Xor original key with a seed. | 
| +  xorl(r0, scratch); | 
| + | 
| +  // Compute the hash code from the untagged key.  This must be kept in sync | 
| +  // with ComputeIntegerHash in utils.h. | 
| +  // | 
| +  // hash = ~hash + (hash << 15); | 
| +  movl(scratch, r0); | 
| +  notl(r0); | 
| +  shll(scratch, Immediate(15)); | 
| +  addl(r0, scratch); | 
| +  // hash = hash ^ (hash >> 12); | 
| +  movl(scratch, r0); | 
| +  shrl(scratch, Immediate(12)); | 
| +  xorl(r0, scratch); | 
| +  // hash = hash + (hash << 2); | 
| +  leal(r0, Operand(r0, r0, times_4, 0)); | 
| +  // hash = hash ^ (hash >> 4); | 
| +  movl(scratch, r0); | 
| +  shrl(scratch, Immediate(4)); | 
| +  xorl(r0, scratch); | 
| +  // hash = hash * 2057; | 
| +  imull(r0, r0, Immediate(2057)); | 
| +  // hash = hash ^ (hash >> 16); | 
| +  movl(scratch, r0); | 
| +  shrl(scratch, Immediate(16)); | 
| +  xorl(r0, scratch); | 
| +} | 
| + | 
| + | 
| + | 
| void MacroAssembler::LoadFromNumberDictionary(Label* miss, | 
| Register elements, | 
| Register key, | 
| @@ -3240,34 +3276,11 @@ | 
|  | 
| Label done; | 
|  | 
| -  // Compute the hash code from the untagged key.  This must be kept in sync | 
| -  // with ComputeIntegerHash in utils.h. | 
| -  // | 
| -  // hash = ~hash + (hash << 15); | 
| -  movl(r1, r0); | 
| -  notl(r0); | 
| -  shll(r1, Immediate(15)); | 
| -  addl(r0, r1); | 
| -  // hash = hash ^ (hash >> 12); | 
| -  movl(r1, r0); | 
| -  shrl(r1, Immediate(12)); | 
| -  xorl(r0, r1); | 
| -  // hash = hash + (hash << 2); | 
| -  leal(r0, Operand(r0, r0, times_4, 0)); | 
| -  // hash = hash ^ (hash >> 4); | 
| -  movl(r1, r0); | 
| -  shrl(r1, Immediate(4)); | 
| -  xorl(r0, r1); | 
| -  // hash = hash * 2057; | 
| -  imull(r0, r0, Immediate(2057)); | 
| -  // hash = hash ^ (hash >> 16); | 
| -  movl(r1, r0); | 
| -  shrl(r1, Immediate(16)); | 
| -  xorl(r0, r1); | 
| +  GetNumberHash(r0, r1); | 
|  | 
| // Compute capacity mask. | 
| -  SmiToInteger32(r1, | 
| -                 FieldOperand(elements, NumberDictionary::kCapacityOffset)); | 
| +  SmiToInteger32(r1, FieldOperand(elements, | 
| +                                  SeededNumberDictionary::kCapacityOffset)); | 
| decl(r1); | 
|  | 
| // Generate an unrolled loop that performs a few probes before giving up. | 
| @@ -3277,19 +3290,19 @@ | 
| movq(r2, r0); | 
| // Compute the masked index: (hash + i + i * i) & mask. | 
| if (i > 0) { | 
| -      addl(r2, Immediate(NumberDictionary::GetProbeOffset(i))); | 
| +      addl(r2, Immediate(SeededNumberDictionary::GetProbeOffset(i))); | 
| } | 
| and_(r2, r1); | 
|  | 
| // Scale the index by multiplying by the entry size. | 
| -    ASSERT(NumberDictionary::kEntrySize == 3); | 
| +    ASSERT(SeededNumberDictionary::kEntrySize == 3); | 
| lea(r2, Operand(r2, r2, times_2, 0));  // r2 = r2 * 3 | 
|  | 
| // Check if the key matches. | 
| cmpq(key, FieldOperand(elements, | 
| r2, | 
| times_pointer_size, | 
| -                           NumberDictionary::kElementsStartOffset)); | 
| +                           SeededNumberDictionary::kElementsStartOffset)); | 
| if (i != (kProbes - 1)) { | 
| j(equal, &done); | 
| } else { | 
| @@ -3300,7 +3313,7 @@ | 
| bind(&done); | 
| // Check that the value is a normal propety. | 
| const int kDetailsOffset = | 
| -      NumberDictionary::kElementsStartOffset + 2 * kPointerSize; | 
| +      SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize; | 
| ASSERT_EQ(NORMAL, 0); | 
| Test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset), | 
| Smi::FromInt(PropertyDetails::TypeField::kMask)); | 
| @@ -3308,7 +3321,7 @@ | 
|  | 
| // Get the value at the masked, scaled index. | 
| const int kValueOffset = | 
| -      NumberDictionary::kElementsStartOffset + kPointerSize; | 
| +      SeededNumberDictionary::kElementsStartOffset + kPointerSize; | 
| movq(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset)); | 
| } | 
|  | 
|  |