summaryrefslogtreecommitdiff
path: root/test/2281-method-handle-invoke-static-class-unload/src-art/Main.java
diff options
context:
space:
mode:
author Almaz Mingaleev <mingaleev@google.com> 2024-09-19 13:03:28 +0100
committer Almaz Mingaleev <mingaleev@google.com> 2024-09-23 09:21:07 +0000
commit56d62450fcd69434b94158a42f1a195bd7ee858b (patch)
treee629e304607c1f3cc185f5b7328872b06ad466e6 /test/2281-method-handle-invoke-static-class-unload/src-art/Main.java
parente5d19588b1b3163193f867e7ddb6cd6d19658841 (diff)
Store reference to the target class in MH object.
Previously MH object only stored pointer to ArtField / ArtMethod and GC could unload target class. Bug: 366474683 Test: ./art/test/testrunner/testrunner.py --host --64 -b Test: ./art/test/testrunner/testrunner.py --host --64 --jvm -b -t 2281-method Test: ./art/test.py --host -g Change-Id: I6e91fc59da7c55c15ed55fadaf796050eebb0f5e
Diffstat (limited to 'test/2281-method-handle-invoke-static-class-unload/src-art/Main.java')
-rw-r--r--test/2281-method-handle-invoke-static-class-unload/src-art/Main.java98
1 files changed, 98 insertions, 0 deletions
diff --git a/test/2281-method-handle-invoke-static-class-unload/src-art/Main.java b/test/2281-method-handle-invoke-static-class-unload/src-art/Main.java
new file mode 100644
index 0000000000..8e03fe04bf
--- /dev/null
+++ b/test/2281-method-handle-invoke-static-class-unload/src-art/Main.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2024 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 dalvik.system.InMemoryDexClassLoader;
+
+import static java.lang.invoke.MethodType.methodType;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.nio.ByteBuffer;
+import java.util.Base64;
+import java.util.List;
+import java.util.function.Consumer;
+
+public class Main {
+ // src-ex/ClassWithAMethod.java
+ private static final String DEX_FILE =
+ "ZGV4CjA0MQC4x9/g6TtIcd5240Zevdlr1D/wRBHV4Tv0BAAAeAAAAHhWNBIAAAAAAAAAADAEAAAW" +
+ "AAAAeAAAAAcAAADQAAAABAAAAOwAAAAAAAAAAAAAAAcAAAAcAQAAAQAAAFQBAAAAAAAAAAAAAPQE" +
+ "AAAAAAAAGgIAAB8CAAAnAgAAOQIAAFACAABTAgAAVgIAAGoCAACOAgAAqgIAAL4CAADfAgAA4gIA" +
+ "AOYCAAD5AgAABQMAABgDAAAeAwAAJgMAADQDAAA7AwAASAMAAAQAAAAGAAAABwAAAAgAAAAJAAAA" +
+ "CgAAAAsAAAAEAAAAAAAAAAAAAAAFAAAABQAAAAAAAAALAAAABgAAAAAAAAAMAAAABgAAABQCAAAB" +
+ "AAIAAQAAAAEAAQANAAAAAQAAABEAAAABAAEAEgAAAAEAAgAUAAAAAwADAAEAAAAEAAIAAQAAAAEA" +
+ "AAABAAAABAAAAAAAAAADAAAAGAQAAPYDAAAAAAAABAAAAAIAAAABAAAAAAAAAPwBAAACAAAAEhAP" +
+ "AAEAAAAAAAAAAAIAAAMAAAD+AAAAEQAAAAEAAAAAAAAABAIAAAUAAABxAAQAAAASABEAAAABAAEA" +
+ "AQAAAAkCAAAEAAAAcBAGAAAADgACAAAAAgAAAA0CAAAIAAAAIgADABoBFABwIAUAEAAnABoADgAs" +
+ "AA4AJwAOPAAYAA4AHgAOAAAAAAEAAAAEAAMoKUkABjxpbml0PgAQQ2xhc3NXaXRoQU1ldGhvZAAV" +
+ "Q2xhc3NXaXRoQU1ldGhvZC5qYXZhAAFJAAFMABJMQ2xhc3NXaXRoQU1ldGhvZDsAIkxhbm5vdGF0" +
+ "aW9ucy9Db25zdGFudE1ldGhvZEhhbmRsZTsAGkxqYXZhL2xhbmcvQXNzZXJ0aW9uRXJyb3I7ABJM" +
+ "amF2YS9sYW5nL09iamVjdDsAH0xqYXZhL2xhbmcvaW52b2tlL01ldGhvZEhhbmRsZTsAAVYAAlZM" +
+ "ABFjb25zdE1ldGhvZEhhbmRsZQAKZGVzY3JpcHRvcgARZmllbGRPck1ldGhvZE5hbWUABGtpbmQA" +
+ "Bm1ldGhvZAAMbWV0aG9kSGFuZGxlAAVvd25lcgALdW5yZWFjaGFibGUAnAF+fkQ4eyJiYWNrZW5k" +
+ "IjoiZGV4IiwiY29tcGlsYXRpb24tbW9kZSI6ImRlYnVnIiwiaGFzLWNoZWNrc3VtcyI6ZmFsc2Us" +
+ "Im1pbi1hcGkiOjI4LCJzaGEtMSI6IjdkZTM3N2E4MGI1MzQ1MGY1Y2ExYTNmYzUwZjZkYzk5M2U3" +
+ "ZThhM2UiLCJ2ZXJzaW9uIjoiOC44LjQtZGV2In0AAQIEDhcADxcREAQEExcCAAAFAACBgATEAwEJ" +
+ "kAMBCfwCAQqoAwEK3AMBAAAA5wMAAAAAAAAAAAAAAQAAAAAAAAADAAAAEAQAABAAAAAAAAAAAQAA" +
+ "AAAAAAABAAAAFgAAAHgAAAACAAAABwAAANAAAAADAAAABAAAAOwAAAAFAAAABwAAABwBAAAGAAAA" +
+ "AQAAAFQBAAAIAAAAAQAAAHQBAAABIAAABQAAAHwBAAADIAAABQAAAPwBAAABEAAAAQAAABQCAAAC" +
+ "IAAAFgAAABoCAAAEIAAAAQAAAOcDAAAAIAAAAQAAAPYDAAADEAAAAQAAABAEAAAGIAAAAQAAABgE" +
+ "AAAAEAAAAQAAADAEAAA=";
+
+ private static final int ITERATIONS = 5;
+
+ public static void main(String[] args) throws Throwable {
+ verify($noinline$getJavaApiMethodHandle());
+ verify($noinline$getConstMethodHandle());
+ }
+
+ private static void verify(MethodHandle mh) {
+ int result = 0;
+ for (int i = 0; i < ITERATIONS; ++i) {
+ try {
+ result += (int) mh.invokeWithArguments(List.of());
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ Runtime.getRuntime().gc();
+ System.runFinalization();
+ }
+
+ if (result != ITERATIONS) {
+ throw new AssertionError();
+ }
+ }
+
+ private static MethodHandle $noinline$getJavaApiMethodHandle() throws Throwable {
+ ClassLoader loader = new InMemoryDexClassLoader(
+ ByteBuffer.wrap(Base64.getDecoder().decode(DEX_FILE)),
+ ClassLoader.getSystemClassLoader());
+ Class<?> clazz = loader.loadClass("ClassWithAMethod");
+ return MethodHandles.publicLookup().findStatic(clazz, "method", methodType(int.class));
+ }
+
+ private static MethodHandle $noinline$getConstMethodHandle() throws Throwable {
+ ClassLoader loader = new InMemoryDexClassLoader(
+ ByteBuffer.wrap(Base64.getDecoder().decode(DEX_FILE)),
+ ClassLoader.getSystemClassLoader());
+ Class<?> clazz = loader.loadClass("ClassWithAMethod");
+
+ return (MethodHandle) clazz.getDeclaredMethod("constMethodHandle").invoke(null);
+ }
+} \ No newline at end of file