From 3c766cc321a77febd8cf726436e22ab385f8ac1b Mon Sep 17 00:00:00 2001 From: mkosiba Date: Fri, 9 Jan 2015 05:10:22 -0800 Subject: mmap V8 snapshot and ICU data file in the android_webview This makes it possible to mmap the V8 snapshot and ICU data file directly from the WebView APK. Doing so makes it possible to remove the android_webview_telemetry_build flag which in turns means we can build the WebView with the same set of flags that Chrome on Android uses. BUG=442338 Review URL: https://codereview.chromium.org/812393002 Cr-Commit-Position: refs/heads/master@{#310765} --- android_webview/android_webview.gyp | 20 +------ android_webview/android_webview_tests.gypi | 8 +-- android_webview/apk/system_webview_apk_common.gypi | 36 ++++++++++--- android_webview/lib/DEPS | 1 + android_webview/lib/main/aw_main_delegate.cc | 21 ++++++++ android_webview/native/aw_assets.cc | 14 +++++ android_webview/native/aw_assets.h | 4 ++ base/files/memory_mapped_file.cc | 2 + base/files/memory_mapped_file_posix.cc | 2 + base/i18n/icu_util.cc | 27 +++++----- base/i18n/icu_util.h | 9 +++- base/posix/global_descriptors.cc | 39 +++++++++++--- base/posix/global_descriptors.h | 26 +++++++-- build/common.gypi | 10 +--- chrome/browser/DEPS | 1 + chrome/browser/chrome_content_browser_client.cc | 8 +-- content/app/DEPS | 1 + content/app/content_main_runner.cc | 21 ++++++-- content/zygote/zygote_linux.cc | 8 +-- gin/isolate_holder.cc | 62 +++++++++++++++++----- gin/public/isolate_holder.h | 12 ++++- 21 files changed, 243 insertions(+), 89 deletions(-) diff --git a/android_webview/android_webview.gyp b/android_webview/android_webview.gyp index 3f91264..a14ba0c 100644 --- a/android_webview/android_webview.gyp +++ b/android_webview/android_webview.gyp @@ -108,6 +108,7 @@ '../components/components.gyp:web_contents_delegate_android', '../content/content.gyp:content_app_both', '../content/content.gyp:content_browser', + '../gin/gin.gyp:gin', '../gpu/blink/gpu_blink.gyp:gpu_blink', '../gpu/command_buffer/command_buffer.gyp:gles2_utils', '../gpu/gpu.gyp:command_buffer_service', @@ -300,25 +301,6 @@ 'shared_resources': 1, }, 'includes': [ 'apk/system_webview_apk_common.gypi' ], - 'copies': [ - { - 'destination': '<(PRODUCT_DIR)/android_webview_assets', - 'files': [], - 'conditions': [ - ['icu_use_data_file_flag==1', { - 'files': [ - '<(PRODUCT_DIR)/icudtl.dat', - ], - }], - ['v8_use_external_startup_data==1', { - 'files': [ - '<(PRODUCT_DIR)/natives_blob.bin', - '<(PRODUCT_DIR)/snapshot_blob.bin', - ], - }], - ], - }, - ], }, ], }, { # android_webview_build==1 diff --git a/android_webview/android_webview_tests.gypi b/android_webview/android_webview_tests.gypi index 2e1ba0e..10ee545 100644 --- a/android_webview/android_webview_tests.gypi +++ b/android_webview/android_webview_tests.gypi @@ -17,11 +17,11 @@ 'java_in_dir': 'test/shell', 'native_lib_target': 'libstandalonelibwebviewchromium', 'resource_dir': 'test/shell/res', - 'extensions_to_not_compress': 'pak', + 'extensions_to_not_compress': 'pak,dat,bin', 'extra_native_libs': ['<(SHARED_LIB_DIR)/libdrawgl.>(android_product_extension)'], 'additional_input_paths': [ - '<(PRODUCT_DIR)/android_webview_assets/webviewchromium.pak', - '<(PRODUCT_DIR)/android_webview_assets/en-US.pak', + '<(PRODUCT_DIR)/android_webview_apk/assets/webviewchromium.pak', + '<(PRODUCT_DIR)/android_webview_apk/assets/en-US.pak', '<(PRODUCT_DIR)/android_webview_apk/assets/asset_file.html', '<(PRODUCT_DIR)/android_webview_apk/assets/cookie_test.html', '<(PRODUCT_DIR)/android_webview_apk/assets/asset_icon.png', @@ -58,7 +58,7 @@ '<(java_in_dir)/assets/full_screen_video_inside_div_test.html', '<(java_in_dir)/assets/video.mp4', ], - 'conditions': [ + 'conditions': [ ['icu_use_data_file_flag==1', { 'files': [ '<(PRODUCT_DIR)/icudtl.dat', diff --git a/android_webview/apk/system_webview_apk_common.gypi b/android_webview/apk/system_webview_apk_common.gypi index 0d19dac..2b24785 100644 --- a/android_webview/apk/system_webview_apk_common.gypi +++ b/android_webview/apk/system_webview_apk_common.gypi @@ -16,29 +16,51 @@ 'never_lint': 1, 'R_package': 'com.android.webview.chromium', 'R_package_relpath': 'com/android/webview/chromium', - 'extensions_to_not_compress': 'pak', - 'asset_location': '<(PRODUCT_DIR)/android_webview_assets', + 'extensions_to_not_compress': 'pak,bin,dat', + 'asset_location': '<(INTERMEDIATE_DIR)/assets/', # TODO: crbug.com/442348 Update proguard.flags and re-enable. 'proguard_enabled': 'false', 'proguard_flags_paths': ['<(DEPTH)/android_webview/apk/java/proguard.flags'], # TODO: crbug.com/405035 Find a better solution for WebView .pak files. 'additional_input_paths': [ - '<(PRODUCT_DIR)/android_webview_assets/webviewchromium.pak', - '<(PRODUCT_DIR)/android_webview_assets/en-US.pak', + '<(asset_location)/webviewchromium.pak', + '<(asset_location)/en-US.pak', ], 'conditions': [ ['icu_use_data_file_flag==1', { 'additional_input_paths': [ - '<(PRODUCT_DIR)/icudtl.dat', + '<(asset_location)/icudtl.dat', ], }], ['v8_use_external_startup_data==1', { 'additional_input_paths': [ - '<(PRODUCT_DIR)/natives_blob.bin', - '<(PRODUCT_DIR)/snapshot_blob.bin', + '<(asset_location)/natives_blob.bin', + '<(asset_location)/snapshot_blob.bin', ], }], ], }, + 'copies': [ + { + 'destination': '<(asset_location)', + 'files': [ + '<(PRODUCT_DIR)/android_webview_assets/webviewchromium.pak', + '<(PRODUCT_DIR)/android_webview_assets/en-US.pak', + ], + 'conditions': [ + ['icu_use_data_file_flag==1', { + 'files': [ + '<(PRODUCT_DIR)/icudtl.dat', + ], + }], + ['v8_use_external_startup_data==1', { + 'files': [ + '<(PRODUCT_DIR)/natives_blob.bin', + '<(PRODUCT_DIR)/snapshot_blob.bin', + ], + }], + ], + }, + ], 'includes': [ '../../build/java_apk.gypi' ], } diff --git a/android_webview/lib/DEPS b/android_webview/lib/DEPS index ab83088..17b7ba6 100644 --- a/android_webview/lib/DEPS +++ b/android_webview/lib/DEPS @@ -2,6 +2,7 @@ include_rules = [ "+cc/base/switches.h", "+components", # For jni registers. "+content/public", + "+gin/public", "+media/base/media_switches.h", # For media command line switches. "+ui/gl", ] diff --git a/android_webview/lib/main/aw_main_delegate.cc b/android_webview/lib/main/aw_main_delegate.cc index 2164521..c996cc4 100644 --- a/android_webview/lib/main/aw_main_delegate.cc +++ b/android_webview/lib/main/aw_main_delegate.cc @@ -8,6 +8,7 @@ #include "android_webview/browser/browser_view_renderer.h" #include "android_webview/browser/scoped_allow_wait_for_legacy_web_view_api.h" #include "android_webview/lib/aw_browser_dependency_factory_impl.h" +#include "android_webview/native/aw_assets.h" #include "android_webview/native/aw_media_url_interceptor.h" #include "android_webview/native/aw_quota_manager_bridge_impl.h" #include "android_webview/native/aw_web_contents_view_delegate.h" @@ -16,6 +17,7 @@ #include "android_webview/renderer/aw_content_renderer_client.h" #include "base/command_line.h" #include "base/cpu.h" +#include "base/i18n/icu_util.h" #include "base/lazy_instance.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" @@ -24,7 +26,9 @@ #include "content/browser/media/android/browser_media_player_manager.h" #include "content/public/browser/browser_main_runner.h" #include "content/public/browser/browser_thread.h" +#include "content/public/common/content_descriptors.h" #include "content/public/common/content_switches.h" +#include "gin/public/isolate_holder.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" @@ -81,6 +85,23 @@ bool AwMainDelegate::BasicStartupComplete(int* exit_code) { // This is needed for sharing textures across the different GL threads. cl->AppendSwitch(switches::kEnableThreadedTextureMailboxes); + // This is needed to be able to mmap the V8 snapshot and ICU data file + // directly from the WebView .apk. + // 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. + // In multi-process mode this code would live in + // AwContentBrowserClient::GetAdditionalMappedFilesForChildProcess. +#ifdef V8_USE_EXTERNAL_STARTUP_DATA + CHECK(AwAssets::RegisterAssetWithGlobalDescriptors( + kV8NativesDataDescriptor, gin::IsolateHolder::kNativesFileName)); + CHECK(AwAssets::RegisterAssetWithGlobalDescriptors( + kV8SnapshotDataDescriptor, gin::IsolateHolder::kSnapshotFileName)); +#endif + // TODO(mkosiba): make this CHECK when the android_webview_build uses an asset + // from the .apk too. + AwAssets::RegisterAssetWithGlobalDescriptors( + kAndroidICUDataDescriptor, base::i18n::kIcuDataFileName); + return false; } diff --git a/android_webview/native/aw_assets.cc b/android_webview/native/aw_assets.cc index 6d5ad72..41f2270 100644 --- a/android_webview/native/aw_assets.cc +++ b/android_webview/native/aw_assets.cc @@ -32,6 +32,20 @@ bool OpenAsset(const std::string& filename, return *fd != -1; } +bool RegisterAssetWithGlobalDescriptors(base::GlobalDescriptors::Key key, + const std::string& asset_filename) { + int asset_fd = 0; + int64 asset_off = 0; + int64 asset_len = 0; + bool result = + AwAssets::OpenAsset(asset_filename, &asset_fd, &asset_off, &asset_len); + if (result) { + base::GlobalDescriptors::GetInstance()->Set( + key, asset_fd, base::MemoryMappedFile::Region(asset_off, asset_len)); + } + return result; +} + } // namespace AwAssets bool RegisterAwAssets(JNIEnv* env) { diff --git a/android_webview/native/aw_assets.h b/android_webview/native/aw_assets.h index 229392c..16fcafb 100644 --- a/android_webview/native/aw_assets.h +++ b/android_webview/native/aw_assets.h @@ -8,6 +8,7 @@ #include #include "base/android/jni_android.h" +#include "base/posix/global_descriptors.h" namespace android_webview { namespace AwAssets { @@ -23,6 +24,9 @@ bool OpenAsset(const std::string& filename, int64* offset, int64* size); +bool RegisterAssetWithGlobalDescriptors(base::GlobalDescriptors::Key key, + const std::string& asset_filename); + } // namespace AwAssets bool RegisterAwAssets(JNIEnv* env); diff --git a/base/files/memory_mapped_file.cc b/base/files/memory_mapped_file.cc index 745a5ff..891fcff 100644 --- a/base/files/memory_mapped_file.cc +++ b/base/files/memory_mapped_file.cc @@ -31,6 +31,7 @@ MemoryMappedFile::~MemoryMappedFile() { CloseHandles(); } +#if !defined(OS_NACL) bool MemoryMappedFile::Initialize(const FilePath& file_name) { if (IsValid()) return false; @@ -85,5 +86,6 @@ void MemoryMappedFile::CalculateVMAlignedBoundaries(int64 start, *aligned_start = start & ~mask; *aligned_size = (size + *offset + mask) & ~mask; } +#endif } // namespace base diff --git a/base/files/memory_mapped_file_posix.cc b/base/files/memory_mapped_file_posix.cc index ebf38779..168da92 100644 --- a/base/files/memory_mapped_file_posix.cc +++ b/base/files/memory_mapped_file_posix.cc @@ -16,6 +16,7 @@ namespace base { MemoryMappedFile::MemoryMappedFile() : data_(NULL), length_(0) { } +#if !defined(OS_NACL) bool MemoryMappedFile::MapFileRegionToMemory( const MemoryMappedFile::Region& region) { ThreadRestrictions::AssertIOAllowed(); @@ -74,6 +75,7 @@ bool MemoryMappedFile::MapFileRegionToMemory( data_ += data_offset; return true; } +#endif void MemoryMappedFile::CloseHandles() { ThreadRestrictions::AssertIOAllowed(); diff --git a/base/i18n/icu_util.cc b/base/i18n/icu_util.cc index e0bd62c..f1fdda7 100644 --- a/base/i18n/icu_util.cc +++ b/base/i18n/icu_util.cc @@ -27,21 +27,21 @@ #define ICU_UTIL_DATA_SHARED 1 #define ICU_UTIL_DATA_STATIC 2 -#if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE +namespace base { +namespace i18n { + // Use an unversioned file name to simplify a icu version update down the road. // No need to change the filename in multiple places (gyp files, windows // build pkg configurations, etc). 'l' stands for Little Endian. -#define ICU_UTIL_DATA_FILE_NAME "icudtl.dat" -#elif ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_SHARED +// This variable is exported through the header file. +const char kIcuDataFileName[] = "icudtl.dat"; +#if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_SHARED #define ICU_UTIL_DATA_SYMBOL "icudt" U_ICU_VERSION_SHORT "_dat" #if defined(OS_WIN) #define ICU_UTIL_DATA_SHARED_MODULE_NAME "icudt.dll" #endif #endif -namespace base { -namespace i18n { - namespace { #if !defined(NDEBUG) @@ -53,9 +53,10 @@ bool g_check_called_once = true; #endif } - #if defined(OS_ANDROID) -bool InitializeICUWithFileDescriptor(int data_fd) { +bool InitializeICUWithFileDescriptor( + int data_fd, + base::MemoryMappedFile::Region data_region) { #if !defined(NDEBUG) DCHECK(!g_check_called_once || !g_called_once); g_called_once = true; @@ -67,7 +68,7 @@ bool InitializeICUWithFileDescriptor(int data_fd) { #elif (ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE) CR_DEFINE_STATIC_LOCAL(base::MemoryMappedFile, mapped_file, ()); if (!mapped_file.IsValid()) { - if (!mapped_file.Initialize(base::File(data_fd))) { + if (!mapped_file.Initialize(base::File(data_fd), data_region)) { LOG(ERROR) << "Couldn't mmap icu data file"; return false; } @@ -135,13 +136,15 @@ bool InitializeICU() { bool path_ok = PathService::Get(base::DIR_EXE, &data_path); #endif DCHECK(path_ok); - data_path = data_path.AppendASCII(ICU_UTIL_DATA_FILE_NAME); + data_path = data_path.AppendASCII(kIcuDataFileName); #else // Assume it is in the framework bundle's Resources directory. + base::ScopedCFTypeRef data_file_name( + SysUTF8ToCFStringRef(kIcuDataFileName)); FilePath data_path = - base::mac::PathForFrameworkBundleResource(CFSTR(ICU_UTIL_DATA_FILE_NAME)); + base::mac::PathForFrameworkBundleResource(data_file_name); if (data_path.empty()) { - LOG(ERROR) << ICU_UTIL_DATA_FILE_NAME << " not found in bundle"; + LOG(ERROR) << kIcuDataFileName << " not found in bundle"; return false; } #endif // OS check diff --git a/base/i18n/icu_util.h b/base/i18n/icu_util.h index b0a5dbc..5094cb0 100644 --- a/base/i18n/icu_util.h +++ b/base/i18n/icu_util.h @@ -5,12 +5,15 @@ #ifndef BASE_I18N_ICU_UTIL_H_ #define BASE_I18N_ICU_UTIL_H_ -#include "build/build_config.h" +#include "base/files/memory_mapped_file.h" #include "base/i18n/base_i18n_export.h" +#include "build/build_config.h" namespace base { namespace i18n { +BASE_I18N_EXPORT extern const char kIcuDataFileName[]; + // Call this function to load ICU's data tables for the current process. This // function should be called before ICU is used. BASE_I18N_EXPORT bool InitializeICU(); @@ -18,7 +21,9 @@ BASE_I18N_EXPORT bool InitializeICU(); #if defined(OS_ANDROID) // Android uses a file descriptor passed by browser process to initialize ICU // in render processes. -BASE_I18N_EXPORT bool InitializeICUWithFileDescriptor(int data_fd); +BASE_I18N_EXPORT bool InitializeICUWithFileDescriptor( + int data_fd, + base::MemoryMappedFile::Region data_region); #endif // In a test binary, the call above might occur twice. diff --git a/base/posix/global_descriptors.cc b/base/posix/global_descriptors.cc index bcca443..6c18783 100644 --- a/base/posix/global_descriptors.cc +++ b/base/posix/global_descriptors.cc @@ -11,6 +11,16 @@ namespace base { +GlobalDescriptors::Descriptor::Descriptor(Key key, int fd) + : key(key), fd(fd), region(base::MemoryMappedFile::Region::kWholeFile) { +} + +GlobalDescriptors::Descriptor::Descriptor(Key key, + int fd, + base::MemoryMappedFile::Region region) + : key(key), fd(fd), region(region) { +} + // static GlobalDescriptors* GlobalDescriptors::GetInstance() { typedef Singletonfirst == key) - return i->second; + if (i->key == key) + return i->fd; } return -1; } void GlobalDescriptors::Set(Key key, int fd) { - for (Mapping::iterator - i = descriptors_.begin(); i != descriptors_.end(); ++i) { - if (i->first == key) { - i->second = fd; + Set(key, fd, base::MemoryMappedFile::Region::kWholeFile); +} + +void GlobalDescriptors::Set(Key key, + int fd, + base::MemoryMappedFile::Region region) { + for (auto& i : descriptors_) { + if (i.key == key) { + i.fd = fd; + i.region = region; return; } } - descriptors_.push_back(std::make_pair(key, fd)); + descriptors_.push_back(Descriptor(key, fd, region)); +} + +base::MemoryMappedFile::Region GlobalDescriptors::GetRegion(Key key) const { + for (const auto& i : descriptors_) { + if (i.key == key) + return i.region; + } + DLOG(FATAL) << "Unknown global descriptor: " << key; + return base::MemoryMappedFile::Region::kWholeFile; } void GlobalDescriptors::Reset(const Mapping& mapping) { diff --git a/base/posix/global_descriptors.h b/base/posix/global_descriptors.h index 3d7369c31..c774634 100644 --- a/base/posix/global_descriptors.h +++ b/base/posix/global_descriptors.h @@ -12,6 +12,7 @@ #include +#include "base/files/memory_mapped_file.h" #include "base/memory/singleton.h" namespace base { @@ -36,8 +37,18 @@ namespace base { class BASE_EXPORT GlobalDescriptors { public: typedef uint32_t Key; - typedef std::pair KeyFDPair; - typedef std::vector Mapping; + struct Descriptor { + Descriptor(Key key, int fd); + Descriptor(Key key, int fd, base::MemoryMappedFile::Region region); + + // Globally unique key. + Key key; + // Actual FD. + int fd; + // Optional region, defaults to kWholeFile. + base::MemoryMappedFile::Region region; + }; + typedef std::vector Mapping; // Often we want a canonical descriptor for a given Key. In this case, we add // the following constant to the key value: @@ -53,12 +64,19 @@ class BASE_EXPORT GlobalDescriptors { // Get a descriptor given a key. It is a fatal error if the key is not known. int Get(Key key) const; - // Get a descriptor give a key. Returns -1 on error. + // Get a descriptor given a key. Returns -1 on error. int MaybeGet(Key key) const; - // Set the descriptor for the given key. + // Get a region given a key. It is a fatal error if the key is not known. + base::MemoryMappedFile::Region GetRegion(Key key) const; + + // Set the descriptor for the given |key|. This sets the region associated + // with |key| to kWholeFile. void Set(Key key, int fd); + // Set the descriptor and |region| for the given |key|. + void Set(Key key, int fd, base::MemoryMappedFile::Region region); + void Reset(const Mapping& mapping); private: diff --git a/build/common.gypi b/build/common.gypi index 83a3df6..77912bb2 100644 --- a/build/common.gypi +++ b/build/common.gypi @@ -161,10 +161,6 @@ # build system. 'android_webview_build%': 0, - # This is set when building the Android WebView in ninja for the - # telemetry bot. - 'android_webview_telemetry_build%': 0, - # Set ARM architecture version. 'arm_version%': 7, @@ -296,7 +292,6 @@ 'enable_hidpi%': '<(enable_hidpi)', 'android_channel%': '<(android_channel)', 'android_webview_build%': '<(android_webview_build)', - 'android_webview_telemetry_build%': '<(android_webview_telemetry_build)', 'use_goma%': '<(use_goma)', 'gomadir%': '<(gomadir)', 'enable_app_list%': '<(enable_app_list)', @@ -970,7 +965,7 @@ # except when building Android WebView. # TODO(jshin): Handle 'use_system_icu' on Linux (Chromium). # Set the data reduction proxy origin for Android Webview. - ['android_webview_build==0 and android_webview_telemetry_build==0', { + ['android_webview_build==0', { 'icu_use_data_file_flag%' : 1, }, { 'icu_use_data_file_flag%' : 0, @@ -996,7 +991,7 @@ # TODO(baixo): Enable v8_use_external_startup_data # http://crbug.com/421063 - ['android_webview_build==0 and android_webview_telemetry_build==0 and chromecast==0 and chromeos==0 and (OS=="android" or OS=="linux" or OS=="mac")', { + ['android_webview_build==0 and chromecast==0 and chromeos==0 and (OS=="android" or OS=="linux" or OS=="mac")', { 'v8_use_external_startup_data%': 1, }, { 'v8_use_external_startup_data%': 0, @@ -1176,7 +1171,6 @@ 'use_system_libjpeg%': '<(use_system_libjpeg)', 'android_channel%': '<(android_channel)', 'android_webview_build%': '<(android_webview_build)', - 'android_webview_telemetry_build%': '<(android_webview_telemetry_build)', 'icu_use_data_file_flag%': '<(icu_use_data_file_flag)', 'gyp_managed_install%': 0, 'create_standalone_apk%': 1, diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS index 923e246..e4ed6c7 100644 --- a/chrome/browser/DEPS +++ b/chrome/browser/DEPS @@ -98,6 +98,7 @@ include_rules = [ "+extensions/components/javascript_dialog_extensions_client", "+extensions/grit", "+extensions/test", + "+gin/public/isolate_holder.h", "+google/cacheinvalidation", # Sync invalidation API protobuf files. "+google_apis", "+google_update", diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index cfab998..25e4fbc 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc @@ -11,6 +11,7 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/files/scoped_file.h" +#include "base/i18n/icu_util.h" #include "base/lazy_instance.h" #include "base/path_service.h" #include "base/prefs/pref_service.h" @@ -122,6 +123,7 @@ #include "content/public/common/content_descriptors.h" #include "content/public/common/url_utils.h" #include "content/public/common/web_preferences.h" +#include "gin/public/isolate_holder.h" #include "net/base/mime_util.h" #include "net/cookies/canonical_cookie.h" #include "net/cookies/cookie_options.h" @@ -2482,7 +2484,7 @@ void ChromeContentBrowserClient::GetAdditionalMappedFilesForChildProcess( flags = base::File::FLAG_OPEN | base::File::FLAG_READ; base::FilePath icudata_path = - app_data_path.AppendASCII("icudtl.dat"); + app_data_path.AppendASCII(base::i18n::kIcuDataFileName); base::File icudata_file(icudata_path, flags); DCHECK(icudata_file.IsValid()); mappings->Transfer(kAndroidICUDataDescriptor, @@ -2495,9 +2497,9 @@ void ChromeContentBrowserClient::GetAdditionalMappedFilesForChildProcess( int file_flags = base::File::FLAG_OPEN | base::File::FLAG_READ; base::FilePath v8_natives_data_path = - v8_data_path.AppendASCII("natives_blob.bin"); + v8_data_path.AppendASCII(gin::IsolateHolder::kNativesFileName); base::FilePath v8_snapshot_data_path = - v8_data_path.AppendASCII("snapshot_blob.bin"); + v8_data_path.AppendASCII(gin::IsolateHolder::kSnapshotFileName); base::File v8_natives_data_file(v8_natives_data_path, file_flags); base::File v8_snapshot_data_file(v8_snapshot_data_path, file_flags); DCHECK(v8_natives_data_file.IsValid()); diff --git a/content/app/DEPS b/content/app/DEPS index f8429fc..61f7537 100644 --- a/content/app/DEPS +++ b/content/app/DEPS @@ -4,5 +4,6 @@ include_rules = [ "+device/vibration", # For loading V8's initial snapshot from external files. "+gin/public/isolate_holder.h", + "+gin/public/snapshot_fd_data.h", "+media/base", # For initializing media library. ] diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc index 2da7dc1..8795067 100644 --- a/content/app/content_main_runner.cc +++ b/content/app/content_main_runner.cc @@ -716,10 +716,14 @@ class ContentMainRunnerImpl : public ContentMainRunner { #if defined(OS_ANDROID) int icudata_fd = base::GlobalDescriptors::GetInstance()->MaybeGet( kAndroidICUDataDescriptor); - if (icudata_fd != -1) - CHECK(base::i18n::InitializeICUWithFileDescriptor(icudata_fd)); - else + if (icudata_fd != -1) { + auto icudata_region = base::GlobalDescriptors::GetInstance()->GetRegion( + kAndroidICUDataDescriptor); + CHECK(base::i18n::InitializeICUWithFileDescriptor(icudata_fd, + icudata_region)); + } else { CHECK(base::i18n::InitializeICU()); + } #if defined(V8_USE_EXTERNAL_STARTUP_DATA) int v8_natives_fd = base::GlobalDescriptors::GetInstance()->MaybeGet( @@ -727,8 +731,15 @@ class ContentMainRunnerImpl : public ContentMainRunner { int v8_snapshot_fd = base::GlobalDescriptors::GetInstance()->MaybeGet( kV8SnapshotDataDescriptor); if (v8_natives_fd != -1 && v8_snapshot_fd != -1) { - CHECK(gin::IsolateHolder::LoadV8SnapshotFD(v8_natives_fd, - v8_snapshot_fd)); + auto v8_natives_region = + base::GlobalDescriptors::GetInstance()->GetRegion( + kV8NativesDataDescriptor); + auto v8_snapshot_region = + base::GlobalDescriptors::GetInstance()->GetRegion( + kV8SnapshotDataDescriptor); + CHECK(gin::IsolateHolder::LoadV8SnapshotFd( + v8_natives_fd, v8_natives_region.offset, v8_natives_region.size, + v8_snapshot_fd, v8_snapshot_region.offset, v8_snapshot_region.size)); } else { CHECK(gin::IsolateHolder::LoadV8Snapshot()); } diff --git a/content/zygote/zygote_linux.cc b/content/zygote/zygote_linux.cc index e9b940e..051f791 100644 --- a/content/zygote/zygote_linux.cc +++ b/content/zygote/zygote_linux.cc @@ -51,8 +51,8 @@ void SIGCHLDHandler(int signal) { int LookUpFd(const base::GlobalDescriptors::Mapping& fd_mapping, uint32_t key) { for (size_t index = 0; index < fd_mapping.size(); ++index) { - if (fd_mapping[index].first == key) - return fd_mapping[index].second; + if (fd_mapping[index].key == key) + return fd_mapping[index].fd; } return -1; } @@ -506,10 +506,10 @@ base::ProcessId Zygote::ReadArgsAndFork(PickleIterator iter, base::GlobalDescriptors::Key key; if (!iter.ReadUInt32(&key)) return -1; - mapping.push_back(std::make_pair(key, fds[i]->get())); + mapping.push_back(base::GlobalDescriptors::Descriptor(key, fds[i]->get())); } - mapping.push_back(std::make_pair( + mapping.push_back(base::GlobalDescriptors::Descriptor( static_cast(kSandboxIPCChannel), GetSandboxFD())); // Returns twice, once per process. diff --git a/gin/isolate_holder.cc b/gin/isolate_holder.cc index 38215b2..ab18ce4 100644 --- a/gin/isolate_holder.cc +++ b/gin/isolate_holder.cc @@ -11,6 +11,7 @@ #include "base/logging.h" #include "base/message_loop/message_loop.h" #include "base/rand_util.h" +#include "base/strings/sys_string_conversions.h" #include "base/sys_info.h" #include "crypto/sha2.h" #include "gin/array_buffer.h" @@ -42,15 +43,23 @@ base::MemoryMappedFile* g_mapped_natives = NULL; base::MemoryMappedFile* g_mapped_snapshot = NULL; #if defined(V8_USE_EXTERNAL_STARTUP_DATA) -bool MapV8Files(base::FilePath* natives_path, base::FilePath* snapshot_path, - int natives_fd = -1, int snapshot_fd = -1) { +bool MapV8Files(base::FilePath* natives_path, + base::FilePath* snapshot_path, + int natives_fd = -1, + int snapshot_fd = -1, + base::MemoryMappedFile::Region natives_region = + base::MemoryMappedFile::Region::kWholeFile, + base::MemoryMappedFile::Region snapshot_region = + base::MemoryMappedFile::Region::kWholeFile) { 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))) { + ? !g_mapped_natives->Initialize(base::File(*natives_path, flags), + natives_region) + : !g_mapped_natives->Initialize(base::File(natives_fd), + natives_region)) { delete g_mapped_natives; g_mapped_natives = NULL; LOG(FATAL) << "Couldn't mmap v8 natives data file"; @@ -61,8 +70,10 @@ bool MapV8Files(base::FilePath* natives_path, base::FilePath* snapshot_path, 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))) { + ? !g_mapped_snapshot->Initialize(base::File(*snapshot_path, flags), + snapshot_region) + : !g_mapped_snapshot->Initialize(base::File(snapshot_fd), + snapshot_region)) { delete g_mapped_snapshot; g_mapped_snapshot = NULL; LOG(ERROR) << "Couldn't mmap v8 snapshot data file"; @@ -106,6 +117,9 @@ extern const unsigned char g_natives_fingerprint[]; extern const unsigned char g_snapshot_fingerprint[]; #endif // V8_VERIFY_EXTERNAL_STARTUP_DATA +const char IsolateHolder::kNativesFileName[] = "natives_blob.bin"; +const char IsolateHolder::kSnapshotFileName[] = "snapshot_blob.bin"; + // static bool IsolateHolder::LoadV8Snapshot() { if (g_mapped_natives && g_mapped_snapshot) @@ -116,13 +130,17 @@ bool IsolateHolder::LoadV8Snapshot() { PathService::Get(v8_snapshot_dir, &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"); + base::FilePath natives_path = data_path.AppendASCII(kNativesFileName); + base::FilePath snapshot_path = data_path.AppendASCII(kSnapshotFileName); #else // !defined(OS_MACOSX) + base::ScopedCFTypeRef natives_file_name( + base::SysUTF8ToCFStringRef(kNativesFileName)); base::FilePath natives_path = base::mac::PathForFrameworkBundleResource( - CFSTR("natives_blob.bin")); + natives_file_name); + base::ScopedCFTypeRef snapshot_file_name( + base::SysUTF8ToCFStringRef(kSnapshotFileName)); base::FilePath snapshot_path = base::mac::PathForFrameworkBundleResource( - CFSTR("snapshot_blob.bin")); + snapshot_file_name); DCHECK(!natives_path.empty()); DCHECK(!snapshot_path.empty()); #endif // !defined(OS_MACOSX) @@ -139,11 +157,31 @@ bool IsolateHolder::LoadV8Snapshot() { } //static -bool IsolateHolder::LoadV8SnapshotFD(int natives_fd, int snapshot_fd) { +bool IsolateHolder::LoadV8SnapshotFd(int natives_fd, + int64 natives_offset, + int64 natives_size, + int snapshot_fd, + int64 snapshot_offset, + int64 snapshot_size) { if (g_mapped_natives && g_mapped_snapshot) return true; - return MapV8Files(NULL, NULL, natives_fd, snapshot_fd); + base::MemoryMappedFile::Region natives_region = + base::MemoryMappedFile::Region::kWholeFile; + if (natives_size != 0 || natives_offset != 0) { + natives_region = + base::MemoryMappedFile::Region(natives_offset, natives_size); + } + + base::MemoryMappedFile::Region snapshot_region = + base::MemoryMappedFile::Region::kWholeFile; + if (natives_size != 0 || natives_offset != 0) { + snapshot_region = + base::MemoryMappedFile::Region(snapshot_offset, snapshot_size); + } + + return MapV8Files( + NULL, NULL, natives_fd, snapshot_fd, natives_region, snapshot_region); } #endif // V8_USE_EXTERNAL_STARTUP_DATA diff --git a/gin/public/isolate_holder.h b/gin/public/isolate_holder.h index 64fc952..44d1d89 100644 --- a/gin/public/isolate_holder.h +++ b/gin/public/isolate_holder.h @@ -33,7 +33,7 @@ class GIN_EXPORT IsolateHolder { // Should be invoked once before creating IsolateHolder instances to // 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. + // LoadV8SnapshotFd) before calling Initialize. static void Initialize(ScriptMode mode, v8::ArrayBuffer::Allocator* allocator); @@ -52,7 +52,15 @@ class GIN_EXPORT IsolateHolder { void RemoveRunMicrotasksObserver(); #if defined(V8_USE_EXTERNAL_STARTUP_DATA) - static bool LoadV8SnapshotFD(int natives_fd, int snapshot_fd); + static const char kNativesFileName[]; + static const char kSnapshotFileName[]; + + static bool LoadV8SnapshotFd(int natives_fd, + int64 natives_offset, + int64 natives_size, + int snapshot_fd, + int64 snapshot_offset, + int64 snapshot_size); static bool LoadV8Snapshot(); #endif // V8_USE_EXTERNAL_STARTUP_DATA static void GetV8ExternalSnapshotData(const char** natives_data_out, -- cgit v1.1