Commit 993e4520 authored by Maciej Goszczycki's avatar Maciej Goszczycki Committed by Commit Bot

Switch RehashBasedOnMap to use ReadOnlyRoots

This means ReadOnlyDeserializer can be made isolate independent. Without
this Isolate is needed for rehashing read-only space.


Bug: v8:7464
Change-Id: Id2c9968a0ecfa2362f499ded6c7e0f7b2be00dfb
Reviewed-on: https://chromium-review.googlesource.com/c/1483054
Commit-Queue: Maciej Goszczycki <goszczycki@google.com>
Reviewed-by: 's avatarDan Elphick <delphick@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59823}
parent 257433ec
......@@ -2356,25 +2356,25 @@ bool HeapObject::CanBeRehashed() const {
return false;
}
void HeapObject::RehashBasedOnMap(Isolate* isolate) {
void HeapObject::RehashBasedOnMap(ReadOnlyRoots roots) {
switch (map()->instance_type()) {
case HASH_TABLE_TYPE:
UNREACHABLE();
break;
case NAME_DICTIONARY_TYPE:
NameDictionary::cast(*this)->Rehash(isolate);
NameDictionary::cast(*this)->Rehash(roots);
break;
case GLOBAL_DICTIONARY_TYPE:
GlobalDictionary::cast(*this)->Rehash(isolate);
GlobalDictionary::cast(*this)->Rehash(roots);
break;
case NUMBER_DICTIONARY_TYPE:
NumberDictionary::cast(*this)->Rehash(isolate);
NumberDictionary::cast(*this)->Rehash(roots);
break;
case SIMPLE_NUMBER_DICTIONARY_TYPE:
SimpleNumberDictionary::cast(*this)->Rehash(isolate);
SimpleNumberDictionary::cast(*this)->Rehash(roots);
break;
case STRING_TABLE_TYPE:
StringTable::cast(*this)->Rehash(isolate);
StringTable::cast(*this)->Rehash(roots);
break;
case DESCRIPTOR_ARRAY_TYPE:
DCHECK_LE(1, DescriptorArray::cast(*this)->number_of_descriptors());
......@@ -6453,7 +6453,7 @@ Handle<Derived> HashTable<Derived, Shape>::NewInternal(
}
template <typename Derived, typename Shape>
void HashTable<Derived, Shape>::Rehash(Isolate* isolate, Derived new_table) {
void HashTable<Derived, Shape>::Rehash(ReadOnlyRoots roots, Derived new_table) {
DisallowHeapAllocation no_gc;
WriteBarrierMode mode = new_table->GetWriteBarrierMode(no_gc);
......@@ -6466,12 +6466,11 @@ void HashTable<Derived, Shape>::Rehash(Isolate* isolate, Derived new_table) {
// Rehash the elements.
int capacity = this->Capacity();
ReadOnlyRoots roots(isolate);
for (int i = 0; i < capacity; i++) {
uint32_t from_index = EntryToIndex(i);
Object k = this->get(from_index);
if (!Shape::IsLive(roots, k)) continue;
uint32_t hash = Shape::HashForObject(isolate, k);
uint32_t hash = Shape::HashForObject(roots, k);
uint32_t insertion_index =
EntryToIndex(new_table->FindInsertionEntry(hash));
for (int j = 0; j < Shape::kEntrySize; j++) {
......@@ -6483,10 +6482,10 @@ void HashTable<Derived, Shape>::Rehash(Isolate* isolate, Derived new_table) {
}
template <typename Derived, typename Shape>
uint32_t HashTable<Derived, Shape>::EntryForProbe(Isolate* isolate, Object k,
uint32_t HashTable<Derived, Shape>::EntryForProbe(ReadOnlyRoots roots, Object k,
int probe,
uint32_t expected) {
uint32_t hash = Shape::HashForObject(isolate, k);
uint32_t hash = Shape::HashForObject(roots, k);
uint32_t capacity = this->Capacity();
uint32_t entry = FirstProbe(hash, capacity);
for (int i = 1; i < probe; i++) {
......@@ -6514,10 +6513,9 @@ void HashTable<Derived, Shape>::Swap(uint32_t entry1, uint32_t entry2,
}
template <typename Derived, typename Shape>
void HashTable<Derived, Shape>::Rehash(Isolate* isolate) {
void HashTable<Derived, Shape>::Rehash(ReadOnlyRoots roots) {
DisallowHeapAllocation no_gc;
WriteBarrierMode mode = GetWriteBarrierMode(no_gc);
ReadOnlyRoots roots(isolate);
uint32_t capacity = Capacity();
bool done = false;
for (int probe = 1; !done; probe++) {
......@@ -6527,11 +6525,11 @@ void HashTable<Derived, Shape>::Rehash(Isolate* isolate) {
for (uint32_t current = 0; current < capacity; current++) {
Object current_key = KeyAt(current);
if (!Shape::IsLive(roots, current_key)) continue;
uint32_t target = EntryForProbe(isolate, current_key, probe, current);
uint32_t target = EntryForProbe(roots, current_key, probe, current);
if (current == target) continue;
Object target_key = KeyAt(target);
if (!Shape::IsLive(roots, target_key) ||
EntryForProbe(isolate, target_key, probe, target) != target) {
EntryForProbe(roots, target_key, probe, target) != target) {
// Put the current element into the correct position.
Swap(current, target, mode);
// The other element will be processed on the next iteration.
......@@ -6569,7 +6567,7 @@ Handle<Derived> HashTable<Derived, Shape>::EnsureCapacity(
Handle<Derived> new_table = HashTable::New(
isolate, new_nof, should_pretenure ? TENURED : NOT_TENURED);
table->Rehash(isolate, *new_table);
table->Rehash(ReadOnlyRoots(isolate), *new_table);
return new_table;
}
......@@ -6618,7 +6616,7 @@ Handle<Derived> HashTable<Derived, Shape>::Shrink(Isolate* isolate,
HashTable::New(isolate, new_capacity, pretenure ? TENURED : NOT_TENURED,
USE_CUSTOM_MINIMUM_CAPACITY);
table->Rehash(isolate, *new_table);
table->Rehash(ReadOnlyRoots(isolate), *new_table);
return new_table;
}
......@@ -7830,7 +7828,7 @@ Handle<Derived> ObjectHashTableBase<Derived, Shape>::Put(Isolate* isolate,
// Rehash if more than 33% of the entries are deleted entries.
// TODO(jochen): Consider to shrink the fixed array in place.
if ((table->NumberOfDeletedElements() << 1) > table->NumberOfElements()) {
table->Rehash(isolate);
table->Rehash(roots);
}
// If we're out of luck, we didn't get a GC recently, and so rehashing
// isn't enough to avoid a crash.
......@@ -7842,7 +7840,7 @@ Handle<Derived> ObjectHashTableBase<Derived, Shape>::Put(Isolate* isolate,
isolate->heap()->CollectAllGarbage(
Heap::kNoGCFlags, GarbageCollectionReason::kFullHashtable);
}
table->Rehash(isolate);
table->Rehash(roots);
}
}
......@@ -8350,7 +8348,7 @@ BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>::Add(
PropertyDetails, int*);
template void HashTable<GlobalDictionary, GlobalDictionaryShape>::Rehash(
Isolate* isolate);
ReadOnlyRoots roots);
template Handle<NameDictionary>
BaseNameDictionary<NameDictionary, NameDictionaryShape>::EnsureCapacity(
......
......@@ -51,11 +51,12 @@ uint32_t CompilationCacheShape::StringSharedHash(String source,
return hash;
}
uint32_t CompilationCacheShape::HashForObject(Isolate* isolate, Object object) {
uint32_t CompilationCacheShape::HashForObject(ReadOnlyRoots roots,
Object object) {
if (object->IsNumber()) return static_cast<uint32_t>(object->Number());
FixedArray val = FixedArray::cast(object);
if (val->map() == val->GetReadOnlyRoots().fixed_cow_array_map()) {
if (val->map() == roots.fixed_cow_array_map()) {
DCHECK_EQ(4, val->length());
SharedFunctionInfo shared = SharedFunctionInfo::cast(val->get(0));
String source = String::cast(val->get(1));
......
......@@ -9,6 +9,7 @@
#include "src/objects/hash-table.h"
#include "src/objects/js-regexp.h"
#include "src/objects/shared-function-info.h"
#include "src/roots.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
......@@ -33,7 +34,7 @@ class CompilationCacheShape : public BaseShape<HashTableKey*> {
LanguageMode language_mode,
int position);
static inline uint32_t HashForObject(Isolate* isolate, Object object);
static inline uint32_t HashForObject(ReadOnlyRoots roots, Object object);
static const int kPrefixSize = 0;
static const int kEntrySize = 3;
......
......@@ -141,11 +141,11 @@ uint32_t NumberDictionaryBaseShape::Hash(Isolate* isolate, uint32_t key) {
return ComputeSeededHash(key, HashSeed(isolate));
}
uint32_t NumberDictionaryBaseShape::HashForObject(Isolate* isolate,
uint32_t NumberDictionaryBaseShape::HashForObject(ReadOnlyRoots roots,
Object other) {
DCHECK(other->IsNumber());
return ComputeSeededHash(static_cast<uint32_t>(other->Number()),
HashSeed(isolate));
HashSeed(roots));
}
Handle<Object> NumberDictionaryBaseShape::AsHandle(Isolate* isolate,
......@@ -171,7 +171,7 @@ uint32_t NameDictionaryShape::Hash(Isolate* isolate, Handle<Name> key) {
return key->Hash();
}
uint32_t NameDictionaryShape::HashForObject(Isolate* isolate, Object other) {
uint32_t NameDictionaryShape::HashForObject(ReadOnlyRoots roots, Object other) {
return Name::cast(other)->Hash();
}
......@@ -180,7 +180,8 @@ bool GlobalDictionaryShape::IsMatch(Handle<Name> key, Object other) {
return *key == PropertyCell::cast(other)->name();
}
uint32_t GlobalDictionaryShape::HashForObject(Isolate* isolate, Object other) {
uint32_t GlobalDictionaryShape::HashForObject(ReadOnlyRoots roots,
Object other) {
return PropertyCell::cast(other)->name()->Hash();
}
......
......@@ -10,6 +10,7 @@
#include "src/objects/hash-table.h"
#include "src/objects/property-array.h"
#include "src/objects/smi.h"
#include "src/roots.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
......@@ -114,7 +115,7 @@ class NameDictionaryShape : public BaseDictionaryShape<Handle<Name>> {
public:
static inline bool IsMatch(Handle<Name> key, Object other);
static inline uint32_t Hash(Isolate* isolate, Handle<Name> key);
static inline uint32_t HashForObject(Isolate* isolate, Object object);
static inline uint32_t HashForObject(ReadOnlyRoots roots, Object object);
static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Name> key);
static inline RootIndex GetMapRootIndex();
static const int kPrefixSize = 2;
......@@ -210,7 +211,7 @@ class NameDictionary
class GlobalDictionaryShape : public NameDictionaryShape {
public:
static inline bool IsMatch(Handle<Name> key, Object other);
static inline uint32_t HashForObject(Isolate* isolate, Object object);
static inline uint32_t HashForObject(ReadOnlyRoots roots, Object object);
static const int kEntrySize = 1; // Overrides NameDictionaryShape::kEntrySize
......@@ -250,7 +251,7 @@ class NumberDictionaryBaseShape : public BaseDictionaryShape<uint32_t> {
static inline Handle<Object> AsHandle(Isolate* isolate, uint32_t key);
static inline uint32_t Hash(Isolate* isolate, uint32_t key);
static inline uint32_t HashForObject(Isolate* isolate, Object object);
static inline uint32_t HashForObject(ReadOnlyRoots roots, Object object);
};
class NumberDictionaryShape : public NumberDictionaryBaseShape {
......
......@@ -171,7 +171,8 @@ uint32_t ObjectHashTableShape::Hash(Isolate* isolate, Handle<Object> key) {
return Smi::ToInt(key->GetHash());
}
uint32_t ObjectHashTableShape::HashForObject(Isolate* isolate, Object other) {
uint32_t ObjectHashTableShape::HashForObject(ReadOnlyRoots roots,
Object other) {
return Smi::ToInt(other->GetHash());
}
......
......@@ -37,7 +37,7 @@ namespace internal {
// // Returns the hash value for key.
// static uint32_t Hash(Isolate* isolate, Key key);
// // Returns the hash value for object.
// static uint32_t HashForObject(Isolate* isolate, Object object);
// static uint32_t HashForObject(ReadOnlyRoots roots, Object object);
// // Convert key to an object.
// static inline Handle<Object> AsHandle(Isolate* isolate, Key key);
// // The prefix size indicates number of elements in the beginning
......@@ -150,7 +150,7 @@ class HashTable : public HashTableBase {
int FindEntry(Isolate* isolate, Key key);
// Rehashes the table in-place.
void Rehash(Isolate* isolate);
void Rehash(ReadOnlyRoots roots);
// Tells whether k is a real key. The hole and undefined are not allowed
// as keys and can be used to indicate missing or deleted elements.
......@@ -233,13 +233,13 @@ class HashTable : public HashTableBase {
// Returns _expected_ if one of entries given by the first _probe_ probes is
// equal to _expected_. Otherwise, returns the entry given by the probe
// number _probe_.
uint32_t EntryForProbe(Isolate* isolate, Object k, int probe,
uint32_t EntryForProbe(ReadOnlyRoots roots, Object k, int probe,
uint32_t expected);
void Swap(uint32_t entry1, uint32_t entry2, WriteBarrierMode mode);
// Rehashes this hash-table into the new table.
void Rehash(Isolate* isolate, Derived new_table);
void Rehash(ReadOnlyRoots roots, Derived new_table);
OBJECT_CONSTRUCTORS(HashTable, HashTableBase);
};
......@@ -271,7 +271,7 @@ class ObjectHashTableShape : public BaseShape<Handle<Object>> {
public:
static inline bool IsMatch(Handle<Object> key, Object other);
static inline uint32_t Hash(Isolate* isolate, Handle<Object> key);
static inline uint32_t HashForObject(Isolate* isolate, Object object);
static inline uint32_t HashForObject(ReadOnlyRoots roots, Object object);
static inline Handle<Object> AsHandle(Handle<Object> key);
static const int kPrefixSize = 0;
static const int kEntryValueIndex = 1;
......
......@@ -6,6 +6,7 @@
#define V8_OBJECTS_HEAP_OBJECT_H_
#include "src/globals.h"
#include "src/roots.h"
#include "src/objects.h"
......@@ -172,7 +173,7 @@ class HeapObject : public Object {
bool CanBeRehashed() const;
// Rehash the object based on the layout inferred from its map.
void RehashBasedOnMap(Isolate* isolate);
void RehashBasedOnMap(ReadOnlyRoots roots);
// Layout description.
#define HEAP_OBJECT_FIELDS(V) \
......
......@@ -36,7 +36,7 @@ uint32_t StringSetShape::Hash(Isolate* isolate, String key) {
return key->Hash();
}
uint32_t StringSetShape::HashForObject(Isolate* isolate, Object object) {
uint32_t StringSetShape::HashForObject(ReadOnlyRoots roots, Object object) {
return String::cast(object)->Hash();
}
......@@ -53,7 +53,7 @@ Handle<Object> StringTableShape::AsHandle(Isolate* isolate,
return key->AsHandle(isolate);
}
uint32_t StringTableShape::HashForObject(Isolate* isolate, Object object) {
uint32_t StringTableShape::HashForObject(ReadOnlyRoots roots, Object object) {
return String::cast(object)->Hash();
}
......
......@@ -39,7 +39,7 @@ class StringTableShape : public BaseShape<StringTableKey*> {
static inline uint32_t Hash(Isolate* isolate, Key key) { return key->Hash(); }
static inline uint32_t HashForObject(Isolate* isolate, Object object);
static inline uint32_t HashForObject(ReadOnlyRoots roots, Object object);
static inline Handle<Object> AsHandle(Isolate* isolate, Key key);
......@@ -100,7 +100,7 @@ class StringSetShape : public BaseShape<String> {
public:
static inline bool IsMatch(String key, Object value);
static inline uint32_t Hash(Isolate* isolate, String key);
static inline uint32_t HashForObject(Isolate* isolate, Object object);
static inline uint32_t HashForObject(ReadOnlyRoots roots, Object object);
static const int kPrefixSize = 0;
static const int kEntrySize = 1;
......
......@@ -20,6 +20,7 @@
#include "src/objects/slots.h"
#include "src/objects/smi.h"
#include "src/objects/string.h"
#include "src/roots.h"
#include "src/snapshot/natives.h"
#include "src/snapshot/snapshot.h"
......@@ -61,7 +62,8 @@ void Deserializer::Initialize(Isolate* isolate) {
void Deserializer::Rehash() {
DCHECK(can_rehash() || deserializing_user_code());
for (HeapObject item : to_rehash_) item->RehashBasedOnMap(isolate());
for (HeapObject item : to_rehash_)
item->RehashBasedOnMap(ReadOnlyRoots(isolate()));
}
Deserializer::~Deserializer() {
......
......@@ -36,6 +36,7 @@
#include "src/heap/spaces.h"
#include "src/objects-inl.h"
#include "src/objects/hash-table-inl.h"
#include "src/roots.h"
#include "test/cctest/heap/heap-utils.h"
namespace v8 {
......@@ -218,7 +219,7 @@ TEST(HashTableRehash) {
for (int i = 0; i < capacity - 1; i++) {
t->insert(i, i * i, i);
}
t->Rehash(isolate);
t->Rehash(ReadOnlyRoots(isolate));
for (int i = 0; i < capacity - 1; i++) {
CHECK_EQ(i, t->lookup(i * i));
}
......@@ -231,7 +232,7 @@ TEST(HashTableRehash) {
for (int i = 0; i < capacity / 2; i++) {
t->insert(i, i * i, i);
}
t->Rehash(isolate);
t->Rehash(ReadOnlyRoots(isolate));
for (int i = 0; i < capacity / 2; i++) {
CHECK_EQ(i, t->lookup(i * i));
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment