[objects] Avoid dependance on non-compactible map space in Map::Hash

Map::Hash relies on the fact that the map space is never compacted.
However this might change in the future, so instead of using the
address of the prototype's map, we use the prototype's identity hash
instead.

Bug: v8:12578
Change-Id: Ia4961ed55119681c0033aa187789f6710ff2d22c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3412085
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78768}
This commit is contained in:
Dominik Inführ 2022-01-25 16:28:15 +01:00 committed by V8 LUCI CQ
parent 12c79495d7
commit f49f6bb571

View File

@ -2056,16 +2056,21 @@ Handle<Map> Map::CopyReplaceDescriptor(Isolate* isolate, Handle<Map> map,
int Map::Hash() {
// For performance reasons we only hash the 2 most variable fields of a map:
// prototype map and bit_field2. For predictability reasons we use objects'
// offsets in respective pages for hashing instead of raw addresses. We use
// the map of the prototype because the prototype itself could be compacted,
// whereas the map will not be moved.
// NOTE: If we want to compact maps, this hash function won't work as intended
// anymore.
// prototype and bit_field2.
// Shift away the tag.
int hash = ObjectAddressForHashing(prototype().map().ptr()) >> 2;
return hash ^ bit_field2();
HeapObject prototype = this->prototype();
int prototype_hash;
if (prototype.IsNull()) {
// No identity hash for null, so just pick a random number.
prototype_hash = 1;
} else {
JSReceiver receiver = JSReceiver::cast(prototype);
Isolate* isolate = GetIsolateFromWritableObject(receiver);
prototype_hash = receiver.GetOrCreateIdentityHash(isolate).value();
}
return prototype_hash ^ bit_field2();
}
namespace {