diff options
| author | 2021-07-06 10:29:19 +0100 | |
|---|---|---|
| committer | 2021-07-07 08:02:41 +0000 | |
| commit | 85d6bf94dc0d3a9c648dc6d614a293c4e416b247 (patch) | |
| tree | 4405a93ef24c21e942a5c4eb95773fa3af257da2 | |
| parent | 24c080f628e7df51460332374f4ebcae2762d155 (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.txt | 2 | ||||
| -rw-r--r-- | test/710-varhandle-creation/run | 18 | ||||
| -rw-r--r-- | test/710-varhandle-creation/src-ex/UnloadTest.java | 19 | ||||
| -rw-r--r-- | test/710-varhandle-creation/src/Main.java | 46 |
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(); } } |