Skip to content

Commit

Permalink
Pass both 32 and 64 bit snapshot and natives fds to child processes.
Browse files Browse the repository at this point in the history
Child processes are in the best position to determine which files
to use, therefore it is simplest just to provide both 32 and 64
bit versions from the parent.

BUG=581409,455699

Committed: https://crrev.com/c560d75783aca05249092dd11503b53f7b631be1
Cr-Commit-Position: refs/heads/master@{#374371}

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

Cr-Commit-Position: refs/heads/master@{#374643}
  • Loading branch information
tobiasjs authored and Commit bot committed Feb 10, 2016
1 parent 5c19be8 commit b200162
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 56 deletions.
1 change: 1 addition & 0 deletions android_webview/lib/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ include_rules = [
"+components", # For jni registers.
"+content/public",
"+gin/public",
"+gin/v8_initializer.h",
"+media/base/media_switches.h", # For media command line switches.
"+ui/events/gesture_detection",
"+ui/gl",
Expand Down
32 changes: 14 additions & 18 deletions android_webview/lib/main/aw_main_delegate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "content/public/common/content_descriptors.h"
#include "content/public/common/content_switches.h"
#include "gin/public/isolate_holder.h"
#include "gin/v8_initializer.h"
#include "gpu/command_buffer/client/gl_in_process_context.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "media/base/media_switches.h"
Expand Down Expand Up @@ -117,24 +118,19 @@ bool AwMainDelegate::BasicStartupComplete(int* exit_code) {
if (cl->GetSwitchValueASCII(switches::kProcessType).empty()) {
// Browser process (no type specified).

// This code is needed to be able to mmap the V8 snapshot directly from
// the WebView .apk using architecture-specific names.
// This needs to be here so that it gets to run before the code in
// content_main_runner that reads these values tries to do so.
#ifdef __LP64__
const char kNativesFileName[] = "assets/natives_blob_64.bin";
const char kSnapshotFileName[] = "assets/snapshot_blob_64.bin";
#else
const char kNativesFileName[] = "assets/natives_blob_32.bin";
const char kSnapshotFileName[] = "assets/snapshot_blob_32.bin";
#endif // __LP64__
// TODO(gsennton) we should use
// gin::IsolateHolder::kNativesFileName/kSnapshotFileName
// here when those files have arch specific names http://crbug.com/455699
CHECK(base::android::RegisterApkAssetWithGlobalDescriptors(
kV8NativesDataDescriptor, kNativesFileName));
CHECK(base::android::RegisterApkAssetWithGlobalDescriptors(
kV8SnapshotDataDescriptor, kSnapshotFileName));
base::android::RegisterApkAssetWithGlobalDescriptors(
kV8NativesDataDescriptor32,
gin::V8Initializer::GetNativesFilePath(true).AsUTF8Unsafe());
base::android::RegisterApkAssetWithGlobalDescriptors(
kV8SnapshotDataDescriptor32,
gin::V8Initializer::GetSnapshotFilePath(true).AsUTF8Unsafe());

base::android::RegisterApkAssetWithGlobalDescriptors(
kV8NativesDataDescriptor64,
gin::V8Initializer::GetNativesFilePath(false).AsUTF8Unsafe());
base::android::RegisterApkAssetWithGlobalDescriptors(
kV8SnapshotDataDescriptor64,
gin::V8Initializer::GetSnapshotFilePath(false).AsUTF8Unsafe());
}

if (cl->HasSwitch(switches::kWebViewSandboxedRenderer)) {
Expand Down
10 changes: 10 additions & 0 deletions content/app/content_main_runner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,16 @@ base::LazyInstance<ContentUtilityClient>
g_empty_content_utility_client = LAZY_INSTANCE_INITIALIZER;
#endif // !OS_IOS && !CHROME_MULTIPLE_DLL_BROWSER

#if defined(V8_USE_EXTERNAL_STARTUP_DATA) && defined(OS_ANDROID)
#if defined __LP64__
#define kV8NativesDataDescriptor kV8NativesDataDescriptor64
#define kV8SnapshotDataDescriptor kV8SnapshotDataDescriptor64
#else
#define kV8NativesDataDescriptor kV8NativesDataDescriptor32
#define kV8SnapshotDataDescriptor kV8SnapshotDataDescriptor32
#endif
#endif

#if defined(OS_POSIX) && !defined(OS_IOS)

// Setup signal-handling state: resanitize most signals, ignore SIGPIPE.
Expand Down
29 changes: 28 additions & 1 deletion content/browser/child_process_launcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,31 @@ void LaunchOnLauncherThread(const NotifyCallback& callback,
#endif
);
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
bool snapshot_loaded = false;
#if defined(OS_ANDROID)
base::MemoryMappedFile::Region region;
auto maybe_register = [&region, &regions, &files_to_register](int key,
int fd) {
if (fd != -1) {
files_to_register->Share(key, fd);
regions.insert(std::make_pair(key, region));
}
};
maybe_register(
kV8NativesDataDescriptor32,
gin::V8Initializer::GetOpenNativesFileForChildProcesses(&region, true));
maybe_register(
kV8NativesDataDescriptor64,
gin::V8Initializer::GetOpenNativesFileForChildProcesses(&region, false));
maybe_register(
kV8SnapshotDataDescriptor32,
gin::V8Initializer::GetOpenSnapshotFileForChildProcesses(&region, true));
maybe_register(
kV8SnapshotDataDescriptor64,
gin::V8Initializer::GetOpenSnapshotFileForChildProcesses(&region, false));

snapshot_loaded = true;
#else
base::PlatformFile natives_pf =
gin::V8Initializer::GetOpenNativesFileForChildProcesses(
&regions[kV8NativesDataDescriptor]);
Expand All @@ -169,13 +194,15 @@ void LaunchOnLauncherThread(const NotifyCallback& callback,
// Failure to load the V8 snapshot is not necessarily an error. V8 can start
// up (slower) without the snapshot.
if (snapshot_pf != -1) {
snapshot_loaded = true;
files_to_register->Share(kV8SnapshotDataDescriptor, snapshot_pf);
regions.insert(std::make_pair(kV8SnapshotDataDescriptor, snapshot_region));
}
#endif

if (process_type != switches::kZygoteProcess) {
cmd_line->AppendSwitch(::switches::kV8NativesPassedByFD);
if (snapshot_pf != -1) {
if (snapshot_loaded) {
cmd_line->AppendSwitch(::switches::kV8SnapshotPassedByFD);
}
}
Expand Down
7 changes: 7 additions & 0 deletions content/public/common/content_descriptors.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,16 @@ enum {
kSandboxIPCChannel, // https://chromium.googlesource.com/chromium/src/+/master/docs/linux_sandbox_ipc.md

#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
#if defined(OS_ANDROID)
kV8NativesDataDescriptor32,
kV8SnapshotDataDescriptor32,
kV8NativesDataDescriptor64,
kV8SnapshotDataDescriptor64,
#else
kV8NativesDataDescriptor,
kV8SnapshotDataDescriptor,
#endif
#endif

#if defined(OS_ANDROID)
kAndroidPropertyDescriptor,
Expand Down
128 changes: 91 additions & 37 deletions gin/v8_initializer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/memory_mapped_file.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram.h"
Expand Down Expand Up @@ -50,19 +51,34 @@ const base::PlatformFile kInvalidPlatformFile =
// File handles intentionally never closed. Not using File here because its
// Windows implementation guards against two instances owning the same
// PlatformFile (which we allow since we know it is never freed).
base::PlatformFile g_natives_pf = kInvalidPlatformFile;
base::PlatformFile g_snapshot_pf = kInvalidPlatformFile;
base::MemoryMappedFile::Region g_natives_region;
base::MemoryMappedFile::Region g_snapshot_region;
typedef std::map<const char*,
std::pair<base::PlatformFile, base::MemoryMappedFile::Region>>
OpenedFileMap;
static base::LazyInstance<OpenedFileMap>::Leaky g_opened_files =
LAZY_INSTANCE_INITIALIZER;

OpenedFileMap::mapped_type& GetOpenedFile(const char* file) {
OpenedFileMap& opened_files(g_opened_files.Get());
if (opened_files.find(file) == opened_files.end()) {
opened_files[file] =
std::make_pair(kInvalidPlatformFile, base::MemoryMappedFile::Region());
}
return opened_files[file];
}

#if defined(OS_ANDROID)
#ifdef __LP64__
const char kNativesFileName[] = "natives_blob_64.bin";
const char kSnapshotFileName[] = "snapshot_blob_64.bin";
const char kNativesFileName64[] = "natives_blob_64.bin";
const char kSnapshotFileName64[] = "snapshot_blob_64.bin";
const char kNativesFileName32[] = "natives_blob_32.bin";
const char kSnapshotFileName32[] = "snapshot_blob_32.bin";

#if defined(__LP64__)
#define kNativesFileName kNativesFileName64
#define kSnapshotFileName kSnapshotFileName64
#else
const char kNativesFileName[] = "natives_blob_32.bin";
const char kSnapshotFileName[] = "snapshot_blob_32.bin";
#endif // __LP64__
#define kNativesFileName kNativesFileName32
#define kSnapshotFileName kSnapshotFileName32
#endif

#else // defined(OS_ANDROID)
const char kNativesFileName[] = "natives_blob.bin";
Expand Down Expand Up @@ -170,16 +186,13 @@ base::PlatformFile OpenV8File(const char* file_name,
return file.TakePlatformFile();
}

void OpenNativesFileIfNecessary() {
if (g_natives_pf == kInvalidPlatformFile) {
g_natives_pf = OpenV8File(kNativesFileName, &g_natives_region);
}
}

void OpenSnapshotFileIfNecessary() {
if (g_snapshot_pf == kInvalidPlatformFile) {
g_snapshot_pf = OpenV8File(kSnapshotFileName, &g_snapshot_region);
static const OpenedFileMap::mapped_type OpenFileIfNecessary(
const char* file_name) {
OpenedFileMap::mapped_type& opened = GetOpenedFile(file_name);
if (opened.first == kInvalidPlatformFile) {
opened.first = OpenV8File(file_name, &opened.second);
}
return opened;
}

#if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
Expand Down Expand Up @@ -236,15 +249,14 @@ enum LoadV8FileResult {
V8_LOAD_MAX_VALUE
};

static LoadV8FileResult MapVerify(base::PlatformFile platform_file,
const base::MemoryMappedFile::Region& region,
static LoadV8FileResult MapVerify(const OpenedFileMap::mapped_type& file_region,
#if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
const unsigned char* fingerprint,
#endif
base::MemoryMappedFile** mmapped_file_out) {
if (platform_file == kInvalidPlatformFile)
if (file_region.first == kInvalidPlatformFile)
return V8_LOAD_FAILED_OPEN;
if (!MapV8File(platform_file, region, mmapped_file_out))
if (!MapV8File(file_region.first, file_region.second, mmapped_file_out))
return V8_LOAD_FAILED_MAP;
#if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
if (!VerifyV8StartupFile(mmapped_file_out, fingerprint))
Expand All @@ -258,8 +270,8 @@ void V8Initializer::LoadV8Snapshot() {
if (g_mapped_snapshot)
return;

OpenSnapshotFileIfNecessary();
LoadV8FileResult result = MapVerify(g_snapshot_pf, g_snapshot_region,
OpenFileIfNecessary(kSnapshotFileName);
LoadV8FileResult result = MapVerify(GetOpenedFile(kSnapshotFileName),
#if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
g_snapshot_fingerprint,
#endif
Expand All @@ -274,8 +286,8 @@ void V8Initializer::LoadV8Natives() {
if (g_mapped_natives)
return;

OpenNativesFileIfNecessary();
LoadV8FileResult result = MapVerify(g_natives_pf, g_natives_region,
OpenFileIfNecessary(kNativesFileName);
LoadV8FileResult result = MapVerify(GetOpenedFile(kNativesFileName),
#if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
g_natives_fingerprint,
#endif
Expand Down Expand Up @@ -311,8 +323,8 @@ void V8Initializer::LoadV8SnapshotFromFD(base::PlatformFile snapshot_pf,
result = V8_LOAD_FAILED_VERIFY;
#endif // V8_VERIFY_EXTERNAL_STARTUP_DATA
if (result == V8_LOAD_SUCCESS) {
g_snapshot_pf = snapshot_pf;
g_snapshot_region = snapshot_region;
g_opened_files.Get()[kSnapshotFileName] =
std::make_pair(snapshot_pf, snapshot_region);
}
UMA_HISTOGRAM_ENUMERATION("V8.Initializer.LoadV8Snapshot.Result", result,
V8_LOAD_MAX_VALUE);
Expand Down Expand Up @@ -342,25 +354,51 @@ void V8Initializer::LoadV8NativesFromFD(base::PlatformFile natives_pf,
LOG(FATAL) << "Couldn't verify contents of v8 natives data file";
}
#endif // V8_VERIFY_EXTERNAL_STARTUP_DATA
g_natives_pf = natives_pf;
g_natives_region = natives_region;
g_opened_files.Get()[kNativesFileName] =
std::make_pair(natives_pf, natives_region);
}

// static
base::PlatformFile V8Initializer::GetOpenNativesFileForChildProcesses(
base::MemoryMappedFile::Region* region_out) {
OpenNativesFileIfNecessary();
*region_out = g_natives_region;
return g_natives_pf;
const OpenedFileMap::mapped_type& opened =
OpenFileIfNecessary(kNativesFileName);
*region_out = opened.second;
return opened.first;
}

// static
base::PlatformFile V8Initializer::GetOpenSnapshotFileForChildProcesses(
base::MemoryMappedFile::Region* region_out) {
OpenSnapshotFileIfNecessary();
*region_out = g_snapshot_region;
return g_snapshot_pf;
const OpenedFileMap::mapped_type& opened =
OpenFileIfNecessary(kSnapshotFileName);
*region_out = opened.second;
return opened.first;
}

#if defined(OS_ANDROID)
// static
base::PlatformFile V8Initializer::GetOpenNativesFileForChildProcesses(
base::MemoryMappedFile::Region* region_out,
bool abi_32_bit) {
const char* natives_file =
abi_32_bit ? kNativesFileName32 : kNativesFileName64;
const OpenedFileMap::mapped_type& opened = OpenFileIfNecessary(natives_file);
*region_out = opened.second;
return opened.first;
}

// static
base::PlatformFile V8Initializer::GetOpenSnapshotFileForChildProcesses(
base::MemoryMappedFile::Region* region_out,
bool abi_32_bit) {
const char* snapshot_file =
abi_32_bit ? kSnapshotFileName32 : kSnapshotFileName64;
const OpenedFileMap::mapped_type& opened = OpenFileIfNecessary(snapshot_file);
*region_out = opened.second;
return opened.first;
}
#endif // defined(OS_ANDROID)
#endif // defined(V8_USE_EXTERNAL_STARTUP_DATA)

// static
Expand Down Expand Up @@ -423,4 +461,20 @@ void V8Initializer::GetV8ExternalSnapshotData(const char** natives_data_out,
}
}

#if defined(OS_ANDROID)
// static
base::FilePath V8Initializer::GetNativesFilePath(bool abi_32_bit) {
base::FilePath path;
GetV8FilePath(abi_32_bit ? kNativesFileName32 : kNativesFileName64, &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)

} // namespace gin
13 changes: 13 additions & 0 deletions gin/v8_initializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,19 @@ class GIN_EXPORT V8Initializer {
// Will return -1 if the file does not exist.
static base::PlatformFile GetOpenSnapshotFileForChildProcesses(
base::MemoryMappedFile::Region* region_out);

#if defined(OS_ANDROID)
static base::PlatformFile GetOpenNativesFileForChildProcesses(
base::MemoryMappedFile::Region* region_out,
bool abi_32_bit);
static base::PlatformFile GetOpenSnapshotFileForChildProcesses(
base::MemoryMappedFile::Region* region_out,
bool abi_32_bit);

static base::FilePath GetNativesFilePath(bool abi_32_bit);
static base::FilePath GetSnapshotFilePath(bool abi_32_bit);
#endif

#endif // V8_USE_EXTERNAL_STARTUP_DATA
};

Expand Down

0 comments on commit b200162

Please sign in to comment.