ART: aarch64 jni compiler needs to extend small return types
As aarch64 calling convention does not mandate extension on return
values anymore and leaves the upper bits undefined, the jni compiler
needs to sign- or zero-extend the returned values when necessary.
As three architectures need extension now, refactor this fact into a
flag into a virtual method.
Add tests to JniTest that exercise the required extension.
Change-Id: Idebb7c4dedebb852e58ade63e1c2b1eeced23104
diff --git a/test/JniTest/JniTest.java b/test/JniTest/JniTest.java
index d53cf5e..3c4ed35 100644
--- a/test/JniTest/JniTest.java
+++ b/test/JniTest/JniTest.java
@@ -24,6 +24,10 @@
testCallStaticVoidMethodOnSubClass();
testGetMirandaMethod();
testZeroLengthByteBuffers();
+ testByteMethod();
+ testShortMethod();
+ testBooleanMethod();
+ testCharMethod();
}
private static native void testFindClassOnAttachedNativeThread();
@@ -79,4 +83,67 @@
private static interface testGetMirandaMethod_MirandaInterface {
public boolean inInterface();
}
+
+ // Test sign-extension for values < 32b
+
+ native static byte byteMethod(byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7,
+ byte b8, byte b9, byte b10);
+
+ private static void testByteMethod() {
+ byte returns[] = { 0, 1, 2, 127, -1, -2, -128 };
+ for (int i = 0; i < returns.length; i++) {
+ byte result = byteMethod((byte)i, (byte)2, (byte)(-3), (byte)4, (byte)(-5), (byte)6,
+ (byte)(-7), (byte)8, (byte)(-9), (byte)10);
+ if (returns[i] != result) {
+ System.out.println("Run " + i + " with " + returns[i] + " vs " + result);
+ throw new AssertionError();
+ }
+ }
+ }
+
+ native static short shortMethod(short s1, short s2, short s3, short s4, short s5, short s6, short s7,
+ short s8, short s9, short s10);
+
+ private static void testShortMethod() {
+ short returns[] = { 0, 1, 2, 127, 32767, -1, -2, -128, -32768 };
+ for (int i = 0; i < returns.length; i++) {
+ short result = shortMethod((short)i, (short)2, (short)(-3), (short)4, (short)(-5), (short)6,
+ (short)(-7), (short)8, (short)(-9), (short)10);
+ if (returns[i] != result) {
+ System.out.println("Run " + i + " with " + returns[i] + " vs " + result);
+ throw new AssertionError();
+ }
+ }
+ }
+
+ // Test zero-extension for values < 32b
+
+ native static boolean booleanMethod(boolean b1, boolean b2, boolean b3, boolean b4, boolean b5, boolean b6, boolean b7,
+ boolean b8, boolean b9, boolean b10);
+
+ private static void testBooleanMethod() {
+ if (booleanMethod(false, true, false, true, false, true, false, true, false, true)) {
+ throw new AssertionError();
+ }
+
+ if (!booleanMethod(true, true, false, true, false, true, false, true, false, true)) {
+ throw new AssertionError();
+ }
+ }
+
+ native static char charMethod(char c1, char c2, char c3, char c4, char c5, char c6, char c7,
+ char c8, char c9, char c10);
+
+ private static void testCharMethod() {
+ char returns[] = { (char)0, (char)1, (char)2, (char)127, (char)255, (char)256, (char)15000,
+ (char)34000 };
+ for (int i = 0; i < returns.length; i++) {
+ char result = charMethod((char)i, 'a', 'b', 'c', '0', '1', '2', (char)1234, (char)2345,
+ (char)3456);
+ if (returns[i] != result) {
+ System.out.println("Run " + i + " with " + (int)returns[i] + " vs " + (int)result);
+ throw new AssertionError();
+ }
+ }
+ }
}