@@ -121,6 +121,8 @@ void Deserializer::Deserialize(Isolate* isolate) {
121
121
LOG_CODE_EVENT (isolate_, LogCodeObjects ());
122
122
LOG_CODE_EVENT (isolate_, LogBytecodeHandlers ());
123
123
LOG_CODE_EVENT (isolate_, LogCompiledFunctions ());
124
+
125
+ if (FLAG_rehash_snapshot && can_rehash_) Rehash ();
124
126
}
125
127
126
128
MaybeHandle<Object> Deserializer::DeserializePartial (
@@ -151,6 +153,9 @@ MaybeHandle<Object> Deserializer::DeserializePartial(
151
153
// changed and logging should be added to notify the profiler et al of the
152
154
// new code, which also has to be flushed from instruction cache.
153
155
CHECK_EQ (start_address, code_space->top ());
156
+
157
+ if (FLAG_rehash_snapshot && can_rehash_) RehashContext (Context::cast (root));
158
+
154
159
return Handle<Object>(root, isolate);
155
160
}
156
161
@@ -177,6 +182,63 @@ MaybeHandle<HeapObject> Deserializer::DeserializeObject(Isolate* isolate) {
177
182
}
178
183
}
179
184
185
+ // We only really just need HashForObject here.
186
+ class StringRehashKey : public HashTableKey {
187
+ public:
188
+ uint32_t HashForObject (Object* other) override {
189
+ return String::cast (other)->Hash ();
190
+ }
191
+
192
+ static uint32_t StringHash (Object* obj) {
193
+ UNREACHABLE ();
194
+ return String::cast (obj)->Hash ();
195
+ }
196
+
197
+ bool IsMatch (Object* string) override {
198
+ UNREACHABLE ();
199
+ return false ;
200
+ }
201
+
202
+ uint32_t Hash () override {
203
+ UNREACHABLE ();
204
+ return 0 ;
205
+ }
206
+
207
+ Handle<Object> AsHandle (Isolate* isolate) override {
208
+ UNREACHABLE ();
209
+ return isolate->factory ()->empty_string ();
210
+ }
211
+ };
212
+
213
+ void Deserializer::Rehash () {
214
+ DCHECK (can_rehash_);
215
+ isolate_->heap ()->InitializeHashSeed ();
216
+ if (FLAG_profile_deserialization) {
217
+ PrintF (" Re-initializing hash seed to %x\n " ,
218
+ isolate_->heap ()->hash_seed ()->value ());
219
+ }
220
+ StringRehashKey string_rehash_key;
221
+ isolate_->heap ()->string_table ()->Rehash (&string_rehash_key);
222
+ SortMapDescriptors ();
223
+ }
224
+
225
+ void Deserializer::RehashContext (Context* context) {
226
+ DCHECK (can_rehash_);
227
+ for (const auto & array : transition_arrays_) array->Sort ();
228
+ Handle<Name> dummy = isolate_->factory ()->empty_string ();
229
+ context->global_object ()->global_dictionary ()->Rehash (dummy);
230
+ SortMapDescriptors ();
231
+ }
232
+
233
+ void Deserializer::SortMapDescriptors () {
234
+ for (const auto & address : allocated_maps_) {
235
+ Map* map = Map::cast (HeapObject::FromAddress (address));
236
+ if (map->instance_descriptors ()->number_of_descriptors () > 1 ) {
237
+ map->instance_descriptors ()->Sort ();
238
+ }
239
+ }
240
+ }
241
+
180
242
Deserializer::~Deserializer () {
181
243
#ifdef DEBUG
182
244
// Do not perform checks if we aborted deserialization.
@@ -367,6 +429,16 @@ HeapObject* Deserializer::PostProcessNewObject(HeapObject* obj, int space) {
367
429
string->resource ()));
368
430
isolate_->heap ()->RegisterExternalString (string);
369
431
}
432
+ if (FLAG_rehash_snapshot && can_rehash_ && !deserializing_user_code ()) {
433
+ if (obj->IsString ()) {
434
+ // Uninitialize hash field as we are going to reinitialize the hash seed.
435
+ String* string = String::cast (obj);
436
+ string->set_hash_field (String::kEmptyHashField );
437
+ } else if (obj->IsTransitionArray () &&
438
+ TransitionArray::cast (obj)->number_of_entries () > 1 ) {
439
+ transition_arrays_.Add (TransitionArray::cast (obj));
440
+ }
441
+ }
370
442
// Check alignment.
371
443
DCHECK_EQ (0 , Heap::GetFillToAlign (obj->address (), obj->RequiredAlignment ()));
372
444
return obj;
0 commit comments