diff options
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.java | 98 |
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 |