Fix and improve ClinitCheck elimination.
Fix erroneous usage of the inner method's access flags
while checking the class of the outer method. This allowed
erroneous elimination of a needed ClinitCheck when inlining.
Treat constructors the same way as static methods as the
instance allocation necessarily preceding the constructor
call performs the class initialization check.
The size of the aosp_taimen-userdebug prebuilts:
- before:
arm/boot*.oat: 20252196
arm64/boot*.oat: 24030776
oat/arm64/services.odex: 22406664
- after:
arm/boot*.oat: 20252092 (-0.1KiB)
arm64/boot*.oat: 24027024 (-3.7KiB)
oat/arm64/services.odex: 22402528 (-4.0KiB)
(Insignificant changes.)
Test: Add regression test to 174-escaping-instance-of-bad-class.
Test: Add optimization test to 551-checker-clinit.
Test: testrunner.py --jvm -t 174
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: Pixel 2 XL boots.
Test: m test-art-target-gtest
Test: testrunner.py --target --optimizing
Bug: 62478025
Change-Id: I591aca2c538d10cf6df1d38d59270af1de380b3e
diff --git a/test/174-escaping-instance-of-bad-class/src/Main.java b/test/174-escaping-instance-of-bad-class/src/Main.java
index 4346152..4f66a31 100644
--- a/test/174-escaping-instance-of-bad-class/src/Main.java
+++ b/test/174-escaping-instance-of-bad-class/src/Main.java
@@ -39,6 +39,17 @@
ncdfe.printStackTrace();
}
}
+ // Call bar() on the escaped instance of Bad.
+ try {
+ bad.bar();
+ } catch (NoClassDefFoundError ncdfe) {
+ // On RI, the NCDFE has no cause. On ART, the badClinit is the cause.
+ if (ncdfe.getCause() == badClinit || ncdfe.getCause() == null) {
+ System.out.println("Caught NoClassDefFoundError.");
+ } else {
+ ncdfe.printStackTrace();
+ }
+ }
}
public static void hierarchyTest() {
@@ -117,9 +128,19 @@
System.out.println("Bad.instanceValue = " + instanceValue);
System.out.println("Bad.staticValue = " + staticValue);
}
+ public void bar() {
+ System.out.println("Bad.bar()");
+ System.out.println("Bad.staticValue [indirect] = " + Helper.$inline$getBadStaticValue());
+ }
public Bad(int iv) { instanceValue = iv; }
public int instanceValue;
public static int staticValue;
+
+ public static class Helper {
+ public static int $inline$getBadStaticValue() {
+ return Bad.staticValue;
+ }
+ }
}
class BadSuper {