OLD | NEW |
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/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
14 #include "base/rand_util.h" | 14 #include "base/rand_util.h" |
15 #include "base/strings/sys_string_conversions.h" | 15 #include "base/strings/sys_string_conversions.h" |
16 #include "base/threading/platform_thread.h" | 16 #include "base/threading/platform_thread.h" |
17 #include "base/time/time.h" | 17 #include "base/time/time.h" |
18 #include "crypto/sha2.h" | 18 #include "crypto/sha2.h" |
19 | 19 |
20 #if defined(V8_USE_EXTERNAL_STARTUP_DATA) | 20 #if defined(V8_USE_EXTERNAL_STARTUP_DATA) |
| 21 #if defined(OS_ANDROID) |
| 22 #include "base/android/apk_assets.h" |
| 23 #endif |
21 #if defined(OS_MACOSX) | 24 #if defined(OS_MACOSX) |
22 #include "base/mac/foundation_util.h" | 25 #include "base/mac/foundation_util.h" |
23 #endif // OS_MACOSX | 26 #endif // OS_MACOSX |
24 #include "base/path_service.h" | 27 #include "base/path_service.h" |
25 #endif // V8_USE_EXTERNAL_STARTUP_DATA | 28 #endif // V8_USE_EXTERNAL_STARTUP_DATA |
26 | 29 |
27 namespace gin { | 30 namespace gin { |
28 | 31 |
29 namespace { | 32 namespace { |
30 | 33 |
(...skipping 11 matching lines...) Expand all Loading... |
42 #endif | 45 #endif |
43 | 46 |
44 // File handles intentionally never closed. Not using File here because its | 47 // File handles intentionally never closed. Not using File here because its |
45 // Windows implementation guards against two instances owning the same | 48 // Windows implementation guards against two instances owning the same |
46 // PlatformFile (which we allow since we know it is never freed). | 49 // PlatformFile (which we allow since we know it is never freed). |
47 base::PlatformFile g_natives_pf = kInvalidPlatformFile; | 50 base::PlatformFile g_natives_pf = kInvalidPlatformFile; |
48 base::PlatformFile g_snapshot_pf = kInvalidPlatformFile; | 51 base::PlatformFile g_snapshot_pf = kInvalidPlatformFile; |
49 base::MemoryMappedFile::Region g_natives_region; | 52 base::MemoryMappedFile::Region g_natives_region; |
50 base::MemoryMappedFile::Region g_snapshot_region; | 53 base::MemoryMappedFile::Region g_snapshot_region; |
51 | 54 |
52 #if !defined(OS_MACOSX) | |
53 const int kV8SnapshotBasePathKey = | |
54 #if defined(OS_ANDROID) | |
55 base::DIR_ANDROID_APP_DATA; | |
56 #elif defined(OS_POSIX) | |
57 base::DIR_EXE; | |
58 #elif defined(OS_WIN) | |
59 base::DIR_MODULE; | |
60 #endif // OS_ANDROID | |
61 #endif // !OS_MACOSX | |
62 | |
63 const char kNativesFileName[] = "natives_blob.bin"; | 55 const char kNativesFileName[] = "natives_blob.bin"; |
64 const char kSnapshotFileName[] = "snapshot_blob.bin"; | 56 const char kSnapshotFileName[] = "snapshot_blob.bin"; |
65 | 57 |
66 // Constants for snapshot loading retries taken from: | |
67 // https://support.microsoft.com/en-us/kb/316609. | |
68 const int kMaxOpenAttempts = 5; | |
69 const int kOpenRetryDelayMillis = 250; | |
70 | |
71 void GetV8FilePath(const char* file_name, base::FilePath* path_out) { | 58 void GetV8FilePath(const char* file_name, base::FilePath* path_out) { |
72 #if !defined(OS_MACOSX) | 59 #if !defined(OS_MACOSX) |
73 base::FilePath data_path; | 60 base::FilePath data_path; |
74 PathService::Get(kV8SnapshotBasePathKey, &data_path); | 61 #if defined(OS_ANDROID) |
| 62 // This is the path within the .apk. |
| 63 data_path = base::FilePath(FILE_PATH_LITERAL("assets")); |
| 64 #elif defined(OS_POSIX) |
| 65 PathService::Get(base::DIR_EXE, &data_path); |
| 66 #elif defined(OS_WIN) |
| 67 PathService::Get(base::DIR_MODULE, &data_path); |
| 68 #endif |
75 DCHECK(!data_path.empty()); | 69 DCHECK(!data_path.empty()); |
76 | 70 |
77 *path_out = data_path.AppendASCII(file_name); | 71 *path_out = data_path.AppendASCII(file_name); |
78 #else // !defined(OS_MACOSX) | 72 #else // !defined(OS_MACOSX) |
79 base::ScopedCFTypeRef<CFStringRef> natives_file_name( | 73 base::ScopedCFTypeRef<CFStringRef> natives_file_name( |
80 base::SysUTF8ToCFStringRef(file_name)); | 74 base::SysUTF8ToCFStringRef(file_name)); |
81 *path_out = base::mac::PathForFrameworkBundleResource(natives_file_name); | 75 *path_out = base::mac::PathForFrameworkBundleResource(natives_file_name); |
82 #endif // !defined(OS_MACOSX) | 76 #endif // !defined(OS_MACOSX) |
83 DCHECK(!path_out->empty()); | 77 DCHECK(!path_out->empty()); |
84 } | 78 } |
(...skipping 16 matching lines...) Expand all Loading... |
101 // for A/V on Windows (https://support.microsoft.com/en-us/kb/316609). | 95 // for A/V on Windows (https://support.microsoft.com/en-us/kb/316609). |
102 | 96 |
103 // These match tools/metrics/histograms.xml | 97 // These match tools/metrics/histograms.xml |
104 enum OpenV8FileResult { | 98 enum OpenV8FileResult { |
105 OPENED = 0, | 99 OPENED = 0, |
106 OPENED_RETRY, | 100 OPENED_RETRY, |
107 FAILED_IN_USE, | 101 FAILED_IN_USE, |
108 FAILED_OTHER, | 102 FAILED_OTHER, |
109 MAX_VALUE | 103 MAX_VALUE |
110 }; | 104 }; |
111 | |
112 base::FilePath path; | 105 base::FilePath path; |
113 GetV8FilePath(file_name, &path); | 106 GetV8FilePath(file_name, &path); |
114 | 107 |
| 108 #if defined(OS_ANDROID) |
| 109 base::File file(base::android::OpenApkAsset(path.value(), region_out)); |
| 110 OpenV8FileResult result = file.IsValid() ? OpenV8FileResult::OPENED |
| 111 : OpenV8FileResult::FAILED_OTHER; |
| 112 #else |
| 113 // Re-try logic here is motivated by http://crbug.com/479537 |
| 114 // for A/V on Windows (https://support.microsoft.com/en-us/kb/316609). |
| 115 const int kMaxOpenAttempts = 5; |
| 116 const int kOpenRetryDelayMillis = 250; |
| 117 |
115 OpenV8FileResult result = OpenV8FileResult::FAILED_IN_USE; | 118 OpenV8FileResult result = OpenV8FileResult::FAILED_IN_USE; |
116 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ; | 119 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ; |
117 base::File file; | 120 base::File file; |
118 for (int attempt = 0; attempt < kMaxOpenAttempts; attempt++) { | 121 for (int attempt = 0; attempt < kMaxOpenAttempts; attempt++) { |
119 file.Initialize(path, flags); | 122 file.Initialize(path, flags); |
120 if (file.IsValid()) { | 123 if (file.IsValid()) { |
121 *region_out = base::MemoryMappedFile::Region::kWholeFile; | 124 *region_out = base::MemoryMappedFile::Region::kWholeFile; |
122 if (attempt == 0) { | 125 if (attempt == 0) { |
123 result = OpenV8FileResult::OPENED; | 126 result = OpenV8FileResult::OPENED; |
124 break; | 127 break; |
125 } else { | 128 } else { |
126 result = OpenV8FileResult::OPENED_RETRY; | 129 result = OpenV8FileResult::OPENED_RETRY; |
127 break; | 130 break; |
128 } | 131 } |
129 } else if (file.error_details() != base::File::FILE_ERROR_IN_USE) { | 132 } else if (file.error_details() != base::File::FILE_ERROR_IN_USE) { |
130 result = OpenV8FileResult::FAILED_OTHER; | 133 result = OpenV8FileResult::FAILED_OTHER; |
131 break; | 134 break; |
132 } else if (kMaxOpenAttempts - 1 != attempt) { | 135 } else if (kMaxOpenAttempts - 1 != attempt) { |
133 base::PlatformThread::Sleep( | 136 base::PlatformThread::Sleep( |
134 base::TimeDelta::FromMilliseconds(kOpenRetryDelayMillis)); | 137 base::TimeDelta::FromMilliseconds(kOpenRetryDelayMillis)); |
135 } | 138 } |
136 } | 139 } |
| 140 #endif // defined(OS_ANDROID) |
137 | 141 |
138 UMA_HISTOGRAM_ENUMERATION("V8.Initializer.OpenV8File.Result", | 142 UMA_HISTOGRAM_ENUMERATION("V8.Initializer.OpenV8File.Result", |
139 result, | 143 result, |
140 OpenV8FileResult::MAX_VALUE); | 144 OpenV8FileResult::MAX_VALUE); |
141 return file.TakePlatformFile(); | 145 return file.TakePlatformFile(); |
142 } | 146 } |
143 | 147 |
144 void OpenNativesFileIfNecessary() { | 148 void OpenNativesFileIfNecessary() { |
145 if (g_natives_pf == kInvalidPlatformFile) { | 149 if (g_natives_pf == kInvalidPlatformFile) { |
146 g_natives_pf = OpenV8File(kNativesFileName, &g_natives_region); | 150 g_natives_pf = OpenV8File(kNativesFileName, &g_natives_region); |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 *snapshot_data_out = | 367 *snapshot_data_out = |
364 reinterpret_cast<const char*>(g_mapped_snapshot->data()); | 368 reinterpret_cast<const char*>(g_mapped_snapshot->data()); |
365 *snapshot_size_out = static_cast<int>(g_mapped_snapshot->length()); | 369 *snapshot_size_out = static_cast<int>(g_mapped_snapshot->length()); |
366 } else { | 370 } else { |
367 *snapshot_data_out = NULL; | 371 *snapshot_data_out = NULL; |
368 *snapshot_size_out = 0; | 372 *snapshot_size_out = 0; |
369 } | 373 } |
370 } | 374 } |
371 | 375 |
372 } // namespace gin | 376 } // namespace gin |
OLD | NEW |