From df2e4f8e9bcdabb8e1f1832a3ccf92fcf9467e69 Mon Sep 17 00:00:00 2001 From: "ishell@chromium.org" Date: Mon, 29 Sep 2014 11:29:43 +0000 Subject: [PATCH] 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 --- src/objects.cc | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/objects.cc b/src/objects.cc index 0ff5973..482b5be 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(reinterpret_cast(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( - reinterpret_cast(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( - reinterpret_cast(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(); } -- 2.7.4