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

Side by Side Diff: base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java

Issue 663543003: Fix low-memory devices crashing on Chrome start up during UMA recodring (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Large update for review feedback Created 6 years, 2 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 package org.chromium.base.library_loader; 5 package org.chromium.base.library_loader;
6 6
7 import android.content.Context; 7 import android.content.Context;
8 import android.os.SystemClock; 8 import android.os.SystemClock;
9 import android.util.Log; 9 import android.util.Log;
10 10
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 // One-way switch becomes true when the libraries are initialized ( 43 // One-way switch becomes true when the libraries are initialized (
44 // by calling nativeLibraryLoaded, which forwards to LibraryLoaded(...) in 44 // by calling nativeLibraryLoaded, which forwards to LibraryLoaded(...) in
45 // library_loader_hooks.cc). 45 // library_loader_hooks.cc).
46 private static boolean sInitialized = false; 46 private static boolean sInitialized = false;
47 47
48 // One-way switches recording attempts to use Relro sharing in the browser. 48 // One-way switches recording attempts to use Relro sharing in the browser.
49 // The flags are used to report UMA stats later. 49 // The flags are used to report UMA stats later.
50 private static boolean sIsUsingBrowserSharedRelros = false; 50 private static boolean sIsUsingBrowserSharedRelros = false;
51 private static boolean sLoadAtFixedAddressFailed = false; 51 private static boolean sLoadAtFixedAddressFailed = false;
52 52
53 // One-way switch recording whether the device supports memory mapping 53 // The name of the APK file.
54 // APK files with executable permissions. Only used in the browser. 54 private static String sApkFileName = null;
55 private static boolean sLibraryLoadFromApkSupported = false; 55
56 // One-way switch becomes true when the library is successfully loaded from
rmcilroy 2014/10/20 10:42:39 nit - One-way switch becomes true if the library w
petrcermak 2014/10/20 15:33:22 Done.
57 // the APK file.
58 private static boolean sLibraryLoadedFromApk = false;
rmcilroy 2014/10/20 10:42:39 nit - sLibraryWasLoadedFromApk
petrcermak 2014/10/20 15:33:22 Done.
56 59
57 // One-way switch becomes true if the system library loading failed, 60 // One-way switch becomes true if the system library loading failed,
58 // and the right native library was found and loaded by the hack. 61 // and the right native library was found and loaded by the hack.
59 // The flag is used to report UMA stats later. 62 // The flag is used to report UMA stats later.
60 private static boolean sNativeLibraryHackWasUsed = false; 63 private static boolean sNativeLibraryHackWasUsed = false;
61 64
62 /** 65 /**
63 * The same as ensureInitialized(null, false), should only be called 66 * The same as ensureInitialized(null, false), should only be called
64 * by non-browser processes. 67 * by non-browser processes.
65 * 68 *
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 private static void loadAlreadyLocked( 156 private static void loadAlreadyLocked(
154 Context context, boolean shouldDeleteOldWorkaroundLibraries) 157 Context context, boolean shouldDeleteOldWorkaroundLibraries)
155 throws ProcessInitException { 158 throws ProcessInitException {
156 try { 159 try {
157 if (!sLoaded) { 160 if (!sLoaded) {
158 assert !sInitialized; 161 assert !sInitialized;
159 162
160 long startTime = SystemClock.uptimeMillis(); 163 long startTime = SystemClock.uptimeMillis();
161 boolean useChromiumLinker = Linker.isUsed(); 164 boolean useChromiumLinker = Linker.isUsed();
162 165
166 if (context != null) {
167 sApkFileName = context.getApplicationInfo().sourceDir;
168 }
169
163 if (useChromiumLinker) { 170 if (useChromiumLinker) {
164 // Load libraries using the Chromium linker. 171 // Load libraries using the Chromium linker.
165 Linker.prepareLibraryLoad(); 172 Linker.prepareLibraryLoad();
166 173
167 // Check if the device supports loading a library directly f rom the APK file.
168 String apkfile = context.getApplicationInfo().sourceDir;
169 if (Linker.isInBrowserProcess()) {
170 sLibraryLoadFromApkSupported = Linker.checkLibraryLoadFr omApkSupport(
171 apkfile);
172 }
173
174 for (String library : NativeLibraries.LIBRARIES) { 174 for (String library : NativeLibraries.LIBRARIES) {
175 String zipfile = null; 175 String zipfile = null;
176 if (Linker.isInZipFile()) { 176 if (Linker.isInZipFile()) {
177 zipfile = apkfile; 177 zipfile = sApkFileName;
178 Log.i(TAG, "Loading " + library + " from within " + zipfile); 178 Log.i(TAG, "Loading " + library + " from within " + zipfile);
179 } else { 179 } else {
180 Log.i(TAG, "Loading: " + library); 180 Log.i(TAG, "Loading: " + library);
181 } 181 }
182 182
183 boolean isLoaded = false; 183 boolean isLoaded = false;
184 if (Linker.isUsingBrowserSharedRelros()) { 184 if (Linker.isUsingBrowserSharedRelros()) {
185 sIsUsingBrowserSharedRelros = true; 185 sIsUsingBrowserSharedRelros = true;
186 try { 186 try {
187 if (zipfile != null) { 187 if (zipfile != null) {
188 Linker.loadLibraryInZipFile(zipfile, library ); 188 Linker.loadLibraryInZipFile(zipfile, library );
189 sLibraryLoadedFromApk = true;
189 } else { 190 } else {
190 Linker.loadLibrary(library); 191 Linker.loadLibrary(library);
191 } 192 }
192 isLoaded = true; 193 isLoaded = true;
193 } catch (UnsatisfiedLinkError e) { 194 } catch (UnsatisfiedLinkError e) {
194 Log.w(TAG, "Failed to load native library with s hared RELRO, " + 195 Log.w(TAG, "Failed to load native library with s hared RELRO, " +
195 "retrying without"); 196 "retrying without");
196 Linker.disableSharedRelros(); 197 Linker.disableSharedRelros();
197 sLoadAtFixedAddressFailed = true; 198 sLoadAtFixedAddressFailed = true;
198 } 199 }
199 } 200 }
200 if (!isLoaded) { 201 if (!isLoaded) {
201 if (zipfile != null) { 202 if (zipfile != null) {
202 Linker.loadLibraryInZipFile(zipfile, library); 203 Linker.loadLibraryInZipFile(zipfile, library);
204 sLibraryLoadedFromApk = true;
203 } else { 205 } else {
204 Linker.loadLibrary(library); 206 Linker.loadLibrary(library);
205 } 207 }
206 } 208 }
207 } 209 }
208 210
209 Linker.finishLibraryLoad(); 211 Linker.finishLibraryLoad();
210 } else { 212 } else {
211 // Load libraries using the system linker. 213 // Load libraries using the system linker.
212 for (String library : NativeLibraries.LIBRARIES) { 214 for (String library : NativeLibraries.LIBRARIES) {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 } 309 }
308 310
309 // Called after all native initializations are complete. 311 // Called after all native initializations are complete.
310 public static void onNativeInitializationComplete() { 312 public static void onNativeInitializationComplete() {
311 recordBrowserProcessHistogram(); 313 recordBrowserProcessHistogram();
312 nativeRecordNativeLibraryHack(sNativeLibraryHackWasUsed); 314 nativeRecordNativeLibraryHack(sNativeLibraryHackWasUsed);
313 } 315 }
314 316
315 // Record Chromium linker histogram state for the main browser process. Call ed from 317 // Record Chromium linker histogram state for the main browser process. Call ed from
316 // onNativeInitializationComplete(). 318 // onNativeInitializationComplete().
317 private static void recordBrowserProcessHistogram() { 319 private static void recordBrowserProcessHistogram() {
rmcilroy 2014/10/20 10:42:39 It looks like this is only called from onNativeIni
petrcermak 2014/10/20 15:33:22 Done.
318 if (Linker.isUsed()) { 320 if (Linker.isUsed()) {
319 assert Linker.isInBrowserProcess(); 321 int libraryLoadFromApkSupport;
rmcilroy 2014/10/20 10:42:39 nit - libraryLoadFromApkStatus
petrcermak 2014/10/20 15:33:22 The variable is not needed now that the code is in
322 if (sLibraryLoadedFromApk) {
323 libraryLoadFromApkSupport = LibraryLoadFromApkSupportCode.SUCCES SFUL;
324 } else if (sApkFileName != null) {
325 libraryLoadFromApkSupport = Linker.checkLibraryLoadFromApkSuppor t(sApkFileName) ?
326 LibraryLoadFromApkSupportCode.SUPPORTED :
327 LibraryLoadFromApkSupportCode.NOT_SUPPORTED;
328 } else {
329 libraryLoadFromApkSupport = LibraryLoadFromApkSupportCode.UNKNOW N;
330 Log.w(TAG, "Unknown APK filename due to null context");
331 }
rmcilroy 2014/10/20 10:42:39 Please pull this out into a separate function whic
petrcermak 2014/10/20 15:33:22 Done.
320 nativeRecordChromiumAndroidLinkerBrowserHistogram(sIsUsingBrowserSha redRelros, 332 nativeRecordChromiumAndroidLinkerBrowserHistogram(sIsUsingBrowserSha redRelros,
321 sLoadAtFixedAddres sFailed, 333 sLoadAtFixedAddres sFailed,
322 sLibraryLoadFromAp kSupported); 334 libraryLoadFromApk Support);
323 } 335 }
324 } 336 }
325 337
326 // Register pending Chromium linker histogram state for renderer processes. This cannot be 338 // Register pending Chromium linker histogram state for renderer processes. This cannot be
327 // recorded as a histogram immediately because histograms and IPC are not re ady at the 339 // recorded as a histogram immediately because histograms and IPC are not re ady at the
328 // time it are captured. This function stores a pending value, so that a lat er call to 340 // time it are captured. This function stores a pending value, so that a lat er call to
329 // RecordChromiumAndroidLinkerRendererHistogram() will record it correctly. 341 // RecordChromiumAndroidLinkerRendererHistogram() will record it correctly.
330 public static void registerRendererProcessHistogram(boolean requestedSharedR elro, 342 public static void registerRendererProcessHistogram(boolean requestedSharedR elro,
331 boolean loadAtFixedAddre ssFailed) { 343 boolean loadAtFixedAddre ssFailed) {
332 if (Linker.isUsed()) { 344 if (Linker.isUsed()) {
333 nativeRegisterChromiumAndroidLinkerRendererHistogram(requestedShared Relro, 345 nativeRegisterChromiumAndroidLinkerRendererHistogram(requestedShared Relro,
334 loadAtFixedAddr essFailed); 346 loadAtFixedAddr essFailed);
335 } 347 }
336 } 348 }
337 349
338 private static native void nativeInitCommandLine(String[] initCommandLine); 350 private static native void nativeInitCommandLine(String[] initCommandLine);
339 351
340 // Only methods needed before or during normal JNI registration are during S ystem.OnLoad. 352 // Only methods needed before or during normal JNI registration are during S ystem.OnLoad.
341 // nativeLibraryLoaded is then called to register everything else. This pro cess is called 353 // nativeLibraryLoaded is then called to register everything else. This pro cess is called
342 // "initialization". This method will be mapped (by generated code) to the LibraryLoaded 354 // "initialization". This method will be mapped (by generated code) to the LibraryLoaded
343 // definition in base/android/library_loader/library_loader_hooks.cc. 355 // definition in base/android/library_loader/library_loader_hooks.cc.
344 // 356 //
345 // Return true on success and false on failure. 357 // Return true on success and false on failure.
346 private static native boolean nativeLibraryLoaded(); 358 private static native boolean nativeLibraryLoaded();
347 359
348 // Method called to record statistics about the Chromium linker operation fo r the main 360 // Method called to record statistics about the Chromium linker operation fo r the main
349 // browser process. Indicates whether the linker attempted relro sharing for the browser, 361 // browser process. Indicates whether the linker attempted relro sharing for the browser,
350 // and if it did, whether the library failed to load at a fixed address. Als o records 362 // and if it did, whether the library failed to load at a fixed address. Als o records
351 // support for memory mapping APK files with executable permissions. 363 // support for loading a library directly from the APK file.
352 private static native void nativeRecordChromiumAndroidLinkerBrowserHistogram ( 364 private static native void nativeRecordChromiumAndroidLinkerBrowserHistogram (
353 boolean isUsingBrowserSharedRelros, 365 boolean isUsingBrowserSharedRelros,
354 boolean loadAtFixedAddressFailed, 366 boolean loadAtFixedAddressFailed,
355 boolean apkMemoryMappingSupported); 367 int libraryLoadFromApkSupport);
356 368
357 // Method called to register (for later recording) statistics about the Chro mium linker 369 // Method called to register (for later recording) statistics about the Chro mium linker
358 // operation for a renderer process. Indicates whether the linker attempted relro sharing, 370 // operation for a renderer process. Indicates whether the linker attempted relro sharing,
359 // and if it did, whether the library failed to load at a fixed address. 371 // and if it did, whether the library failed to load at a fixed address.
360 private static native void nativeRegisterChromiumAndroidLinkerRendererHistog ram( 372 private static native void nativeRegisterChromiumAndroidLinkerRendererHistog ram(
361 boolean requestedSharedRelro, 373 boolean requestedSharedRelro,
362 boolean loadAtFixedAddressFailed); 374 boolean loadAtFixedAddressFailed);
363 375
364 // Get the version of the native library. This is needed so that we can chec k we 376 // Get the version of the native library. This is needed so that we can chec k we
365 // have the right version before initializing the (rest of the) JNI. 377 // have the right version before initializing the (rest of the) JNI.
366 private static native String nativeGetVersionNumber(); 378 private static native String nativeGetVersionNumber();
367 379
368 private static native void nativeRecordNativeLibraryHack(boolean usedHack); 380 private static native void nativeRecordNativeLibraryHack(boolean usedHack);
369 } 381 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698