Skip to content

Commit

Permalink
gin: Hide V8 context snapshot behind a build flag
Browse files Browse the repository at this point in the history
We had V8 context snapshot in C++ code regardless V8 settings,
but it introduced some complex errors.
This CL disables usages of V8 context snapshot if a GN flag
"v8_use_external_startup_data" is not true, because V8 context
snapshot depends on what is built with the flag.


Bug: 764576
Change-Id: If9b1cc497a6f6122f213b83ed2f9746d9af8bb62
Reviewed-on: https://chromium-review.googlesource.com/788631
Reviewed-by: Kinuko Yasuda <kinuko@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Commit-Queue: Hitoshi Yoshida <peria@chromium.org>
Cr-Commit-Position: refs/heads/master@{#519208}
  • Loading branch information
peria authored and Commit Bot committed Nov 27, 2017
1 parent a92cfc9 commit ba9c2f0
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 136 deletions.
16 changes: 8 additions & 8 deletions content/app/content_main_runner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ void InitializeFieldTrialAndFeatureList(
base::FeatureList::SetInstance(std::move(feature_list));
}

#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
void LoadV8ContextSnapshotFile() {
#if defined(OS_POSIX) && !defined(OS_MACOSX)
base::FileDescriptorStore& file_descriptor_store =
Expand All @@ -181,14 +182,13 @@ void LoadV8ContextSnapshotFile() {
region.size);
return;
}
#endif // OS
#endif // OS_POSIX && !OS_MACOSX
#if !defined(CHROME_MULTIPLE_DLL_BROWSER)
gin::V8Initializer::LoadV8ContextSnapshot();
#endif
#endif // !CHROME_MULTIPLE_DLL_BROWSER
}

