Index: gin/isolate_holder.cc |
diff --git a/gin/isolate_holder.cc b/gin/isolate_holder.cc |
index 740e13640a0ab40ebbc35df043906e96f8904b1e..334c0e0ee5130c6e1c081cb40c9f0541b06a2da9 100644 |
--- a/gin/isolate_holder.cc |
+++ b/gin/isolate_holder.cc |
@@ -18,6 +18,11 @@ |
#include "gin/public/v8_platform.h" |
#include "gin/run_microtasks_observer.h" |
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA |
+#include "base/files/memory_mapped_file.h" |
+#include "base/path_service.h" |
+#endif // V8_USE_EXTERNAL_STARTUP_DATA |
+ |
namespace gin { |
namespace { |
@@ -29,8 +34,70 @@ bool GenerateEntropy(unsigned char* buffer, size_t amount) { |
return true; |
} |
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA |
+base::MemoryMappedFile* g_mapped_natives = NULL; |
+base::MemoryMappedFile* g_mapped_snapshot = NULL; |
+ |
+bool MapV8Files(base::FilePath* natives_path, base::FilePath* snapshot_path, |
+ int natives_fd = -1, int snapshot_fd = -1) { |
+ int flags = base::File::FLAG_OPEN | base::File::FLAG_READ; |
+ |
+ g_mapped_natives = new base::MemoryMappedFile; |
+ if (!g_mapped_natives->IsValid()) { |
+ if (natives_fd == -1 |
+ ? !g_mapped_natives->Initialize(base::File(*natives_path, flags)) |
+ : !g_mapped_natives->Initialize(base::File(natives_fd))) { |
+ delete g_mapped_natives; |
+ g_mapped_natives = NULL; |
+ LOG(FATAL) << "Couldn't mmap v8 natives data file"; |
+ return false; |
+ } |
+ } |
+ |
+ g_mapped_snapshot = new base::MemoryMappedFile; |
+ if (!g_mapped_snapshot->IsValid()) { |
+ if (snapshot_fd == -1 |
+ ? !g_mapped_snapshot->Initialize(base::File(*snapshot_path, flags)) |
+ : !g_mapped_snapshot->Initialize(base::File(snapshot_fd))) { |
+ delete g_mapped_snapshot; |
+ g_mapped_snapshot = NULL; |
+ LOG(ERROR) << "Couldn't mmap v8 snapshot data file"; |
+ return false; |
+ } |
+ } |
+ |
+ return true; |
+} |
+#endif // V8_USE_EXTERNAL_STARTUP_DATA |
+ |
} // namespace |
+ |
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA |
+// static |
+bool IsolateHolder::LoadV8Snapshot() { |
+ if (g_mapped_natives && g_mapped_snapshot) |
+ return true; |
+ |
+ base::FilePath data_path; |
+ PathService::Get(base::DIR_ANDROID_APP_DATA, &data_path); |
+ DCHECK(!data_path.empty()); |
+ |
+ base::FilePath natives_path = data_path.AppendASCII("natives_blob.bin"); |
+ base::FilePath snapshot_path = data_path.AppendASCII("snapshot_blob.bin"); |
+ |
+ return MapV8Files(&natives_path, &snapshot_path); |
+} |
+ |
+//static |
+bool IsolateHolder::LoadV8SnapshotFD(int natives_fd, int snapshot_fd) { |
+ if (g_mapped_natives && g_mapped_snapshot) |
+ return true; |
+ |
+ return MapV8Files(NULL, NULL, natives_fd, snapshot_fd); |
+} |
+#endif // V8_USE_EXTERNAL_STARTUP_DATA |
+ |
IsolateHolder::IsolateHolder() { |
CHECK(g_array_buffer_allocator) |
<< "You need to invoke gin::IsolateHolder::Initialize first"; |
@@ -88,6 +155,19 @@ void IsolateHolder::Initialize(ScriptMode mode, |
v8::V8::SetFlagsFromString(v8_flags, sizeof(v8_flags) - 1); |
} |
v8::V8::SetEntropySource(&GenerateEntropy); |
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA |
+ v8::StartupData natives; |
+ natives.data = reinterpret_cast<const char*>(g_mapped_natives->data()); |
+ natives.raw_size = g_mapped_natives->length(); |
+ natives.compressed_size = g_mapped_natives->length(); |
+ v8::V8::SetNativesDataBlob(&natives); |
+ |
+ v8::StartupData snapshot; |
+ snapshot.data = reinterpret_cast<const char*>(g_mapped_snapshot->data()); |
+ snapshot.raw_size = g_mapped_snapshot->length(); |
+ snapshot.compressed_size = g_mapped_snapshot->length(); |
+ v8::V8::SetSnapshotDataBlob(&snapshot); |
+#endif // V8_USE_EXTERNAL_STARTUP_DATA |
v8::V8::Initialize(); |
v8_is_initialized = true; |
} |