Map::Hash() calculation made deterministic in predictable mode.

BUG=v8:3563
LOG=N
R=jkummerow@chromium.org

Review URL: https://codereview.chromium.org/610363002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24281 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
ishell@chromium.org 2014-09-29 11:29:43 +00:00
parent baae3f8e1e
commit df2e4f8e9b

View File

@ -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();
}