Clean up JNI dlsym lookup trampoline.
Make sure the GenericJniTrampoline recognizes the trampoline
in primary boot image oat file. Rename that trampoline, add
a test and flag some issues in the code.
Test: New test 178-app-image-native-method.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: testrunner.py --host -t 178-app-image-native-method
Bug: 112189621
Change-Id: I8f8cd11998af536fd3842dd4183a25f0367655a6
diff --git a/test/178-app-image-native-method/src/Main.java b/test/178-app-image-native-method/src/Main.java
new file mode 100644
index 0000000..d63d112
--- /dev/null
+++ b/test/178-app-image-native-method/src/Main.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright 2019 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.annotation.optimization.FastNative;
+import dalvik.annotation.optimization.CriticalNative;
+
+public class Main {
+
+ public static void main(String[] args) throws Exception {
+ System.loadLibrary(args[0]);
+
+ if (!checkAppImageLoaded()) {
+ System.out.println("AppImage not loaded.");
+ }
+ // To avoid going through resolution trampoline, make test classes visibly initialized.
+ new Test();
+ new TestFast();
+ new TestCritical();
+ new TestMissing();
+ new TestMissingFast();
+ new TestMissingCritical();
+ makeVisiblyInitialized(); // Make sure they are visibly initialized.
+
+ // FIXME: @FastNative and @CriticalNative fail a state check in artFindNativeMethod().
+ test();
+ // testFast();
+ // testCritical();
+ testMissing();
+ // testMissingFast();
+ // testMissingCritical();
+ }
+
+ static void test() {
+ System.out.println("test");
+ assertEquals(42, Test.nativeMethod(42));
+ assertEquals(42, Test.nativeMethodWithManyParameters(
+ 11, 12L, 13.0f, 14.0d,
+ 21, 22L, 23.0f, 24.0d,
+ 31, 32L, 33.0f, 34.0d,
+ 41, 42L, 43.0f, 44.0d,
+ 51, 52L, 53.0f, 54.0d,
+ 61, 62L, 63.0f, 64.0d,
+ 71, 72L, 73.0f, 74.0d,
+ 81, 82L, 83.0f, 84.0d));
+ }
+
+ static void testFast() {
+ System.out.println("testFast");
+ assertEquals(42, TestFast.nativeMethod(42));
+ assertEquals(42, TestFast.nativeMethodWithManyParameters(
+ 11, 12L, 13.0f, 14.0d,
+ 21, 22L, 23.0f, 24.0d,
+ 31, 32L, 33.0f, 34.0d,
+ 41, 42L, 43.0f, 44.0d,
+ 51, 52L, 53.0f, 54.0d,
+ 61, 62L, 63.0f, 64.0d,
+ 71, 72L, 73.0f, 74.0d,
+ 81, 82L, 83.0f, 84.0d));
+ }
+
+ static void testCritical() {
+ System.out.println("testCritical");
+ assertEquals(42, TestCritical.nativeMethod(42));
+ assertEquals(42, TestCritical.nativeMethodWithManyParameters(
+ 11, 12L, 13.0f, 14.0d,
+ 21, 22L, 23.0f, 24.0d,
+ 31, 32L, 33.0f, 34.0d,
+ 41, 42L, 43.0f, 44.0d,
+ 51, 52L, 53.0f, 54.0d,
+ 61, 62L, 63.0f, 64.0d,
+ 71, 72L, 73.0f, 74.0d,
+ 81, 82L, 83.0f, 84.0d));
+ }
+
+ static void testMissing() {
+ System.out.println("testMissing");
+
+ try {
+ TestMissing.nativeMethod(42);
+ throw new Error("UNREACHABLE");
+ } catch (LinkageError expected) {}
+
+ try {
+ TestMissing.nativeMethodWithManyParameters(
+ 11, 12L, 13.0f, 14.0d,
+ 21, 22L, 23.0f, 24.0d,
+ 31, 32L, 33.0f, 34.0d,
+ 41, 42L, 43.0f, 44.0d,
+ 51, 52L, 53.0f, 54.0d,
+ 61, 62L, 63.0f, 64.0d,
+ 71, 72L, 73.0f, 74.0d,
+ 81, 82L, 83.0f, 84.0d);
+ throw new Error("UNREACHABLE");
+ } catch (LinkageError expected) {}
+ }
+
+ static void testMissingFast() {
+ System.out.println("testMissingFast");
+
+ try {
+ TestMissingFast.nativeMethod(42);
+ throw new Error("UNREACHABLE");
+ } catch (LinkageError expected) {}
+
+ try {
+ TestMissingFast.nativeMethodWithManyParameters(
+ 11, 12L, 13.0f, 14.0d,
+ 21, 22L, 23.0f, 24.0d,
+ 31, 32L, 33.0f, 34.0d,
+ 41, 42L, 43.0f, 44.0d,
+ 51, 52L, 53.0f, 54.0d,
+ 61, 62L, 63.0f, 64.0d,
+ 71, 72L, 73.0f, 74.0d,
+ 81, 82L, 83.0f, 84.0d);
+ throw new Error("UNREACHABLE");
+ } catch (LinkageError expected) {}
+ }
+
+ static void testMissingCritical() {
+ System.out.println("testMissingCritical");
+
+ try {
+ TestMissingCritical.nativeMethod(42);
+ throw new Error("UNREACHABLE");
+ } catch (LinkageError expected) {}
+
+ try {
+ TestMissingCritical.nativeMethodWithManyParameters(
+ 11, 12L, 13.0f, 14.0d,
+ 21, 22L, 23.0f, 24.0d,
+ 31, 32L, 33.0f, 34.0d,
+ 41, 42L, 43.0f, 44.0d,
+ 51, 52L, 53.0f, 54.0d,
+ 61, 62L, 63.0f, 64.0d,
+ 71, 72L, 73.0f, 74.0d,
+ 81, 82L, 83.0f, 84.0d);
+ throw new Error("UNREACHABLE");
+ } catch (LinkageError expected) {}
+ }
+
+ static void assertEquals(int expected, int actual) {
+ if (expected != actual) {
+ throw new AssertionError("Expected " + expected + " got " + actual);
+ }
+ }
+
+ public static native boolean checkAppImageLoaded();
+ public static native void makeVisiblyInitialized();
+}
+
+class Test {
+ public static native int nativeMethod(int i);
+
+ public static native int nativeMethodWithManyParameters(
+ int i1, long l1, float f1, double d1,
+ int i2, long l2, float f2, double d2,
+ int i3, long l3, float f3, double d3,
+ int i4, long l4, float f4, double d4,
+ int i5, long l5, float f5, double d5,
+ int i6, long l6, float f6, double d6,
+ int i7, long l7, float f7, double d7,
+ int i8, long l8, float f8, double d8);
+}
+
+class TestFast {
+ @FastNative
+ public static native int nativeMethod(int i);
+
+ @FastNative
+ public static native int nativeMethodWithManyParameters(
+ int i1, long l1, float f1, double d1,
+ int i2, long l2, float f2, double d2,
+ int i3, long l3, float f3, double d3,
+ int i4, long l4, float f4, double d4,
+ int i5, long l5, float f5, double d5,
+ int i6, long l6, float f6, double d6,
+ int i7, long l7, float f7, double d7,
+ int i8, long l8, float f8, double d8);
+}
+
+class TestCritical {
+ @CriticalNative
+ public static native int nativeMethod(int i);
+
+ @CriticalNative
+ public static native int nativeMethodWithManyParameters(
+ int i1, long l1, float f1, double d1,
+ int i2, long l2, float f2, double d2,
+ int i3, long l3, float f3, double d3,
+ int i4, long l4, float f4, double d4,
+ int i5, long l5, float f5, double d5,
+ int i6, long l6, float f6, double d6,
+ int i7, long l7, float f7, double d7,
+ int i8, long l8, float f8, double d8);
+}
+
+class TestMissing {
+ public static native int nativeMethod(int i);
+
+ public static native int nativeMethodWithManyParameters(
+ int i1, long l1, float f1, double d1,
+ int i2, long l2, float f2, double d2,
+ int i3, long l3, float f3, double d3,
+ int i4, long l4, float f4, double d4,
+ int i5, long l5, float f5, double d5,
+ int i6, long l6, float f6, double d6,
+ int i7, long l7, float f7, double d7,
+ int i8, long l8, float f8, double d8);
+}
+
+class TestMissingFast {
+ @FastNative
+ public static native int nativeMethod(int i);
+
+ @FastNative
+ public static native int nativeMethodWithManyParameters(
+ int i1, long l1, float f1, double d1,
+ int i2, long l2, float f2, double d2,
+ int i3, long l3, float f3, double d3,
+ int i4, long l4, float f4, double d4,
+ int i5, long l5, float f5, double d5,
+ int i6, long l6, float f6, double d6,
+ int i7, long l7, float f7, double d7,
+ int i8, long l8, float f8, double d8);
+}
+
+class TestMissingCritical {
+ @CriticalNative
+ public static native int nativeMethod(int i);
+
+ @CriticalNative
+ public static native int nativeMethodWithManyParameters(
+ int i1, long l1, float f1, double d1,
+ int i2, long l2, float f2, double d2,
+ int i3, long l3, float f3, double d3,
+ int i4, long l4, float f4, double d4,
+ int i5, long l5, float f5, double d5,
+ int i6, long l6, float f6, double d6,
+ int i7, long l7, float f7, double d7,
+ int i8, long l8, float f8, double d8);
+}