summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/004-UnsafeTest/src/Main.java48
-rw-r--r--test/048-reflect-v8/expected.txt99
-rw-r--r--test/048-reflect-v8/src/AnnotationTest.java291
-rw-r--r--test/048-reflect-v8/src/AnnotationTestFixture.java48
-rw-r--r--test/048-reflect-v8/src/AnnotationTestHelpers.java86
-rw-r--r--test/048-reflect-v8/src/Calendar.java32
-rw-r--r--test/048-reflect-v8/src/Calendars.java26
-rw-r--r--test/048-reflect-v8/src/IFaceA.java24
-rw-r--r--test/048-reflect-v8/src/IFaceSimple.java21
-rw-r--r--test/048-reflect-v8/src/IsDefaultTest.java60
-rw-r--r--test/048-reflect-v8/src/Main.java43
-rw-r--r--test/048-reflect-v8/src/SingleUser.java21
-rw-r--r--test/048-reflect-v8/src/User.java31
-rw-r--r--test/048-reflect-v8/src/User2.java27
-rw-r--r--test/048-reflect-v8/src/UserComplex.java31
-rw-r--r--test/048-reflect-v8/src/UserSub.java21
-rw-r--r--test/048-reflect-v8/src/UserSub2.java23
-rw-r--r--test/137-cfi/cfi.cc36
-rw-r--r--test/137-cfi/expected.txt1
-rwxr-xr-xtest/137-cfi/run8
-rw-r--r--test/137-cfi/src/Main.java23
-rw-r--r--test/564-checker-bitcount/src/Main.java20
-rw-r--r--test/565-checker-irreducible-loop/expected.txt2
-rw-r--r--test/565-checker-irreducible-loop/info.txt2
-rw-r--r--test/565-checker-irreducible-loop/smali/IrreducibleLoop.smali101
-rw-r--r--test/565-checker-irreducible-loop/src/Main.java37
-rw-r--r--test/565-checker-rotate/expected.txt1
-rw-r--r--test/565-checker-rotate/info.txt1
-rw-r--r--test/565-checker-rotate/src/Main.java129
-rw-r--r--test/566-checker-signum/expected.txt1
-rw-r--r--test/566-checker-signum/info.txt1
-rw-r--r--test/566-checker-signum/src/Main.java72
-rw-r--r--test/567-checker-compare/expected.txt1
-rw-r--r--test/567-checker-compare/info.txt1
-rw-r--r--test/567-checker-compare/src/Main.java108
-rw-r--r--test/568-checker-onebit/expected.txt1
-rw-r--r--test/568-checker-onebit/info.txt1
-rw-r--r--test/568-checker-onebit/src/Main.java95
-rw-r--r--test/Android.run-test.mk12
-rwxr-xr-xtest/etc/run-test-jar9
40 files changed, 1506 insertions, 89 deletions
diff --git a/test/004-UnsafeTest/src/Main.java b/test/004-UnsafeTest/src/Main.java
index 5b22e88014..a9a7a058e0 100644
--- a/test/004-UnsafeTest/src/Main.java
+++ b/test/004-UnsafeTest/src/Main.java
@@ -110,23 +110,35 @@ public class Main {
check(unsafe.getObject(t, objectOffset), objectValue, "Unsafe.getObject(Object, long)");
if (unsafe.compareAndSwapInt(t, intOffset, 0, 1)) {
- System.out.println("Unexpectedly succeeding compareAndSwap...");
+ System.out.println("Unexpectedly succeeding compareAndSwapInt(t, intOffset, 0, 1)");
}
if (!unsafe.compareAndSwapInt(t, intOffset, intValue, 0)) {
- System.out.println("Unexpectedly not succeeding compareAndSwap...");
+ System.out.println(
+ "Unexpectedly not succeeding compareAndSwapInt(t, intOffset, intValue, 0)");
}
if (!unsafe.compareAndSwapInt(t, intOffset, 0, 1)) {
- System.out.println("Unexpectedly not succeeding compareAndSwap...");
+ System.out.println("Unexpectedly not succeeding compareAndSwapInt(t, intOffset, 0, 1)");
+ }
+ // Exercise sun.misc.Unsafe.compareAndSwapInt using the same
+ // integer (1) for the `expectedValue` and `newValue` arguments.
+ if (!unsafe.compareAndSwapInt(t, intOffset, 1, 1)) {
+ System.out.println("Unexpectedly not succeeding compareAndSwapInt(t, intOffset, 1, 1)");
}
if (unsafe.compareAndSwapLong(t, longOffset, 0, 1)) {
- System.out.println("Unexpectedly succeeding compareAndSwapLong...");
+ System.out.println("Unexpectedly succeeding compareAndSwapLong(t, longOffset, 0, 1)");
}
if (!unsafe.compareAndSwapLong(t, longOffset, longValue, 0)) {
- System.out.println("Unexpectedly not succeeding compareAndSwapLong...");
+ System.out.println(
+ "Unexpectedly not succeeding compareAndSwapLong(t, longOffset, longValue, 0)");
}
if (!unsafe.compareAndSwapLong(t, longOffset, 0, 1)) {
- System.out.println("Unexpectedly not succeeding compareAndSwapLong...");
+ System.out.println("Unexpectedly not succeeding compareAndSwapLong(t, longOffset, 0, 1)");
+ }
+ // Exercise sun.misc.Unsafe.compareAndSwapLong using the same
+ // integer (1) for the `expectedValue` and `newValue` arguments.
+ if (!unsafe.compareAndSwapLong(t, longOffset, 1, 1)) {
+ System.out.println("Unexpectedly not succeeding compareAndSwapLong(t, longOffset, 1, 1)");
}
// We do not use `null` as argument to sun.misc.Unsafe.compareAndSwapObject
@@ -135,31 +147,41 @@ public class Main {
// references). This way, when heap poisoning is enabled, we can
// better exercise its implementation within that method.
if (unsafe.compareAndSwapObject(t, objectOffset, new Object(), new Object())) {
- System.out.println("Unexpectedly succeeding compareAndSwapObject...");
+ System.out.println("Unexpectedly succeeding " +
+ "compareAndSwapObject(t, objectOffset, new Object(), new Object())");
}
Object objectValue2 = new Object();
if (!unsafe.compareAndSwapObject(t, objectOffset, objectValue, objectValue2)) {
- System.out.println("Unexpectedly not succeeding compareAndSwapObject...");
+ System.out.println("Unexpectedly not succeeding " +
+ "compareAndSwapObject(t, objectOffset, objectValue, objectValue2)");
}
Object objectValue3 = new Object();
if (!unsafe.compareAndSwapObject(t, objectOffset, objectValue2, objectValue3)) {
- System.out.println("Unexpectedly not succeeding compareAndSwapObject...");
+ System.out.println("Unexpectedly not succeeding " +
+ "compareAndSwapObject(t, objectOffset, objectValue2, objectValue3)");
+ }
+ // Exercise sun.misc.Unsafe.compareAndSwapObject using the same
+ // object (`objectValue3`) for the `expectedValue` and `newValue` arguments.
+ if (!unsafe.compareAndSwapObject(t, objectOffset, objectValue3, objectValue3)) {
+ System.out.println("Unexpectedly not succeeding " +
+ "compareAndSwapObject(t, objectOffset, objectValue3, objectValue3)");
}
-
// Exercise sun.misc.Unsafe.compareAndSwapObject using the same
// object (`t`) for the `obj` and `newValue` arguments.
if (!unsafe.compareAndSwapObject(t, objectOffset, objectValue3, t)) {
- System.out.println("Unexpectedly not succeeding compareAndSwapObject...");
+ System.out.println(
+ "Unexpectedly not succeeding compareAndSwapObject(t, objectOffset, objectValue3, t)");
}
// Exercise sun.misc.Unsafe.compareAndSwapObject using the same
// object (`t`) for the `obj`, `expectedValue` and `newValue` arguments.
if (!unsafe.compareAndSwapObject(t, objectOffset, t, t)) {
- System.out.println("Unexpectedly not succeeding compareAndSwapObject...");
+ System.out.println("Unexpectedly not succeeding compareAndSwapObject(t, objectOffset, t, t)");
}
// Exercise sun.misc.Unsafe.compareAndSwapObject using the same
// object (`t`) for the `obj` and `expectedValue` arguments.
if (!unsafe.compareAndSwapObject(t, objectOffset, t, new Object())) {
- System.out.println("Unexpectedly not succeeding compareAndSwapObject...");
+ System.out.println(
+ "Unexpectedly not succeeding compareAndSwapObject(t, objectOffset, t, new Object())");
}
}
diff --git a/test/048-reflect-v8/expected.txt b/test/048-reflect-v8/expected.txt
index 2d0b4ccb6b..3109eccda6 100644
--- a/test/048-reflect-v8/expected.txt
+++ b/test/048-reflect-v8/expected.txt
@@ -1,4 +1,95 @@
-Main$DefaultInterface is default = yes
-Main$RegularInterface is default = no
-Main$ImplementsWithDefault is default = yes
-Main$ImplementsWithRegular is default = no
+==============================
+Are These Methods Default:
+==============================
+IsDefaultTest$DefaultInterface is default = yes
+IsDefaultTest$RegularInterface is default = no
+IsDefaultTest$ImplementsWithDefault is default = yes
+IsDefaultTest$ImplementsWithRegular is default = no
+==============================
+Class annotations by type:
+==============================
+Annotations by type, defined by class SingleUser with annotation Calendar: @Calendar(dayOfMonth=unspecified_month, dayOfWeek=single, hour=23)
+Annotations by type, defined by class SingleUser with annotation Calendars: <empty>
+Annotations by type, defined by class User with annotation Calendar: @Calendar(dayOfMonth=last, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=unspecified_month, dayOfWeek=Fri, hour=23)
+Annotations by type, defined by class User with annotation Calendars: @Calendars(value=[@Calendar(dayOfMonth=last, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=unspecified_month, dayOfWeek=Fri, hour=23)])
+Annotations by type, defined by class User2 with annotation Calendar: @Calendar(dayOfMonth=z, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=x, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=y, dayOfWeek=unspecified_week, hour=6)
+Annotations by type, defined by class User2 with annotation Calendars: @Calendars(value=[@Calendar(dayOfMonth=z, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=x, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=y, dayOfWeek=unspecified_week, hour=6)])
+Annotations by type, defined by class UserComplex with annotation Calendar: @Calendar(dayOfMonth=afirst, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=zsecond, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=athird, dayOfWeek=unspecified_week, hour=23)
+Annotations by type, defined by class UserComplex with annotation Calendars: @Calendars(value=[@Calendar(dayOfMonth=zsecond, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=athird, dayOfWeek=unspecified_week, hour=23)])
+Annotations by type, defined by class UserSub with annotation Calendar: @Calendar(dayOfMonth=last, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=unspecified_month, dayOfWeek=Fri, hour=23)
+Annotations by type, defined by class UserSub with annotation Calendars: @Calendars(value=[@Calendar(dayOfMonth=last, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=unspecified_month, dayOfWeek=Fri, hour=23)])
+Annotations by type, defined by class UserSub2 with annotation Calendar: @Calendar(dayOfMonth=sub2, dayOfWeek=unspecified_week, hour=6)
+Annotations by type, defined by class UserSub2 with annotation Calendars: @Calendars(value=[@Calendar(dayOfMonth=last, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=unspecified_month, dayOfWeek=Fri, hour=23)])
+-----------------------------
+-----------------------------
+==============================
+Class declared annotation:
+==============================
+Declared annotations by class class SingleUser, annotation interface Calendar: @Calendar(dayOfMonth=unspecified_month, dayOfWeek=single, hour=23)
+Declared annotations by class class SingleUser, annotation interface Calendars: <null>
+Declared annotations by class class User, annotation interface Calendar: <null>
+Declared annotations by class class User, annotation interface Calendars: @Calendars(value=[@Calendar(dayOfMonth=last, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=unspecified_month, dayOfWeek=Fri, hour=23)])
+Declared annotations by class class UserComplex, annotation interface Calendar: @Calendar(dayOfMonth=afirst, dayOfWeek=unspecified_week, hour=6)
+Declared annotations by class class UserComplex, annotation interface Calendars: @Calendars(value=[@Calendar(dayOfMonth=zsecond, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=athird, dayOfWeek=unspecified_week, hour=23)])
+Declared annotations by class class UserSub, annotation interface Calendar: <null>
+Declared annotations by class class UserSub, annotation interface Calendars: <null>
+Declared annotations by class class UserSub2, annotation interface Calendar: @Calendar(dayOfMonth=sub2, dayOfWeek=unspecified_week, hour=6)
+Declared annotations by class class UserSub2, annotation interface Calendars: <null>
+-----------------------------
+-----------------------------
+==============================
+Declared class annotations by type:
+==============================
+Declared annnotations by type, defined by class SingleUser with annotation Calendar: @Calendar(dayOfMonth=unspecified_month, dayOfWeek=single, hour=23)
+Declared annnotations by type, defined by class SingleUser with annotation Calendars: <empty>
+Declared annnotations by type, defined by class User with annotation Calendar: @Calendar(dayOfMonth=last, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=unspecified_month, dayOfWeek=Fri, hour=23)
+Declared annnotations by type, defined by class User with annotation Calendars: @Calendars(value=[@Calendar(dayOfMonth=last, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=unspecified_month, dayOfWeek=Fri, hour=23)])
+Declared annnotations by type, defined by class User2 with annotation Calendar: @Calendar(dayOfMonth=z, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=x, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=y, dayOfWeek=unspecified_week, hour=6)
+Declared annnotations by type, defined by class User2 with annotation Calendars: @Calendars(value=[@Calendar(dayOfMonth=z, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=x, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=y, dayOfWeek=unspecified_week, hour=6)])
+Declared annnotations by type, defined by class UserComplex with annotation Calendar: @Calendar(dayOfMonth=afirst, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=zsecond, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=athird, dayOfWeek=unspecified_week, hour=23)
+Declared annnotations by type, defined by class UserComplex with annotation Calendars: @Calendars(value=[@Calendar(dayOfMonth=zsecond, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=athird, dayOfWeek=unspecified_week, hour=23)])
+Declared annnotations by type, defined by class UserSub with annotation Calendar: <empty>
+Declared annnotations by type, defined by class UserSub with annotation Calendars: <empty>
+Declared annnotations by type, defined by class UserSub2 with annotation Calendar: @Calendar(dayOfMonth=sub2, dayOfWeek=unspecified_week, hour=6)
+Declared annnotations by type, defined by class UserSub2 with annotation Calendars: <empty>
+-----------------------------
+-----------------------------
+==============================
+Method annotations by type:
+==============================
+Annotations by type, defined by method singleUser with annotation Calendar: @Calendar(dayOfMonth=unspecified_month, dayOfWeek=single, hour=23)
+Annotations by type, defined by method singleUser with annotation Calendars: <empty>
+Annotations by type, defined by method user with annotation Calendar: @Calendar(dayOfMonth=last, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=unspecified_month, dayOfWeek=Fri, hour=23)
+Annotations by type, defined by method user with annotation Calendars: @Calendars(value=[@Calendar(dayOfMonth=last, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=unspecified_month, dayOfWeek=Fri, hour=23)])
+Annotations by type, defined by method user2 with annotation Calendar: @Calendar(dayOfMonth=z, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=x, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=y, dayOfWeek=unspecified_week, hour=6)
+Annotations by type, defined by method user2 with annotation Calendars: @Calendars(value=[@Calendar(dayOfMonth=z, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=x, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=y, dayOfWeek=unspecified_week, hour=6)])
+Annotations by type, defined by method userComplex with annotation Calendar: @Calendar(dayOfMonth=afirst, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=zsecond, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=athird, dayOfWeek=unspecified_week, hour=23)
+Annotations by type, defined by method userComplex with annotation Calendars: @Calendars(value=[@Calendar(dayOfMonth=zsecond, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=athird, dayOfWeek=unspecified_week, hour=23)])
+-----------------------------
+-----------------------------
+==============================
+Declared method annotations:
+==============================
+Annotations declared by method singleUser with annotation Calendar: @Calendar(dayOfMonth=unspecified_month, dayOfWeek=single, hour=23)
+Annotations declared by method singleUser with annotation Calendars: <null>
+Annotations declared by method user with annotation Calendar: <null>
+Annotations declared by method user with annotation Calendars: @Calendars(value=[@Calendar(dayOfMonth=last, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=unspecified_month, dayOfWeek=Fri, hour=23)])
+Annotations declared by method user2 with annotation Calendar: <null>
+Annotations declared by method user2 with annotation Calendars: @Calendars(value=[@Calendar(dayOfMonth=z, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=x, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=y, dayOfWeek=unspecified_week, hour=6)])
+Annotations declared by method userComplex with annotation Calendar: @Calendar(dayOfMonth=afirst, dayOfWeek=unspecified_week, hour=6)
+Annotations declared by method userComplex with annotation Calendars: @Calendars(value=[@Calendar(dayOfMonth=zsecond, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=athird, dayOfWeek=unspecified_week, hour=23)])
+-----------------------------
+-----------------------------
+==============================
+Declared method annotations by type:
+==============================
+Annotations by type, defined by method singleUser with annotation Calendar: @Calendar(dayOfMonth=unspecified_month, dayOfWeek=single, hour=23)
+Annotations by type, defined by method singleUser with annotation Calendars: <empty>
+Annotations by type, defined by method user with annotation Calendar: @Calendar(dayOfMonth=last, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=unspecified_month, dayOfWeek=Fri, hour=23)
+Annotations by type, defined by method user with annotation Calendars: @Calendars(value=[@Calendar(dayOfMonth=last, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=unspecified_month, dayOfWeek=Fri, hour=23)])
+Annotations by type, defined by method user2 with annotation Calendar: @Calendar(dayOfMonth=z, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=x, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=y, dayOfWeek=unspecified_week, hour=6)
+Annotations by type, defined by method user2 with annotation Calendars: @Calendars(value=[@Calendar(dayOfMonth=z, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=x, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=y, dayOfWeek=unspecified_week, hour=6)])
+Annotations by type, defined by method userComplex with annotation Calendar: @Calendar(dayOfMonth=afirst, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=zsecond, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=athird, dayOfWeek=unspecified_week, hour=23)
+Annotations by type, defined by method userComplex with annotation Calendars: @Calendars(value=[@Calendar(dayOfMonth=zsecond, dayOfWeek=unspecified_week, hour=6), @Calendar(dayOfMonth=athird, dayOfWeek=unspecified_week, hour=23)])
+-----------------------------
+-----------------------------
diff --git a/test/048-reflect-v8/src/AnnotationTest.java b/test/048-reflect-v8/src/AnnotationTest.java
new file mode 100644
index 0000000000..75e684557c
--- /dev/null
+++ b/test/048-reflect-v8/src/AnnotationTest.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2016 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 java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+
+public class AnnotationTest extends AnnotationTestHelpers {
+ public static void testAnnotationsByType() {
+ System.out.println("==============================");
+ System.out.println("Class annotations by type:");
+ System.out.println("==============================");
+
+ // Print associated annotations:
+ // * A is directly present or repeatably present on an element E;
+ // * No annotation of A is directly/repeatably present on an element
+ // AND E is a class AND A's type is inheritable, AND A is associated with its superclass.
+ // (Looks through subtypes recursively only if there's 0 result at each level,
+ // and the annotation is @Inheritable).
+ printAnnotationsByType(Calendar.class, SingleUser.class);
+ printAnnotationsByType(Calendars.class, SingleUser.class);
+
+ printAnnotationsByType(Calendar.class, User.class);
+ printAnnotationsByType(Calendars.class, User.class);
+
+ printAnnotationsByType(Calendar.class, User2.class); // Enforce ordering 'z,x,y'
+ printAnnotationsByType(Calendars.class, User2.class);
+
+ // NOTE:
+ // Order of outer-most annotations Calendars[C,C],S vs C,Calendars[C,C] is unspecified.
+ // In particular it's the order of #getDeclaredAnnotations which is completely unmentioned.
+ // The only requirement for #getAnnotationsByType is to have same ordering as
+ // #getDeclaredAnnotations.
+ // (Calendars[] itself has to maintain value() order).
+ printAnnotationsByType(Calendar.class, UserComplex.class); // Cs(C,C),C collapses into C,C,C.
+ printAnnotationsByType(Calendars.class, UserComplex.class);
+
+ printAnnotationsByType(Calendar.class, UserSub.class);
+ printAnnotationsByType(Calendars.class, UserSub.class);
+
+ printAnnotationsByType(Calendar.class, UserSub2.class);
+ // The directly present "Calendar" annotation masks all the repeatably present
+ // "Calendar" annotations coming from User.
+ printAnnotationsByType(Calendars.class, UserSub2.class);
+ // Edge case: UserSub2 doesn't directly have a Calendars annotation,
+ // so it doesn't mask the "User" Calendars annotation.
+
+ System.out.println("-----------------------------");
+ System.out.println("-----------------------------");
+
+ }
+
+ public static void testDeclaredAnnotation() {
+ System.out.println("==============================");
+ System.out.println("Class declared annotation:");
+ System.out.println("==============================");
+
+ // Print directly present annotations:
+ //
+ // The element E has an annotation_item for it (accessible through an
+ // annotations_directory_item) corresponding to an annotation A,
+ // and A's type_idx must match that on the encoded_annotation (from the annotation_item).
+ // (Does not look through the subtypes recursively)
+ printDeclaredAnnotation(SingleUser.class, Calendar.class);
+ printDeclaredAnnotation(SingleUser.class, Calendars.class);
+
+ printDeclaredAnnotation(User.class, Calendar.class);
+ printDeclaredAnnotation(User.class, Calendars.class);
+
+ printDeclaredAnnotation(UserComplex.class, Calendar.class);
+ printDeclaredAnnotation(UserComplex.class, Calendars.class);
+
+ printDeclaredAnnotation(UserSub.class, Calendar.class);
+ printDeclaredAnnotation(UserSub.class, Calendars.class);
+
+ printDeclaredAnnotation(UserSub2.class, Calendar.class);
+ printDeclaredAnnotation(UserSub2.class, Calendars.class);
+
+ System.out.println("-----------------------------");
+ System.out.println("-----------------------------");
+ }
+
+ public static void testDeclaredAnnotationsByType() {
+ System.out.println("==============================");
+ System.out.println("Declared class annotations by type:");
+ System.out.println("==============================");
+
+ // A is directly present or repeatably present on an element E;
+ // -- (does not do any recursion for classes regardless of @Inherited)
+ printDeclaredAnnotationsByType(Calendar.class, SingleUser.class);
+ printDeclaredAnnotationsByType(Calendars.class, SingleUser.class);
+
+ printDeclaredAnnotationsByType(Calendar.class, User.class);
+ printDeclaredAnnotationsByType(Calendars.class, User.class);
+
+ printDeclaredAnnotationsByType(Calendar.class, User2.class); // Enforce ordering 'z,x,y'
+ printDeclaredAnnotationsByType(Calendars.class, User2.class);
+
+ printDeclaredAnnotationsByType(Calendar.class, UserComplex.class);
+ printDeclaredAnnotationsByType(Calendars.class, UserComplex.class);
+
+ printDeclaredAnnotationsByType(Calendar.class, UserSub.class);
+ printDeclaredAnnotationsByType(Calendars.class, UserSub.class);
+
+ printDeclaredAnnotationsByType(Calendar.class, UserSub2.class);
+ // The directly present "Calendar" annotation masks all the repeatably present "Calendar"
+ // annotations coming from User.
+ printDeclaredAnnotationsByType(Calendars.class, UserSub2.class);
+ // Edge case: UserSub2 doesn't directly have a Calendars annotation,
+ // so it doesn't mask the "User" Calendars annotation.
+
+ System.out.println("-----------------------------");
+ System.out.println("-----------------------------");
+ }
+
+ // Print the annotation "annotationClass" that is associated with an element denoted by
+ // "annotationUseClass."
+ private static <A extends Annotation> void printAnnotationsByType(Class<A> annotationClass,
+ Class<?> annotationUseClass) {
+ A[] annotationsByType = annotationUseClass.getAnnotationsByType(annotationClass);
+
+ String msg = "Annotations by type, defined by class "
+ + annotationUseClass.getName() + " with annotation " + annotationClass.getName() + ": "
+ + asString(annotationsByType);
+
+
+ System.out.println(msg);
+ }
+
+ private static <A extends Annotation> void printDeclaredAnnotation(Class<?> annotationUseClass,
+ Class<A> annotationDefClass) {
+ A anno = annotationUseClass.getDeclaredAnnotation(annotationDefClass);
+
+ String msg = asString(anno);
+
+ System.out.println("Declared annotations by class " + annotationUseClass
+ + ", annotation " + annotationDefClass + ": " + msg);
+ }
+
+ // Print the annotation "annotationClass" that is directly/indirectly present with an element
+ // denoted by "annotationUseClass."
+ private static <A extends Annotation> void printDeclaredAnnotationsByType(
+ Class<A> annotationClass, Class<?> annotationUseClass) {
+ A[] annotationsByType = annotationUseClass.getDeclaredAnnotationsByType(annotationClass);
+
+ String msg = "Declared annnotations by type, defined by class " + annotationUseClass.getName()
+ + " with annotation " + annotationClass.getName() + ": "
+ + asString(annotationsByType);
+
+ System.out.println(msg);
+ }
+
+ public static void testMethodAnnotationsByType() {
+ System.out.println("==============================");
+ System.out.println("Method annotations by type:");
+ System.out.println("==============================");
+
+ // Print associated annotations:
+ // * A is directly present or repeatably present on an element E;
+ // * No annotation of A is directly/repeatably present on an element AND E is a class
+ // AND A's type is inheritable, AND A is associated with its superclass.
+ // (Looks through subtypes recursively only if there's 0 result at each level,
+ // and the annotation is @Inheritable).
+ printMethodAnnotationsByType(Calendar.class, "singleUser", AnnotationTestFixture.class);
+ printMethodAnnotationsByType(Calendars.class, "singleUser", AnnotationTestFixture.class);
+
+ printMethodAnnotationsByType(Calendar.class, "user", AnnotationTestFixture.class);
+ printMethodAnnotationsByType(Calendars.class, "user", AnnotationTestFixture.class);
+
+ printMethodAnnotationsByType(Calendar.class, "user2", AnnotationTestFixture.class);
+ printMethodAnnotationsByType(Calendars.class, "user2", AnnotationTestFixture.class);
+
+ printMethodAnnotationsByType(Calendar.class, "userComplex", AnnotationTestFixture.class);
+ printMethodAnnotationsByType(Calendars.class, "userComplex", AnnotationTestFixture.class);
+
+ System.out.println("-----------------------------");
+ System.out.println("-----------------------------");
+ }
+
+ // Print the annotation "annotationClass" that is associated with an element denoted by
+ // "annotationUseClass" method methodName.
+ private static <A extends Annotation> void printMethodAnnotationsByType(Class<A> annotationClass,
+ String methodName, Class<?> annotationUseClass) {
+ Method m = null;
+ try {
+ m = annotationUseClass.getDeclaredMethod(methodName);
+ } catch (Throwable t) {
+ throw new AssertionError(t);
+ }
+ A[] annotationsByType = m.getAnnotationsByType(annotationClass);
+
+ String msg = "Annotations by type, defined by method " + m.getName() + " with annotation " +
+ annotationClass.getName() + ": " +
+ asString(annotationsByType);
+
+ System.out.println(msg);
+ }
+
+ public static void testMethodDeclaredAnnotations() {
+ System.out.println("==============================");
+ System.out.println("Declared method annotations:");
+ System.out.println("==============================");
+
+ printMethodDeclaredAnnotation(Calendar.class, "singleUser", AnnotationTestFixture.class);
+ printMethodDeclaredAnnotation(Calendars.class, "singleUser", AnnotationTestFixture.class);
+
+ printMethodDeclaredAnnotation(Calendar.class, "user", AnnotationTestFixture.class);
+ printMethodDeclaredAnnotation(Calendars.class, "user", AnnotationTestFixture.class);
+
+ printMethodDeclaredAnnotation(Calendar.class, "user2", AnnotationTestFixture.class);
+ printMethodDeclaredAnnotation(Calendars.class, "user2", AnnotationTestFixture.class);
+
+ printMethodDeclaredAnnotation(Calendar.class, "userComplex", AnnotationTestFixture.class);
+ printMethodDeclaredAnnotation(Calendars.class, "userComplex", AnnotationTestFixture.class);
+
+ System.out.println("-----------------------------");
+ System.out.println("-----------------------------");
+ }
+
+ // Print the annotation "annotationClass" that is associated with an element denoted by
+ // methodName in annotationUseClass.
+ private static <A extends Annotation> void printMethodDeclaredAnnotation(Class<A> annotationClass,
+ String methodName, Class<?> annotationUseClass) {
+ Method m = null;
+ try {
+ m = annotationUseClass.getDeclaredMethod(methodName);
+ } catch (Throwable t) {
+ throw new AssertionError(t);
+ }
+ Annotation annotationsByType = m.getDeclaredAnnotation(annotationClass);
+
+ String msg = "Annotations declared by method " + m.getName() + " with annotation "
+ + annotationClass.getName() + ": "
+ + asString(annotationsByType);
+
+ System.out.println(msg);
+ }
+
+ public static void testMethodDeclaredAnnotationsByType() {
+ System.out.println("==============================");
+ System.out.println("Declared method annotations by type:");
+ System.out.println("==============================");
+
+ printMethodDeclaredAnnotationByType(Calendar.class, "singleUser", AnnotationTestFixture.class);
+ printMethodDeclaredAnnotationByType(Calendars.class, "singleUser", AnnotationTestFixture.class);
+
+ printMethodDeclaredAnnotationByType(Calendar.class, "user", AnnotationTestFixture.class);
+ printMethodDeclaredAnnotationByType(Calendars.class, "user", AnnotationTestFixture.class);
+
+ printMethodDeclaredAnnotationByType(Calendar.class, "user2", AnnotationTestFixture.class);
+ printMethodDeclaredAnnotationByType(Calendars.class, "user2", AnnotationTestFixture.class);
+
+ printMethodDeclaredAnnotationByType(Calendar.class, "userComplex", AnnotationTestFixture.class);
+ printMethodDeclaredAnnotationByType(Calendars.class, "userComplex",
+ AnnotationTestFixture.class);
+
+ System.out.println("-----------------------------");
+ System.out.println("-----------------------------");
+ }
+
+ // Print the annotation "annotationClass" that is associated with an element denoted by
+ // methodName in annotationUseClass.
+ private static <A extends Annotation> void printMethodDeclaredAnnotationByType(
+ Class<A> annotationClass, String methodName, Class<?> annotationUseClass) {
+ Method m = null;
+ try {
+ m = annotationUseClass.getDeclaredMethod(methodName);
+ } catch (Throwable t) {
+ throw new AssertionError(t);
+ }
+ A[] annotationsByType = m.getDeclaredAnnotationsByType(annotationClass);
+
+ String msg = "Annotations by type, defined by method " + m.getName() + " with annotation "
+ + annotationClass.getName() + ": "
+ + asString(annotationsByType);
+
+ System.out.println(msg);
+ }
+}
diff --git a/test/048-reflect-v8/src/AnnotationTestFixture.java b/test/048-reflect-v8/src/AnnotationTestFixture.java
new file mode 100644
index 0000000000..248dfacf3b
--- /dev/null
+++ b/test/048-reflect-v8/src/AnnotationTestFixture.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+public class AnnotationTestFixture {
+
+ @Calendar(dayOfWeek="single", hour=23)
+ public static void singleUser() {
+
+ }
+ @Calendars ({
+ @Calendar(dayOfMonth="last"),
+ @Calendar(dayOfWeek="Fri", hour=23)
+ })
+ public static void user() {
+
+ }
+
+ @Calendars ({
+ @Calendar(dayOfMonth="z"),
+ @Calendar(dayOfMonth="x"),
+ @Calendar(dayOfMonth="y")
+ })
+ public static void user2() {
+
+ }
+
+ @Calendar(dayOfMonth="afirst")
+ @Calendars ({
+ @Calendar(dayOfMonth="zsecond"),
+ @Calendar(dayOfMonth="athird", hour=23)
+ })
+ public static void userComplex() {
+
+ }
+}
diff --git a/test/048-reflect-v8/src/AnnotationTestHelpers.java b/test/048-reflect-v8/src/AnnotationTestHelpers.java
new file mode 100644
index 0000000000..6b5bea266e
--- /dev/null
+++ b/test/048-reflect-v8/src/AnnotationTestHelpers.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2016 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 java.lang.annotation.Annotation;
+
+public class AnnotationTestHelpers {
+ // Provide custom print function that print a deterministic output.
+ // Note that Annotation#toString has unspecified order: it prints out the
+ // fields, which is why we can't rely on it.
+
+ public static String asString(Annotation anno) {
+ if (anno instanceof Calendar) {
+ return asString((Calendar)anno);
+ } else if (anno instanceof Calendars) {
+ return asString((Calendars)anno);
+ } else {
+ if (anno == null) {
+ return "<null>";
+ }
+ // Fall-back, usually would only go here in a test failure.
+ return anno.toString();
+ }
+ }
+
+ public static String asString(Annotation[] annos) {
+ String msg = "";
+
+ if (annos == null) {
+ msg += "<null>";
+ } else if (annos.length == 0) {
+ msg += "<empty>";
+ } else {
+ for (int i = 0; i < annos.length; ++i) {
+ msg += asString(annos[i]);
+
+ if (i != annos.length - 1) {
+ msg += ", ";
+ }
+ }
+ }
+
+ return msg;
+ }
+
+ public static String asString(Calendar calendar) {
+ if (calendar == null) {
+ return "<null>";
+ }
+
+ return "@Calendar(dayOfMonth=" + calendar.dayOfMonth() + ", dayOfWeek=" +
+ calendar.dayOfWeek() + ", hour=" + calendar.hour() + ")";
+ }
+
+ public static String asString(Calendars calendars) {
+ if (calendars == null) {
+ return "<null>";
+ }
+
+ String s = "@Calendars(value=[";
+
+ Calendar[] allValues = calendars.value();
+ for (int i = 0; i < allValues.length; ++i) {
+ s += asString(allValues[i]);
+ if (i != allValues.length - 1) {
+ s += ", ";
+ }
+ }
+
+ s += "])";
+
+ return s;
+ }
+}
diff --git a/test/048-reflect-v8/src/Calendar.java b/test/048-reflect-v8/src/Calendar.java
new file mode 100644
index 0000000000..4a16573bca
--- /dev/null
+++ b/test/048-reflect-v8/src/Calendar.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2016 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 java.lang.annotation.Inherited;
+import java.lang.annotation.Repeatable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+// This is a plain old non-1.8 annotation. At runtime we can see that it has a
+// "Repeatable" annotation if we query with getDeclaredAnnotation(Repeatable.class)
+@Retention(RetentionPolicy.RUNTIME)
+@Repeatable(Calendars.class)
+@Inherited // note: container must also be @Inherited by JLS.
+public @interface Calendar {
+ String dayOfMonth() default "unspecified_month";
+ String dayOfWeek() default "unspecified_week";
+ int hour() default 6;
+}
+
diff --git a/test/048-reflect-v8/src/Calendars.java b/test/048-reflect-v8/src/Calendars.java
new file mode 100644
index 0000000000..caeda52ea6
--- /dev/null
+++ b/test/048-reflect-v8/src/Calendars.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2016 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 java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+// Plain old annotation, there's nothing 1.8 specific about it.
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited // note: elements must also be @Inherited by JLS.
+public @interface Calendars {
+ Calendar[] value();
+}
diff --git a/test/048-reflect-v8/src/IFaceA.java b/test/048-reflect-v8/src/IFaceA.java
new file mode 100644
index 0000000000..9b1f610f84
--- /dev/null
+++ b/test/048-reflect-v8/src/IFaceA.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+// Stored as a complex annotation Calendars(Calendar,Calendar)
+// in the binary.
+@Calendars ({
+ @Calendar(dayOfMonth="if_a_first"),
+ @Calendar(dayOfMonth="if_b_last")
+})
+public interface IFaceA {
+}
diff --git a/test/048-reflect-v8/src/IFaceSimple.java b/test/048-reflect-v8/src/IFaceSimple.java
new file mode 100644
index 0000000000..93cf61057e
--- /dev/null
+++ b/test/048-reflect-v8/src/IFaceSimple.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+// Simple annotation, no container.
+@Calendar(dayOfMonth="if_simple_first")
+public interface IFaceSimple {
+
+}
diff --git a/test/048-reflect-v8/src/IsDefaultTest.java b/test/048-reflect-v8/src/IsDefaultTest.java
new file mode 100644
index 0000000000..177dcf1ab9
--- /dev/null
+++ b/test/048-reflect-v8/src/IsDefaultTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016 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 java.lang.reflect.Method;
+
+public class IsDefaultTest {
+ interface DefaultInterface {
+ default void sayHi() {
+ System.out.println("hi default");
+ }
+ }
+
+ interface RegularInterface {
+ void sayHi();
+ }
+
+ class ImplementsWithDefault implements DefaultInterface {}
+ class ImplementsWithRegular implements RegularInterface {
+ public void sayHi() {
+ System.out.println("hello specific");
+ }
+ }
+
+ private static void printIsDefault(Class<?> klass) {
+ Method m;
+ try {
+ m = klass.getMethod("sayHi");
+ } catch (Throwable t) {
+ System.out.println(t);
+ return;
+ }
+
+ boolean isDefault = m.isDefault();
+ System.out.println(klass.getName() + " is default = " + (isDefault ? "yes" : "no"));
+ }
+
+ public static void test() {
+ System.out.println("==============================");
+ System.out.println("Are These Methods Default:");
+ System.out.println("==============================");
+
+ printIsDefault(DefaultInterface.class);
+ printIsDefault(RegularInterface.class);
+ printIsDefault(ImplementsWithDefault.class);
+ printIsDefault(ImplementsWithRegular.class);
+ }
+}
diff --git a/test/048-reflect-v8/src/Main.java b/test/048-reflect-v8/src/Main.java
index 7fa2a923d7..f2b8287d18 100644
--- a/test/048-reflect-v8/src/Main.java
+++ b/test/048-reflect-v8/src/Main.java
@@ -14,43 +14,14 @@
* limitations under the License.
*/
-import java.lang.reflect.Method;
-
public class Main {
- interface DefaultInterface {
- default void sayHi() {
- System.out.println("hi default");
- }
- }
-
- interface RegularInterface {
- void sayHi();
- }
-
- class ImplementsWithDefault implements DefaultInterface {}
- class ImplementsWithRegular implements RegularInterface {
- public void sayHi() {
- System.out.println("hello specific");
- }
- }
-
- private static void printIsDefault(Class<?> klass) {
- Method m;
- try {
- m = klass.getMethod("sayHi");
- } catch (Throwable t) {
- System.out.println(t);
- return;
- }
-
- boolean isDefault = m.isDefault();
- System.out.println(klass.getName() + " is default = " + (isDefault ? "yes" : "no"));
- }
-
public static void main(String[] args) {
- printIsDefault(DefaultInterface.class);
- printIsDefault(RegularInterface.class);
- printIsDefault(ImplementsWithDefault.class);
- printIsDefault(ImplementsWithRegular.class);
+ IsDefaultTest.test();
+ AnnotationTest.testAnnotationsByType();
+ AnnotationTest.testDeclaredAnnotation();
+ AnnotationTest.testDeclaredAnnotationsByType();
+ AnnotationTest.testMethodAnnotationsByType();
+ AnnotationTest.testMethodDeclaredAnnotations();
+ AnnotationTest.testMethodDeclaredAnnotationsByType();
}
}
diff --git a/test/048-reflect-v8/src/SingleUser.java b/test/048-reflect-v8/src/SingleUser.java
new file mode 100644
index 0000000000..0f9c430109
--- /dev/null
+++ b/test/048-reflect-v8/src/SingleUser.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+// Stored as a single "Calendar" annotation in the binary.
+@Calendar(dayOfWeek="single", hour=23)
+public class SingleUser {
+
+}
diff --git a/test/048-reflect-v8/src/User.java b/test/048-reflect-v8/src/User.java
new file mode 100644
index 0000000000..003ceeb093
--- /dev/null
+++ b/test/048-reflect-v8/src/User.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+// Stored as a complex annotation Calendars(Calendar,Calendar)
+// in the binary.
+//
+/* FIXME: Use this code instead, when Jack supports repeatable annotations properly.
+ *
+ * @Calendar(dayOfMonth="last")
+ * @Calendar(dayOfWeek="Fri", hour=23)
+ */
+@Calendars ({
+ @Calendar(dayOfMonth="last"),
+ @Calendar(dayOfWeek="Fri", hour=23)
+})
+public class User {
+
+}
diff --git a/test/048-reflect-v8/src/User2.java b/test/048-reflect-v8/src/User2.java
new file mode 100644
index 0000000000..1a6049f508
--- /dev/null
+++ b/test/048-reflect-v8/src/User2.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+// Stored as a complex annotation Calendars(Calendar,Calendar,Calendar)
+// in the binary.
+// (Check for order, should be z,x,y)
+@Calendars ({
+ @Calendar(dayOfMonth="z"),
+ @Calendar(dayOfMonth="x"),
+ @Calendar(dayOfMonth="y")
+})
+public class User2 {
+
+}
diff --git a/test/048-reflect-v8/src/UserComplex.java b/test/048-reflect-v8/src/UserComplex.java
new file mode 100644
index 0000000000..e26234960b
--- /dev/null
+++ b/test/048-reflect-v8/src/UserComplex.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+// Stored as a complex annotation Calendars(Calendar,Calendar)
+// followed by a Calendar in the binary.
+// In other words { Calendars([C,C]), C }
+//
+// Note that trying to do {C,Calendars,C} or similar
+// is illegal by the JLS.
+@Calendar(dayOfMonth="afirst")
+@Calendars ({
+ @Calendar(dayOfMonth="zsecond"),
+ @Calendar(dayOfMonth="athird", hour=23)
+})
+// @Calendar(dayOfMonth="zlast") // Leave for future ordering test
+public class UserComplex {
+
+}
diff --git a/test/048-reflect-v8/src/UserSub.java b/test/048-reflect-v8/src/UserSub.java
new file mode 100644
index 0000000000..d60aa6a3f1
--- /dev/null
+++ b/test/048-reflect-v8/src/UserSub.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+public class UserSub
+ extends User
+ implements IFaceA, IFaceSimple {
+
+}
diff --git a/test/048-reflect-v8/src/UserSub2.java b/test/048-reflect-v8/src/UserSub2.java
new file mode 100644
index 0000000000..13e2eb07c8
--- /dev/null
+++ b/test/048-reflect-v8/src/UserSub2.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+// This calendar subsumes anything else we would've normally gotten from the subclass.
+@Calendar(dayOfMonth="sub2")
+public class UserSub2
+ extends User
+ implements IFaceA, IFaceSimple {
+
+}
diff --git a/test/137-cfi/cfi.cc b/test/137-cfi/cfi.cc
index 77301d20e8..87656bcf0e 100644
--- a/test/137-cfi/cfi.cc
+++ b/test/137-cfi/cfi.cc
@@ -101,7 +101,12 @@ static bool IsPicImage() {
}
#endif
-extern "C" JNIEXPORT jboolean JNICALL Java_Main_unwindInProcess(JNIEnv*, jobject, jint, jboolean) {
+extern "C" JNIEXPORT jboolean JNICALL Java_Main_unwindInProcess(
+ JNIEnv*,
+ jobject,
+ jboolean full_signatrues,
+ jint,
+ jboolean) {
#if __linux__
if (IsPicImage()) {
LOG(INFO) << "Image is pic, in-process unwinding check bypassed.";
@@ -122,14 +127,21 @@ extern "C" JNIEXPORT jboolean JNICALL Java_Main_unwindInProcess(JNIEnv*, jobject
// We cannot really parse an exact stack, as the optimizing compiler may inline some functions.
// This is also risky, as deduping might play a trick on us, so the test needs to make sure that
// only unique functions are being expected.
+ // "mini-debug-info" does not include parameters to save space.
std::vector<std::string> seq = {
"Java_Main_unwindInProcess", // This function.
- "boolean Main.unwindInProcess(int, boolean)", // The corresponding Java native method frame.
+ "Main.unwindInProcess", // The corresponding Java native method frame.
+ "int java.util.Arrays.binarySearch(java.lang.Object[], int, int, java.lang.Object, java.util.Comparator)", // Framework method.
+ "Main.main" // The Java entry method.
+ };
+ std::vector<std::string> full_seq = {
+ "Java_Main_unwindInProcess", // This function.
+ "boolean Main.unwindInProcess(boolean, int, boolean)", // The corresponding Java native method frame.
"int java.util.Arrays.binarySearch(java.lang.Object[], int, int, java.lang.Object, java.util.Comparator)", // Framework method.
"void Main.main(java.lang.String[])" // The Java entry method.
};
- bool result = CheckStack(bt.get(), seq);
+ bool result = CheckStack(bt.get(), full_signatrues ? full_seq : seq);
if (!kCauseSegfault) {
return result ? JNI_TRUE : JNI_FALSE;
} else {
@@ -178,7 +190,11 @@ int wait_for_sigstop(pid_t tid, int* total_sleep_time_usec, bool* detach_failed
}
#endif
-extern "C" JNIEXPORT jboolean JNICALL Java_Main_unwindOtherProcess(JNIEnv*, jobject, jint pid_int) {
+extern "C" JNIEXPORT jboolean JNICALL Java_Main_unwindOtherProcess(
+ JNIEnv*,
+ jobject,
+ jboolean full_signatrues,
+ jint pid_int) {
#if __linux__
// TODO: What to do on Valgrind?
pid_t pid = static_cast<pid_t>(pid_int);
@@ -214,17 +230,27 @@ extern "C" JNIEXPORT jboolean JNICALL Java_Main_unwindOtherProcess(JNIEnv*, jobj
if (result) {
// See comment in unwindInProcess for non-exact stack matching.
+ // "mini-debug-info" does not include parameters to save space.
std::vector<std::string> seq = {
// "Java_Main_sleep", // The sleep function being executed in the
// other runtime.
// Note: For some reason, the name isn't
// resolved, so don't look for it right now.
+ "Main.sleep", // The corresponding Java native method frame.
+ "int java.util.Arrays.binarySearch(java.lang.Object[], int, int, java.lang.Object, java.util.Comparator)", // Framework method.
+ "Main.main" // The Java entry method.
+ };
+ std::vector<std::string> full_seq = {
+ // "Java_Main_sleep", // The sleep function being executed in the
+ // other runtime.
+ // Note: For some reason, the name isn't
+ // resolved, so don't look for it right now.
"boolean Main.sleep(int, boolean, double)", // The corresponding Java native method frame.
"int java.util.Arrays.binarySearch(java.lang.Object[], int, int, java.lang.Object, java.util.Comparator)", // Framework method.
"void Main.main(java.lang.String[])" // The Java entry method.
};
- result = CheckStack(bt.get(), seq);
+ result = CheckStack(bt.get(), full_signatrues ? full_seq : seq);
}
if (ptrace(PTRACE_DETACH, pid, 0, 0) != 0) {
diff --git a/test/137-cfi/expected.txt b/test/137-cfi/expected.txt
index 6a5618ebc6..8db7853696 100644
--- a/test/137-cfi/expected.txt
+++ b/test/137-cfi/expected.txt
@@ -1 +1,2 @@
JNI_OnLoad called
+JNI_OnLoad called
diff --git a/test/137-cfi/run b/test/137-cfi/run
index 9c567b6813..6f4bcfe658 100755
--- a/test/137-cfi/run
+++ b/test/137-cfi/run
@@ -14,4 +14,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-exec ${RUN} "$@" -Xcompiler-option --generate-debug-info
+# Test with full DWARF debugging information.
+# Check full signatures of methods.
+${RUN} "$@" -Xcompiler-option --generate-debug-info --args --full-signatures
+
+# Test with minimal compressed debugging information.
+# Check only method names (parameters are omitted to save space).
+${RUN} "$@" -Xcompiler-option --generate-mini-debug-info
diff --git a/test/137-cfi/src/Main.java b/test/137-cfi/src/Main.java
index 5474c9b7b6..77553380c8 100644
--- a/test/137-cfi/src/Main.java
+++ b/test/137-cfi/src/Main.java
@@ -34,19 +34,28 @@ public class Main implements Comparator<Main> {
private boolean secondary;
+ private boolean full_signatures;
+
private boolean passed;
- public Main(boolean secondary) {
+ public Main(boolean secondary, boolean full_signatures) {
this.secondary = secondary;
+ this.full_signatures = full_signatures;
}
public static void main(String[] args) throws Exception {
System.loadLibrary(args[0]);
boolean secondary = false;
- if (args.length > 0 && args[args.length - 1].equals("--secondary")) {
+ boolean full_signatures = false;
+ for (String arg : args) {
+ if (arg.equals("--secondary")) {
secondary = true;
+ }
+ if (arg.equals("--full-signatures")) {
+ full_signatures = true;
+ }
}
- new Main(secondary).run();
+ new Main(secondary, full_signatures).run();
}
private void run() {
@@ -96,7 +105,7 @@ public class Main implements Comparator<Main> {
throw new RuntimeException(e);
}
- if (!unwindOtherProcess(pid)) {
+ if (!unwindOtherProcess(full_signatures, pid)) {
System.out.println("Unwinding other process failed.");
}
} finally {
@@ -154,7 +163,7 @@ public class Main implements Comparator<Main> {
if (b) {
return sleep(2, b, 1.0);
} else {
- return unwindInProcess(1, b);
+ return unwindInProcess(full_signatures, 1, b);
}
}
@@ -162,6 +171,6 @@ public class Main implements Comparator<Main> {
public native boolean sleep(int i, boolean b, double dummy);
- public native boolean unwindInProcess(int i, boolean b);
- public native boolean unwindOtherProcess(int pid);
+ public native boolean unwindInProcess(boolean full_signatures, int i, boolean b);
+ public native boolean unwindOtherProcess(boolean full_signatures, int pid);
}
diff --git a/test/564-checker-bitcount/src/Main.java b/test/564-checker-bitcount/src/Main.java
index b250145ef3..2683b2548f 100644
--- a/test/564-checker-bitcount/src/Main.java
+++ b/test/564-checker-bitcount/src/Main.java
@@ -16,24 +16,20 @@
public class Main {
- // TODO: make this work when b/26700769 is done.
- //
+ // TODO: make something like this work when b/26700769 is done.
// CHECK-START-X86_64: int Main.bits32(int) disassembly (after)
// CHECK-DAG: popcnt
- //
- // CHECK-START-X86_64: int Main.bits32(int) disassembly (after)
- // CHECK-NOT: call
+
+ /// CHECK-START: int Main.bits32(int) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerBitCount
+ /// CHECK-DAG: Return [<<Result>>]
private static int bits32(int x) {
return Integer.bitCount(x);
}
- // TODO: make this work when b/26700769 is done.
- //
- // CHECK-START-X86_64: int Main.bits64(long) disassembly (after)
- // CHECK-DAG: popcnt
- //
- // CHECK-START-X86_64: int Main.bits64(long) disassembly (after)
- // CHECK-NOT: call
+ /// CHECK-START: int Main.bits64(long) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:LongBitCount
+ /// CHECK-DAG: Return [<<Result>>]
private static int bits64(long x) {
return Long.bitCount(x);
}
diff --git a/test/565-checker-irreducible-loop/expected.txt b/test/565-checker-irreducible-loop/expected.txt
new file mode 100644
index 0000000000..6ed281c757
--- /dev/null
+++ b/test/565-checker-irreducible-loop/expected.txt
@@ -0,0 +1,2 @@
+1
+1
diff --git a/test/565-checker-irreducible-loop/info.txt b/test/565-checker-irreducible-loop/info.txt
new file mode 100644
index 0000000000..1e0dd02284
--- /dev/null
+++ b/test/565-checker-irreducible-loop/info.txt
@@ -0,0 +1,2 @@
+Regression test for optimizing in the presence of
+an irreducible loop.
diff --git a/test/565-checker-irreducible-loop/smali/IrreducibleLoop.smali b/test/565-checker-irreducible-loop/smali/IrreducibleLoop.smali
new file mode 100644
index 0000000000..29547ca85e
--- /dev/null
+++ b/test/565-checker-irreducible-loop/smali/IrreducibleLoop.smali
@@ -0,0 +1,101 @@
+# Copyright (C) 2016 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.
+
+.class public LIrreducibleLoop;
+
+.super Ljava/lang/Object;
+
+# Check that both the irreducible loop and the other loop entry
+# move the constant-folded value to where it's expected.
+
+## CHECK-START-X86: int IrreducibleLoop.test1(int, long) register (after)
+## CHECK-DAG: ParallelMove {{.*84->.*}} loop:none
+## CHECK-DAG: ParallelMove {{.*84->.*}} loop:{{B\d+}} irreducible:true
+.method public static test1(IJ)I
+ .registers 10
+ const/16 v6, 2
+ const/16 v4, 1
+ const-wide/16 v0, 42
+ add-long v2, v0, v0
+
+ if-eqz p0, :loop_entry
+ goto :other_loop_pre_entry
+
+ # The then part: beginning of the irreducible loop.
+ :loop_entry
+ if-eqz p0, :exit
+ cmp-long v6, v2, p1
+ :other_loop_entry
+ sub-int p0, p0, v4
+ goto :loop_entry
+
+ # The other block branching to the irreducible loop.
+ # In that block, v4 has no live range.
+ :other_loop_pre_entry
+ goto :other_loop_entry
+
+ :exit
+ return v6
+.end method
+
+# Check that the compiler does not crash when
+# a live interval is found while connecting siblings, but that
+# live interval is inactive at the desired position.
+
+## CHECK-START-X86: int IrreducibleLoop.test2(int, long) register (after)
+## CHECK-DAG: ParallelMove {{.*84->.*}} loop:none
+## CHECK-DAG: ParallelMove {{.*84->.*}} loop:{{B\d+}} irreducible:true
+.method public static test2(IJ)I
+ .registers 14
+ const/16 v6, 2
+ const/16 v4, 1
+ const-wide/16 v0, 42
+ const-wide/16 v8, 68
+ add-long v2, v0, v0
+
+ if-eqz p0, :loop_entry
+ goto :other_loop_pre_entry
+
+ # The then part: beginning of the irreducible loop.
+ :loop_entry
+ if-eqz p0, :exit
+ cmp-long v6, v2, p1
+ :other_loop_entry
+ sub-int p0, p0, v4
+ goto :loop_entry
+
+ # The other block branching to the irreducible loop.
+ :other_loop_pre_entry
+ # Make v2 have a register location.
+ sput-wide v2, LIrreducibleLoop;->myField:J
+ # Stress register allocator on x86 to split v2.
+ sput-wide v0, LIrreducibleLoop;->myField:J
+ sput-wide p1, LIrreducibleLoop;->myField:J
+ sput-wide v8, LIrreducibleLoop;->myField:J
+ if-eqz p0, :join
+ # Stress register allocator on x86 to split v2.
+ sput-wide p1, LIrreducibleLoop;->myField:J
+ sput-wide v8, LIrreducibleLoop;->myField:J
+ sput-wide v0, LIrreducibleLoop;->myField:J
+ # Last use of v2 before the irreducible loop, that
+ # will create an interval hole.
+ sput-wide v2, LIrreducibleLoop;->myField:J
+ :join
+ goto :other_loop_entry
+
+ :exit
+ return v6
+.end method
+
+.field public static volatile myField:J
diff --git a/test/565-checker-irreducible-loop/src/Main.java b/test/565-checker-irreducible-loop/src/Main.java
new file mode 100644
index 0000000000..e48bd6b411
--- /dev/null
+++ b/test/565-checker-irreducible-loop/src/Main.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2016 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 java.lang.reflect.Method;
+
+public class Main {
+ // Workaround for b/18051191.
+ class InnerClass {}
+
+ public static void main(String[] args) throws Exception {
+ Class<?> c = Class.forName("IrreducibleLoop");
+ {
+ Method m = c.getMethod("test1", int.class, long.class);
+ Object[] arguments = { 42, 31L };
+ System.out.println(m.invoke(null, arguments));
+ }
+
+ {
+ Method m = c.getMethod("test2", int.class, long.class);
+ Object[] arguments = { 42, 31L };
+ System.out.println(m.invoke(null, arguments));
+ }
+ }
+}
diff --git a/test/565-checker-rotate/expected.txt b/test/565-checker-rotate/expected.txt
new file mode 100644
index 0000000000..b0aad4deb5
--- /dev/null
+++ b/test/565-checker-rotate/expected.txt
@@ -0,0 +1 @@
+passed
diff --git a/test/565-checker-rotate/info.txt b/test/565-checker-rotate/info.txt
new file mode 100644
index 0000000000..c6a8091d6c
--- /dev/null
+++ b/test/565-checker-rotate/info.txt
@@ -0,0 +1 @@
+Unit test for 32-bit and 64-bit rotate operations.
diff --git a/test/565-checker-rotate/src/Main.java b/test/565-checker-rotate/src/Main.java
new file mode 100644
index 0000000000..33bbe0255a
--- /dev/null
+++ b/test/565-checker-rotate/src/Main.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+public class Main {
+
+ /// CHECK-START: int Main.rotateLeft32(int, int) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerRotateLeft
+ /// CHECK-DAG: Return [<<Result>>]
+ private static int rotateLeft32(int x, int y) {
+ return Integer.rotateLeft(x, y);
+ }
+
+ /// CHECK-START: long Main.rotateLeft64(long, int) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Result:j\d+>> InvokeStaticOrDirect intrinsic:LongRotateLeft
+ /// CHECK-DAG: Return [<<Result>>]
+ private static long rotateLeft64(long x, int y) {
+ return Long.rotateLeft(x, y);
+ }
+
+ /// CHECK-START: int Main.rotateRight32(int, int) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerRotateRight
+ /// CHECK-DAG: Return [<<Result>>]
+ private static int rotateRight32(int x, int y) {
+ return Integer.rotateRight(x, y);
+ }
+
+ /// CHECK-START: long Main.rotateRight64(long, int) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Result:j\d+>> InvokeStaticOrDirect intrinsic:LongRotateRight
+ /// CHECK-DAG: Return [<<Result>>]
+ private static long rotateRight64(long x, int y) {
+ return Long.rotateRight(x, y);
+ }
+
+ public static void main(String args[]) {
+ expectEquals32(0x00000001, rotateLeft32(0x00000001, 0));
+ expectEquals32(0x00000002, rotateLeft32(0x00000001, 1));
+ expectEquals32(0x80000000, rotateLeft32(0x00000001, 31));
+ expectEquals32(0x00000001, rotateLeft32(0x00000001, 32)); // overshoot
+ expectEquals32(0x00000003, rotateLeft32(0x80000001, 1));
+ expectEquals32(0x00000006, rotateLeft32(0x80000001, 2));
+ expectEquals32(0x23456781, rotateLeft32(0x12345678, 4));
+ expectEquals32(0xBCDEF09A, rotateLeft32(0x9ABCDEF0, 8));
+ for (int i = 0; i < 40; i++) { // overshoot a bit
+ int j = i & 31;
+ expectEquals32(0x00000000, rotateLeft32(0x00000000, i));
+ expectEquals32(0xFFFFFFFF, rotateLeft32(0xFFFFFFFF, i));
+ expectEquals32(1 << j, rotateLeft32(0x00000001, i));
+ expectEquals32((0x12345678 << j) | (0x12345678 >>> -j),
+ rotateLeft32(0x12345678, i));
+ }
+
+ expectEquals64(0x0000000000000001L, rotateLeft64(0x0000000000000001L, 0));
+ expectEquals64(0x0000000000000002L, rotateLeft64(0x0000000000000001L, 1));
+ expectEquals64(0x8000000000000000L, rotateLeft64(0x0000000000000001L, 63));
+ expectEquals64(0x0000000000000001L, rotateLeft64(0x0000000000000001L, 64)); // overshoot
+ expectEquals64(0x0000000000000003L, rotateLeft64(0x8000000000000001L, 1));
+ expectEquals64(0x0000000000000006L, rotateLeft64(0x8000000000000001L, 2));
+ expectEquals64(0x23456789ABCDEF01L, rotateLeft64(0x123456789ABCDEF0L, 4));
+ expectEquals64(0x3456789ABCDEF012L, rotateLeft64(0x123456789ABCDEF0L, 8));
+ for (int i = 0; i < 70; i++) { // overshoot a bit
+ int j = i & 63;
+ expectEquals64(0x0000000000000000L, rotateLeft64(0x0000000000000000L, i));
+ expectEquals64(0xFFFFFFFFFFFFFFFFL, rotateLeft64(0xFFFFFFFFFFFFFFFFL, i));
+ expectEquals64(1L << j, rotateLeft64(0x0000000000000001, i));
+ expectEquals64((0x123456789ABCDEF0L << j) | (0x123456789ABCDEF0L >>> -j),
+ rotateLeft64(0x123456789ABCDEF0L, i));
+ }
+
+ expectEquals32(0x80000000, rotateRight32(0x80000000, 0));
+ expectEquals32(0x40000000, rotateRight32(0x80000000, 1));
+ expectEquals32(0x00000001, rotateRight32(0x80000000, 31));
+ expectEquals32(0x80000000, rotateRight32(0x80000000, 32)); // overshoot
+ expectEquals32(0xC0000000, rotateRight32(0x80000001, 1));
+ expectEquals32(0x60000000, rotateRight32(0x80000001, 2));
+ expectEquals32(0x81234567, rotateRight32(0x12345678, 4));
+ expectEquals32(0xF09ABCDE, rotateRight32(0x9ABCDEF0, 8));
+ for (int i = 0; i < 40; i++) { // overshoot a bit
+ int j = i & 31;
+ expectEquals32(0x00000000, rotateRight32(0x00000000, i));
+ expectEquals32(0xFFFFFFFF, rotateRight32(0xFFFFFFFF, i));
+ expectEquals32(0x80000000 >>> j, rotateRight32(0x80000000, i));
+ expectEquals32((0x12345678 >>> j) | (0x12345678 << -j),
+ rotateRight32(0x12345678, i));
+ }
+
+ expectEquals64(0x8000000000000000L, rotateRight64(0x8000000000000000L, 0));
+ expectEquals64(0x4000000000000000L, rotateRight64(0x8000000000000000L, 1));
+ expectEquals64(0x0000000000000001L, rotateRight64(0x8000000000000000L, 63));
+ expectEquals64(0x8000000000000000L, rotateRight64(0x8000000000000000L, 64)); // overshoot
+ expectEquals64(0xC000000000000000L, rotateRight64(0x8000000000000001L, 1));
+ expectEquals64(0x6000000000000000L, rotateRight64(0x8000000000000001L, 2));
+ expectEquals64(0x0123456789ABCDEFL, rotateRight64(0x123456789ABCDEF0L, 4));
+ expectEquals64(0xF0123456789ABCDEL, rotateRight64(0x123456789ABCDEF0L, 8));
+ for (int i = 0; i < 70; i++) { // overshoot a bit
+ int j = i & 63;
+ expectEquals64(0x0000000000000000L, rotateRight64(0x0000000000000000L, i));
+ expectEquals64(0xFFFFFFFFFFFFFFFFL, rotateRight64(0xFFFFFFFFFFFFFFFFL, i));
+ expectEquals64(0x8000000000000000L >>> j, rotateRight64(0x8000000000000000L, i));
+ expectEquals64((0x123456789ABCDEF0L >>> j) | (0x123456789ABCDEF0L << -j),
+ rotateRight64(0x123456789ABCDEF0L, i));
+ }
+
+ System.out.println("passed");
+ }
+
+ private static void expectEquals32(int expected, int result) {
+ if (expected != result) {
+ throw new Error("Expected: " + expected + ", found: " + result);
+ }
+ }
+ private static void expectEquals64(long expected, long result) {
+ if (expected != result) {
+ throw new Error("Expected: " + expected + ", found: " + result);
+ }
+ }
+}
diff --git a/test/566-checker-signum/expected.txt b/test/566-checker-signum/expected.txt
new file mode 100644
index 0000000000..b0aad4deb5
--- /dev/null
+++ b/test/566-checker-signum/expected.txt
@@ -0,0 +1 @@
+passed
diff --git a/test/566-checker-signum/info.txt b/test/566-checker-signum/info.txt
new file mode 100644
index 0000000000..328e494291
--- /dev/null
+++ b/test/566-checker-signum/info.txt
@@ -0,0 +1 @@
+Unit test for 32-bit and 64-bit signum operations.
diff --git a/test/566-checker-signum/src/Main.java b/test/566-checker-signum/src/Main.java
new file mode 100644
index 0000000000..cc4a98469c
--- /dev/null
+++ b/test/566-checker-signum/src/Main.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+public class Main {
+
+ /// CHECK-START: int Main.sign32(int) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerSignum
+ /// CHECK-DAG: Return [<<Result>>]
+ private static int sign32(int x) {
+ return Integer.signum(x);
+ }
+
+ /// CHECK-START: int Main.sign64(long) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:LongSignum
+ /// CHECK-DAG: Return [<<Result>>]
+ private static int sign64(long x) {
+ return Long.signum(x);
+ }
+
+ public static void main(String args[]) {
+ expectEquals(-1, sign32(Integer.MIN_VALUE));
+ expectEquals(-1, sign32(-12345));
+ expectEquals(-1, sign32(-1));
+ expectEquals(0, sign32(0));
+ expectEquals(1, sign32(1));
+ expectEquals(1, sign32(12345));
+ expectEquals(1, sign32(Integer.MAX_VALUE));
+
+ for (int i = -11; i <= 11; i++) {
+ int expected = 0;
+ if (i < 0) expected = -1;
+ else if (i > 0) expected = 1;
+ expectEquals(expected, sign32(i));
+ }
+
+ expectEquals(-1, sign64(Long.MIN_VALUE));
+ expectEquals(-1, sign64(-12345L));
+ expectEquals(-1, sign64(-1L));
+ expectEquals(0, sign64(0L));
+ expectEquals(1, sign64(1L));
+ expectEquals(1, sign64(12345L));
+ expectEquals(1, sign64(Long.MAX_VALUE));
+
+ for (long i = -11L; i <= 11L; i++) {
+ int expected = 0;
+ if (i < 0) expected = -1;
+ else if (i > 0) expected = 1;
+ expectEquals(expected, sign64(i));
+ }
+
+ System.out.println("passed");
+ }
+
+ private static void expectEquals(int expected, int result) {
+ if (expected != result) {
+ throw new Error("Expected: " + expected + ", found: " + result);
+ }
+ }
+}
diff --git a/test/567-checker-compare/expected.txt b/test/567-checker-compare/expected.txt
new file mode 100644
index 0000000000..b0aad4deb5
--- /dev/null
+++ b/test/567-checker-compare/expected.txt
@@ -0,0 +1 @@
+passed
diff --git a/test/567-checker-compare/info.txt b/test/567-checker-compare/info.txt
new file mode 100644
index 0000000000..5bac7b1165
--- /dev/null
+++ b/test/567-checker-compare/info.txt
@@ -0,0 +1 @@
+Unit test for 32-bit and 64-bit compare operations.
diff --git a/test/567-checker-compare/src/Main.java b/test/567-checker-compare/src/Main.java
new file mode 100644
index 0000000000..52abb75e89
--- /dev/null
+++ b/test/567-checker-compare/src/Main.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+public class Main {
+
+ /// CHECK-START: int Main.compare32(int, int) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare
+ /// CHECK-DAG: Return [<<Result>>]
+ private static int compare32(int x, int y) {
+ return Integer.compare(x, y);
+ }
+
+ /// CHECK-START: int Main.compare64(long, long) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:LongCompare
+ /// CHECK-DAG: Return [<<Result>>]
+ private static int compare64(long x, long y) {
+ return Long.compare(x, y);
+ }
+
+ public static void main(String args[]) {
+ expectEquals(-1, compare32(Integer.MIN_VALUE, Integer.MIN_VALUE + 1));
+ expectEquals(-1, compare32(Integer.MIN_VALUE, -1));
+ expectEquals(-1, compare32(Integer.MIN_VALUE, 0));
+ expectEquals(-1, compare32(Integer.MIN_VALUE, 1));
+ expectEquals(-1, compare32(Integer.MIN_VALUE, Integer.MAX_VALUE));
+ expectEquals(-1, compare32(-1, 0));
+ expectEquals(-1, compare32(-1, 1));
+ expectEquals(-1, compare32(0, 1));
+
+ expectEquals(0, compare32(Integer.MIN_VALUE, Integer.MIN_VALUE));
+ expectEquals(0, compare32(-1, -1));
+ expectEquals(0, compare32(0, 0));
+ expectEquals(0, compare32(1, 1));
+ expectEquals(0, compare32(Integer.MAX_VALUE, Integer.MAX_VALUE));
+
+ expectEquals(1, compare32(0, -1));
+ expectEquals(1, compare32(1, -1));
+ expectEquals(1, compare32(1, 0));
+ expectEquals(1, compare32(Integer.MAX_VALUE, Integer.MIN_VALUE));
+ expectEquals(1, compare32(Integer.MAX_VALUE, -1));
+ expectEquals(1, compare32(Integer.MAX_VALUE, 0));
+ expectEquals(1, compare32(Integer.MAX_VALUE, 1));
+ expectEquals(1, compare32(Integer.MAX_VALUE, Integer.MAX_VALUE - 1));
+
+ for (int i = -11; i <= 11; i++) {
+ for (int j = -11; j <= 11; j++) {
+ int expected = 0;
+ if (i < j) expected = -1;
+ else if (i > j) expected = 1;
+ expectEquals(expected, compare32(i, j));
+ }
+ }
+
+ expectEquals(-1, compare64(Long.MIN_VALUE, Long.MIN_VALUE + 1L));
+ expectEquals(-1, compare64(Long.MIN_VALUE, -1L));
+ expectEquals(-1, compare64(Long.MIN_VALUE, 0L));
+ expectEquals(-1, compare64(Long.MIN_VALUE, 1L));
+ expectEquals(-1, compare64(Long.MIN_VALUE, Long.MAX_VALUE));
+ expectEquals(-1, compare64(-1L, 0L));
+ expectEquals(-1, compare64(-1L, 1L));
+ expectEquals(-1, compare64(0L, 1L));
+
+ expectEquals(0, compare64(Long.MIN_VALUE, Long.MIN_VALUE));
+ expectEquals(0, compare64(-1L, -1L));
+ expectEquals(0, compare64(0L, 0L));
+ expectEquals(0, compare64(1L, 1L));
+ expectEquals(0, compare64(Long.MAX_VALUE, Long.MAX_VALUE));
+
+ expectEquals(1, compare64(0L, -1L));
+ expectEquals(1, compare64(1L, -1L));
+ expectEquals(1, compare64(1L, 0L));
+ expectEquals(1, compare64(Long.MAX_VALUE, Long.MIN_VALUE));
+ expectEquals(1, compare64(Long.MAX_VALUE, -1L));
+ expectEquals(1, compare64(Long.MAX_VALUE, 0L));
+ expectEquals(1, compare64(Long.MAX_VALUE, 1L));
+ expectEquals(1, compare64(Long.MAX_VALUE, Long.MAX_VALUE - 1L));
+
+ for (long i = -11L; i <= 11L; i++) {
+ for (long j = -11L; j <= 11L; j++) {
+ int expected = 0;
+ if (i < j) expected = -1;
+ else if (i > j) expected = 1;
+ expectEquals(expected, compare64(i, j));
+ }
+ }
+
+ System.out.println("passed");
+ }
+
+ private static void expectEquals(int expected, int result) {
+ if (expected != result) {
+ throw new Error("Expected: " + expected + ", found: " + result);
+ }
+ }
+}
diff --git a/test/568-checker-onebit/expected.txt b/test/568-checker-onebit/expected.txt
new file mode 100644
index 0000000000..b0aad4deb5
--- /dev/null
+++ b/test/568-checker-onebit/expected.txt
@@ -0,0 +1 @@
+passed
diff --git a/test/568-checker-onebit/info.txt b/test/568-checker-onebit/info.txt
new file mode 100644
index 0000000000..c2b5bf8688
--- /dev/null
+++ b/test/568-checker-onebit/info.txt
@@ -0,0 +1 @@
+Unit test for 32-bit and 64-bit high/low-bit operations.
diff --git a/test/568-checker-onebit/src/Main.java b/test/568-checker-onebit/src/Main.java
new file mode 100644
index 0000000000..7007c6a507
--- /dev/null
+++ b/test/568-checker-onebit/src/Main.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+public class Main {
+
+ /// CHECK-START: int Main.hi32(int) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerHighestOneBit
+ /// CHECK-DAG: Return [<<Result>>]
+ private static int hi32(int x) {
+ return Integer.highestOneBit(x);
+ }
+
+ /// CHECK-START: int Main.lo32(int) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerLowestOneBit
+ /// CHECK-DAG: Return [<<Result>>]
+ private static int lo32(int x) {
+ return Integer.lowestOneBit(x);
+ }
+
+ /// CHECK-START: long Main.hi64(long) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Result:j\d+>> InvokeStaticOrDirect intrinsic:LongHighestOneBit
+ /// CHECK-DAG: Return [<<Result>>]
+ private static long hi64(long x) {
+ return Long.highestOneBit(x);
+ }
+
+ /// CHECK-START: long Main.lo64(long) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Result:j\d+>> InvokeStaticOrDirect intrinsic:LongLowestOneBit
+ /// CHECK-DAG: Return [<<Result>>]
+ private static long lo64(long x) {
+ return Long.lowestOneBit(x);
+ }
+
+ public static void main(String args[]) {
+ expectEquals32(0x00000000, hi32(0x00000000));
+ expectEquals32(0x00000000, lo32(0x00000000));
+ expectEquals32(0x00010000, hi32(0x00010000));
+ expectEquals32(0x00010000, lo32(0x00010000));
+ expectEquals32(0x00800000, hi32(0x00FF0000));
+ expectEquals32(0x00010000, lo32(0x00FF0000));
+ expectEquals32(0x80000000, hi32(0xFFFFFFFF));
+ expectEquals32(0x00000001, lo32(0xFFFFFFFF));
+
+ for (int i = 0; i < 32; i++) {
+ expectEquals32(1 << i, hi32(1 << i));
+ expectEquals32(1 << i, lo32(1 << i));
+ int expected = i < 29 ? 0x8 << i : 0x80000000;
+ expectEquals32(expected, hi32(0xF << i));
+ expectEquals32(0x1 << i, lo32(0xF << i));
+ }
+
+ expectEquals64(0x0000000000000000L, hi64(0x0000000000000000L));
+ expectEquals64(0x0000000000000000L, lo64(0x0000000000000000L));
+ expectEquals64(0x0000000100000000L, hi64(0x0000000100000000L));
+ expectEquals64(0x0000000100000000L, lo64(0x0000000100000000L));
+ expectEquals64(0x0000008000000000L, hi64(0x000000FF00000000L));
+ expectEquals64(0x0000000100000000L, lo64(0x000000FF00000000L));
+ expectEquals64(0x8000000000000000L, hi64(0xFFFFFFFFFFFFFFFFL));
+ expectEquals64(0x0000000000000001L, lo64(0xFFFFFFFFFFFFFFFFL));
+
+ for (int i = 0; i < 64; i++) {
+ expectEquals64(1L << i, hi64(1L << i));
+ expectEquals64(1L << i, lo64(1L << i));
+ long expected = i < 61 ? 0x8L << i : 0x8000000000000000L;
+ expectEquals64(expected, hi64(0xFL << i));
+ expectEquals64(0x1L << i, lo64(0xFL << i));
+ }
+
+ System.out.println("passed");
+ }
+
+ private static void expectEquals32(int expected, int result) {
+ if (expected != result) {
+ throw new Error("Expected: " + expected + ", found: " + result);
+ }
+ }
+ private static void expectEquals64(long expected, long result) {
+ if (expected != result) {
+ throw new Error("Expected: " + expected + ", found: " + result);
+ }
+ }
+}
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index 429af6a9e3..d6c29837b7 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -526,11 +526,7 @@ endif
TEST_ART_BROKEN_OPTIMIZING_DEBUGGABLE_RUN_TESTS :=
# Tests that should fail in the read barrier configuration with the interpreter.
-# 004: Occasional timeout: "TEST TIMED OUT!" (b/26786154).
-# 141: Occasional failures: "Aborted" (b/25866001).
-TEST_ART_BROKEN_INTERPRETER_READ_BARRIER_RUN_TESTS := \
- 004-ThreadStress \
- 141-class-unload
+TEST_ART_BROKEN_INTERPRETER_READ_BARRIER_RUN_TESTS :=
# Tests that should fail in the read barrier configuration with the default (Quick) compiler (AOT).
# Quick has no support for read barriers and punts to the interpreter, so this list is composed of
@@ -540,7 +536,6 @@ TEST_ART_BROKEN_DEFAULT_READ_BARRIER_RUN_TESTS := \
$(TEST_ART_BROKEN_INTERPRETER_RUN_TESTS)
# Tests that should fail in the read barrier configuration with the Optimizing compiler (AOT).
-# 004: Occasional timeout: "TEST TIMED OUT!" (b/26786154).
# 484: Baker's fast path based read barrier compiler instrumentation generates code containing
# more parallel moves on x86, thus some Checker assertions may fail.
# 527: On ARM64, the read barrier instrumentation does not support the HArm64IntermediateAddress
@@ -548,18 +543,13 @@ TEST_ART_BROKEN_DEFAULT_READ_BARRIER_RUN_TESTS := \
# 537: Expects an array copy to be intrinsified on x86-64, but calling-on-slowpath intrinsics are
# not yet handled in the read barrier configuration.
TEST_ART_BROKEN_OPTIMIZING_READ_BARRIER_RUN_TESTS := \
- 004-ThreadStress \
484-checker-register-hints \
527-checker-array-access-split \
537-checker-arraycopy
# Tests that should fail in the read barrier configuration with JIT.
-# 004: Occasional timeout: "TEST TIMED OUT!" (b/26786154).
-# 141: Disabled because of intermittent failures on the ART Builtbot (b/25866001).
# 496: Occasional timeout: "Fault message: timeout: the monitored command dumped core" (b/26786304).
TEST_ART_BROKEN_JIT_READ_BARRIER_RUN_TESTS := \
- 004-ThreadStress \
- 141-class-unload \
496-checker-inlining-and-class-loader
ifeq ($(ART_USE_READ_BARRIER),true)
diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar
index e004b6cff4..8245ccfde5 100755
--- a/test/etc/run-test-jar
+++ b/test/etc/run-test-jar
@@ -74,6 +74,14 @@ while true; do
fi
ARGS="${ARGS} $1"
shift
+ elif [ "x$1" = "x--args" ]; then
+ shift
+ if [ "x$1" = "x" ]; then
+ echo "$0 missing argument to --args" 1>&2
+ exit 1
+ fi
+ ARGS="${ARGS} $1"
+ shift
elif [ "x$1" = "x-Xcompiler-option" ]; then
shift
option="$1"
@@ -533,6 +541,7 @@ else
cd $ANDROID_BUILD_TOP
+ rm -rf ${DEX_LOCATION}/dalvik-cache/
$mkdir_cmdline || exit 1
$dex2oat_cmdline || { echo "Dex2oat failed." >&2 ; exit 2; }