| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index 0ff59732be3b2de19613dd9dd43daf802b86bdcb..482b5beae81ef1d4d3f62c57c9c1f37c9ba2a73f 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -9010,19 +9010,25 @@ void String::PrintOn(FILE* file) {
|
| }
|
|
|
|
|
| +inline static uint32_t ObjectAddressForHashing(Object* object) {
|
| + uint32_t value = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(object));
|
| + return value & MemoryChunk::kAlignmentMask;
|
| +}
|
| +
|
| +
|
| int Map::Hash() {
|
| // For performance reasons we only hash the 3 most variable fields of a map:
|
| - // constructor, prototype and bit_field2.
|
| + // constructor, prototype and bit_field2. For predictability reasons we
|
| + // use objects' offsets in respective pages for hashing instead of raw
|
| + // addresses.
|
|
|
| // Shift away the tag.
|
| - int hash = (static_cast<uint32_t>(
|
| - reinterpret_cast<uintptr_t>(constructor())) >> 2);
|
| + int hash = ObjectAddressForHashing(constructor()) >> 2;
|
|
|
| // XOR-ing the prototype and constructor directly yields too many zero bits
|
| // when the two pointers are close (which is fairly common).
|
| - // To avoid this we shift the prototype 4 bits relatively to the constructor.
|
| - hash ^= (static_cast<uint32_t>(
|
| - reinterpret_cast<uintptr_t>(prototype())) << 2);
|
| + // To avoid this we shift the prototype bits relatively to the constructor.
|
| + hash ^= ObjectAddressForHashing(prototype()) << (32 - kPageSizeBits);
|
|
|
| return hash ^ (hash >> 16) ^ bit_field2();
|
| }
|
|
|