@@ -109,6 +109,8 @@ void Deserializer::Deserialize(Isolate* isolate) {
109109  LOG_CODE_EVENT (isolate_, LogCodeObjects ());
110110  LOG_CODE_EVENT (isolate_, LogBytecodeHandlers ());
111111  LOG_CODE_EVENT (isolate_, LogCompiledFunctions ());
112+ 
113+   if  (FLAG_rehash_snapshot && can_rehash_) Rehash ();
112114}
113115
114116MaybeHandle<Object> Deserializer::DeserializePartial (
@@ -138,6 +140,9 @@ MaybeHandle<Object> Deserializer::DeserializePartial(
138140  //  changed and logging should be added to notify the profiler et al of the
139141  //  new code, which also has to be flushed from instruction cache.
140142  CHECK_EQ (start_address, code_space->top ());
143+ 
144+   if  (FLAG_rehash_snapshot && can_rehash_) RehashContext (Context::cast (root));
145+ 
141146  return  Handle<Object>(root, isolate);
142147}
143148
@@ -164,6 +169,64 @@ MaybeHandle<SharedFunctionInfo> Deserializer::DeserializeCode(
164169  }
165170}
166171
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+ 
167230Deserializer::~Deserializer () {
168231  //  TODO(svenpanne) Re-enable this assertion when v8 initialization is fixed.
169232  //  DCHECK(source_.AtEOF());
@@ -288,6 +351,18 @@ HeapObject* Deserializer::PostProcessNewObject(HeapObject* obj, int space) {
288351      new_code_objects_.Add (Code::cast (obj));
289352    }
290353  }
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+   }
291366  //  Check alignment.
292367  DCHECK_EQ (0 , Heap::GetFillToAlign (obj->address (), obj->RequiredAlignment ()));
293368  return  obj;
0 commit comments