@@ -15,7 +15,9 @@ PartialSerializer::PartialSerializer(
15
15
v8::SerializeEmbedderFieldsCallback callback)
16
16
: Serializer(isolate),
17
17
startup_serializer_(startup_serializer),
18
- serialize_embedder_fields_(callback) {
18
+ serialize_embedder_fields_(callback),
19
+ rehashable_global_dictionary_(nullptr),
20
+ can_be_rehashed_(true) {
19
21
InitializeCodeAddressMap();
20
22
}
21
23
@@ -24,22 +26,26 @@ PartialSerializer::~PartialSerializer() {
24
26
}
25
27
26
28
void PartialSerializer::Serialize(Object** o, bool include_global_proxy) {
27
- if ((*o)->IsContext ()) {
29
+ if ((*o)->IsNativeContext ()) {
28
30
Context* context = Context::cast(*o);
29
31
reference_map()->AddAttachedReference(context->global_proxy());
30
32
// The bootstrap snapshot has a code-stub context. When serializing the
31
33
// partial snapshot, it is chained into the weak context list on the isolate
32
34
// and it's next context pointer may point to the code-stub context. Clear
33
35
// it before serializing, it will get re-added to the context list
34
36
// explicitly when it's loaded.
35
- if (context->IsNativeContext ()) {
36
- context->set (Context::NEXT_CONTEXT_LINK,
37
- isolate_->heap ()->undefined_value ());
38
- DCHECK (!context->global_object ()->IsUndefined (context->GetIsolate ()));
39
- // Reset math random cache to get fresh random numbers.
40
- context->set_math_random_index (Smi::kZero );
41
- context->set_math_random_cache (isolate_->heap ()->undefined_value ());
42
- }
37
+ context->set(Context::NEXT_CONTEXT_LINK,
38
+ isolate_->heap()->undefined_value());
39
+ DCHECK(!context->global_object()->IsUndefined(context->GetIsolate()));
40
+ // Reset math random cache to get fresh random numbers.
41
+ context->set_math_random_index(Smi::kZero);
42
+ context->set_math_random_cache(isolate_->heap()->undefined_value());
43
+ DCHECK_NULL(rehashable_global_dictionary_);
44
+ rehashable_global_dictionary_ =
45
+ context->global_object()->global_dictionary();
46
+ } else {
47
+ // We only do rehashing for native contexts.
48
+ can_be_rehashed_ = false;
43
49
}
44
50
VisitRootPointer(Root::kPartialSnapshotCache, o);
45
51
SerializeDeferredObjects();
@@ -104,6 +110,8 @@ void PartialSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
104
110
}
105
111
}
106
112
113
+ if (obj->IsHashTable()) CheckRehashability(obj);
114
+
107
115
// Object has not yet been serialized. Serialize it here.
108
116
ObjectSerializer serializer(this, obj, &sink_, how_to_code, where_to_point);
109
117
serializer.Serialize();
@@ -152,5 +160,14 @@ void PartialSerializer::SerializeEmbedderFields() {
152
160
sink_.Put(kSynchronize, "Finished with embedder fields data");
153
161
}
154
162
163
+ void PartialSerializer::CheckRehashability(HeapObject* table) {
164
+ DCHECK(table->IsHashTable());
165
+ if (!can_be_rehashed_) return;
166
+ // We can only correctly rehash if the global dictionary is the only hash
167
+ // table that we deserialize.
168
+ if (table == rehashable_global_dictionary_) return;
169
+ can_be_rehashed_ = false;
170
+ }
171
+
155
172
} // namespace internal
156
173
} // namespace v8
0 commit comments