summaryrefslogtreecommitdiffstats
path: root/gin
diff options
context:
space:
mode:
Diffstat (limited to 'gin')
-rw-r--r--gin/isolate_holder.cc80
-rw-r--r--gin/public/isolate_holder.h11
-rw-r--r--gin/shell/gin_main.cc3
-rw-r--r--gin/shell_runner_unittest.cc8
-rw-r--r--gin/test/file_runner.cc8
-rw-r--r--gin/test/v8_test.cc7
-rw-r--r--gin/v8.isolate15
7 files changed, 131 insertions, 1 deletions
diff --git a/gin/isolate_holder.cc b/gin/isolate_holder.cc
index 740e136..334c0e0 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;
}
diff --git a/gin/public/isolate_holder.h b/gin/public/isolate_holder.h
index 29cc208..4e14ade 100644
--- a/gin/public/isolate_holder.h
+++ b/gin/public/isolate_holder.h
@@ -31,7 +31,9 @@ class GIN_EXPORT IsolateHolder {
~IsolateHolder();
// Should be invoked once before creating IsolateHolder instances to
- // initialize V8 and Gin.
+ // initialize V8 and Gin. In case V8_USE_EXTERNAL_STARTUP_DATA is defined,
+ // V8's initial snapshot should be loaded (by calling LoadV8Snapshot or
+ // LoadV8SnapshotFD) before calling Initialize.
static void Initialize(ScriptMode mode,
v8::ArrayBuffer::Allocator* allocator);
@@ -49,6 +51,13 @@ class GIN_EXPORT IsolateHolder {
// thread.
void RemoveRunMicrotasksObserver();
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+#ifdef OS_ANDROID
+ static bool LoadV8SnapshotFD(int natives_fd, int snapshot_fd);
+#endif
+ static bool LoadV8Snapshot();
+#endif // V8_USE_EXTERNAL_STARTUP_DATA
+
private:
v8::Isolate* isolate_;
scoped_ptr<PerIsolateData> isolate_data_;
diff --git a/gin/shell/gin_main.cc b/gin/shell/gin_main.cc
index b17ec0a..2f7998e 100644
--- a/gin/shell/gin_main.cc
+++ b/gin/shell/gin_main.cc
@@ -60,6 +60,9 @@ int main(int argc, char** argv) {
base::AtExitManager at_exit;
CommandLine::Init(argc, argv);
base::i18n::InitializeICU();
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+ gin::IsolateHolder::LoadV8Snapshot();
+#endif
gin::IsolateHolder::Initialize(gin::IsolateHolder::kStrictMode,
gin::ArrayBufferAllocator::SharedInstance());
diff --git a/gin/shell_runner_unittest.cc b/gin/shell_runner_unittest.cc
index 07ab678..7134de1 100644
--- a/gin/shell_runner_unittest.cc
+++ b/gin/shell_runner_unittest.cc
@@ -10,6 +10,10 @@
#include "gin/public/isolate_holder.h"
#include "testing/gtest/include/gtest/gtest.h"
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+#include "gin/public/isolate_holder.h"
+#endif
+
using v8::Isolate;
using v8::Object;
using v8::Script;
@@ -20,6 +24,10 @@ namespace gin {
TEST(RunnerTest, Run) {
std::string source = "this.result = 'PASS';\n";
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+ gin::IsolateHolder::LoadV8Snapshot();
+#endif
+
gin::IsolateHolder::Initialize(gin::IsolateHolder::kStrictMode,
gin::ArrayBufferAllocator::SharedInstance());
gin::IsolateHolder instance;
diff --git a/gin/test/file_runner.cc b/gin/test/file_runner.cc
index 83228d6..b639d06 100644
--- a/gin/test/file_runner.cc
+++ b/gin/test/file_runner.cc
@@ -19,6 +19,10 @@
#include "gin/try_catch.h"
#include "testing/gtest/include/gtest/gtest.h"
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+#include "gin/public/isolate_holder.h"
+#endif
+
namespace gin {
namespace {
@@ -58,6 +62,10 @@ void RunTestFromFile(const base::FilePath& path, FileRunnerDelegate* delegate,
base::MessageLoop message_loop;
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+ gin::IsolateHolder::LoadV8Snapshot();
+#endif
+
gin::IsolateHolder::Initialize(gin::IsolateHolder::kStrictMode,
gin::ArrayBufferAllocator::SharedInstance());
gin::IsolateHolder instance;
diff --git a/gin/test/v8_test.cc b/gin/test/v8_test.cc
index cb6d573..a022511 100644
--- a/gin/test/v8_test.cc
+++ b/gin/test/v8_test.cc
@@ -7,6 +7,10 @@
#include "gin/array_buffer.h"
#include "gin/public/isolate_holder.h"
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+#include "gin/public/isolate_holder.h"
+#endif
+
using v8::Context;
using v8::Local;
using v8::HandleScope;
@@ -20,6 +24,9 @@ V8Test::~V8Test() {
}
void V8Test::SetUp() {
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+ gin::IsolateHolder::LoadV8Snapshot();
+#endif
gin::IsolateHolder::Initialize(gin::IsolateHolder::kStrictMode,
gin::ArrayBufferAllocator::SharedInstance());
instance_.reset(new gin::IsolateHolder);
diff --git a/gin/v8.isolate b/gin/v8.isolate
new file mode 100644
index 0000000..14d8a2c
--- /dev/null
+++ b/gin/v8.isolate
@@ -0,0 +1,15 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+{
+ 'conditions': [
+ ['v8_use_external_startup_data==1', {
+ 'variables': {
+ 'isolate_dependency_tracked': [
+ '<(PRODUCT_DIR)/natives_blob.bin',
+ '<(PRODUCT_DIR)/snapshot_blob.bin',
+ ],
+ },
+ }],
+ ],
+}