From 251c1b1788a2568af4cb667f687eedd4e1e21bd9 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Fri, 29 May 2020 20:38:12 +0800 Subject: [PATCH 1/3] deps: V8: backport ea0719b8ed08 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Original commit message: [snapshot] Do not defer ArrayBuffers during snapshotting ArrayBuffer instances are serialized by first re-assigning a index to the backing store field, then serializing the object, and then storing the actual backing store address again (and the same for the ArrayBufferExtension). If serialization of the object itself is deferred, the real backing store address is written into the snapshot, which cannot be processed when deserializing, leading to a crash. This fixes this by not deferring ArrayBuffer serialization and adding a DCHECK for the crash that previously occurred. Change-Id: Id9bea8268061bd0770cde7bfeb6695248978f994 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2144123 Commit-Queue: Jakob Gruber Reviewed-by: Dan Elphick Cr-Commit-Position: refs/heads/master@{#67114} Refs: https://github.com/v8/v8/commit/ea0719b8ed087d1f511e78595dcb596faa7638d0 PR-URL: https://github.com/nodejs/node/pull/33300 Refs: https://github.com/v8/v8/commit/bb9f0c2b2fe920a717794f3279758846f59f7840 Refs: https://github.com/v8/v8/commit/22014de00115dae09ae3d4a6c3a9f178d5495ef2 Refs: https://github.com/nodejs/node/issues/17058 Reviewed-By: Jiawen Geng Reviewed-By: Michaël Zasso --- common.gypi | 2 +- deps/v8/src/snapshot/deserializer.h | 1 + deps/v8/src/snapshot/serializer-common.cc | 9 ++++++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/common.gypi b/common.gypi index 3afe3c133f8d0f..6f0866dd57093d 100644 --- a/common.gypi +++ b/common.gypi @@ -36,7 +36,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.14', + 'v8_embedder_string': '-node.15', ##### V8 defaults for Node.js ##### diff --git a/deps/v8/src/snapshot/deserializer.h b/deps/v8/src/snapshot/deserializer.h index 62814a881ae9e3..c09c589633c601 100644 --- a/deps/v8/src/snapshot/deserializer.h +++ b/deps/v8/src/snapshot/deserializer.h @@ -107,6 +107,7 @@ class V8_EXPORT_PRIVATE Deserializer : public SerializerDeserializer { } std::shared_ptr backing_store(size_t i) { + DCHECK_LT(i, backing_stores_.size()); return backing_stores_[i]; } diff --git a/deps/v8/src/snapshot/serializer-common.cc b/deps/v8/src/snapshot/serializer-common.cc index 9218d4eaa92969..46b8e36e9c64a9 100644 --- a/deps/v8/src/snapshot/serializer-common.cc +++ b/deps/v8/src/snapshot/serializer-common.cc @@ -125,7 +125,14 @@ void SerializerDeserializer::Iterate(Isolate* isolate, RootVisitor* visitor) { } bool SerializerDeserializer::CanBeDeferred(HeapObject o) { - return !o.IsString() && !o.IsScript() && !o.IsJSTypedArray(); + // ArrayBuffer instances are serialized by first re-assigning a index + // to the backing store field, then serializing the object, and then + // storing the actual backing store address again (and the same for the + // ArrayBufferExtension). If serialization of the object itself is deferred, + // the real backing store address is written into the snapshot, which cannot + // be processed when deserializing. + return !o.IsString() && !o.IsScript() && !o.IsJSTypedArray() && + !o.IsJSArrayBuffer(); } void SerializerDeserializer::RestoreExternalReferenceRedirectors( From c5a0b888f61ac67e4589494253743924ede0e50a Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Fri, 29 May 2020 20:49:21 +0800 Subject: [PATCH 2/3] deps: V8: backport bb9f0c2b2fe9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Original commit message: [snapshot] Improve snapshot docs and error printing - Minor improvements to the documentation for snapshotting. - Add newlines to printed errors where necessary. Change-Id: I822e7e850adb67eae73b51c23cf34e40ba3106f0 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2144954 Reviewed-by: Toon Verwaest Commit-Queue: Toon Verwaest Cr-Commit-Position: refs/heads/master@{#67111} Refs: https://github.com/v8/v8/commit/bb9f0c2b2fe920a717794f3279758846f59f7840 PR-URL: https://github.com/nodejs/node/pull/33300 Refs: https://github.com/v8/v8/commit/ea0719b8ed087d1f511e78595dcb596faa7638d0 Refs: https://github.com/v8/v8/commit/22014de00115dae09ae3d4a6c3a9f178d5495ef2 Refs: https://github.com/nodejs/node/issues/17058 Reviewed-By: Jiawen Geng Reviewed-By: Michaël Zasso --- common.gypi | 2 +- deps/v8/include/v8.h | 9 +++++++++ deps/v8/src/snapshot/serializer-common.cc | 3 ++- deps/v8/src/snapshot/startup-serializer.cc | 1 + 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/common.gypi b/common.gypi index 6f0866dd57093d..15bef5bb08e9e2 100644 --- a/common.gypi +++ b/common.gypi @@ -36,7 +36,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.15', + 'v8_embedder_string': '-node.16', ##### V8 defaults for Node.js ##### diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h index 5dcb6765608aac..7c6fdb748bf368 100644 --- a/deps/v8/include/v8.h +++ b/deps/v8/include/v8.h @@ -9788,6 +9788,11 @@ class V8_EXPORT V8 { /** * Helper class to create a snapshot data blob. + * + * The Isolate used by a SnapshotCreator is owned by it, and will be entered + * and exited by the constructor and destructor, respectively; The destructor + * will also destroy the Isolate. Experimental language features, including + * those available by default, are not available while creating a snapshot. */ class V8_EXPORT SnapshotCreator { public: @@ -9816,6 +9821,10 @@ class V8_EXPORT SnapshotCreator { SnapshotCreator(const intptr_t* external_references = nullptr, StartupData* existing_blob = nullptr); + /** + * Destroy the snapshot creator, and exit and dispose of the Isolate + * associated with it. + */ ~SnapshotCreator(); /** diff --git a/deps/v8/src/snapshot/serializer-common.cc b/deps/v8/src/snapshot/serializer-common.cc index 46b8e36e9c64a9..a843771fdbb37e 100644 --- a/deps/v8/src/snapshot/serializer-common.cc +++ b/deps/v8/src/snapshot/serializer-common.cc @@ -76,7 +76,8 @@ ExternalReferenceEncoder::Value ExternalReferenceEncoder::Encode( if (maybe_index.IsNothing()) { void* addr = reinterpret_cast(address); v8::base::OS::PrintError("Unknown external reference %p.\n", addr); - v8::base::OS::PrintError("%s", ExternalReferenceTable::ResolveSymbol(addr)); + v8::base::OS::PrintError("%s\n", + ExternalReferenceTable::ResolveSymbol(addr)); v8::base::OS::Abort(); } Value result(maybe_index.FromJust()); diff --git a/deps/v8/src/snapshot/startup-serializer.cc b/deps/v8/src/snapshot/startup-serializer.cc index 8b95ca6b6ac9a1..141fcfb23f1746 100644 --- a/deps/v8/src/snapshot/startup-serializer.cc +++ b/deps/v8/src/snapshot/startup-serializer.cc @@ -193,6 +193,7 @@ void SerializedHandleChecker::VisitRootPointers(Root root, PrintF("%s handle not serialized: ", root == Root::kGlobalHandles ? "global" : "eternal"); (*p).Print(); + PrintF("\n"); ok_ = false; } } From 0cb194ec6aae41e6c4400a28bab83b0d59e6f460 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Fri, 29 May 2020 20:51:31 +0800 Subject: [PATCH 3/3] deps: V8: backport 22014de00115 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Original commit message: Reland "[snapshot] rehash JSMap and JSSet during deserialization" This is a reland of 8374feed55a5b3010f2e9593560a2d84f9f6725f. Fixed rehashing of global proxy keys by creating its identity hash early, before the deserialization of the context snapshot. Original change's description: > [snapshot] rehash JSMap and JSSet during deserialization > > To rehash JSMap and JSSet, we simply replace the backing store > with a new one created with the new hash. > > Bug: v8:9187 > Change-Id: I90c25b18b33b7bc2b6ffe1b89fe17aa5f978b517 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2143983 > Commit-Queue: Joyee Cheung > Reviewed-by: Jakob Gruber > Reviewed-by: Camillo Bruni > Cr-Commit-Position: refs/heads/master@{#67663} Bug: v8:9187, v8:10523 Change-Id: I7a0319b1d10ff07644de902fec43e7c2b1dd8da9 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2212085 Reviewed-by: Leszek Swirski Reviewed-by: Camillo Bruni Reviewed-by: Jakob Gruber Commit-Queue: Joyee Cheung Cr-Commit-Position: refs/heads/master@{#67999} Refs: https://github.com/v8/v8/commit/22014de00115dae09ae3d4a6c3a9f178d5495ef2 PR-URL: https://github.com/nodejs/node/pull/33300 Refs: https://github.com/v8/v8/commit/ea0719b8ed087d1f511e78595dcb596faa7638d0 Refs: https://github.com/v8/v8/commit/bb9f0c2b2fe920a717794f3279758846f59f7840 Refs: https://github.com/nodejs/node/issues/17058 Reviewed-By: Jiawen Geng Reviewed-By: Michaël Zasso --- common.gypi | 2 +- deps/v8/src/heap/factory.cc | 6 +++- deps/v8/src/objects/heap-object.h | 2 +- deps/v8/src/objects/js-collection.h | 2 ++ deps/v8/src/objects/objects.cc | 38 +++++++++++++++++--- deps/v8/src/objects/ordered-hash-table.cc | 21 +++++++++++ deps/v8/src/objects/ordered-hash-table.h | 7 ++++ deps/v8/src/snapshot/deserializer.cc | 16 +++++++-- deps/v8/src/snapshot/deserializer.h | 5 +++ deps/v8/src/snapshot/object-deserializer.cc | 2 +- deps/v8/src/snapshot/partial-deserializer.cc | 2 +- deps/v8/test/cctest/test-serialize.cc | 17 ++++++--- 12 files changed, 104 insertions(+), 16 deletions(-) diff --git a/common.gypi b/common.gypi index 15bef5bb08e9e2..6fe46076ff8def 100644 --- a/common.gypi +++ b/common.gypi @@ -36,7 +36,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.16', + 'v8_embedder_string': '-node.17', ##### V8 defaults for Node.js ##### diff --git a/deps/v8/src/heap/factory.cc b/deps/v8/src/heap/factory.cc index 933a51425f9376..85760a31c91511 100644 --- a/deps/v8/src/heap/factory.cc +++ b/deps/v8/src/heap/factory.cc @@ -2761,8 +2761,12 @@ Handle Factory::NewUninitializedJSGlobalProxy(int size) { map->set_is_access_check_needed(true); map->set_may_have_interesting_symbols(true); LOG(isolate(), MapDetails(*map)); - return Handle::cast( + Handle proxy = Handle::cast( NewJSObjectFromMap(map, AllocationType::kYoung)); + // Create identity hash early in case there is any JS collection containing + // a global proxy key and needs to be rehashed after deserialization. + proxy->GetOrCreateIdentityHash(isolate()); + return proxy; } void Factory::ReinitializeJSGlobalProxy(Handle object, diff --git a/deps/v8/src/objects/heap-object.h b/deps/v8/src/objects/heap-object.h index b19d429320b5be..74fe664ca35d6d 100644 --- a/deps/v8/src/objects/heap-object.h +++ b/deps/v8/src/objects/heap-object.h @@ -191,7 +191,7 @@ class HeapObject : public Object { bool CanBeRehashed() const; // Rehash the object based on the layout inferred from its map. - void RehashBasedOnMap(ReadOnlyRoots root); + void RehashBasedOnMap(Isolate* isolate); // Layout description. #define HEAP_OBJECT_FIELDS(V) \ diff --git a/deps/v8/src/objects/js-collection.h b/deps/v8/src/objects/js-collection.h index 17f9c3e198ba8b..a0350726c02db7 100644 --- a/deps/v8/src/objects/js-collection.h +++ b/deps/v8/src/objects/js-collection.h @@ -30,6 +30,7 @@ class JSSet : public TorqueGeneratedJSSet { public: static void Initialize(Handle set, Isolate* isolate); static void Clear(Isolate* isolate, Handle set); + void Rehash(Isolate* isolate); // Dispatched behavior. DECL_PRINTER(JSSet) @@ -56,6 +57,7 @@ class JSMap : public TorqueGeneratedJSMap { public: static void Initialize(Handle map, Isolate* isolate); static void Clear(Isolate* isolate, Handle map); + void Rehash(Isolate* isolate); // Dispatched behavior. DECL_PRINTER(JSMap) diff --git a/deps/v8/src/objects/objects.cc b/deps/v8/src/objects/objects.cc index c45562965124cb..e457d6270617f3 100644 --- a/deps/v8/src/objects/objects.cc +++ b/deps/v8/src/objects/objects.cc @@ -2305,9 +2305,8 @@ bool HeapObject::NeedsRehashing() const { case TRANSITION_ARRAY_TYPE: return TransitionArray::cast(*this).number_of_entries() > 1; case ORDERED_HASH_MAP_TYPE: - return OrderedHashMap::cast(*this).NumberOfElements() > 0; case ORDERED_HASH_SET_TYPE: - return OrderedHashSet::cast(*this).NumberOfElements() > 0; + return false; // We'll rehash from the JSMap or JSSet referencing them. case NAME_DICTIONARY_TYPE: case GLOBAL_DICTIONARY_TYPE: case NUMBER_DICTIONARY_TYPE: @@ -2317,6 +2316,8 @@ bool HeapObject::NeedsRehashing() const { case SMALL_ORDERED_HASH_MAP_TYPE: case SMALL_ORDERED_HASH_SET_TYPE: case SMALL_ORDERED_NAME_DICTIONARY_TYPE: + case JS_MAP_TYPE: + case JS_SET_TYPE: return true; default: return false; @@ -2326,10 +2327,13 @@ bool HeapObject::NeedsRehashing() const { bool HeapObject::CanBeRehashed() const { DCHECK(NeedsRehashing()); switch (map().instance_type()) { + case JS_MAP_TYPE: + case JS_SET_TYPE: + return true; case ORDERED_HASH_MAP_TYPE: case ORDERED_HASH_SET_TYPE: + UNREACHABLE(); // We'll rehash from the JSMap or JSSet referencing them. case ORDERED_NAME_DICTIONARY_TYPE: - // TODO(yangguo): actually support rehashing OrderedHash{Map,Set}. return false; case NAME_DICTIONARY_TYPE: case GLOBAL_DICTIONARY_TYPE: @@ -2353,7 +2357,8 @@ bool HeapObject::CanBeRehashed() const { return false; } -void HeapObject::RehashBasedOnMap(ReadOnlyRoots roots) { +void HeapObject::RehashBasedOnMap(Isolate* isolate) { + ReadOnlyRoots roots = ReadOnlyRoots(isolate); switch (map().instance_type()) { case HASH_TABLE_TYPE: UNREACHABLE(); @@ -2385,6 +2390,17 @@ void HeapObject::RehashBasedOnMap(ReadOnlyRoots roots) { case SMALL_ORDERED_HASH_SET_TYPE: DCHECK_EQ(0, SmallOrderedHashSet::cast(*this).NumberOfElements()); break; + case ORDERED_HASH_MAP_TYPE: + case ORDERED_HASH_SET_TYPE: + UNREACHABLE(); // We'll rehash from the JSMap or JSSet referencing them. + case JS_MAP_TYPE: { + JSMap::cast(*this).Rehash(isolate); + break; + } + case JS_SET_TYPE: { + JSSet::cast(*this).Rehash(isolate); + break; + } case SMALL_ORDERED_NAME_DICTIONARY_TYPE: DCHECK_EQ(0, SmallOrderedNameDictionary::cast(*this).NumberOfElements()); break; @@ -7864,6 +7880,13 @@ void JSSet::Clear(Isolate* isolate, Handle set) { set->set_table(*table); } +void JSSet::Rehash(Isolate* isolate) { + Handle table_handle(OrderedHashSet::cast(table()), isolate); + Handle new_table = + OrderedHashSet::Rehash(isolate, table_handle).ToHandleChecked(); + set_table(*new_table); +} + void JSMap::Initialize(Handle map, Isolate* isolate) { Handle table = isolate->factory()->NewOrderedHashMap(); map->set_table(*table); @@ -7875,6 +7898,13 @@ void JSMap::Clear(Isolate* isolate, Handle map) { map->set_table(*table); } +void JSMap::Rehash(Isolate* isolate) { + Handle table_handle(OrderedHashMap::cast(table()), isolate); + Handle new_table = + OrderedHashMap::Rehash(isolate, table_handle).ToHandleChecked(); + set_table(*new_table); +} + void JSWeakCollection::Initialize(Handle weak_collection, Isolate* isolate) { Handle table = EphemeronHashTable::New(isolate, 0); diff --git a/deps/v8/src/objects/ordered-hash-table.cc b/deps/v8/src/objects/ordered-hash-table.cc index cbf3ba373b9c24..d3250bd92db8d2 100644 --- a/deps/v8/src/objects/ordered-hash-table.cc +++ b/deps/v8/src/objects/ordered-hash-table.cc @@ -194,6 +194,13 @@ HeapObject OrderedHashMap::GetEmpty(ReadOnlyRoots ro_roots) { return ro_roots.empty_ordered_hash_map(); } +template +MaybeHandle OrderedHashTable::Rehash( + Isolate* isolate, Handle table) { + return OrderedHashTable::Rehash(isolate, table, + table->Capacity()); +} + template MaybeHandle OrderedHashTable::Rehash( Isolate* isolate, Handle table, int new_capacity) { @@ -250,6 +257,20 @@ MaybeHandle OrderedHashSet::Rehash(Isolate* isolate, new_capacity); } +MaybeHandle OrderedHashSet::Rehash( + Isolate* isolate, Handle table) { + return OrderedHashTable< + OrderedHashSet, OrderedHashSet::kEntrySizeWithoutChain>::Rehash(isolate, + table); +} + +MaybeHandle OrderedHashMap::Rehash( + Isolate* isolate, Handle table) { + return OrderedHashTable< + OrderedHashMap, OrderedHashMap::kEntrySizeWithoutChain>::Rehash(isolate, + table); +} + MaybeHandle OrderedHashMap::Rehash(Isolate* isolate, Handle table, int new_capacity) { diff --git a/deps/v8/src/objects/ordered-hash-table.h b/deps/v8/src/objects/ordered-hash-table.h index b587960432caf5..5f3c45a110aa48 100644 --- a/deps/v8/src/objects/ordered-hash-table.h +++ b/deps/v8/src/objects/ordered-hash-table.h @@ -138,6 +138,7 @@ class OrderedHashTable : public FixedArray { // The extra +1 is for linking the bucket chains together. static const int kEntrySize = entrysize + 1; + static const int kEntrySizeWithoutChain = entrysize; static const int kChainOffset = entrysize; static const int kNotFound = -1; @@ -200,6 +201,8 @@ class OrderedHashTable : public FixedArray { static MaybeHandle Allocate( Isolate* isolate, int capacity, AllocationType allocation = AllocationType::kYoung); + + static MaybeHandle Rehash(Isolate* isolate, Handle table); static MaybeHandle Rehash(Isolate* isolate, Handle table, int new_capacity); @@ -244,6 +247,8 @@ class V8_EXPORT_PRIVATE OrderedHashSet static MaybeHandle Rehash(Isolate* isolate, Handle table, int new_capacity); + static MaybeHandle Rehash(Isolate* isolate, + Handle table); static MaybeHandle Allocate( Isolate* isolate, int capacity, AllocationType allocation = AllocationType::kYoung); @@ -273,6 +278,8 @@ class V8_EXPORT_PRIVATE OrderedHashMap static MaybeHandle Rehash(Isolate* isolate, Handle table, int new_capacity); + static MaybeHandle Rehash(Isolate* isolate, + Handle table); Object ValueAt(int entry); // This takes and returns raw Address values containing tagged Object diff --git a/deps/v8/src/snapshot/deserializer.cc b/deps/v8/src/snapshot/deserializer.cc index fdb4babe0712b3..761ece803745f1 100644 --- a/deps/v8/src/snapshot/deserializer.cc +++ b/deps/v8/src/snapshot/deserializer.cc @@ -70,7 +70,7 @@ void Deserializer::Initialize(Isolate* isolate) { void Deserializer::Rehash() { DCHECK(can_rehash() || deserializing_user_code()); for (HeapObject item : to_rehash_) { - item.RehashBasedOnMap(ReadOnlyRoots(isolate_)); + item.RehashBasedOnMap(isolate_); } } @@ -130,6 +130,14 @@ void Deserializer::DeserializeDeferredObjects() { } } } + + // When the deserialization of maps are deferred, they will be created + // as filler maps, and we postpone the post processing until the maps + // are also deserialized. + for (const auto& pair : fillers_to_post_process_) { + DCHECK(!pair.first.IsFiller()); + PostProcessNewObject(pair.first, pair.second); + } } void Deserializer::LogNewObjectEvents() { @@ -201,7 +209,11 @@ HeapObject Deserializer::PostProcessNewObject(HeapObject obj, DisallowHeapAllocation no_gc; if ((FLAG_rehash_snapshot && can_rehash_) || deserializing_user_code()) { - if (obj.IsString()) { + if (obj.IsFiller()) { + DCHECK_EQ(fillers_to_post_process_.find(obj), + fillers_to_post_process_.end()); + fillers_to_post_process_.insert({obj, space}); + } else if (obj.IsString()) { // Uninitialize hash field as we need to recompute the hash. String string = String::cast(obj); string.set_hash_field(String::kEmptyHashField); diff --git a/deps/v8/src/snapshot/deserializer.h b/deps/v8/src/snapshot/deserializer.h index c09c589633c601..153fda4a902cf2 100644 --- a/deps/v8/src/snapshot/deserializer.h +++ b/deps/v8/src/snapshot/deserializer.h @@ -194,6 +194,11 @@ class V8_EXPORT_PRIVATE Deserializer : public SerializerDeserializer { // TODO(6593): generalize rehashing, and remove this flag. bool can_rehash_; std::vector to_rehash_; + // Store the objects whose maps are deferred and thus initialized as filler + // maps during deserialization, so that they can be processed later when the + // maps become available. + std::unordered_map + fillers_to_post_process_; #ifdef DEBUG uint32_t num_api_references_; diff --git a/deps/v8/src/snapshot/object-deserializer.cc b/deps/v8/src/snapshot/object-deserializer.cc index cca8d4224099f8..6b02f22e6582f8 100644 --- a/deps/v8/src/snapshot/object-deserializer.cc +++ b/deps/v8/src/snapshot/object-deserializer.cc @@ -48,9 +48,9 @@ MaybeHandle ObjectDeserializer::Deserialize(Isolate* isolate) { LinkAllocationSites(); LogNewMapEvents(); result = handle(HeapObject::cast(root), isolate); - Rehash(); allocator()->RegisterDeserializedObjectsForBlackAllocation(); } + Rehash(); CommitPostProcessedObjects(); return scope.CloseAndEscape(result); } diff --git a/deps/v8/src/snapshot/partial-deserializer.cc b/deps/v8/src/snapshot/partial-deserializer.cc index 8a215b6b871e94..e15cf6c678fbb8 100644 --- a/deps/v8/src/snapshot/partial-deserializer.cc +++ b/deps/v8/src/snapshot/partial-deserializer.cc @@ -57,12 +57,12 @@ MaybeHandle PartialDeserializer::Deserialize( // new code, which also has to be flushed from instruction cache. CHECK_EQ(start_address, code_space->top()); - if (FLAG_rehash_snapshot && can_rehash()) Rehash(); LogNewMapEvents(); result = handle(root, isolate); } + if (FLAG_rehash_snapshot && can_rehash()) Rehash(); SetupOffHeapArrayBufferBackingStores(); return result; diff --git a/deps/v8/test/cctest/test-serialize.cc b/deps/v8/test/cctest/test-serialize.cc index 7ce8ef71529658..b7590cd0217cff 100644 --- a/deps/v8/test/cctest/test-serialize.cc +++ b/deps/v8/test/cctest/test-serialize.cc @@ -3778,7 +3778,7 @@ UNINITIALIZED_TEST(SnapshotCreatorIncludeGlobalProxy) { FreeCurrentEmbeddedBlob(); } -UNINITIALIZED_TEST(ReinitializeHashSeedNotRehashable) { +UNINITIALIZED_TEST(ReinitializeHashSeedJSCollectionRehashable) { DisableAlwaysOpt(); i::FLAG_rehash_snapshot = true; i::FLAG_hash_seed = 42; @@ -3796,13 +3796,18 @@ UNINITIALIZED_TEST(ReinitializeHashSeedNotRehashable) { CompileRun( "var m = new Map();" "m.set('a', 1);" - "m.set('b', 2);"); + "m.set('b', 2);" + "var s = new Set();" + "s.add(1);" + "s.add(globalThis);"); ExpectInt32("m.get('b')", 2); + ExpectTrue("s.has(1)"); + ExpectTrue("s.has(globalThis)"); creator.SetDefaultContext(context); } blob = creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear); - CHECK(!blob.CanBeRehashed()); + CHECK(blob.CanBeRehashed()); } ReadOnlyHeap::ClearSharedHeapForTest(); @@ -3812,8 +3817,8 @@ UNINITIALIZED_TEST(ReinitializeHashSeedNotRehashable) { create_params.snapshot_blob = &blob; v8::Isolate* isolate = v8::Isolate::New(create_params); { - // Check that no rehashing has been performed. - CHECK_EQ(static_cast(42), + // Check that rehashing has been performed. + CHECK_EQ(static_cast(1337), HashSeed(reinterpret_cast(isolate))); v8::Isolate::Scope isolate_scope(isolate); v8::HandleScope handle_scope(isolate); @@ -3821,6 +3826,8 @@ UNINITIALIZED_TEST(ReinitializeHashSeedNotRehashable) { CHECK(!context.IsEmpty()); v8::Context::Scope context_scope(context); ExpectInt32("m.get('b')", 2); + ExpectTrue("s.has(1)"); + ExpectTrue("s.has(globalThis)"); } isolate->Dispose(); delete[] blob.data;