Serialzier: expand string table as last step before deserializing.
authoryangguo <yangguo@chromium.org>
Fri, 19 Jun 2015 08:07:01 +0000 (01:07 -0700)
committerCommit bot <commit-bot@chromium.org>
Fri, 19 Jun 2015 08:07:08 +0000 (08:07 +0000)
Not doing so could result in this scenario:
- We ensure that the string table is large enough. It is.
- We compile code stubs, which triggers a GC.
- The GC clears string table entries.
- This increases the number of deleted entries in the table.
- When the deserializer hooks up internalized strings into the
  table, we ensure that the table is large enough every time.
- Due to changed number of deleted entries, the heuristic
  decides to expand the string table.
- Allocation during deserialization causes assertion to fail.

BUG=chromium:502085
LOG=N

Review URL: https://codereview.chromium.org/1197633002

Cr-Commit-Position: refs/heads/master@{#29134}

src/snapshot/serialize.cc

index fe33c3e..980e499 100644 (file)
@@ -564,11 +564,15 @@ void Deserializer::Deserialize(Isolate* isolate) {
   DCHECK_NULL(isolate_->thread_manager()->FirstThreadStateInUse());
   // No active handles.
   DCHECK(isolate_->handle_scope_implementer()->blocks()->is_empty());
-  isolate_->heap()->IterateSmiRoots(this);
-  isolate_->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG);
-  isolate_->heap()->RepairFreeListsAfterDeserialization();
-  isolate_->heap()->IterateWeakRoots(this, VISIT_ALL);
-  DeserializeDeferredObjects();
+
+  {
+    DisallowHeapAllocation no_gc;
+    isolate_->heap()->IterateSmiRoots(this);
+    isolate_->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG);
+    isolate_->heap()->RepairFreeListsAfterDeserialization();
+    isolate_->heap()->IterateWeakRoots(this, VISIT_ALL);
+    DeserializeDeferredObjects();
+  }
 
   isolate_->heap()->set_native_contexts_list(
       isolate_->heap()->undefined_value());
@@ -2431,10 +2435,6 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
     return MaybeHandle<SharedFunctionInfo>();
   }
 
-  // Eagerly expand string table to avoid allocations during deserialization.
-  StringTable::EnsureCapacityForDeserialization(isolate,
-                                                scd->NumInternalizedStrings());
-
   // Prepare and register list of attached objects.
   Vector<const uint32_t> code_stub_keys = scd->CodeStubKeys();
   Vector<Handle<Object> > attached_objects = Vector<Handle<Object> >::New(
@@ -2445,6 +2445,10 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
         CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked();
   }
 
+  // Eagerly expand string table to avoid allocations during deserialization.
+  StringTable::EnsureCapacityForDeserialization(isolate,
+                                                scd->NumInternalizedStrings());
+
   Deserializer deserializer(scd.get());
   deserializer.SetAttachedObjects(attached_objects);