summaryrefslogtreecommitdiff
path: root/test/2277-methodhandle-invokeexact/src/JavaApiTest.java
diff options
context:
space:
mode:
author Almaz Mingaleev <mingaleev@google.com> 2024-11-07 10:01:49 +0000
committer Almaz Mingaleev <mingaleev@google.com> 2024-11-12 14:27:31 +0000
commit3051a5e03f32ca7aaae6041025ec60f90d41e34c (patch)
tree6d253e5c533e032ef1a43a914410d32f7e31081a /test/2277-methodhandle-invokeexact/src/JavaApiTest.java
parent20cdc427d5f5875c2d58f9fde775957ad2e28cfd (diff)
Remove now unnecessary checks from invokeExact intrinsic.
Also rewrote tests to make sure that MethodHandle-s created via const-method-handle and Java API behave identically. They can be slightly different even if lookup is done in the same class for the same method as const-method-handle can target copied methods. Bug: 297147201 Test: ./art/test/testrunner/testrunner.py -b --host --64 Test: ./art/test/testrunner/testrunner.py -b --jvm Change-Id: I69cdf2c44f2838ee0e57eaa2e93a6ed5276c39fb
Diffstat (limited to 'test/2277-methodhandle-invokeexact/src/JavaApiTest.java')
-rw-r--r--test/2277-methodhandle-invokeexact/src/JavaApiTest.java351
1 files changed, 351 insertions, 0 deletions
diff --git a/test/2277-methodhandle-invokeexact/src/JavaApiTest.java b/test/2277-methodhandle-invokeexact/src/JavaApiTest.java
new file mode 100644
index 0000000000..77b4bc0c73
--- /dev/null
+++ b/test/2277-methodhandle-invokeexact/src/JavaApiTest.java
@@ -0,0 +1,351 @@
+/*
+ * 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 static java.lang.invoke.MethodType.methodType;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.util.Arrays;
+import java.util.Optional;
+
+public class JavaApiTest extends AbstractInvokeExactTest {
+
+ private static final MethodHandle OPTIONAL_GET;
+
+ private static final MethodHandle VOID_METHOD;
+ private static final MethodHandle RETURN_INT;
+ private static final MethodHandle RETURN_DOUBLE;
+ private static final MethodHandle PRIVATE_INTERFACE_METHOD;
+ private static final MethodHandle B_PRIVATE_RETURN_INT;
+ private static final MethodHandle A_PRIVATE_RETURN_INT;
+ private static final MethodHandle STATIC_METHOD;
+ private static final MethodHandle EXCEPTION_THROWING_METHOD;
+ private static final MethodHandle INTERFACE_DEFAULT_METHOD;
+ private static final MethodHandle OVERWRITTEN_INTERFACE_DEFAULT_METHOD;
+
+ private static final MethodHandle SUM_I;
+ private static final MethodHandle SUM_2I;
+ private static final MethodHandle SUM_3I;
+ private static final MethodHandle SUM_4I;
+ private static final MethodHandle SUM_5I;
+ private static final MethodHandle SUM_6I;
+ private static final MethodHandle SUM_7I;
+ private static final MethodHandle SUM_8I;
+ private static final MethodHandle SUM_9I;
+ private static final MethodHandle SUM_10I;
+
+ private static final MethodHandle SUM_IJ;
+ private static final MethodHandle SUM_2IJ;
+ private static final MethodHandle SUM_3IJ;
+ private static final MethodHandle SUM_4IJ;
+ private static final MethodHandle SUM_5IJ;
+
+ private static final MethodHandle FOO_NONDEFAULT;
+ private static final MethodHandle FOOBARIMPL_NONDEFAULT;
+ private static final MethodHandle FOO_DEFAULT;
+ private static final MethodHandle BAR_DEFAULT;
+ private static final MethodHandle FOOBAR_DEFINEDINABSTRACT;
+ private static final MethodHandle FOOBAR_NONDEFAULT;
+ private static final MethodHandle FOOBARIMPL_DEFINEDINABSTRACT;
+ private static final MethodHandle FOOBARIMPL_DEFAULT;
+ private static final MethodHandle FOO_NONOVERRIDDEN_DEFAULT;
+ private static final MethodHandle BAR_NONOVERRIDDEN_DEFAULT;
+
+ static {
+ try {
+ OPTIONAL_GET = MethodHandles.lookup()
+ .findVirtual(Optional.class, "get", methodType(Object.class));
+
+ VOID_METHOD = MethodHandles.lookup()
+ .findVirtual(A.class, "voidMethod", methodType(void.class));
+ RETURN_DOUBLE = MethodHandles.lookup()
+ .findVirtual(A.class, "returnDouble", methodType(double.class));
+ RETURN_INT = MethodHandles.lookup()
+ .findVirtual(A.class, "returnInt", methodType(int.class));
+ PRIVATE_INTERFACE_METHOD = MethodHandles.privateLookupIn(I.class, MethodHandles.lookup())
+ .findVirtual(I.class, "innerPrivateMethod", methodType(String.class));
+ A_PRIVATE_RETURN_INT = MethodHandles.privateLookupIn(A.class, MethodHandles.lookup())
+ .findVirtual(A.class, "privateReturnInt", methodType(int.class));
+ B_PRIVATE_RETURN_INT = MethodHandles.privateLookupIn(B.class, MethodHandles.lookup())
+ .findVirtual(B.class, "privateReturnInt", methodType(int.class));
+ STATIC_METHOD = MethodHandles.lookup()
+ .findStatic(A.class, "staticMethod", methodType(String.class, A.class));
+ EXCEPTION_THROWING_METHOD = MethodHandles.lookup()
+ .findVirtual(A.class, "throwException", methodType(void.class));
+ INTERFACE_DEFAULT_METHOD = MethodHandles.lookup()
+ .findVirtual(I.class, "defaultMethod", methodType(void.class));
+ OVERWRITTEN_INTERFACE_DEFAULT_METHOD = MethodHandles.lookup()
+ .findVirtual(I.class, "overrideMe", methodType(void.class));
+
+ SUM_I = MethodHandles.lookup()
+ .findVirtual(Sums.class, "sum", methodType(int.class, repeat(1, int.class)));
+ SUM_2I = MethodHandles.lookup()
+ .findVirtual(Sums.class, "sum", methodType(int.class, repeat(2, int.class)));
+ SUM_3I = MethodHandles.lookup()
+ .findVirtual(Sums.class, "sum", methodType(int.class, repeat(3, int.class)));
+ SUM_4I = MethodHandles.lookup()
+ .findVirtual(Sums.class, "sum", methodType(int.class, repeat(4, int.class)));
+ SUM_5I = MethodHandles.lookup()
+ .findVirtual(Sums.class, "sum", methodType(int.class, repeat(5, int.class)));
+ SUM_6I = MethodHandles.lookup()
+ .findVirtual(Sums.class, "sum", methodType(int.class, repeat(6, int.class)));
+ SUM_7I = MethodHandles.lookup()
+ .findVirtual(Sums.class, "sum", methodType(int.class, repeat(7, int.class)));
+ SUM_8I = MethodHandles.lookup()
+ .findVirtual(Sums.class, "sum", methodType(int.class, repeat(8, int.class)));
+ SUM_9I = MethodHandles.lookup()
+ .findVirtual(Sums.class, "sum", methodType(int.class, repeat(9, int.class)));
+ SUM_10I = MethodHandles.lookup()
+ .findVirtual(Sums.class, "sum", methodType(int.class, repeat(10, int.class)));
+
+ SUM_IJ = MethodHandles.lookup()
+ .findVirtual(Sums.class, "sum", methodType(long.class, int.class, long.class));
+ SUM_2IJ = MethodHandles.lookup()
+ .findVirtual(Sums.class,
+ "sum",
+ methodType(long.class, repeat(2, int.class, long.class)));
+ SUM_3IJ = MethodHandles.lookup()
+ .findVirtual(Sums.class,
+ "sum",
+ methodType(long.class, repeat(3, int.class, long.class)));
+ SUM_4IJ = MethodHandles.lookup()
+ .findVirtual(Sums.class,
+ "sum",
+ methodType(long.class, repeat(4, int.class, long.class)));
+ SUM_5IJ = MethodHandles.lookup()
+ .findVirtual(Sums.class,
+ "sum",
+ methodType(long.class, repeat(5, int.class, long.class)));
+
+ FOO_NONDEFAULT = MethodHandles.lookup()
+ .findVirtual(Foo.class, "nonDefault", methodType(String.class));
+ FOOBARIMPL_NONDEFAULT = MethodHandles.lookup()
+ .findVirtual(FooBarImpl.class, "nonDefault", methodType(String.class));
+ FOO_DEFAULT = MethodHandles.lookup()
+ .findVirtual(Foo.class, "defaultToOverride", methodType(String.class));
+ BAR_DEFAULT = MethodHandles.lookup()
+ .findVirtual(Bar.class, "defaultToOverride", methodType(String.class));
+ FOOBAR_DEFINEDINABSTRACT = MethodHandles.lookup()
+ .findVirtual(FooBar.class, "definedInAbstract", methodType(String.class));
+ FOOBAR_NONDEFAULT = MethodHandles.lookup()
+ .findVirtual(FooBar.class, "nonDefault", methodType(String.class));
+ FOOBARIMPL_DEFINEDINABSTRACT = MethodHandles.lookup()
+ .findVirtual(FooBarImpl.class, "definedInAbstract", methodType(String.class));
+ FOOBARIMPL_DEFAULT = MethodHandles.lookup()
+ .findVirtual(FooBarImpl.class, "defaultToOverride", methodType(String.class));
+ FOO_NONOVERRIDDEN_DEFAULT = MethodHandles.lookup()
+ .findVirtual(Foo.class, "nonOverriddenDefault", methodType(String.class));
+ BAR_NONOVERRIDDEN_DEFAULT = MethodHandles.lookup()
+ .findVirtual(Bar.class, "nonOverriddenDefault", methodType(String.class));
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static Class<?>[] repeat(int times, Class<?> clazz) {
+ Class<?>[] classes = new Class<?>[times];
+ Arrays.fill(classes, clazz);
+ return classes;
+ }
+
+ private static Class<?>[] repeat(int times, Class<?> first, Class<?> second) {
+ Class<?>[] classes = new Class<?>[times * 2];
+ for (int i = 0; i < 2 * times;) {
+ classes[i++] = first;
+ classes[i++] = second;
+ }
+ return classes;
+ }
+
+ @Override
+ void $noinline$privateMethods() throws Throwable {
+ assertEquals("boo", (String) PRIVATE_INTERFACE_METHOD.invokeExact((I) new A()));
+
+ int privateIntA = (int) A_PRIVATE_RETURN_INT.invokeExact(new A());
+ assertEquals(1042, privateIntA);
+
+ int privateIntB = (int) B_PRIVATE_RETURN_INT.invokeExact(new B());
+ assertEquals(9999, privateIntB);
+
+ privateIntB = (int) B_PRIVATE_RETURN_INT.invokeExact((B) new A());
+ assertEquals(9999, privateIntB);
+ }
+
+ @Override
+ public MethodHandle voidMethod() {
+ return VOID_METHOD;
+ }
+
+ @Override
+ public MethodHandle returnDouble() {
+ return RETURN_DOUBLE;
+ }
+
+ @Override
+ public MethodHandle returnInt() {
+ return RETURN_INT;
+ }
+
+ @Override
+ public MethodHandle interfaceDefaultMethod() {
+ return INTERFACE_DEFAULT_METHOD;
+ }
+
+ @Override
+ public MethodHandle overwrittenInterfaceDefaultMethod() {
+ return OVERWRITTEN_INTERFACE_DEFAULT_METHOD;
+ }
+
+ @Override
+ public MethodHandle exceptionThrowingMethod() {
+ return EXCEPTION_THROWING_METHOD;
+ }
+
+ @Override
+ public MethodHandle staticMethod() {
+ return STATIC_METHOD;
+ }
+
+ @Override
+ public MethodHandle sumI() {
+ return SUM_I;
+ }
+
+ @Override
+ public MethodHandle sum2I() {
+ return SUM_2I;
+ }
+
+ @Override
+ public MethodHandle sum3I() {
+ return SUM_3I;
+ }
+
+ @Override
+ public MethodHandle sum4I() {
+ return SUM_4I;
+ }
+
+ @Override
+ public MethodHandle sum5I() {
+ return SUM_5I;
+ }
+
+ @Override
+ public MethodHandle sum6I() {
+ return SUM_6I;
+ }
+
+ @Override
+ public MethodHandle sum7I() {
+ return SUM_7I;
+ }
+
+ @Override
+ public MethodHandle sum8I() {
+ return SUM_8I;
+ }
+
+ @Override
+ public MethodHandle sum9I() {
+ return SUM_9I;
+ }
+
+ @Override
+ public MethodHandle sum10I() {
+ return SUM_10I;
+ }
+
+ @Override
+ public MethodHandle sumIJ() {
+ return SUM_IJ;
+ }
+
+ @Override
+ public MethodHandle sum2IJ() {
+ return SUM_2IJ;
+ }
+
+ @Override
+ public MethodHandle sum3IJ() {
+ return SUM_3IJ;
+ }
+
+ @Override
+ public MethodHandle sum4IJ() {
+ return SUM_4IJ;
+ }
+
+ @Override
+ public MethodHandle sum5IJ() {
+ return SUM_5IJ;
+ }
+
+ @Override
+ public MethodHandle fooNonDefault() {
+ return FOO_NONDEFAULT;
+ }
+
+ @Override
+ public MethodHandle fooBarImplNonDefault() {
+ return FOOBARIMPL_NONDEFAULT;
+ }
+
+ @Override
+ public MethodHandle barDefault() {
+ return BAR_DEFAULT;
+ }
+
+ @Override
+ public MethodHandle fooDefault() {
+ return FOO_DEFAULT;
+ }
+
+ @Override
+ public MethodHandle fooBarImplDefault() {
+ return FOOBARIMPL_DEFAULT;
+ }
+
+ @Override
+ public MethodHandle fooNonOverriddenDefault() {
+ return FOO_NONOVERRIDDEN_DEFAULT;
+ }
+
+ @Override
+ public MethodHandle barNonOverriddenDefault() {
+ return BAR_NONOVERRIDDEN_DEFAULT;
+ }
+
+ @Override
+ public MethodHandle fooBarDefinedInAbstract() {
+ return FOOBAR_DEFINEDINABSTRACT;
+ }
+
+ @Override
+ public MethodHandle fooBarImplDefinedInAbstract() {
+ return FOOBARIMPL_DEFINEDINABSTRACT;
+ }
+
+ @Override
+ public MethodHandle fooBarNonDefault() {
+ return FOOBAR_NONDEFAULT;
+ }
+
+ @Override
+ public MethodHandle optionalGet() {
+ return OPTIONAL_GET;
+ }
+}