Rewrite Class init entrypoint to take a Class arg.
Fixes invalid type index being passed to the entrypoint for
class init check across dex files when the target type does
not have a TypeId in the compilation unit's DexFile.
The size of the aosp_taimen-userdebug prebuilts:
- before:
arm/boot*.oat: 16782748
arm64/boot*.oat: 19764400
oat/arm64/services.odex: 20162432
- after:
arm/boot*.oat: 16811692 (+28.3KiB, +0.17%)
arm64/boot*.oat: 19801032 (+35.8KiB, +0.19%)
oat/arm64/services.odex: 20232208 (+68.1KiB, +0.35%)
This increase comes from doing two runtime calls instead of
one for HLoadClass/kBssEntry that MustGenerateClinitCheck().
Test: Additional test in 476-clinit-inline-static-invoke
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing --jit
Test: Pixel 2 XL boots.
Test: testrunner.py --target --optimizing --jit
Test: testrunner.py --jvm
Bug: 111433619
Change-Id: I2fccd6944480ab4dac514f60d38e72c1014ae7b2
diff --git a/test/683-clinit-inline-static-invoke/expected.txt b/test/683-clinit-inline-static-invoke/expected.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/683-clinit-inline-static-invoke/expected.txt
diff --git a/test/683-clinit-inline-static-invoke/info.txt b/test/683-clinit-inline-static-invoke/info.txt
new file mode 100644
index 0000000..32e5cdc
--- /dev/null
+++ b/test/683-clinit-inline-static-invoke/info.txt
@@ -0,0 +1,3 @@
+Regression test for a bug where the class initialization check for an inlined
+call to a static method used a type index from the wrong dex file because the
+current dex file does not have a TypeId for it. This was likely to crash.
diff --git a/test/683-clinit-inline-static-invoke/multidex.jpp b/test/683-clinit-inline-static-invoke/multidex.jpp
new file mode 100644
index 0000000..b0d200e
--- /dev/null
+++ b/test/683-clinit-inline-static-invoke/multidex.jpp
@@ -0,0 +1,3 @@
+Main:
+ @@com.android.jack.annotations.ForceInMainDex
+ class Main
diff --git a/test/683-clinit-inline-static-invoke/src-multidex/MyTimeZone.java b/test/683-clinit-inline-static-invoke/src-multidex/MyTimeZone.java
new file mode 100644
index 0000000..b74b310
--- /dev/null
+++ b/test/683-clinit-inline-static-invoke/src-multidex/MyTimeZone.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import android.icu.util.TimeZone;
+
+public abstract class MyTimeZone extends TimeZone {
+ // Reference to MyTimeZone.getDefaultTimeZoneType() shall resolve
+ // to TimeZone.getDefaultTimeZoneType() which should be easily inlined.
+}
diff --git a/test/683-clinit-inline-static-invoke/src/Main.java b/test/683-clinit-inline-static-invoke/src/Main.java
new file mode 100644
index 0000000..b4ccfaa
--- /dev/null
+++ b/test/683-clinit-inline-static-invoke/src/Main.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+public class Main {
+ public static void main(String[] args) {
+ // The following is a simple static field getter that can be inlined, referenced
+ // through a subclass with the declaring class having no TypeId in current DexFile.
+ // When we inline this getter, we're left with HLoadClass+HClinitCheck which cannot
+ // be merged back to the InvokeStaticOrDirect for implicit class init check.
+ // The declaring class is in the boot image, so the LoadClass can load it using the
+ // .data.bimg.rel.ro section. However, the ClinitCheck entrypoint was previously
+ // taking a type index of the declaring class and since we did not have a valid
+ // TypeId in the current DexFile, we erroneously provided the type index from the
+ // declaring DexFile and that caused a crash. This was fixed by changing the
+ // ClinitCheck entrypoint to take the Class reference from LoadClass.
+ int dummy = MyTimeZone.getDefaultTimeZoneType();
+ }
+}