Skip to content

Commit 3d52c32

Browse files
committed
[snapshot] rehash JSMap and JSSet during deserialization
1 parent 6700ce8 commit 3d52c32

File tree

8 files changed

+76
-10
lines changed

8 files changed

+76
-10
lines changed

deps/v8/src/objects/heap-object.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ class HeapObject : public Object {
190190
bool CanBeRehashed() const;
191191

192192
// Rehash the object based on the layout inferred from its map.
193-
void RehashBasedOnMap(ReadOnlyRoots root);
193+
void RehashBasedOnMap(Isolate* isolate, ReadOnlyRoots root);
194194

195195
// Layout description.
196196
#define HEAP_OBJECT_FIELDS(V) \

deps/v8/src/objects/objects.cc

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2285,9 +2285,9 @@ bool HeapObject::NeedsRehashing() const {
22852285
case TRANSITION_ARRAY_TYPE:
22862286
return TransitionArray::cast(*this).number_of_entries() > 1;
22872287
case ORDERED_HASH_MAP_TYPE:
2288-
return OrderedHashMap::cast(*this).NumberOfElements() > 0;
2288+
return false; // We'll rehash from the JSMap referecing it
22892289
case ORDERED_HASH_SET_TYPE:
2290-
return OrderedHashSet::cast(*this).NumberOfElements() > 0;
2290+
return false; // We'll rehash from the JSSap referecing it
22912291
case NAME_DICTIONARY_TYPE:
22922292
case GLOBAL_DICTIONARY_TYPE:
22932293
case NUMBER_DICTIONARY_TYPE:
@@ -2297,6 +2297,8 @@ bool HeapObject::NeedsRehashing() const {
22972297
case SMALL_ORDERED_HASH_MAP_TYPE:
22982298
case SMALL_ORDERED_HASH_SET_TYPE:
22992299
case SMALL_ORDERED_NAME_DICTIONARY_TYPE:
2300+
case JS_MAP_TYPE:
2301+
case JS_SET_TYPE:
23002302
return true;
23012303
default:
23022304
return false;
@@ -2306,8 +2308,12 @@ bool HeapObject::NeedsRehashing() const {
23062308
bool HeapObject::CanBeRehashed() const {
23072309
DCHECK(NeedsRehashing());
23082310
switch (map().instance_type()) {
2311+
case JS_MAP_TYPE:
2312+
case JS_SET_TYPE:
2313+
return true;
23092314
case ORDERED_HASH_MAP_TYPE:
23102315
case ORDERED_HASH_SET_TYPE:
2316+
UNREACHABLE(); // We'll rehash from the JSMap or JSSet referecing them
23112317
case ORDERED_NAME_DICTIONARY_TYPE:
23122318
// TODO(yangguo): actually support rehashing OrderedHash{Map,Set}.
23132319
return false;
@@ -2333,7 +2339,7 @@ bool HeapObject::CanBeRehashed() const {
23332339
return false;
23342340
}
23352341

2336-
void HeapObject::RehashBasedOnMap(ReadOnlyRoots roots) {
2342+
void HeapObject::RehashBasedOnMap(Isolate* isolate, ReadOnlyRoots roots) {
23372343
switch (map().instance_type()) {
23382344
case HASH_TABLE_TYPE:
23392345
UNREACHABLE();
@@ -2365,6 +2371,25 @@ void HeapObject::RehashBasedOnMap(ReadOnlyRoots roots) {
23652371
case SMALL_ORDERED_HASH_SET_TYPE:
23662372
DCHECK_EQ(0, SmallOrderedHashSet::cast(*this).NumberOfElements());
23672373
break;
2374+
case ORDERED_HASH_MAP_TYPE:
2375+
case ORDERED_HASH_SET_TYPE:
2376+
UNREACHABLE(); // We'll rehash from the JSMap or JSSet referecing them
2377+
case JS_MAP_TYPE: {
2378+
JSMap map = JSMap::cast(*this);
2379+
Handle<OrderedHashMap> table(OrderedHashMap::cast(map.table()), isolate);
2380+
Handle<OrderedHashMap> new_table =
2381+
OrderedHashMap::Rehash(isolate, table).ToHandleChecked();
2382+
map.set_table(*new_table);
2383+
break;
2384+
}
2385+
case JS_SET_TYPE: {
2386+
JSSet set = JSSet::cast(*this);
2387+
Handle<OrderedHashSet> table(OrderedHashSet::cast(set.table()), isolate);
2388+
Handle<OrderedHashSet> new_table =
2389+
OrderedHashSet::Rehash(isolate, table).ToHandleChecked();
2390+
set.set_table(*new_table);
2391+
break;
2392+
}
23682393
case SMALL_ORDERED_NAME_DICTIONARY_TYPE:
23692394
DCHECK_EQ(0, SmallOrderedNameDictionary::cast(*this).NumberOfElements());
23702395
break;

deps/v8/src/objects/ordered-hash-table.cc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,13 @@ HeapObject OrderedHashMap::GetEmpty(ReadOnlyRoots ro_roots) {
193193
return ro_roots.empty_ordered_hash_map();
194194
}
195195

196+
template <class Derived, int entrysize>
197+
MaybeHandle<Derived> OrderedHashTable<Derived, entrysize>::Rehash(
198+
Isolate* isolate, Handle<Derived> table) {
199+
return OrderedHashTable<Derived, entrysize>::Rehash(isolate, table,
200+
table->Capacity());
201+
}
202+
196203
template <class Derived, int entrysize>
197204
MaybeHandle<Derived> OrderedHashTable<Derived, entrysize>::Rehash(
198205
Isolate* isolate, Handle<Derived> table, int new_capacity) {
@@ -249,6 +256,16 @@ MaybeHandle<OrderedHashSet> OrderedHashSet::Rehash(Isolate* isolate,
249256
new_capacity);
250257
}
251258

259+
MaybeHandle<OrderedHashSet> OrderedHashSet::Rehash(
260+
Isolate* isolate, Handle<OrderedHashSet> table) {
261+
return OrderedHashTable<OrderedHashSet, 1>::Rehash(isolate, table);
262+
}
263+
264+
MaybeHandle<OrderedHashMap> OrderedHashMap::Rehash(
265+
Isolate* isolate, Handle<OrderedHashMap> table) {
266+
return OrderedHashTable<OrderedHashMap, 2>::Rehash(isolate, table);
267+
}
268+
252269
MaybeHandle<OrderedHashMap> OrderedHashMap::Rehash(Isolate* isolate,
253270
Handle<OrderedHashMap> table,
254271
int new_capacity) {

deps/v8/src/objects/ordered-hash-table.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,8 @@ class OrderedHashTable : public FixedArray {
200200
static MaybeHandle<Derived> Allocate(
201201
Isolate* isolate, int capacity,
202202
AllocationType allocation = AllocationType::kYoung);
203+
204+
static MaybeHandle<Derived> Rehash(Isolate* isolate, Handle<Derived> table);
203205
static MaybeHandle<Derived> Rehash(Isolate* isolate, Handle<Derived> table,
204206
int new_capacity);
205207

@@ -244,6 +246,8 @@ class V8_EXPORT_PRIVATE OrderedHashSet
244246
static MaybeHandle<OrderedHashSet> Rehash(Isolate* isolate,
245247
Handle<OrderedHashSet> table,
246248
int new_capacity);
249+
static MaybeHandle<OrderedHashSet> Rehash(Isolate* isolate,
250+
Handle<OrderedHashSet> table);
247251
static MaybeHandle<OrderedHashSet> Allocate(
248252
Isolate* isolate, int capacity,
249253
AllocationType allocation = AllocationType::kYoung);
@@ -273,6 +277,8 @@ class V8_EXPORT_PRIVATE OrderedHashMap
273277
static MaybeHandle<OrderedHashMap> Rehash(Isolate* isolate,
274278
Handle<OrderedHashMap> table,
275279
int new_capacity);
280+
static MaybeHandle<OrderedHashMap> Rehash(Isolate* isolate,
281+
Handle<OrderedHashMap> table);
276282
Object ValueAt(int entry);
277283

278284
// This takes and returns raw Address values containing tagged Object

deps/v8/src/snapshot/deserializer.cc

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ void Deserializer::Initialize(Isolate* isolate) {
7070
void Deserializer::Rehash() {
7171
DCHECK(can_rehash() || deserializing_user_code());
7272
for (HeapObject item : to_rehash_) {
73-
item.RehashBasedOnMap(ReadOnlyRoots(isolate_));
73+
item.RehashBasedOnMap(isolate_, ReadOnlyRoots(isolate_));
7474
}
7575
}
7676

@@ -130,6 +130,13 @@ void Deserializer::DeserializeDeferredObjects() {
130130
}
131131
}
132132
}
133+
134+
// When the deserialization of maps are deferred, they will be created
135+
// as filler maps, and we postpone the post processing until the maps
136+
// are also deserialized.
137+
for (auto pair : fillers_to_post_process_) {
138+
PostProcessNewObject(pair.first, pair.second);
139+
}
133140
}
134141

135142
void Deserializer::LogNewObjectEvents() {
@@ -201,6 +208,11 @@ HeapObject Deserializer::PostProcessNewObject(HeapObject obj,
201208
DisallowHeapAllocation no_gc;
202209

203210
if ((FLAG_rehash_snapshot && can_rehash_) || deserializing_user_code()) {
211+
if (obj.IsFiller()) {
212+
CHECK_EQ(fillers_to_post_process_.find(obj), fillers_to_post_process_.end());
213+
fillers_to_post_process_.insert({obj, space});
214+
}
215+
204216
if (obj.IsString()) {
205217
// Uninitialize hash field as we need to recompute the hash.
206218
String string = String::cast(obj);

deps/v8/src/snapshot/deserializer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ class V8_EXPORT_PRIVATE Deserializer : public SerializerDeserializer {
194194
// TODO(6593): generalize rehashing, and remove this flag.
195195
bool can_rehash_;
196196
std::vector<HeapObject> to_rehash_;
197+
std::unordered_map<HeapObject, SnapshotSpace, Object::Hasher>
198+
fillers_to_post_process_;
197199

198200
#ifdef DEBUG
199201
uint32_t num_api_references_;

deps/v8/src/snapshot/partial-deserializer.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ MaybeHandle<Object> PartialDeserializer::Deserialize(
5757
// new code, which also has to be flushed from instruction cache.
5858
CHECK_EQ(start_address, code_space->top());
5959

60-
if (FLAG_rehash_snapshot && can_rehash()) Rehash();
6160
LogNewMapEvents();
6261

6362
result = handle(root, isolate);
6463
}
6564

65+
if (FLAG_rehash_snapshot && can_rehash()) Rehash();
6666
SetupOffHeapArrayBufferBackingStores();
6767

6868
return result;

deps/v8/test/cctest/test-serialize.cc

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3715,7 +3715,7 @@ UNINITIALIZED_TEST(SnapshotCreatorIncludeGlobalProxy) {
37153715
FreeCurrentEmbeddedBlob();
37163716
}
37173717

3718-
UNINITIALIZED_TEST(ReinitializeHashSeedNotRehashable) {
3718+
UNINITIALIZED_TEST(ReinitializeHashSeedJSCollectionRehashable) {
37193719
DisableAlwaysOpt();
37203720
i::FLAG_rehash_snapshot = true;
37213721
i::FLAG_hash_seed = 42;
@@ -3733,13 +3733,16 @@ UNINITIALIZED_TEST(ReinitializeHashSeedNotRehashable) {
37333733
CompileRun(
37343734
"var m = new Map();"
37353735
"m.set('a', 1);"
3736-
"m.set('b', 2);");
3736+
"m.set('b', 2);"
3737+
"var s = new Set();"
3738+
"s.add(1)");
37373739
ExpectInt32("m.get('b')", 2);
3740+
ExpectTrue("s.has(1)");
37383741
creator.SetDefaultContext(context);
37393742
}
37403743
blob =
37413744
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
3742-
CHECK(!blob.CanBeRehashed());
3745+
CHECK(blob.CanBeRehashed());
37433746
}
37443747

37453748
ReadOnlyHeap::ClearSharedHeapForTest();
@@ -3750,14 +3753,15 @@ UNINITIALIZED_TEST(ReinitializeHashSeedNotRehashable) {
37503753
v8::Isolate* isolate = v8::Isolate::New(create_params);
37513754
{
37523755
// Check that no rehashing has been performed.
3753-
CHECK_EQ(static_cast<uint64_t>(42),
3756+
CHECK_EQ(static_cast<uint64_t>(1337),
37543757
HashSeed(reinterpret_cast<i::Isolate*>(isolate)));
37553758
v8::Isolate::Scope isolate_scope(isolate);
37563759
v8::HandleScope handle_scope(isolate);
37573760
v8::Local<v8::Context> context = v8::Context::New(isolate);
37583761
CHECK(!context.IsEmpty());
37593762
v8::Context::Scope context_scope(context);
37603763
ExpectInt32("m.get('b')", 2);
3764+
ExpectTrue("s.has(1)");
37613765
}
37623766
isolate->Dispose();
37633767
delete[] blob.data;

0 commit comments

Comments
 (0)