xref: /aosp_15_r20/external/cronet/build/android/docs/java_asserts.md (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker# Java Asserts in Chromium
2*6777b538SAndroid Build Coastguard WorkerThis doc exists to explain how asserts in Java are enabled and disabled by
3*6777b538SAndroid Build Coastguard WorkerChromium's build system.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker## javac Assertion Bytecode
6*6777b538SAndroid Build Coastguard WorkerWhenever javac compiles a Java class, assertions are transformed into the
7*6777b538SAndroid Build Coastguard Workerfollowing bytecode:
8*6777b538SAndroid Build Coastguard Worker
9*6777b538SAndroid Build Coastguard Worker```
10*6777b538SAndroid Build Coastguard Worker    Code:
11*6777b538SAndroid Build Coastguard Worker       0: getstatic     #2            // Static field $assertionsDisabled
12*6777b538SAndroid Build Coastguard Worker       3: ifne          20            // Conditional jump past assertion throw
13*6777b538SAndroid Build Coastguard Worker      12: new           #3            // Class java/lang/AssertionError
14*6777b538SAndroid Build Coastguard Worker      19: athrow                      // Throwing AssertionError
15*6777b538SAndroid Build Coastguard Worker      20: return
16*6777b538SAndroid Build Coastguard Worker
17*6777b538SAndroid Build Coastguard Worker// NOTE: this static block was made just to check the desiredAssertionStatus.
18*6777b538SAndroid Build Coastguard Worker// There was no static block on the class before javac created one.
19*6777b538SAndroid Build Coastguard Worker  static {};
20*6777b538SAndroid Build Coastguard Worker    Code:
21*6777b538SAndroid Build Coastguard Worker       2: invokevirtual #6            // Method java/lang/Class.desiredAssertionStatus()
22*6777b538SAndroid Build Coastguard Worker       5: ifne          12
23*6777b538SAndroid Build Coastguard Worker       8: iconst_1
24*6777b538SAndroid Build Coastguard Worker       9: goto          13
25*6777b538SAndroid Build Coastguard Worker      12: iconst_0
26*6777b538SAndroid Build Coastguard Worker      13: putstatic     #2            // Static field $assertionsDisabled
27*6777b538SAndroid Build Coastguard Worker      16: return
28*6777b538SAndroid Build Coastguard Worker```
29*6777b538SAndroid Build Coastguard Worker
30*6777b538SAndroid Build Coastguard WorkerTL;DR - every single assertion is gated behind a `assertionDisabled` flag check,
31*6777b538SAndroid Build Coastguard Workerwhich is a static field that can be set by the JRE's
32*6777b538SAndroid Build Coastguard Worker`setDefaultAssertionStatus`, `setPackageAssertionStatus`, and
33*6777b538SAndroid Build Coastguard Worker`setClassAssertionStatus` methods.
34*6777b538SAndroid Build Coastguard Worker
35*6777b538SAndroid Build Coastguard Worker## Assertion Enabling/Disabling
36*6777b538SAndroid Build Coastguard WorkerOur tools which consume javac output, namely R8 and D8, each have flags which
37*6777b538SAndroid Build Coastguard Workerthe build system uses to enable or disable asserts. We control this with the
38*6777b538SAndroid Build Coastguard Worker`enable_java_asserts` gn arg. It does this by deleting the gating check on
39*6777b538SAndroid Build Coastguard Worker`assertionsDisabled` when enabling, and by eliminating any reference to the
40*6777b538SAndroid Build Coastguard Workerassert when disabling.
41*6777b538SAndroid Build Coastguard Worker
42*6777b538SAndroid Build Coastguard Worker```java
43*6777b538SAndroid Build Coastguard Worker// Example equivalents of:
44*6777b538SAndroid Build Coastguard Workera = foo();
45*6777b538SAndroid Build Coastguard Workerassert a != 0;
46*6777b538SAndroid Build Coastguard Workerreturn a;
47*6777b538SAndroid Build Coastguard Worker
48*6777b538SAndroid Build Coastguard Worker// Traditional, unoptimized javac output.
49*6777b538SAndroid Build Coastguard Workera = foo();
50*6777b538SAndroid Build Coastguard Workerif (!assertionsDisabled && a == 0) {
51*6777b538SAndroid Build Coastguard Worker  throw new AssertionError();
52*6777b538SAndroid Build Coastguard Worker}
53*6777b538SAndroid Build Coastguard Workerreturn a;
54*6777b538SAndroid Build Coastguard Worker
55*6777b538SAndroid Build Coastguard Worker// Optimized with assertions enabled.
56*6777b538SAndroid Build Coastguard Workera = foo();
57*6777b538SAndroid Build Coastguard Workerif (a == 0) {
58*6777b538SAndroid Build Coastguard Worker  throw new AssertionError();
59*6777b538SAndroid Build Coastguard Worker}
60*6777b538SAndroid Build Coastguard Workerreturn a;
61*6777b538SAndroid Build Coastguard Worker
62*6777b538SAndroid Build Coastguard Worker// Optimized with assertions disabled.
63*6777b538SAndroid Build Coastguard Workera = foo();
64*6777b538SAndroid Build Coastguard Workerreturn a;
65*6777b538SAndroid Build Coastguard Worker```
66*6777b538SAndroid Build Coastguard Worker
67*6777b538SAndroid Build Coastguard Worker## Assertion Enabling on Canary
68*6777b538SAndroid Build Coastguard WorkerRecently we [enabled
69*6777b538SAndroid Build Coastguard Workerasserts](https://chromium-review.googlesource.com/c/chromium/src/+/3307087) on
70*6777b538SAndroid Build Coastguard WorkerCanary. It spiked our crash rate, and it was decided to not do this again, as
71*6777b538SAndroid Build Coastguard Workerit's bad user experience to crash the app incessantly for non-fatal issues.
72*6777b538SAndroid Build Coastguard Worker
73*6777b538SAndroid Build Coastguard WorkerSo, we asked the R8 team for a feature which would rewrite the bytecode of these
74*6777b538SAndroid Build Coastguard Workerassertions, which they implemented for us. Now, instead of just turning it on
75*6777b538SAndroid Build Coastguard Workerand throwing an `AssertionError`, [R8 would call a provided assertion
76*6777b538SAndroid Build Coastguard Workerhandler](https://r8.googlesource.com/r8/+/aefe7bc18a7ce19f3e9c6dac0bedf6d182bbe142/src/main/java/com/android/tools/r8/ParseFlagInfoImpl.java#124)
77*6777b538SAndroid Build Coastguard Workerwith the `AssertionError`. We then wrote a [silent assertion
78*6777b538SAndroid Build Coastguard Workerreporter](https://chromium-review.googlesource.com/c/chromium/src/+/3746261)
79*6777b538SAndroid Build Coastguard Workerand this reports Java `AssertionErrors` to our crash server without crashing
80*6777b538SAndroid Build Coastguard Workerthe browser.
81