Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Side by Side Diff: gin/v8_initializer.cc

Issue 1182443003: Moved logic for mapping child process FDs for ICU and V8 into child_process_launcher.cc (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: allow icu init to fail (for tests) Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "gin/v8_initializer.h" 5 #include "gin/v8_initializer.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/files/file.h" 8 #include "base/files/file.h"
9 #include "base/files/file_path.h" 9 #include "base/files/file_path.h"
10 #include "base/files/memory_mapped_file.h" 10 #include "base/files/memory_mapped_file.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/rand_util.h" 13 #include "base/rand_util.h"
14 #include "base/strings/sys_string_conversions.h" 14 #include "base/strings/sys_string_conversions.h"
15 #include "base/threading/platform_thread.h" 15 #include "base/threading/platform_thread.h"
16 #include "base/time/time.h" 16 #include "base/time/time.h"
17 #include "crypto/sha2.h" 17 #include "crypto/sha2.h"
18 18
19 #if defined(V8_USE_EXTERNAL_STARTUP_DATA) 19 #if defined(V8_USE_EXTERNAL_STARTUP_DATA)
20 #if defined(OS_MACOSX) 20 #if defined(OS_MACOSX)
21 #include "base/mac/foundation_util.h" 21 #include "base/mac/foundation_util.h"
22 #endif // OS_MACOSX 22 #endif // OS_MACOSX
23 #include "base/path_service.h" 23 #include "base/path_service.h"
24 #endif // V8_USE_EXTERNAL_STARTUP_DATA 24 #endif // V8_USE_EXTERNAL_STARTUP_DATA
25 25
26 namespace gin { 26 namespace gin {
27 27
28 namespace { 28 namespace {
29
30 base::MemoryMappedFile* g_mapped_natives = nullptr; 29 base::MemoryMappedFile* g_mapped_natives = nullptr;
31 base::MemoryMappedFile* g_mapped_snapshot = nullptr; 30 base::MemoryMappedFile* g_mapped_snapshot = nullptr;
32 31
33 #if defined(V8_USE_EXTERNAL_STARTUP_DATA) 32 #if defined(V8_USE_EXTERNAL_STARTUP_DATA)
33 base::File* g_natives_file = nullptr;
34 base::File* g_snapshot_file = nullptr;
35 base::MemoryMappedFile::Region g_natives_region;
36 base::MemoryMappedFile::Region g_snapshot_region;
37
34 #if !defined(OS_MACOSX) 38 #if !defined(OS_MACOSX)
35 const int kV8SnapshotBasePathKey = 39 const int kV8SnapshotBasePathKey =
36 #if defined(OS_ANDROID) 40 #if defined(OS_ANDROID)
37 base::DIR_ANDROID_APP_DATA; 41 base::DIR_ANDROID_APP_DATA;
38 #elif defined(OS_POSIX) 42 #elif defined(OS_POSIX)
39 base::DIR_EXE; 43 base::DIR_EXE;
40 #elif defined(OS_WIN) 44 #elif defined(OS_WIN)
41 base::DIR_MODULE; 45 base::DIR_MODULE;
42 #endif // OS_ANDROID 46 #endif // OS_ANDROID
43 #endif // !OS_MACOSX 47 #endif // !OS_MACOSX
(...skipping 29 matching lines...) Expand all
73 new base::MemoryMappedFile; 77 new base::MemoryMappedFile;
74 if (!mmapped_file->Initialize(file.Pass(), region)) { 78 if (!mmapped_file->Initialize(file.Pass(), region)) {
75 delete mmapped_file; 79 delete mmapped_file;
76 *mmapped_file_out = NULL; 80 *mmapped_file_out = NULL;
77 return false; 81 return false;
78 } 82 }
79 83
80 return true; 84 return true;
81 } 85 }
82 86
83 static bool OpenV8File(const base::FilePath& path, 87 base::File OpenV8File(const char* file_name,
84 int flags, 88 base::MemoryMappedFile::Region* region_out) {
85 base::File& file) {
86 // Re-try logic here is motivated by http://crbug.com/479537 89 // Re-try logic here is motivated by http://crbug.com/479537
87 // for A/V on Windows (https://support.microsoft.com/en-us/kb/316609). 90 // for A/V on Windows (https://support.microsoft.com/en-us/kb/316609).
88 91
89 // These match tools/metrics/histograms.xml 92 // These match tools/metrics/histograms.xml
90 enum OpenV8FileResult { 93 enum OpenV8FileResult {
91 OPENED = 0, 94 OPENED = 0,
92 OPENED_RETRY, 95 OPENED_RETRY,
93 FAILED_IN_USE, 96 FAILED_IN_USE,
94 FAILED_OTHER, 97 FAILED_OTHER,
95 MAX_VALUE 98 MAX_VALUE
96 }; 99 };
97 100
101 base::FilePath path;
102 GetV8FilePath(file_name, &path);
103
98 OpenV8FileResult result = OpenV8FileResult::FAILED_IN_USE; 104 OpenV8FileResult result = OpenV8FileResult::FAILED_IN_USE;
105 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ;
106 base::File file;
99 for (int attempt = 0; attempt < kMaxOpenAttempts; attempt++) { 107 for (int attempt = 0; attempt < kMaxOpenAttempts; attempt++) {
100 file.Initialize(path, flags); 108 file.Initialize(path, flags);
101 if (file.IsValid()) { 109 if (file.IsValid()) {
110 *region_out = base::MemoryMappedFile::Region::kWholeFile;
102 if (attempt == 0) { 111 if (attempt == 0) {
103 result = OpenV8FileResult::OPENED; 112 result = OpenV8FileResult::OPENED;
104 break; 113 break;
105 } else { 114 } else {
106 result = OpenV8FileResult::OPENED_RETRY; 115 result = OpenV8FileResult::OPENED_RETRY;
107 break; 116 break;
108 } 117 }
109 } else if (file.error_details() != base::File::FILE_ERROR_IN_USE) { 118 } else if (file.error_details() != base::File::FILE_ERROR_IN_USE) {
110 result = OpenV8FileResult::FAILED_OTHER; 119 result = OpenV8FileResult::FAILED_OTHER;
111 break; 120 break;
112 } else if (kMaxOpenAttempts - 1 != attempt) { 121 } else if (kMaxOpenAttempts - 1 != attempt) {
113 base::PlatformThread::Sleep( 122 base::PlatformThread::Sleep(
114 base::TimeDelta::FromMilliseconds(kOpenRetryDelayMillis)); 123 base::TimeDelta::FromMilliseconds(kOpenRetryDelayMillis));
115 } 124 }
116 } 125 }
117 126
118 UMA_HISTOGRAM_ENUMERATION("V8.Initializer.OpenV8File.Result", 127 UMA_HISTOGRAM_ENUMERATION("V8.Initializer.OpenV8File.Result",
119 result, 128 result,
120 OpenV8FileResult::MAX_VALUE); 129 OpenV8FileResult::MAX_VALUE);
130 return file.Pass();
131 }
121 132
122 return result == OpenV8FileResult::OPENED 133 void OpenNativesFileIfNecessary() {
123 || result == OpenV8FileResult::OPENED_RETRY; 134 if (g_natives_file == nullptr) {
135 g_natives_file =
136 new base::File(OpenV8File(kNativesFileName, &g_natives_region));
137 }
138 }
139
140 void OpenSnapshotFileIfNecessary() {
141 if (g_snapshot_file == nullptr) {
142 g_snapshot_file =
143 new base::File(OpenV8File(kSnapshotFileName, &g_snapshot_region));
144 }
124 } 145 }
125 146
126 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA) 147 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
127 bool VerifyV8StartupFile(base::MemoryMappedFile** file, 148 bool VerifyV8StartupFile(base::MemoryMappedFile** file,
128 const unsigned char* fingerprint) { 149 const unsigned char* fingerprint) {
129 unsigned char output[crypto::kSHA256Length]; 150 unsigned char output[crypto::kSHA256Length];
130 crypto::SHA256HashString( 151 crypto::SHA256HashString(
131 base::StringPiece(reinterpret_cast<const char*>((*file)->data()), 152 base::StringPiece(reinterpret_cast<const char*>((*file)->data()),
132 (*file)->length()), 153 (*file)->length()),
133 output, sizeof(output)); 154 output, sizeof(output));
(...skipping 22 matching lines...) Expand all
156 #endif // V8_VERIFY_EXTERNAL_STARTUP_DATA 177 #endif // V8_VERIFY_EXTERNAL_STARTUP_DATA
157 178
158 enum LoadV8FileResult { 179 enum LoadV8FileResult {
159 V8_LOAD_SUCCESS = 0, 180 V8_LOAD_SUCCESS = 0,
160 V8_LOAD_FAILED_OPEN, 181 V8_LOAD_FAILED_OPEN,
161 V8_LOAD_FAILED_MAP, 182 V8_LOAD_FAILED_MAP,
162 V8_LOAD_FAILED_VERIFY, 183 V8_LOAD_FAILED_VERIFY,
163 V8_LOAD_MAX_VALUE 184 V8_LOAD_MAX_VALUE
164 }; 185 };
165 186
166 static LoadV8FileResult OpenMapVerify( 187 static LoadV8FileResult MapVerify(base::File& file,
167 const char* file_name, 188 const base::MemoryMappedFile::Region& region,
168 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA) 189 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
169 const unsigned char* fingerprint, 190 const unsigned char* fingerprint,
170 #endif 191 #endif
171 base::MemoryMappedFile** mmapped_file_out) { 192 base::MemoryMappedFile** mmapped_file_out) {
172 base::FilePath path; 193 if (!file.IsValid())
173 GetV8FilePath(file_name, &path);
174
175 base::File file;
176 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ;
177
178 if (!OpenV8File(path, flags, file))
179 return V8_LOAD_FAILED_OPEN; 194 return V8_LOAD_FAILED_OPEN;
180 if (!MapV8File(file.Pass(), base::MemoryMappedFile::Region::kWholeFile, 195 // It would be more correct to use File::Duplicate() here, but since
181 mmapped_file_out)) 196 // the file is never closed, sharing it is fine.
197 if (!MapV8File(base::File(file.GetPlatformFile()), region, mmapped_file_out))
182 return V8_LOAD_FAILED_MAP; 198 return V8_LOAD_FAILED_MAP;
183 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA) 199 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
184 if (!VerifyV8StartupFile(mmapped_file_out, fingerprint)) 200 if (!VerifyV8StartupFile(mmapped_file_out, fingerprint))
185 return V8_LOAD_FAILED_VERIFY; 201 return V8_LOAD_FAILED_VERIFY;
186 #endif // V8_VERIFY_EXTERNAL_STARTUP_DATA 202 #endif // V8_VERIFY_EXTERNAL_STARTUP_DATA
187 return V8_LOAD_SUCCESS; 203 return V8_LOAD_SUCCESS;
188 } 204 }
189 205
190 // static 206 // static
191 void V8Initializer::LoadV8Snapshot() { 207 void V8Initializer::LoadV8Snapshot() {
192 if (g_mapped_snapshot) 208 if (g_mapped_snapshot)
193 return; 209 return;
194 210
195 LoadV8FileResult result = OpenMapVerify(kSnapshotFileName, 211 OpenSnapshotFileIfNecessary();
212 LoadV8FileResult result = MapVerify(*g_snapshot_file, g_snapshot_region,
196 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA) 213 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
197 g_snapshot_fingerprint, 214 g_snapshot_fingerprint,
198 #endif 215 #endif
199 &g_mapped_snapshot); 216 &g_mapped_snapshot);
217 // V8 can't start up without the source of the natives, but it can
218 // start up (slower) without the snapshot.
200 UMA_HISTOGRAM_ENUMERATION("V8.Initializer.LoadV8Snapshot.Result", result, 219 UMA_HISTOGRAM_ENUMERATION("V8.Initializer.LoadV8Snapshot.Result", result,
201 V8_LOAD_MAX_VALUE); 220 V8_LOAD_MAX_VALUE);
202 } 221 }
203 222
204 void V8Initializer::LoadV8Natives() { 223 void V8Initializer::LoadV8Natives() {
205 if (g_mapped_natives) 224 if (g_mapped_natives)
206 return; 225 return;
207 226
208 LoadV8FileResult result = OpenMapVerify(kNativesFileName, 227 OpenNativesFileIfNecessary();
228 LoadV8FileResult result = MapVerify(*g_natives_file, g_natives_region,
209 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA) 229 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
210 g_natives_fingerprint, 230 g_natives_fingerprint,
211 #endif 231 #endif
212 &g_mapped_natives); 232 &g_mapped_natives);
213 if (result != V8_LOAD_SUCCESS) { 233 if (result != V8_LOAD_SUCCESS) {
214 LOG(FATAL) << "Couldn't mmap v8 natives data file, status code is " 234 LOG(FATAL) << "Couldn't mmap v8 natives data file, status code is "
215 << static_cast<int>(result); 235 << static_cast<int>(result);
216 } 236 }
217 } 237 }
218 238
219 // static 239 // static
220 void V8Initializer::LoadV8SnapshotFromFD(base::PlatformFile snapshot_pf, 240 void V8Initializer::LoadV8SnapshotFromFD(base::PlatformFile snapshot_pf,
221 int64 snapshot_offset, 241 int64 snapshot_offset,
222 int64 snapshot_size) { 242 int64 snapshot_size) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 LOG(FATAL) << "Couldn't mmap v8 natives data file"; 284 LOG(FATAL) << "Couldn't mmap v8 natives data file";
265 } 285 }
266 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA) 286 #if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA)
267 if (!VerifyV8StartupFile(&g_mapped_natives, g_natives_fingerprint)) { 287 if (!VerifyV8StartupFile(&g_mapped_natives, g_natives_fingerprint)) {
268 LOG(FATAL) << "Couldn't verify contents of v8 natives data file"; 288 LOG(FATAL) << "Couldn't verify contents of v8 natives data file";
269 } 289 }
270 #endif // V8_VERIFY_EXTERNAL_STARTUP_DATA 290 #endif // V8_VERIFY_EXTERNAL_STARTUP_DATA
271 } 291 }
272 292
273 // static 293 // static
274 bool V8Initializer::OpenV8FilesForChildProcesses( 294 base::PlatformFile V8Initializer::OpenNativesFileForChildProcesses(
275 base::PlatformFile* natives_fd_out, 295 base::MemoryMappedFile::Region* region_out) {
276 base::PlatformFile* snapshot_fd_out) { 296 OpenNativesFileIfNecessary();
277 base::FilePath natives_data_path; 297 *region_out = g_natives_region;
278 base::FilePath snapshot_data_path; 298 return g_natives_file->GetPlatformFile();
279 GetV8FilePath(kNativesFileName, &natives_data_path);
280 GetV8FilePath(kSnapshotFileName, &snapshot_data_path);
281
282 base::File natives_data_file;
283 base::File snapshot_data_file;
284 int file_flags = base::File::FLAG_OPEN | base::File::FLAG_READ;
285
286 bool natives_success =
287 OpenV8File(natives_data_path, file_flags, natives_data_file);
288 if (natives_success) {
289 *natives_fd_out = natives_data_file.TakePlatformFile();
290 }
291 bool snapshot_success =
292 OpenV8File(snapshot_data_path, file_flags, snapshot_data_file);
293 if (snapshot_success) {
294 *snapshot_fd_out = snapshot_data_file.TakePlatformFile();
295 }
296 // We can start up without the snapshot file, but not without the natives.
297 return natives_success;
298 } 299 }
299 300
300 #endif // V8_USE_EXTERNAL_STARTUP_DATA 301 // static
302 base::PlatformFile V8Initializer::OpenSnapshotFileForChildProcesses(
rmcilroy 2015/06/12 22:09:25 How about GetOpenSnapshotFileForChildProcess (to m
303 base::MemoryMappedFile::Region* region_out) {
304 OpenSnapshotFileIfNecessary();
305 *region_out = g_snapshot_region;
306 return g_snapshot_file->GetPlatformFile();
307 }
308 #endif // defined(V8_USE_EXTERNAL_STARTUP_DATA)
301 309
302 // static 310 // static
303 void V8Initializer::Initialize(gin::IsolateHolder::ScriptMode mode) { 311 void V8Initializer::Initialize(gin::IsolateHolder::ScriptMode mode) {
304 static bool v8_is_initialized = false; 312 static bool v8_is_initialized = false;
305 if (v8_is_initialized) 313 if (v8_is_initialized)
306 return; 314 return;
307 315
308 v8::V8::InitializePlatform(V8Platform::Get()); 316 v8::V8::InitializePlatform(V8Platform::Get());
309 317
310 if (gin::IsolateHolder::kStrictMode == mode) { 318 if (gin::IsolateHolder::kStrictMode == mode) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 *snapshot_data_out = 356 *snapshot_data_out =
349 reinterpret_cast<const char*>(g_mapped_snapshot->data()); 357 reinterpret_cast<const char*>(g_mapped_snapshot->data());
350 *snapshot_size_out = static_cast<int>(g_mapped_snapshot->length()); 358 *snapshot_size_out = static_cast<int>(g_mapped_snapshot->length());
351 } else { 359 } else {
352 *snapshot_data_out = NULL; 360 *snapshot_data_out = NULL;
353 *snapshot_size_out = 0; 361 *snapshot_size_out = 0;
354 } 362 }
355 } 363 }
356 364
357 } // namespace gin 365 } // namespace gin
OLDNEW
« content/browser/child_process_launcher.cc ('K') | « gin/v8_initializer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698