void LoadV8SnapshotFile() {
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
#if defined(OS_POSIX) && !defined(OS_MACOSX)
base::FileDescriptorStore& file_descriptor_store =
base::FileDescriptorStore::GetInstance();
Expand All @@ -203,12 +203,10 @@ void LoadV8SnapshotFile() {
#endif // OS_POSIX && !OS_MACOSX
#if !defined(CHROME_MULTIPLE_DLL_BROWSER)
gin::V8Initializer::LoadV8Snapshot();
#endif
#endif // V8_USE_EXTERNAL_STARTUP_DATA
#endif // !CHROME_MULTIPLE_DLL_BROWSER
}

void LoadV8NativesFile() {
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
#if defined(OS_POSIX) && !defined(OS_MACOSX)
base::FileDescriptorStore& file_descriptor_store =
base::FileDescriptorStore::GetInstance();
Expand All @@ -223,18 +221,20 @@ void LoadV8NativesFile() {
#endif // OS_POSIX && !OS_MACOSX
#if !defined(CHROME_MULTIPLE_DLL_BROWSER)
gin::V8Initializer::LoadV8Natives();
#endif
#endif // V8_USE_EXTERNAL_STARTUP_DATA
#endif // !CHROME_MULTIPLE_DLL_BROWSER
}
#endif // V8_USE_EXTERNAL_STARTUP_DATA

void InitializeV8IfNeeded(const base::CommandLine& command_line,
const std::string& process_type) {
if (process_type == switches::kGpuProcess)
return;

#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
LoadV8SnapshotFile();
LoadV8NativesFile();
LoadV8ContextSnapshotFile();
#endif // V8_USE_EXTERNAL_STARTUP_DATA
}

} // namespace
Expand Down
215 changes: 107 additions & 108 deletions gin/v8_initializer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,23 @@ base::MemoryMappedFile* g_mapped_natives = nullptr;
base::MemoryMappedFile* g_mapped_snapshot = nullptr;
base::MemoryMappedFile* g_mapped_v8_context_snapshot = nullptr;

const char kV8ContextSnapshotFileName[] = "v8_context_snapshot.bin";
bool GenerateEntropy(unsigned char* buffer, size_t amount) {
base::RandBytes(buffer, amount);
return true;
}

void GetMappedFileData(base::MemoryMappedFile* mapped_file,
v8::StartupData* data) {
if (mapped_file) {
data->data = reinterpret_cast<const char*>(mapped_file->data());
data->raw_size = static_cast<int>(mapped_file->length());
} else {
data->data = nullptr;
data->raw_size = 0;
}
}

#if defined(V8_USE_EXTERNAL_STARTUP_DATA)

// File handles intentionally never closed. Not using File here because its
// Windows implementation guards against two instances owning the same
Expand All @@ -54,9 +70,8 @@ using OpenedFileMap =
base::LazyInstance<OpenedFileMap>::Leaky g_opened_files =
LAZY_INSTANCE_INITIALIZER;

#if defined(V8_USE_EXTERNAL_STARTUP_DATA)

const char kNativesFileName[] = "natives_blob.bin";
const char kV8ContextSnapshotFileName[] = "v8_context_snapshot.bin";

#if defined(OS_ANDROID)
const char kSnapshotFileName64[] = "snapshot_blob_64.bin";
Expand All @@ -72,8 +87,6 @@ const char kSnapshotFileName32[] = "snapshot_blob_32.bin";
const char kSnapshotFileName[] = "snapshot_blob.bin";
#endif // defined(OS_ANDROID)

#endif // defined(V8_USE_EXTERNAL_STATUP_DATA)

void GetV8FilePath(const char* file_name, base::FilePath* path_out) {
#if !defined(OS_MACOSX)
base::FilePath data_path;
Expand Down Expand Up @@ -188,11 +201,6 @@ OpenedFileMap::mapped_type& GetOpenedFile(const char* filename) {
return opened_file;
}

bool GenerateEntropy(unsigned char* buffer, size_t amount) {
base::RandBytes(buffer, amount);
return true;
}

enum LoadV8FileResult {
V8_LOAD_SUCCESS = 0,
V8_LOAD_FAILED_OPEN,
Expand All @@ -210,18 +218,73 @@ LoadV8FileResult MapOpenedFile(const OpenedFileMap::mapped_type& file_region,
return V8_LOAD_SUCCESS;
}

void GetMappedFileData(base::MemoryMappedFile* mapped_file,
v8::StartupData* data) {
if (mapped_file) {
data->data = reinterpret_cast<const char*>(mapped_file->data());
data->raw_size = static_cast<int>(mapped_file->length());
} else {
data->data = nullptr;
data->raw_size = 0;
#endif // defined(V8_USE_EXTERNAL_STATUP_DATA)

} // namespace

// static
void V8Initializer::Initialize(IsolateHolder::ScriptMode mode,
IsolateHolder::V8ExtrasMode v8_extras_mode) {
static bool v8_is_initialized = false;
if (v8_is_initialized)
return;

v8::V8::InitializePlatform(V8Platform::Get());

if (IsolateHolder::kStrictMode == mode) {
static const char use_strict[] = "--use_strict";
v8::V8::SetFlagsFromString(use_strict, sizeof(use_strict) - 1);
}
if (IsolateHolder::kStableAndExperimentalV8Extras == v8_extras_mode) {
static const char flag[] = "--experimental_extras";
v8::V8::SetFlagsFromString(flag, sizeof(flag) - 1);
}

#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
v8::StartupData natives;
natives.data = reinterpret_cast<const char*>(g_mapped_natives->data());
natives.raw_size = static_cast<int>(g_mapped_natives->length());
v8::V8::SetNativesDataBlob(&natives);

if (g_mapped_snapshot) {
v8::StartupData snapshot;
snapshot.data = reinterpret_cast<const char*>(g_mapped_snapshot->data());
snapshot.raw_size = static_cast<int>(g_mapped_snapshot->length());
v8::V8::SetSnapshotDataBlob(&snapshot);
}
#endif // V8_USE_EXTERNAL_STARTUP_DATA

v8::V8::SetEntropySource(&GenerateEntropy);
v8::V8::Initialize();

v8_is_initialized = true;
}

} // namespace
// static
void V8Initializer::GetV8ExternalSnapshotData(v8::StartupData* natives,
v8::StartupData* snapshot) {
GetMappedFileData(g_mapped_natives, natives);
GetMappedFileData(g_mapped_snapshot, snapshot);
}

// static
void V8Initializer::GetV8ExternalSnapshotData(const char** natives_data_out,
int* natives_size_out,
const char** snapshot_data_out,
int* snapshot_size_out) {
v8::StartupData natives;
v8::StartupData snapshot;
GetV8ExternalSnapshotData(&natives, &snapshot);
*natives_data_out = natives.data;
*natives_size_out = natives.raw_size;
*snapshot_data_out = snapshot.data;
*snapshot_size_out = snapshot.raw_size;
}

// static
void V8Initializer::GetV8ContextSnapshotData(v8::StartupData* snapshot) {
GetMappedFileData(g_mapped_v8_context_snapshot, snapshot);
}

#if defined(V8_USE_EXTERNAL_STARTUP_DATA)

Expand Down Expand Up @@ -250,6 +313,17 @@ void V8Initializer::LoadV8Natives() {
}
}

// static
void V8Initializer::LoadV8ContextSnapshot() {
if (g_mapped_v8_context_snapshot)
return;

MapOpenedFile(GetOpenedFile(kV8ContextSnapshotFileName),
&g_mapped_v8_context_snapshot);

// TODO(peria): Check if the snapshot file is loaded successfully.
}

// static
void V8Initializer::LoadV8SnapshotFromFD(base::PlatformFile snapshot_pf,
int64_t snapshot_offset,
Expand Down Expand Up @@ -301,93 +375,6 @@ void V8Initializer::LoadV8NativesFromFD(base::PlatformFile natives_pf,
std::make_pair(natives_pf, natives_region);
}

#if defined(OS_ANDROID)
// static
base::FilePath V8Initializer::GetNativesFilePath() {
base::FilePath path;
GetV8FilePath(kNativesFileName, &path);
return path;
}

// static
base::FilePath V8Initializer::GetSnapshotFilePath(bool abi_32_bit) {
base::FilePath path;
GetV8FilePath(abi_32_bit ? kSnapshotFileName32 : kSnapshotFileName64, &path);
return path;
}
#endif // defined(OS_ANDROID)
#endif // defined(V8_USE_EXTERNAL_STARTUP_DATA)

// static
void V8Initializer::Initialize(IsolateHolder::ScriptMode mode,
IsolateHolder::V8ExtrasMode v8_extras_mode) {
static bool v8_is_initialized = false;
if (v8_is_initialized)
return;

v8::V8::InitializePlatform(V8Platform::Get());

if (IsolateHolder::kStrictMode == mode) {
static const char use_strict[] = "--use_strict";
v8::V8::SetFlagsFromString(use_strict, sizeof(use_strict) - 1);
}
if (IsolateHolder::kStableAndExperimentalV8Extras == v8_extras_mode) {
static const char flag[] = "--experimental_extras";
v8::V8::SetFlagsFromString(flag, sizeof(flag) - 1);
}

#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
v8::StartupData natives;
natives.data = reinterpret_cast<const char*>(g_mapped_natives->data());
natives.raw_size = static_cast<int>(g_mapped_natives->length());
v8::V8::SetNativesDataBlob(&natives);

if (g_mapped_snapshot) {
v8::StartupData snapshot;
snapshot.data = reinterpret_cast<const char*>(g_mapped_snapshot->data());
snapshot.raw_size = static_cast<int>(g_mapped_snapshot->length());
v8::V8::SetSnapshotDataBlob(&snapshot);
}
#endif // V8_USE_EXTERNAL_STARTUP_DATA

v8::V8::SetEntropySource(&GenerateEntropy);
v8::V8::Initialize();

v8_is_initialized = true;
}

// static
void V8Initializer::GetV8ExternalSnapshotData(v8::StartupData* natives,
v8::StartupData* snapshot) {
GetMappedFileData(g_mapped_natives, natives);
GetMappedFileData(g_mapped_snapshot, snapshot);
}

// static
void V8Initializer::GetV8ExternalSnapshotData(const char** natives_data_out,
int* natives_size_out,
const char** snapshot_data_out,
int* snapshot_size_out) {
v8::StartupData natives;
v8::StartupData snapshot;
GetV8ExternalSnapshotData(&natives, &snapshot);
*natives_data_out = natives.data;
*natives_size_out = natives.raw_size;
*snapshot_data_out = snapshot.data;
*snapshot_size_out = snapshot.raw_size;
}

// static
void V8Initializer::LoadV8ContextSnapshot() {
if (g_mapped_v8_context_snapshot)
return;

MapOpenedFile(GetOpenedFile(kV8ContextSnapshotFileName),
&g_mapped_v8_context_snapshot);

// TODO(peria): Check if the snapshot file is loaded successfully.
}

// static
void V8Initializer::LoadV8ContextSnapshotFromFD(base::PlatformFile snapshot_pf,
int64_t snapshot_offset,
Expand All @@ -409,9 +396,21 @@ void V8Initializer::LoadV8ContextSnapshotFromFD(base::PlatformFile snapshot_pf,
}
}

#if defined(OS_ANDROID)
// static
void V8Initializer::GetV8ContextSnapshotData(v8::StartupData* snapshot) {
GetMappedFileData(g_mapped_v8_context_snapshot, snapshot);
base::FilePath V8Initializer::GetNativesFilePath() {
base::FilePath path;
GetV8FilePath(kNativesFileName, &path);
return path;
}

// static
base::FilePath V8Initializer::GetSnapshotFilePath(bool abi_32_bit) {
base::FilePath path;
GetV8FilePath(abi_32_bit ? kSnapshotFileName32 : kSnapshotFileName64, &path);
return path;
}
#endif // defined(OS_ANDROID)
#endif // defined(V8_USE_EXTERNAL_STARTUP_DATA)

} // namespace gin
36 changes: 17 additions & 19 deletions gin/v8_initializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,20 @@ class GIN_EXPORT V8Initializer {
const char** snapshot_data_out,
int* snapshot_size_out);

// Get address and size information for currently loaded V8 context snapshot.
// If no snapshot is loaded, the return values are nullptr and 0.
static void GetV8ContextSnapshotData(v8::StartupData* snapshot);

#if defined(V8_USE_EXTERNAL_STARTUP_DATA)

// Load V8 snapshot from default resources, if they are available.
static void LoadV8Snapshot();
// Load V8 natives source from default resources. Contains asserts
// so that it will not return if natives cannot be loaded.
static void LoadV8Natives();
// Load V8 context snapshot from default resources, if they are available.
static void LoadV8ContextSnapshot();

// Load V8 snapshot from user provided platform file descriptors.
// The offset and size arguments, if non-zero, specify the portions
// of the files to be loaded. Since the VM can boot with or without
Expand All @@ -48,13 +60,11 @@ class GIN_EXPORT V8Initializer {
static void LoadV8NativesFromFD(base::PlatformFile natives_fd,
int64_t natives_offset,
int64_t natives_size);

// Load V8 snapshot from default resources, if they are available.
static void LoadV8Snapshot();

// Load V8 natives source from default resources. Contains asserts
// so that it will not return if natives cannot be loaded.
static void LoadV8Natives();
// Load V8 context snapshot from user provided platform file descriptors.
// Other details are same with LoadV8SnapshotFromFD.
static void LoadV8ContextSnapshotFromFD(base::PlatformFile snapshot_fd,
int64_t snapshot_offset,
int64_t snapshot_size);

#if defined(OS_ANDROID)
static base::FilePath GetNativesFilePath();
Expand All @@ -63,18 +73,6 @@ class GIN_EXPORT V8Initializer {

#endif // V8_USE_EXTERNAL_STARTUP_DATA

// Load V8 context snapshot from user provided platform file descriptors.
// Other details are same with LoadV8SnapshotFromFD.
static void LoadV8ContextSnapshotFromFD(base::PlatformFile snapshot_fd,
int64_t snapshot_offset,
int64_t snapshot_size);

// Load V8 context snapshot from default resources, if they are available.
static void LoadV8ContextSnapshot();

// Get address and size information for currently loaded V8 context snapshot.
// If no snapshot is loaded, the return values are nullptr and 0.
static void GetV8ContextSnapshotData(v8::StartupData* snapshot);
};

} // namespace gin
Expand Down
Loading

0 comments on commit ba9c2f0

Please sign in to comment.