Index: src/ia32/macro-assembler-ia32.cc |
=================================================================== |
--- src/ia32/macro-assembler-ia32.cc (revision 10379) |
+++ src/ia32/macro-assembler-ia32.cc (working copy) |
@@ -752,6 +752,51 @@ |
} |
+// Compute the hash code from the untagged key. This must be kept in sync |
+// with ComputeIntegerHash in utils.h. |
+// |
+// Note: r0 will contain hash code |
+void MacroAssembler::GetNumberHash(Register r0, Register scratch) { |
+ // Xor original key with a seed. |
+ if (Serializer::enabled()) { |
+ ExternalReference roots_address = |
+ ExternalReference::roots_address(isolate()); |
+ mov(scratch, Immediate(Heap::kHashSeedRootIndex)); |
+ mov(scratch, Operand::StaticArray(scratch, |
+ times_pointer_size, |
+ roots_address)); |
+ SmiUntag(scratch); |
+ xor_(r0, Operand(scratch)); |
+ } else { |
+ int32_t seed = isolate()->heap()->HashSeed(); |
+ xor_(r0, seed); |
+ } |
+ |
+ // hash = ~hash + (hash << 15); |
+ mov(scratch, r0); |
+ not_(r0); |
+ shl(scratch, 15); |
+ add(r0, Operand(scratch)); |
+ // hash = hash ^ (hash >> 12); |
+ mov(scratch, r0); |
+ shr(scratch, 12); |
+ xor_(r0, Operand(scratch)); |
+ // hash = hash + (hash << 2); |
+ lea(r0, Operand(r0, r0, times_4, 0)); |
+ // hash = hash ^ (hash >> 4); |
+ mov(scratch, r0); |
+ shr(scratch, 4); |
+ xor_(r0, Operand(scratch)); |
+ // hash = hash * 2057; |
+ imul(r0, r0, 2057); |
+ // hash = hash ^ (hash >> 16); |
+ mov(scratch, r0); |
+ shr(scratch, 16); |
+ xor_(r0, Operand(scratch)); |
+} |
+ |
+ |
+ |
void MacroAssembler::LoadFromNumberDictionary(Label* miss, |
Register elements, |
Register key, |
@@ -777,33 +822,10 @@ |
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); |
- mov(r1, r0); |
- not_(r0); |
- shl(r1, 15); |
- add(r0, Operand(r1)); |
- // hash = hash ^ (hash >> 12); |
- mov(r1, r0); |
- shr(r1, 12); |
- xor_(r0, Operand(r1)); |
- // hash = hash + (hash << 2); |
- lea(r0, Operand(r0, r0, times_4, 0)); |
- // hash = hash ^ (hash >> 4); |
- mov(r1, r0); |
- shr(r1, 4); |
- xor_(r0, Operand(r1)); |
- // hash = hash * 2057; |
- imul(r0, r0, 2057); |
- // hash = hash ^ (hash >> 16); |
- mov(r1, r0); |
- shr(r1, 16); |
- xor_(r0, Operand(r1)); |
+ GetNumberHash(r0, r1); |
// Compute capacity mask. |
- mov(r1, FieldOperand(elements, NumberDictionary::kCapacityOffset)); |
+ mov(r1, FieldOperand(elements, SeededNumberDictionary::kCapacityOffset)); |
shr(r1, kSmiTagSize); // convert smi to int |
dec(r1); |
@@ -814,19 +836,19 @@ |
mov(r2, r0); |
// Compute the masked index: (hash + i + i * i) & mask. |
if (i > 0) { |
- add(Operand(r2), Immediate(NumberDictionary::GetProbeOffset(i))); |
+ add(Operand(r2), Immediate(SeededNumberDictionary::GetProbeOffset(i))); |
} |
and_(r2, Operand(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. |
cmp(key, FieldOperand(elements, |
r2, |
times_pointer_size, |
- NumberDictionary::kElementsStartOffset)); |
+ SeededNumberDictionary::kElementsStartOffset)); |
if (i != (kProbes - 1)) { |
j(equal, &done); |
} else { |
@@ -837,7 +859,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), |
Immediate(PropertyDetails::TypeField::kMask << kSmiTagSize)); |
@@ -845,7 +867,7 @@ |
// Get the value at the masked, scaled index. |
const int kValueOffset = |
- NumberDictionary::kElementsStartOffset + kPointerSize; |
+ SeededNumberDictionary::kElementsStartOffset + kPointerSize; |
mov(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset)); |
} |