@@ -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