@@ -109,6 +109,8 @@ void Deserializer::Deserialize(Isolate* isolate) {
109
109
LOG_CODE_EVENT (isolate_, LogCodeObjects ());
110
110
LOG_CODE_EVENT (isolate_, LogBytecodeHandlers ());
111
111
LOG_CODE_EVENT (isolate_, LogCompiledFunctions ());
112
+
113
+ if (FLAG_rehash_snapshot && can_rehash_) Rehash ();
112
114
}
113
115
114
116
MaybeHandle<Object> Deserializer::DeserializePartial (
@@ -138,6 +140,9 @@ MaybeHandle<Object> Deserializer::DeserializePartial(
138
140
// changed and logging should be added to notify the profiler et al of the
139
141
// new code, which also has to be flushed from instruction cache.
140
142
CHECK_EQ (start_address, code_space->top ());
143
+
144
+ if (FLAG_rehash_snapshot && can_rehash_) RehashContext (Context::cast (root));
145
+
141
146
return Handle <Object>(root, isolate);
142
147
}
143
148
@@ -164,6 +169,64 @@ MaybeHandle<SharedFunctionInfo> Deserializer::DeserializeCode(
164
169
}
165
170
}
166
171
172
+ // We only really just need HashForObject here.
173
+ class StringRehashKey : public HashTableKey {
174
+ public:
175
+ uint32_t HashForObject (Object* other) override {
176
+ return String::cast (other)->Hash ();
177
+ }
178
+
179
+ static uint32_t StringHash (Object* obj) {
180
+ UNREACHABLE ();
181
+ return String::cast (obj)->Hash ();
182
+ }
183
+
184
+ bool IsMatch (Object* string) override {
185
+ UNREACHABLE ();
186
+ return false ;
187
+ }
188
+
189
+ uint32_t Hash () override {
190
+ UNREACHABLE ();
191
+ return 0 ;
192
+ }
193
+
194
+ Handle <Object> AsHandle (Isolate* isolate) override {
195
+ UNREACHABLE ();
196
+ return isolate->factory ()->empty_string ();
197
+ }
198
+ };
199
+
200
+ void Deserializer::Rehash () {
201
+ DCHECK (can_rehash_);
202
+ isolate_->heap ()->InitializeHashSeed ();
203
+ if (FLAG_profile_deserialization) {
204
+ PrintF (" Re-initializing hash seed to %x\n " ,
205
+ isolate_->heap ()->hash_seed ()->value ());
206
+ }
207
+ StringRehashKey string_rehash_key;
208
+ isolate_->heap ()->string_table ()->Rehash (&string_rehash_key);
209
+ isolate_->heap ()->intrinsic_function_names ()->Rehash (
210
+ isolate_->factory ()->empty_string ());
211
+ SortMapDescriptors ();
212
+ }
213
+
214
+ void Deserializer::RehashContext (Context* context) {
215
+ DCHECK (can_rehash_);
216
+ for (const auto & array : transition_arrays_) array->Sort ();
217
+ Handle <Name> dummy = isolate_->factory ()->empty_string ();
218
+ context->global_object ()->global_dictionary ()->Rehash (dummy);
219
+ SortMapDescriptors ();
220
+ }
221
+
222
+ void Deserializer::SortMapDescriptors () {
223
+ for (const auto & map : maps_) {
224
+ if (map->instance_descriptors ()->number_of_descriptors () > 1 ) {
225
+ map->instance_descriptors ()->Sort ();
226
+ }
227
+ }
228
+ }
229
+
167
230
Deserializer::~Deserializer () {
168
231
// TODO(svenpanne) Re-enable this assertion when v8 initialization is fixed.
169
232
// DCHECK(source_.AtEOF());
@@ -288,6 +351,18 @@ HeapObject* Deserializer::PostProcessNewObject(HeapObject* obj, int space) {
288
351
new_code_objects_.Add (Code::cast (obj));
289
352
}
290
353
}
354
+ if (FLAG_rehash_snapshot && can_rehash_ && !deserializing_user_code ()) {
355
+ if (obj->IsString ()) {
356
+ // Uninitialize hash field as we are going to reinitialize the hash seed.
357
+ String* string = String::cast (obj);
358
+ string->set_hash_field (String::kEmptyHashField );
359
+ } else if (obj->IsTransitionArray () &&
360
+ TransitionArray::cast (obj)->number_of_entries () > 1 ) {
361
+ transition_arrays_.Add (TransitionArray::cast (obj));
362
+ } else if (obj->IsMap ()) {
363
+ maps_.Add (Map::cast (obj));
364
+ }
365
+ }
291
366
// Check alignment.
292
367
DCHECK_EQ (0 , Heap::GetFillToAlign (obj->address (), obj->RequiredAlignment ()));
293
368
return obj;
0 commit comments