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