summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2021-07-06 10:29:19 +0100
committer Vladimir Marko <vmarko@google.com> 2021-07-07 08:02:41 +0000
commit85d6bf94dc0d3a9c648dc6d614a293c4e416b247 (patch)
tree4405a93ef24c21e942a5c4eb95773fa3af257da2
parent24c080f628e7df51460332374f4ebcae2762d155 (diff)
Test for static field VarHandle and class unloading.
Test: Additional test in 710-varhandle-creation Test: testrunner.py --host --optimizing -t 710-varhandle-creation Bug: 191980149 Change-Id: I95b7d8c435fcf5286a57bba3d4877dfac65b5771
-rw-r--r--test/710-varhandle-creation/expected-stdout.txt2
-rw-r--r--test/710-varhandle-creation/run18
-rw-r--r--test/710-varhandle-creation/src-ex/UnloadTest.java19
-rw-r--r--test/710-varhandle-creation/src/Main.java46
4 files changed, 85 insertions, 0 deletions
diff --git a/test/710-varhandle-creation/expected-stdout.txt b/test/710-varhandle-creation/expected-stdout.txt
index 89dfb48245..7c858a68ac 100644
--- a/test/710-varhandle-creation/expected-stdout.txt
+++ b/test/710-varhandle-creation/expected-stdout.txt
@@ -4,3 +4,5 @@ LookupCheckA...PASS
LookupCheckB...PASS
UnreflectCheck...PASS
LookupCheckC...PASS
+Initial value of UnloadTest.i: 42
+Final value of UnloadTest.i: 42
diff --git a/test/710-varhandle-creation/run b/test/710-varhandle-creation/run
new file mode 100644
index 0000000000..46b1a8308b
--- /dev/null
+++ b/test/710-varhandle-creation/run
@@ -0,0 +1,18 @@
+#!/bin/bash
+#
+# Copyright (C) 2021 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.
+
+# Currently app images aren't unloaded when dex files are unloaded.
+exec ${RUN} $@ --no-secondary-app-image
diff --git a/test/710-varhandle-creation/src-ex/UnloadTest.java b/test/710-varhandle-creation/src-ex/UnloadTest.java
new file mode 100644
index 0000000000..f6d366ace0
--- /dev/null
+++ b/test/710-varhandle-creation/src-ex/UnloadTest.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2021 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 UnloadTest {
+ public static int i = 42;
+}
diff --git a/test/710-varhandle-creation/src/Main.java b/test/710-varhandle-creation/src/Main.java
index 246aac6900..c4fe2ffed1 100644
--- a/test/710-varhandle-creation/src/Main.java
+++ b/test/710-varhandle-creation/src/Main.java
@@ -17,6 +17,7 @@
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.lang.invoke.VarHandle.AccessMode;
+import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.nio.ByteOrder;
import java.util.ArrayList;
@@ -2401,6 +2402,50 @@ public final class Main {
}
}
+ private static ClassLoader createExClassLoader() throws Exception {
+ String location = System.getenv("DEX_LOCATION");
+ try {
+ Class<?> class_loader_class = Class.forName("dalvik.system.PathClassLoader");
+ Constructor<?> ctor =
+ class_loader_class.getConstructor(String.class, ClassLoader.class);
+
+ return (ClassLoader)ctor.newInstance(location + "/710-varhandle-creation-ex.jar",
+ Main.class.getClassLoader());
+ } catch (ClassNotFoundException e) {
+ // Running on RI. Use URLClassLoader.
+ return new java.net.URLClassLoader(
+ new java.net.URL[] { new java.net.URL("file://" + location + "/classes-ex/") });
+ }
+ }
+
+ private static Class<?> loadUnloadTestClass() throws Exception {
+ ClassLoader loader = createExClassLoader();
+ return Class.forName("UnloadTest", true, loader);
+ }
+
+ private static VarHandle createUnloadTestVarHandle() throws Exception {
+ Class<?> klass = loadUnloadTestClass();
+ return MethodHandles.lookup().findStaticVarHandle(klass, "i", int.class);
+ }
+
+ // Regression test for static field VarHandle previously not keeping
+ // the target class alive, leading to a crash. Bug: 191980149
+ private static void checkStaticFieldVarHandleGc() {
+ try {
+ VarHandle vh = createUnloadTestVarHandle();
+ // Print the initial value.
+ System.out.println("Initial value of UnloadTest.i: " + (int) vh.get());
+ // Try to collect all garbage thoroughly.
+ for (int i = 0; i < 5; ++i) {
+ Runtime.getRuntime().gc();
+ }
+ // Print the value again.
+ System.out.println("Final value of UnloadTest.i: " + (int) vh.get());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
public static void main(String[] args) {
checkAccessModes();
checkInstantiatedVarHandles();
@@ -2408,6 +2453,7 @@ public final class Main {
LookupCheckB.run();
LookupCheckC.run();
UnreflectCheck.run();
+ checkStaticFieldVarHandleGc();
}
}