summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/build/android/docs/java_optimization.md
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/build/android/docs/java_optimization.md')
-rw-r--r--third_party/libwebrtc/build/android/docs/java_optimization.md149
1 files changed, 149 insertions, 0 deletions
diff --git a/third_party/libwebrtc/build/android/docs/java_optimization.md b/third_party/libwebrtc/build/android/docs/java_optimization.md
new file mode 100644
index 0000000000..0ba0d50358
--- /dev/null
+++ b/third_party/libwebrtc/build/android/docs/java_optimization.md
@@ -0,0 +1,149 @@
+# Optimizing Java Code
+
+This doc describes how Java code is optimized in Chrome on Android and how to
+deal with issues caused by the optimizer. For tips on how to write optimized
+code, see [//docs/speed/binary_size/optimization_advice.md#optimizing-java-code](/docs/speed/binary_size/optimization_advice.md#optimizing-java-code).
+
+[TOC]
+
+## ProGuard vs R8
+
+ProGuard is the original open-source tool used by many Android applications to
+perform whole-program bytecode optimization. [R8](https://r8.googlesource.com/r8),
+is a re-implementation that is used by Chrome (and the default for Android Studio).
+The terms "ProGuard" and "R8" are used interchangeably within Chromium but
+generally they're meant to refer to the tool providing Java code optimizations.
+
+## What does ProGuard do?
+
+1. Shrinking: ProGuard will remove unused code. This is especially useful
+ when depending on third party libraries where only a few functions are used.
+
+2. Obfuscation: ProGuard will rename classes/fields/methods to use shorter
+ names. Obfuscation is used for minification purposes only (not security).
+
+3. Optimization: ProGuard performs a series of optimizations to shrink code
+ further through various approaches (ex. inlining, outlining, class merging,
+ etc).
+
+## Build Process
+
+ProGuard is enabled only for release builds of Chrome because it is a slow build
+step and breaks Java debugging. It can also be enabled manually via the GN arg:
+```is_java_debug = false```
+
+### ProGuard configuration files
+
+Most GN Java targets can specify ProGuard configuration files by setting the
+`proguard_configs` variable. [//base/android/proguard](/base/android/proguard)
+contains common flags shared by most Chrome applications.
+
+### GN build rules
+
+When `is_java_debug = false` and a target has enabled ProGuard, the `proguard`
+step generates the `.dex` files for the application. The `proguard` step takes
+as input a list of `.jar` files, runs R8/ProGuard on those `.jar` files, and
+produces the final `.dex` file(s) that will be packaged into your `.apk`
+
+## Deobfuscation
+
+Obfuscation can be turned off for local builds while leaving ProGuard enabled
+by setting `enable_proguard_obfuscation = false` in GN args.
+
+There are two main methods for deobfuscating Java stack traces locally:
+1. Using APK wrapper scripts (stacks are automatically deobfuscated)
+ * `$OUT/bin/chrome_public_apk logcat` # Run adb logcat
+ * `$OUT/bin/chrome_public_apk run` # Launch chrome and run adb logcat
+
+2. Using `java_deobfuscate`
+ * build/android/stacktrace/java_deobfuscate.py $OUT/apks/ChromePublic.apk.mapping < logcat.txt`
+ * ProGuard mapping files are located beside APKs (ex.
+ `$OUT/apks/ChromePublic.apk` and `$OUT/apks/ChromePublic.apk.mapping`)
+
+Helpful links for deobfuscation:
+
+* [Internal bits about how mapping files are archived][proguard-site]
+* [More detailed deobfuscation instructions][proguard-doc]
+* [Script for deobfuscating official builds][deob-official]
+
+[proguard-site]: http://goto.google.com/chrome-android-proguard
+[proguard-doc]: http://goto.google.com/chromejavadeobfuscation
+[deob-official]: http://goto.google.com/chrome-android-official-deobfuscation
+
+## Debugging common failures
+
+ProGuard failures are often hard to debug. This section aims to outline some of
+the more common errors.
+
+### Classes expected to be discarded
+
+The `-checkdiscard` directive can be used to ensure that certain items are
+removed by ProGuard. A common use of `-checkdiscard` it to ensure that ProGuard
+optimizations do not regress in their ability to remove code, such as code
+intended only for debug builds, or generated JNI classes that are meant to be
+zero-overhead abstractions. Annotating a class with
+[@CheckDiscard][checkdiscard] will add a `-checkdiscard` rule automatically.
+
+[checkdiscard]: /base/android/java/src/org/chromium/base/annotations/CheckDiscard.java
+
+```
+Item void org.chromium.base.library_loader.LibraryPrefetcherJni.<init>() was not discarded.
+void org.chromium.base.library_loader.LibraryPrefetcherJni.<init>()
+|- is invoked from:
+| void org.chromium.base.library_loader.LibraryPrefetcher.asyncPrefetchLibrariesToMemory()
+... more code path lines
+|- is referenced in keep rule:
+| obj/chrome/android/chrome_public_apk/chrome_public_apk.resources.proguard.txt:104:1
+
+Error: Discard checks failed.
+```
+
+Things to check
+ * Did you add code that is referenced by code path in the error message?
+ * If so, check the original class for why the `CheckDiscard` was added
+ originally and verify that the reason is still valid with your change (may
+ need git blame to do this).
+ * Try the extra debugging steps listed in the JNI section below.
+
+### JNI wrapper classes not discarded
+
+Proxy native methods (`@NativeMethods`) use generated wrapper classes to provide
+access to native methods. We rely on ProGuard to fully optimize the generated
+code so that native methods aren't a source of binary size bloat. The above
+error message is an example when a JNI wrapper class wasn't discarded (notice
+the name of the offending class).
+ * The ProGuard rule pointed to in the error message isn't helpful (just tells
+ us a code path that reaches the not-inlined class).
+ * Common causes:
+ * Caching the result of `ClassNameJni.get()` in a member variable.
+ * Passing a native wrapper method reference instead of using a lambda (i.e.
+ `Jni.get()::methodName` vs. `() -> Jni.get.methodName()`).
+ * For more debugging info, add to `base/android/proguard/chromium_code.flags`:
+ ```
+ -whyareyounotinlining class org.chromium.base.library_loader.LibraryPrefetcherJni {
+ <init>();
+ }
+ ```
+
+### Duplicate classes
+
+```
+Type YourClassName is defined multiple times: obj/jar1.jar:YourClassName.class, obj/jar2.jar:YourClassName.class
+```
+
+Common causes:
+ * Multiple targets with overlapping `srcjar_deps`:
+ * Each `.srcjar` can only be depended on by a single Java target in any
+ given APK target. `srcjar_deps` are just a convenient way to depend on
+ generated files and should be treated like source files rather than
+ `deps`.
+ * Solution: Wrap the `srcjar` in an `android_library` target or have only a
+ single Java target depend on the `srcjar` and have other targets depend on
+ the containing Java target instead.
+ * Accidentally enabling APK level generated files for multiple targets that
+ share generated code (ex. Trichrome or App Bundles):
+ * Solution: Make sure the generated file is only added once.
+
+Debugging ProGuard failures isn't easy, so please message java@chromium.org
+or [file a bug](crbug.com/new) with `component=Build os=Android` for any
+issues related to Java code optimization.