forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bug: 1185148 Change-Id: If2cc0c16b03b83498c090e577533377b9cd04811 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3778200 Reviewed-by: Samuel Huang <huangs@chromium.org> Commit-Queue: Sam Maier <smaier@chromium.org> Cr-Commit-Position: refs/heads/main@{#1027330}
- Loading branch information
Sam Maier
authored and
Chromium LUCI CQ
committed
Jul 22, 2022
1 parent
fe7c98c
commit 11ca8b4
Showing
1 changed file
with
80 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
# Java Asserts in Chromium | ||
This doc exists to explain how asserts in Java are enabled and disabled by | ||
Chromium's build system. | ||
|
||
## javac Assertion Bytecode | ||
Whenever javac compiles a Java class, assertions are transformed into the | ||
following bytecode: | ||
|
||
``` | ||
Code: | ||
0: getstatic #2 // Static field $assertionsDisabled | ||
3: ifne 20 // Conditional jump past assertion throw | ||
12: new #3 // Class java/lang/AssertionError | ||
19: athrow // Throwing AssertionError | ||
20: return | ||
// NOTE: this static block was made just to check the desiredAssertionStatus. | ||
// There was no static block on the class before javac created one. | ||
static {}; | ||
Code: | ||
2: invokevirtual #6 // Method java/lang/Class.desiredAssertionStatus() | ||
5: ifne 12 | ||
8: iconst_1 | ||
9: goto 13 | ||
12: iconst_0 | ||
13: putstatic #2 // Static field $assertionsDisabled | ||
16: return | ||
``` | ||
|
||
TL;DR - every single assertion is gated behind a `assertionDisabled` flag check, | ||
which is a static field that can be set by the JRE's | ||
`setDefaultAssertionStatus`, `setPackageAssertionStatus`, and | ||
`setClassAssertionStatus` methods. | ||
|
||
## Assertion Enabling/Disabling | ||
Our tools which consume javac output, namely R8 and D8, each have flags which | ||
the build system uses to enable or disable asserts. We control this with the | ||
`enable_java_asserts` gn arg. It does this by deleting the gating check on | ||
`assertionsDisabled` when enabling, and by eliminating any reference to the | ||
assert when disabling. | ||
|
||
```java | ||
// Example equivalents of: | ||
a = foo(); | ||
assert a != 0; | ||
return a; | ||
|
||
// Traditional, unoptimized javac output. | ||
a = foo(); | ||
if (!assertionsDisabled && a == 0) { | ||
throw new AssertionError(); | ||
} | ||
return a; | ||
|
||
// Optimized with assertions enabled. | ||
a = foo(); | ||
if (a == 0) { | ||
throw new AssertionError(); | ||
} | ||
return a; | ||
|
||
// Optimized with assertions disabled. | ||
a = foo(); | ||
return a; | ||
``` | ||
|
||
## Assertion Enabling on Canary | ||
Recently we [enabled | ||
asserts](https://chromium-review.googlesource.com/c/chromium/src/+/3307087) on | ||
Canary. It spiked our crash rate, and it was decided to not do this again, as | ||
it's bad user experience to crash the app incessantly for non-fatal issues. | ||
|
||
So, we asked the R8 team with an ask to allow us to rewrite the bytecode of | ||
these assertions, which they implemented for us. Now, instead of just turning | ||
it on and throwing an `AssertionError`, [R8 would call a provided assertion | ||
handler](https://r8.googlesource.com/r8/+/aefe7bc18a7ce19f3e9c6dac0bedf6d182bbe142/src/main/java/com/android/tools/r8/ParseFlagInfoImpl.java#124) | ||
with the `AssertionError`. We then wrote a [silent assertion | ||
reporter](https://chromium-review.googlesource.com/c/chromium/src/+/3746261) | ||
and this reports Java `AssertionErrors` to our crash server without crashing | ||
the browser. |