@@ -121,6 +121,8 @@ void Deserializer::Deserialize(Isolate* isolate) {
121121 LOG_CODE_EVENT (isolate_, LogCodeObjects ());
122122 LOG_CODE_EVENT (isolate_, LogBytecodeHandlers ());
123123 LOG_CODE_EVENT (isolate_, LogCompiledFunctions ());
124+
125+ if (FLAG_rehash_snapshot && can_rehash_) Rehash ();
124126}
125127
126128MaybeHandle<Object> Deserializer::DeserializePartial (
@@ -151,6 +153,9 @@ MaybeHandle<Object> Deserializer::DeserializePartial(
151153 // changed and logging should be added to notify the profiler et al of the
152154 // new code, which also has to be flushed from instruction cache.
153155 CHECK_EQ (start_address, code_space->top ());
156+
157+ if (FLAG_rehash_snapshot && can_rehash_) RehashContext (Context::cast (root));
158+
154159 return Handle<Object>(root, isolate);
155160}
156161
@@ -177,6 +182,63 @@ MaybeHandle<HeapObject> Deserializer::DeserializeObject(Isolate* isolate) {
177182 }
178183}
179184
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+
180242Deserializer::~Deserializer () {
181243#ifdef DEBUG
182244 // Do not perform checks if we aborted deserialization.
@@ -367,6 +429,16 @@ HeapObject* Deserializer::PostProcessNewObject(HeapObject* obj, int space) {
367429 string->resource ()));
368430 isolate_->heap ()->RegisterExternalString (string);
369431 }
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+ }
370442 // Check alignment.
371443 DCHECK_EQ (0 , Heap::GetFillToAlign (obj->address (), obj->RequiredAlignment ()));
372444 return obj;
0 commit comments