Reviewers: jochen (traveling),

Description:
Fix Initialize & Dispose for external snapshot. Make sure
v8::V8::(Initialize|Dispose) can be called in any order.



This is a follow-on to crrev.com/960883003, which fixed a memory leak in this
code, but uncovered another, more subtle bug:

Previously, the code expected you would v8::V8::Initialize once, and
v8::V8::Dispose once. The first bug was that in this case the holder_ variable would point to deallocated memory. The second bug was that once the snapshot was
disposed, there was no way to get it back on a future Initialize. These are
uncovered by the InitializeAndDisposeMultiple test case.

The fix is to keep memory to the raw snapshot and to then cleanly build &
destroy the tables in Initialize & Dispose. Since sometimes setNativesBlob is
called just after Initialize, that situation must be handled, too.

BUG=

Please review this at https://codereview.chromium.org/974943003/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+29, -6 lines):
  M src/api.cc
  M src/natives.h
  M src/natives-external.cc
  M src/snapshot-empty.cc


Index: src/api.cc
diff --git a/src/api.cc b/src/api.cc
index 1dd3f616660997266414cd5556540a2c4d697758..3b09e675d35331d34bf743746c26631c81818a77 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -5362,6 +5362,9 @@ void v8::V8::ShutdownPlatform() {

 bool v8::V8::Initialize() {
   i::V8::Initialize();
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+  i::ReadNatives();
+#endif
   return true;
 }

Index: src/natives-external.cc
diff --git a/src/natives-external.cc b/src/natives-external.cc
index 109f9c5f47bfe14cf25a69365502ac1ef7993df7..437addc213ddbd5a34524f4b0c185d987afefd74 100644
--- a/src/natives-external.cc
+++ b/src/natives-external.cc
@@ -132,9 +132,10 @@ class NativesHolder {
     DCHECK(store);
     holder_ = store;
   }
+  static bool empty() { return holder_ == NULL; }
   static void Dispose() {
-    DCHECK(holder_);
     delete holder_;
+    holder_ = NULL;
   }

  private:
@@ -145,19 +146,36 @@ template<NativeType type>
 NativesStore* NativesHolder<type>::holder_ = NULL;


+// The natives blob. Memory is owned by caller.
+static StartupData* natives_blob_ = NULL;
+
+
+/**
+ * Read the Natives blob, as previously set by SetNativesFromFile.
+ */
+void ReadNatives() {
+  if (natives_blob_ && NativesHolder<CORE>::empty()) {
+    SnapshotByteSource bytes(natives_blob_->data, natives_blob_->raw_size);
+    NativesHolder<CORE>::set(NativesStore::MakeFromScriptsSource(&bytes));
+    NativesHolder<EXPERIMENTAL>::set(
+        NativesStore::MakeFromScriptsSource(&bytes));
+    DCHECK(!bytes.HasMore());
+  }
+}
+
+
 /**
- * Read the Natives (library sources) blob, as generated by js2c + the build
+ * Set the Natives (library sources) blob, as generated by js2c + the build
  * system.
  */
 void SetNativesFromFile(StartupData* natives_blob) {
+  DCHECK(!natives_blob_);
   DCHECK(natives_blob);
   DCHECK(natives_blob->data);
   DCHECK(natives_blob->raw_size > 0);

-  SnapshotByteSource bytes(natives_blob->data, natives_blob->raw_size);
-  NativesHolder<CORE>::set(NativesStore::MakeFromScriptsSource(&bytes));
- NativesHolder<EXPERIMENTAL>::set(NativesStore::MakeFromScriptsSource(&bytes));
-  DCHECK(!bytes.HasMore());
+  natives_blob_ = natives_blob;
+  ReadNatives();
 }


Index: src/natives.h
diff --git a/src/natives.h b/src/natives.h
index bec7128a1216ab0f16db245029733b4d697bf200..357faad1f89c824d682292ede5d8001fee4fd4f0 100644
--- a/src/natives.h
+++ b/src/natives.h
@@ -40,6 +40,7 @@ typedef NativesCollection<EXPERIMENTAL> ExperimentalNatives;
 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
// Used for reading the natives at runtime. Implementation in natives-empty.cc
 void SetNativesFromFile(StartupData* natives_blob);
+void ReadNatives();
 void DisposeNatives();
 #endif

Index: src/snapshot-empty.cc
diff --git a/src/snapshot-empty.cc b/src/snapshot-empty.cc
index 9817b2b83b768418a46a2d73de242ff3e2245384..a825b3d7f2735a167524a5a5e8a2f5645cee6b3c 100644
--- a/src/snapshot-empty.cc
+++ b/src/snapshot-empty.cc
@@ -19,6 +19,7 @@ namespace internal {
 // below. This happens when compiling the mksnapshot utility.
 void SetNativesFromFile(StartupData* data) { CHECK(false); }
 void SetSnapshotFromFile(StartupData* data) { CHECK(false); }
+void ReadNatives() {}
 void DisposeNatives() {}
 #endif  // V8_USE_EXTERNAL_STARTUP_DATA



--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to