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