summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/003-omnibus-opcodes/build4
-rw-r--r--test/004-JniTest/expected.txt27
-rw-r--r--test/004-JniTest/jni_test.cc82
-rw-r--r--test/004-JniTest/smali/AbstractInterface.smali26
-rw-r--r--test/004-JniTest/smali/ConcreteClass.smali72
-rw-r--r--test/004-JniTest/smali/ConflictInterface.smali35
-rw-r--r--test/004-JniTest/smali/DefaultInterface.smali77
-rw-r--r--test/004-JniTest/src/Main.java35
-rw-r--r--test/005-annotations/build4
-rw-r--r--test/022-interface/build4
-rw-r--r--test/082-inline-execute/src/Main.java2
-rw-r--r--test/085-old-style-inner-class/build4
-rwxr-xr-xtest/091-override-package-private-method/build10
-rw-r--r--test/097-duplicate-method/build4
-rw-r--r--test/111-unresolvable-exception/build4
-rw-r--r--test/113-multidex/build10
-rw-r--r--test/121-modifiers/build4
-rw-r--r--test/124-missing-classes/build4
-rw-r--r--test/126-miranda-multidex/build10
-rwxr-xr-xtest/127-checker-secondarydex/build10
-rw-r--r--test/130-hprof/src-ex/Allocator.java22
-rw-r--r--test/130-hprof/src/Main.java67
-rw-r--r--test/442-checker-constant-folding/smali/TestCmp.smali332
-rw-r--r--test/442-checker-constant-folding/src/Main.java353
-rw-r--r--test/449-checker-bce/src/Main.java36
-rw-r--r--test/529-checker-unresolved/build10
-rw-r--r--test/566-checker-codegen-select/src/Main.java7
-rw-r--r--test/570-checker-osr/osr.cc9
-rwxr-xr-xtest/570-checker-osr/run18
-rw-r--r--test/570-checker-osr/src/Main.java34
-rw-r--r--test/570-checker-select/src/Main.java58
-rw-r--r--test/574-irreducible-and-constant-area/expected.txt0
-rw-r--r--test/574-irreducible-and-constant-area/info.txt3
-rwxr-xr-xtest/574-irreducible-and-constant-area/run18
-rw-r--r--test/574-irreducible-and-constant-area/smali/IrreducibleLoop.smali35
-rw-r--r--test/574-irreducible-and-constant-area/src/Main.java41
-rw-r--r--test/575-checker-isnan/expected.txt1
-rw-r--r--test/575-checker-isnan/info.txt1
-rw-r--r--test/575-checker-isnan/src/Main.java126
-rw-r--r--test/575-checker-string-init-alias/expected.txt1
-rw-r--r--test/575-checker-string-init-alias/info.txt2
-rw-r--r--test/575-checker-string-init-alias/smali/TestCase.smali72
-rw-r--r--test/575-checker-string-init-alias/src/Main.java68
-rw-r--r--test/576-polymorphic-inlining/expected.txt0
-rw-r--r--test/576-polymorphic-inlining/info.txt1
-rw-r--r--test/576-polymorphic-inlining/src/Main.java103
-rw-r--r--test/Android.run-test.mk7
-rwxr-xr-xtest/run-test6
48 files changed, 1774 insertions, 85 deletions
diff --git a/test/003-omnibus-opcodes/build b/test/003-omnibus-opcodes/build
index faa298337c..56e87844c0 100644
--- a/test/003-omnibus-opcodes/build
+++ b/test/003-omnibus-opcodes/build
@@ -23,8 +23,8 @@ rm classes/UnresClass.class
${JAVAC} -d classes `find src2 -name '*.java'`
if [ ${USE_JACK} = "true" ]; then
- ${JILL} classes --output classes.jack
- ${JACK} --import classes.jack --output-dex .
+ jar cf classes.jill.jar -C classes .
+ ${JACK} --import classes.jill.jar --output-dex .
else
${DX} -JXmx256m --debug --dex --output=classes.dex classes
fi
diff --git a/test/004-JniTest/expected.txt b/test/004-JniTest/expected.txt
index 86ab37e1e5..155c6ae5f3 100644
--- a/test/004-JniTest/expected.txt
+++ b/test/004-JniTest/expected.txt
@@ -28,3 +28,30 @@ Subclass.<init>
RUNNING sub object, sub class, sub nonstatic
Subclass.nonstaticMethod
PASSED sub object, sub class, sub nonstatic
+Calling method ConcreteClass->JniCallNonOverridenDefaultMethod on object of type ConcreteClass
+DefaultInterface.JniCallNonOverridenDefaultMethod
+Calling method ConcreteClass->JniCallOverridenDefaultMethod on object of type ConcreteClass
+ConcreteClass.JniCallOverridenDefaultMethod
+Calling method ConcreteClass->JniCallOverridenDefaultMethodWithSuper on object of type ConcreteClass
+ConcreteClass.JniCallOverridenDefaultMethodWithSuper
+DefaultInterface.JniCallOverridenDefaultMethod
+Calling method ConcreteClass->JniCallOverridenAbstractMethod on object of type ConcreteClass
+ConcreteClass.JniCallOverridenAbstractMethod
+Calling method ConcreteClass->JniCallConflictDefaultMethod on object of type ConcreteClass
+EXCEPTION OCCURED: java.lang.IncompatibleClassChangeError: Conflicting default method implementations void ConflictInterface.JniCallConflictDefaultMethod()
+Calling method ConcreteClass->JniCallSoftConflictMethod on object of type ConcreteClass
+DefaultInterface.JniCallSoftConflictMethod
+Calling method DefaultInterface->JniCallNonOverridenDefaultMethod on object of type ConcreteClass
+DefaultInterface.JniCallNonOverridenDefaultMethod
+Calling method DefaultInterface->JniCallOverridenDefaultMethod on object of type ConcreteClass
+ConcreteClass.JniCallOverridenDefaultMethod
+Calling method DefaultInterface->JniCallOverridenAbstractMethod on object of type ConcreteClass
+ConcreteClass.JniCallOverridenAbstractMethod
+Calling method DefaultInterface->JniCallConflictDefaultMethod on object of type ConcreteClass
+EXCEPTION OCCURED: java.lang.IncompatibleClassChangeError: Conflicting default method implementations void ConflictInterface.JniCallConflictDefaultMethod()
+Calling method DefaultInterface->JniCallSoftConflictMethod on object of type ConcreteClass
+DefaultInterface.JniCallSoftConflictMethod
+Calling method AbstractInterface->JniCallSoftConflictMethod on object of type ConcreteClass
+DefaultInterface.JniCallSoftConflictMethod
+Calling method ConflictInterface->JniCallConflictDefaultMethod on object of type ConcreteClass
+EXCEPTION OCCURED: java.lang.IncompatibleClassChangeError: Conflicting default method implementations void ConflictInterface.JniCallConflictDefaultMethod()
diff --git a/test/004-JniTest/jni_test.cc b/test/004-JniTest/jni_test.cc
index be7888b04a..f632331fe3 100644
--- a/test/004-JniTest/jni_test.cc
+++ b/test/004-JniTest/jni_test.cc
@@ -639,3 +639,85 @@ extern "C" JNIEXPORT void JNICALL Java_Main_testNewStringObject(JNIEnv* env, jcl
extern "C" JNIEXPORT jlong JNICALL Java_Main_testGetMethodID(JNIEnv* env, jclass, jclass c) {
return reinterpret_cast<jlong>(env->GetMethodID(c, "a", "()V"));
}
+
+extern "C" JNIEXPORT void JNICALL Java_Main_enterJniCriticalSection(JNIEnv* env, jclass,
+ jint arraySize,
+ jbyteArray array0,
+ jbyteArray array1) {
+ for (int i = 0; i < 50000; ++i) {
+ char* data0 = reinterpret_cast<char*>(env->GetPrimitiveArrayCritical(array0, nullptr));
+ char* data1 = reinterpret_cast<char*>(env->GetPrimitiveArrayCritical(array1, nullptr));
+ bool up = i % 2 == 0;
+ for (int j = 0; j < arraySize; ++j) {
+ if (up) {
+ data1[j] = data0[j] + 1;
+ } else {
+ data0[j] = data1[j] + 1;
+ }
+ }
+ env->ReleasePrimitiveArrayCritical(array1, data1, 0);
+ env->ReleasePrimitiveArrayCritical(array0, data0, 0);
+ }
+}
+
+class JniCallDefaultMethodsTest {
+ public:
+ explicit JniCallDefaultMethodsTest(JNIEnv* env)
+ : env_(env), concrete_class_(env_->FindClass("ConcreteClass")) {
+ assert(!env_->ExceptionCheck());
+ assert(concrete_class_ != nullptr);
+ }
+
+ void Test() {
+ TestCalls("ConcreteClass", { "JniCallNonOverridenDefaultMethod",
+ "JniCallOverridenDefaultMethod",
+ "JniCallOverridenDefaultMethodWithSuper",
+ "JniCallOverridenAbstractMethod",
+ "JniCallConflictDefaultMethod",
+ "JniCallSoftConflictMethod" });
+ TestCalls("DefaultInterface", { "JniCallNonOverridenDefaultMethod",
+ "JniCallOverridenDefaultMethod",
+ "JniCallOverridenAbstractMethod",
+ "JniCallConflictDefaultMethod",
+ "JniCallSoftConflictMethod" });
+ TestCalls("AbstractInterface", { "JniCallSoftConflictMethod" });
+ TestCalls("ConflictInterface", { "JniCallConflictDefaultMethod" });
+ }
+
+ private:
+ void TestCalls(const char* declaring_class, std::vector<const char*> methods) {
+ jmethodID new_method = env_->GetMethodID(concrete_class_, "<init>", "()V");
+ jobject obj = env_->NewObject(concrete_class_, new_method);
+ assert(!env_->ExceptionCheck());
+ assert(obj != nullptr);
+ jclass decl_class = env_->FindClass(declaring_class);
+ assert(!env_->ExceptionCheck());
+ assert(decl_class != nullptr);
+ for (const char* method : methods) {
+ jmethodID method_id = env_->GetMethodID(decl_class, method, "()V");
+ assert(!env_->ExceptionCheck());
+ printf("Calling method %s->%s on object of type ConcreteClass\n", declaring_class, method);
+ env_->CallVoidMethod(obj, method_id);
+ if (env_->ExceptionCheck()) {
+ jthrowable thrown = env_->ExceptionOccurred();
+ env_->ExceptionClear();
+ jmethodID to_string = env_->GetMethodID(
+ env_->FindClass("java/lang/Object"), "toString", "()Ljava/lang/String;");
+ jstring exception_string = (jstring) env_->CallObjectMethod(thrown, to_string);
+ assert(!env_->ExceptionCheck());
+ const char* exception_string_utf8 = env_->GetStringUTFChars(exception_string, nullptr);
+ assert(!env_->ExceptionCheck());
+ assert(exception_string_utf8 != nullptr);
+ printf("EXCEPTION OCCURED: %s\n", exception_string_utf8);
+ env_->ReleaseStringUTFChars(exception_string, exception_string_utf8);
+ }
+ }
+ }
+
+ JNIEnv* env_;
+ jclass concrete_class_;
+};
+
+extern "C" JNIEXPORT void JNICALL Java_Main_testCallDefaultMethods(JNIEnv* env) {
+ JniCallDefaultMethodsTest(env).Test();
+}
diff --git a/test/004-JniTest/smali/AbstractInterface.smali b/test/004-JniTest/smali/AbstractInterface.smali
new file mode 100644
index 0000000000..52b2fc537e
--- /dev/null
+++ b/test/004-JniTest/smali/AbstractInterface.smali
@@ -0,0 +1,26 @@
+# /*
+# * Copyright 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 interface LAbstractInterface;
+.super Ljava/lang/Object;
+
+# public interface AbstractInterface {
+# public void JniCallSoftConflictMethod();
+# }
+
+.method public abstract JniCallSoftConflictMethod()V
+.end method
+
diff --git a/test/004-JniTest/smali/ConcreteClass.smali b/test/004-JniTest/smali/ConcreteClass.smali
new file mode 100644
index 0000000000..a9c072fc2f
--- /dev/null
+++ b/test/004-JniTest/smali/ConcreteClass.smali
@@ -0,0 +1,72 @@
+# /*
+# * Copyright 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 LConcreteClass;
+.super Ljava/lang/Object;
+.implements LDefaultInterface;
+.implements LConflictInterface;
+.implements LAbstractInterface;
+
+# public class ConcreteClass implements DefaultInterface, ConflictInterface, AbstractInterface {
+# public void JniCallOverridenAbstractMethod() {
+# System.out.println("ConcreteClass.JniCallOverridenAbstractMethod");
+# }
+#
+# public void JniCallOverridenDefaultMethod() {
+# System.out.println("ConcreteClass.JniCallOverridenDefaultMethod");
+# }
+#
+# public void JniCallOverridenDefaultMethodWithSuper() {
+# System.out.println("ConcreteClass.JniCallOverridenDefaultMethodWithSuper");
+# DefaultInterface.super.JniCallOverridenDefaultMethod();
+# }
+# }
+
+.method public constructor <init>()V
+ .registers 1
+ invoke-direct {p0}, Ljava/lang/Object;-><init>()V
+ return-void
+.end method
+
+.method public JniCallOverridenAbstractMethod()V
+ .locals 2
+
+ const-string v0, "ConcreteClass.JniCallOverridenAbstractMethod"
+ sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
+ invoke-virtual {v1,v0}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
+ return-void
+.end method
+
+.method public JniCallOverridenDefaultMethod()V
+ .locals 2
+
+ const-string v0, "ConcreteClass.JniCallOverridenDefaultMethod"
+ sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
+ invoke-virtual {v1,v0}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
+ return-void
+.end method
+
+.method public JniCallOverridenDefaultMethodWithSuper()V
+ .locals 2
+
+ const-string v0, "ConcreteClass.JniCallOverridenDefaultMethodWithSuper"
+ sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
+ invoke-virtual {v1,v0}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
+
+ invoke-super {p0}, LDefaultInterface;->JniCallOverridenDefaultMethod()V
+
+ return-void
+.end method
diff --git a/test/004-JniTest/smali/ConflictInterface.smali b/test/004-JniTest/smali/ConflictInterface.smali
new file mode 100644
index 0000000000..fc3d474df0
--- /dev/null
+++ b/test/004-JniTest/smali/ConflictInterface.smali
@@ -0,0 +1,35 @@
+# /*
+# * Copyright 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 interface LConflictInterface;
+.super Ljava/lang/Object;
+
+# public interface ConflictInterface {
+# public default void JniCallConflictDefaultMethod() {
+# System.out.println("ConflictInterface.JniCallConflictDefaultMethod");
+# }
+#
+# }
+
+.method public JniCallConflictDefaultMethod()V
+ .locals 2
+
+ const-string v0, "ConflictInterface.JniCallConflictDefaultMethod"
+ sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
+ invoke-virtual {v1,v0}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
+ return-void
+.end method
+
diff --git a/test/004-JniTest/smali/DefaultInterface.smali b/test/004-JniTest/smali/DefaultInterface.smali
new file mode 100644
index 0000000000..1ee872154b
--- /dev/null
+++ b/test/004-JniTest/smali/DefaultInterface.smali
@@ -0,0 +1,77 @@
+# /*
+# * Copyright 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 interface LDefaultInterface;
+.super Ljava/lang/Object;
+
+# public interface DefaultInterface {
+# public default void JniCallNonOverridenDefaultMethod() {
+# System.out.println("DefaultInterface.JniCallNonOverridenDefaultMethod");
+# }
+#
+# public default void JniCallOverridenDefaultMethod() {
+# System.out.println("DefaultInterface.JniCallOverridenDefaultMethod");
+# }
+#
+# public void JniCallOverridenAbstractMethod();
+#
+# public default void JniCallConflictDefaultMethod() {
+# System.out.println("DefaultInterface.JniCallConflictDefaultMethod");
+# }
+#
+# public default void JniCallSoftConflictMethod() {
+# System.out.println("DefaultInterface.JniCallSoftConflictMethod");
+# }
+# }
+
+.method public JniCallNonOverridenDefaultMethod()V
+ .locals 2
+
+ const-string v0, "DefaultInterface.JniCallNonOverridenDefaultMethod"
+ sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
+ invoke-virtual {v1,v0}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
+ return-void
+.end method
+
+.method public JniCallOverridenDefaultMethod()V
+ .locals 2
+
+ const-string v0, "DefaultInterface.JniCallOverridenDefaultMethod"
+ sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
+ invoke-virtual {v1,v0}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
+ return-void
+.end method
+
+.method public abstract JniCallOverridenAbstractMethod()V
+.end method
+
+.method public JniCallConflictDefaultMethod()V
+ .locals 2
+
+ const-string v0, "DefaultInterface.JniCallConflictDefaultMethod"
+ sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
+ invoke-virtual {v1,v0}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
+ return-void
+.end method
+
+.method public JniCallSoftConflictMethod()V
+ .locals 2
+
+ const-string v0, "DefaultInterface.JniCallSoftConflictMethod"
+ sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
+ invoke-virtual {v1,v0}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
+ return-void
+.end method
diff --git a/test/004-JniTest/src/Main.java b/test/004-JniTest/src/Main.java
index ee3a3b9830..9f4a8522e7 100644
--- a/test/004-JniTest/src/Main.java
+++ b/test/004-JniTest/src/Main.java
@@ -38,8 +38,12 @@ public class Main {
testNewStringObject();
testRemoveLocalObject();
testProxyGetMethodID();
+ testJniCriticalSectionAndGc();
+ testCallDefaultMethods();
}
+ private static native void testCallDefaultMethods();
+
private static native void testFindClassOnAttachedNativeThread();
private static boolean testFindFieldOnAttachedNativeThreadField;
@@ -120,7 +124,7 @@ public class Main {
private static void testRemoveLocalObject() {
removeLocalObject(new Object());
}
-
+
private static native short shortMethod(short s1, short s2, short s3, short s4, short s5, short s6, short s7,
short s8, short s9, short s10);
@@ -222,6 +226,35 @@ public class Main {
}
private static native long testGetMethodID(Class<?> c);
+
+ // Exercise GC and JNI critical sections in parallel.
+ private static void testJniCriticalSectionAndGc() {
+ Thread runGcThread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ for (int i = 0; i < 10; ++i) {
+ Runtime.getRuntime().gc();
+ }
+ }
+ });
+ Thread jniCriticalThread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ final int arraySize = 32;
+ byte[] array0 = new byte[arraySize];
+ byte[] array1 = new byte[arraySize];
+ enterJniCriticalSection(arraySize, array0, array1);
+ }
+ });
+ jniCriticalThread.start();
+ runGcThread.start();
+ try {
+ jniCriticalThread.join();
+ runGcThread.join();
+ } catch (InterruptedException ignored) {}
+ }
+
+ private static native void enterJniCriticalSection(int arraySize, byte[] array0, byte[] array);
}
class JniCallNonvirtualTest {
diff --git a/test/005-annotations/build b/test/005-annotations/build
index 057b351dab..93bee507df 100644
--- a/test/005-annotations/build
+++ b/test/005-annotations/build
@@ -29,8 +29,8 @@ rm 'classes/android/test/anno/MissingAnnotation.class'
rm 'classes/android/test/anno/ClassWithInnerAnnotationClass$MissingInnerAnnotationClass.class'
if [ ${USE_JACK} = "true" ]; then
- ${JILL} classes --output classes.jack
- ${JACK} --import classes.jack --output-dex .
+ jar cf classes.jill.jar -C classes .
+ ${JACK} --import classes.jill.jar --output-dex .
else
${DX} -JXmx256m --debug --dex --output=classes.dex classes
fi
diff --git a/test/022-interface/build b/test/022-interface/build
index 3f8915c27e..5cfc7f25b7 100644
--- a/test/022-interface/build
+++ b/test/022-interface/build
@@ -20,8 +20,8 @@ set -e
# Use classes that are compiled with ecj that exposes an invokeinterface
# issue when interfaces override methods in Object
if [ ${USE_JACK} = "true" ]; then
- ${JILL} classes --output classes.jack
- ${JACK} --import classes.jack --output-dex .
+ jar cf classes.jill.jar -C classes .
+ ${JACK} --import classes.jill.jar --output-dex .
else
${DX} --debug --dex --dump-to=classes.lst --output=classes.dex classes
fi
diff --git a/test/082-inline-execute/src/Main.java b/test/082-inline-execute/src/Main.java
index af25d9bc54..e5c9dba63f 100644
--- a/test/082-inline-execute/src/Main.java
+++ b/test/082-inline-execute/src/Main.java
@@ -804,6 +804,7 @@ public class Main {
Assert.assertEquals(Math.round(-2.9d), -3l);
Assert.assertEquals(Math.round(-3.0d), -3l);
Assert.assertEquals(Math.round(0.49999999999999994d), 0l);
+ Assert.assertEquals(Math.round(9007199254740991.0d), 9007199254740991l); // 2^53 - 1
Assert.assertEquals(Math.round(Double.NaN), (long)+0.0d);
Assert.assertEquals(Math.round(Long.MAX_VALUE + 1.0d), Long.MAX_VALUE);
Assert.assertEquals(Math.round(Long.MIN_VALUE - 1.0d), Long.MIN_VALUE);
@@ -825,6 +826,7 @@ public class Main {
Assert.assertEquals(Math.round(-2.5f), -2);
Assert.assertEquals(Math.round(-2.9f), -3);
Assert.assertEquals(Math.round(-3.0f), -3);
+ Assert.assertEquals(Math.round(16777215.0f), 16777215); // 2^24 - 1
Assert.assertEquals(Math.round(Float.NaN), (int)+0.0f);
Assert.assertEquals(Math.round(Integer.MAX_VALUE + 1.0f), Integer.MAX_VALUE);
Assert.assertEquals(Math.round(Integer.MIN_VALUE - 1.0f), Integer.MIN_VALUE);
diff --git a/test/085-old-style-inner-class/build b/test/085-old-style-inner-class/build
index 6f50a76863..21dc66269d 100644
--- a/test/085-old-style-inner-class/build
+++ b/test/085-old-style-inner-class/build
@@ -23,8 +23,8 @@ mkdir classes
${JAVAC} -source 1.4 -target 1.4 -d classes `find src -name '*.java'`
if [ ${USE_JACK} = "true" ]; then
- ${JILL} classes --output classes.jack
- ${JACK} --import classes.jack --output-dex .
+ jar cf classes.jill.jar -C classes .
+ ${JACK} --import classes.jill.jar --output-dex .
else
# Suppress stderr to keep the inner class warnings out of the expected output.
${DX} --debug --dex --dump-to=classes.lst --output=classes.dex --dump-width=1000 classes 2>/dev/null
diff --git a/test/091-override-package-private-method/build b/test/091-override-package-private-method/build
index 5a340dcf6d..073a4ba9bc 100755
--- a/test/091-override-package-private-method/build
+++ b/test/091-override-package-private-method/build
@@ -24,14 +24,12 @@ mkdir classes-ex
mv classes/OverridePackagePrivateMethodSuper.class classes-ex
if [ ${USE_JACK} = "true" ]; then
- # Create .jack files from classes generated with javac.
- ${JILL} classes --output classes.jack
- ${JILL} classes-ex --output classes-ex.jack
+ jar cf classes.jill.jar -C classes .
+ jar cf classes-ex.jill.jar -C classes-ex .
- # Create DEX files from .jack files.
- ${JACK} --import classes.jack --output-dex .
+ ${JACK} --import classes.jill.jar --output-dex .
zip $TEST_NAME.jar classes.dex
- ${JACK} --import classes-ex.jack --output-dex .
+ ${JACK} --import classes-ex.jill.jar --output-dex .
zip ${TEST_NAME}-ex.jar classes.dex
else
if [ ${NEED_DEX} = "true" ]; then
diff --git a/test/097-duplicate-method/build b/test/097-duplicate-method/build
index a8558739de..4525549905 100644
--- a/test/097-duplicate-method/build
+++ b/test/097-duplicate-method/build
@@ -23,10 +23,10 @@ if [ ${USE_JACK} = "true" ]; then
${JACK} --output-jack src.jack src
${JASMIN} -d classes src/*.j
- ${JILL} classes --output jasmin.jack
+ jar cf jasmin.jill.jar -C classes .
# We set jack.import.type.policy=keep-first to consider class definitions from jasmin first.
- ${JACK} --import jasmin.jack --import src.jack -D jack.import.type.policy=keep-first --output-dex .
+ ${JACK} --import jasmin.jill.jar --import src.jack -D jack.import.type.policy=keep-first --output-dex .
else
${JAVAC} -d classes src/*.java
${JASMIN} -d classes src/*.j
diff --git a/test/111-unresolvable-exception/build b/test/111-unresolvable-exception/build
index e772fb812f..58ac26d836 100644
--- a/test/111-unresolvable-exception/build
+++ b/test/111-unresolvable-exception/build
@@ -22,8 +22,8 @@ ${JAVAC} -d classes `find src -name '*.java'`
rm classes/TestException.class
if [ ${USE_JACK} = "true" ]; then
- ${JILL} classes --output classes.jack
- ${JACK} --import classes.jack --output-dex .
+ jar cf classes.jill.jar -C classes .
+ ${JACK} --import classes.jill.jar --output-dex .
else
${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex classes
fi
diff --git a/test/113-multidex/build b/test/113-multidex/build
index 8ef5c0eb0f..4557ccd22a 100644
--- a/test/113-multidex/build
+++ b/test/113-multidex/build
@@ -28,14 +28,12 @@ ${JAVAC} -d classes2 `find src -name '*.java'`
rm classes2/Second.class classes2/FillerA.class classes2/FillerB.class classes2/Inf*.class
if [ ${USE_JACK} = "true" ]; then
- # Create .jack files from classes generated with javac.
- ${JILL} classes --output classes.jack
- ${JILL} classes2 --output classes2.jack
+ jar cf classes.jill.jar -C classes .
+ jar cf classes2.jill.jar -C classes2 .
- # Create DEX files from .jack files.
- ${JACK} --import classes.jack --output-dex .
+ ${JACK} --import classes.jill.jar --output-dex .
mv classes.dex classes-1.dex
- ${JACK} --import classes2.jack --output-dex .
+ ${JACK} --import classes2.jill.jar --output-dex .
mv classes.dex classes2.dex
mv classes-1.dex classes.dex
else
diff --git a/test/121-modifiers/build b/test/121-modifiers/build
index 85b69e92a6..771dd51829 100644
--- a/test/121-modifiers/build
+++ b/test/121-modifiers/build
@@ -31,9 +31,9 @@ set -e
# mv Main.class A.class A\$B.class A\$C.class classes/
if [ ${USE_JACK} = "true" ]; then
- ${JILL} classes --output classes.jack
+ jar cf classes.jill.jar -C classes .
# Workaround b/19561685: disable sanity checks to produce a DEX file with invalid modifiers.
- ${JACK} --sanity-checks off --import classes.jack --output-dex .
+ ${JACK} --sanity-checks off --import classes.jill.jar --output-dex .
else
${DX} --debug --dex --dump-to=classes.lst --output=classes.dex classes
fi
diff --git a/test/124-missing-classes/build b/test/124-missing-classes/build
index b92ecf9382..0a340a26d6 100644
--- a/test/124-missing-classes/build
+++ b/test/124-missing-classes/build
@@ -27,8 +27,8 @@ rm 'classes/MissingClass.class'
rm 'classes/Main$MissingInnerClass.class'
if [ ${USE_JACK} = "true" ]; then
- ${JILL} classes --output classes.jack
- ${JACK} --import classes.jack --output-dex .
+ jar cf classes.jill.jar -C classes .
+ ${JACK} --import classes.jill.jar --output-dex .
else
${DX} -JXmx256m --debug --dex --output=classes.dex classes
fi
diff --git a/test/126-miranda-multidex/build b/test/126-miranda-multidex/build
index b7f2118d2f..00b9ba0ac2 100644
--- a/test/126-miranda-multidex/build
+++ b/test/126-miranda-multidex/build
@@ -28,14 +28,12 @@ ${JAVAC} -d classes2 `find src -name '*.java'`
rm classes2/Main.class classes2/MirandaAbstract.class classes2/MirandaClass*.class classes2/MirandaInterface2*.class
if [ ${USE_JACK} = "true" ]; then
- # Create .jack files from classes generated with javac.
- ${JILL} classes --output classes.jack
- ${JILL} classes2 --output classes2.jack
+ jar cf classes.jill.jar -C classes .
+ jar cf classes2.jill.jar -C classes2 .
- # Create DEX files from .jack files.
- ${JACK} --import classes.jack --output-dex .
+ ${JACK} --import classes.jill.jar --output-dex .
mv classes.dex classes-1.dex
- ${JACK} --import classes2.jack --output-dex .
+ ${JACK} --import classes2.jill.jar --output-dex .
mv classes.dex classes2.dex
mv classes-1.dex classes.dex
else
diff --git a/test/127-checker-secondarydex/build b/test/127-checker-secondarydex/build
index 0d9f4d6291..7ce46acfed 100755
--- a/test/127-checker-secondarydex/build
+++ b/test/127-checker-secondarydex/build
@@ -24,14 +24,12 @@ mkdir classes-ex
mv classes/Super.class classes-ex
if [ ${USE_JACK} = "true" ]; then
- # Create .jack files from classes generated with javac.
- ${JILL} classes --output classes.jack
- ${JILL} classes-ex --output classes-ex.jack
+ jar cf classes.jill.jar -C classes .
+ jar cf classes-ex.jill.jar -C classes-ex .
- # Create DEX files from .jack files.
- ${JACK} --import classes.jack --output-dex .
+ ${JACK} --import classes.jill.jar --output-dex .
zip $TEST_NAME.jar classes.dex
- ${JACK} --import classes-ex.jack --output-dex .
+ ${JACK} --import classes-ex.jill.jar --output-dex .
zip ${TEST_NAME}-ex.jar classes.dex
else
if [ ${NEED_DEX} = "true" ]; then
diff --git a/test/130-hprof/src-ex/Allocator.java b/test/130-hprof/src-ex/Allocator.java
new file mode 100644
index 0000000000..ee75a14f30
--- /dev/null
+++ b/test/130-hprof/src-ex/Allocator.java
@@ -0,0 +1,22 @@
+/*
+ * 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 allocator that returns a boot class path object.
+public class Allocator {
+ public static Object allocObject() {
+ return new Object();
+ }
+}
diff --git a/test/130-hprof/src/Main.java b/test/130-hprof/src/Main.java
index 67e52323dd..9868c617f5 100644
--- a/test/130-hprof/src/Main.java
+++ b/test/130-hprof/src/Main.java
@@ -16,6 +16,7 @@
import java.io.File;
import java.lang.ref.WeakReference;
+import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
@@ -34,24 +35,21 @@ public class Main {
}
}
- public static void main(String[] args) {
- // Create some data.
- Object data[] = new Object[TEST_LENGTH];
- for (int i = 0; i < data.length; i++) {
- if (makeArray(i)) {
- data[i] = new Object[TEST_LENGTH];
- } else {
- data[i] = String.valueOf(i);
- }
+ private static Object allocInDifferentLoader() throws Exception {
+ final String DEX_FILE = System.getenv("DEX_LOCATION") + "/130-hprof-ex.jar";
+ Class pathClassLoader = Class.forName("dalvik.system.PathClassLoader");
+ if (pathClassLoader == null) {
+ throw new AssertionError("Couldn't find path class loader class");
}
- for (int i = 0; i < data.length; i++) {
- if (makeArray(i)) {
- Object data2[] = (Object[]) data[i];
- fillArray(data, data2, i);
- }
- }
- System.out.println("Generated data.");
+ Constructor constructor =
+ pathClassLoader.getDeclaredConstructor(String.class, ClassLoader.class);
+ ClassLoader loader = (ClassLoader)constructor.newInstance(
+ DEX_FILE, ClassLoader.getSystemClassLoader());
+ Class allocator = loader.loadClass("Allocator");
+ return allocator.getDeclaredMethod("allocObject", null).invoke(null);
+ }
+ private static void createDumpAndConv() throws RuntimeException {
File dumpFile = null;
File convFile = null;
@@ -88,6 +86,43 @@ public class Main {
}
}
+ public static void main(String[] args) throws Exception {
+ // Create some data.
+ Object data[] = new Object[TEST_LENGTH];
+ for (int i = 0; i < data.length; i++) {
+ if (makeArray(i)) {
+ data[i] = new Object[TEST_LENGTH];
+ } else {
+ data[i] = String.valueOf(i);
+ }
+ }
+ for (int i = 0; i < data.length; i++) {
+ if (makeArray(i)) {
+ Object data2[] = (Object[]) data[i];
+ fillArray(data, data2, i);
+ }
+ }
+ System.out.println("Generated data.");
+
+ createDumpAndConv();
+ Class klass = Class.forName("org.apache.harmony.dalvik.ddmc.DdmVmInternal");
+ if (klass == null) {
+ throw new AssertionError("Couldn't find path class loader class");
+ }
+ Method enableMethod = klass.getDeclaredMethod("enableRecentAllocations",
+ Boolean.TYPE);
+ if (enableMethod == null) {
+ throw new AssertionError("Couldn't find path class loader class");
+ }
+ enableMethod.invoke(null, true);
+ Object o = allocInDifferentLoader();
+ // Run GC to cause class unloading.
+ Runtime.getRuntime().gc();
+ createDumpAndConv();
+ // TODO: Somehow check contents of hprof file.
+ enableMethod.invoke(null, false);
+ }
+
private static File getHprofConf() {
// Use the java.library.path. It points to the lib directory.
File libDir = new File(System.getProperty("java.library.path"));
diff --git a/test/442-checker-constant-folding/smali/TestCmp.smali b/test/442-checker-constant-folding/smali/TestCmp.smali
new file mode 100644
index 0000000000..df631bc202
--- /dev/null
+++ b/test/442-checker-constant-folding/smali/TestCmp.smali
@@ -0,0 +1,332 @@
+# Copyright (C) 2015 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 LTestCmp;
+
+.super Ljava/lang/Object;
+
+
+## CHECK-START: int TestCmp.$opt$CmpLongConstants() constant_folding (before)
+## CHECK-DAG: <<Const13:j\d+>> LongConstant 13
+## CHECK-DAG: <<Const7:j\d+>> LongConstant 7
+## CHECK-DAG: <<Cmp:i\d+>> Compare [<<Const13>>,<<Const7>>]
+## CHECK-DAG: Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLongConstants() constant_folding (after)
+## CHECK-DAG: LongConstant 13
+## CHECK-DAG: LongConstant 7
+## CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+## CHECK-DAG: Return [<<Const1>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLongConstants() constant_folding (after)
+## CHECK-NOT: Compare
+
+.method public static $opt$CmpLongConstants()I
+ .registers 5
+ const-wide v1, 13
+ const-wide v3, 7
+ cmp-long v0, v1, v3
+ return v0
+.end method
+
+## CHECK-START: int TestCmp.$opt$CmpGtFloatConstants() constant_folding (before)
+## CHECK-DAG: <<Const11:f\d+>> FloatConstant 11
+## CHECK-DAG: <<Const22:f\d+>> FloatConstant 22
+## CHECK-DAG: <<Cmp:i\d+>> Compare [<<Const11>>,<<Const22>>] bias:gt
+## CHECK-DAG: Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpGtFloatConstants() constant_folding (after)
+## CHECK-DAG: FloatConstant 11
+## CHECK-DAG: FloatConstant 22
+## CHECK-DAG: <<ConstM1:i\d+>> IntConstant -1
+## CHECK-DAG: Return [<<ConstM1>>]
+
+## CHECK-START: int TestCmp.$opt$CmpGtFloatConstants() constant_folding (after)
+## CHECK-NOT: Compare
+
+.method public static $opt$CmpGtFloatConstants()I
+ .registers 3
+ const v1, 11.f
+ const v2, 22.f
+ cmpg-float v0, v1, v2
+ return v0
+.end method
+
+## CHECK-START: int TestCmp.$opt$CmpLtFloatConstants() constant_folding (before)
+## CHECK-DAG: <<Const33:f\d+>> FloatConstant 33
+## CHECK-DAG: <<Const44:f\d+>> FloatConstant 44
+## CHECK-DAG: <<Cmp:i\d+>> Compare [<<Const33>>,<<Const44>>] bias:lt
+## CHECK-DAG: Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLtFloatConstants() constant_folding (after)
+## CHECK-DAG: FloatConstant 33
+## CHECK-DAG: FloatConstant 44
+## CHECK-DAG: <<ConstM1:i\d+>> IntConstant -1
+## CHECK-DAG: Return [<<ConstM1>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLtFloatConstants() constant_folding (after)
+## CHECK-NOT: Compare
+
+.method public static $opt$CmpLtFloatConstants()I
+ .registers 3
+ const v1, 33.f
+ const v2, 44.f
+ cmpl-float v0, v1, v2
+ return v0
+.end method
+
+## CHECK-START: int TestCmp.$opt$CmpGtDoubleConstants() constant_folding (before)
+## CHECK-DAG: <<Const55:d\d+>> DoubleConstant 55
+## CHECK-DAG: <<Const66:d\d+>> DoubleConstant 66
+## CHECK-DAG: <<Cmp:i\d+>> Compare [<<Const55>>,<<Const66>>] bias:gt
+## CHECK-DAG: Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpGtDoubleConstants() constant_folding (after)
+## CHECK-DAG: DoubleConstant 55
+## CHECK-DAG: DoubleConstant 66
+## CHECK-DAG: <<ConstM1:i\d+>> IntConstant -1
+## CHECK-DAG: Return [<<ConstM1>>]
+
+## CHECK-START: int TestCmp.$opt$CmpGtDoubleConstants() constant_folding (after)
+## CHECK-NOT: Compare
+
+.method public static $opt$CmpGtDoubleConstants()I
+ .registers 5
+ const-wide v1, 55.
+ const-wide v3, 66.
+ cmpg-double v0, v1, v3
+ return v0
+.end method
+
+## CHECK-START: int TestCmp.$opt$CmpLtDoubleConstants() constant_folding (before)
+## CHECK-DAG: <<Const77:d\d+>> DoubleConstant 77
+## CHECK-DAG: <<Const88:d\d+>> DoubleConstant 88
+## CHECK-DAG: <<Cmp:i\d+>> Compare [<<Const77>>,<<Const88>>] bias:lt
+## CHECK-DAG: Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLtDoubleConstants() constant_folding (after)
+## CHECK-DAG: DoubleConstant 77
+## CHECK-DAG: DoubleConstant 88
+## CHECK-DAG: <<ConstM1:i\d+>> IntConstant -1
+## CHECK-DAG: Return [<<ConstM1>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLtDoubleConstants() constant_folding (after)
+## CHECK-NOT: Compare
+
+.method public static $opt$CmpLtDoubleConstants()I
+ .registers 5
+ const-wide v1, 77.
+ const-wide v3, 88.
+ cmpl-double v0, v1, v3
+ return v0
+.end method
+
+
+## CHECK-START: int TestCmp.$opt$CmpLongSameConstant() constant_folding (before)
+## CHECK-DAG: <<Const100:j\d+>> LongConstant 100
+## CHECK-DAG: <<Cmp:i\d+>> Compare [<<Const100>>,<<Const100>>]
+## CHECK-DAG: Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLongSameConstant() constant_folding (after)
+## CHECK-DAG: LongConstant 100
+## CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+## CHECK-DAG: Return [<<Const0>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLongSameConstant() constant_folding (after)
+## CHECK-NOT: Compare
+
+.method public static $opt$CmpLongSameConstant()I
+ .registers 5
+ const-wide v1, 100
+ const-wide v3, 100
+ cmp-long v0, v1, v3
+ return v0
+.end method
+
+## CHECK-START: int TestCmp.$opt$CmpGtFloatSameConstant() constant_folding (before)
+## CHECK-DAG: <<Const200:f\d+>> FloatConstant 200
+## CHECK-DAG: <<Cmp:i\d+>> Compare [<<Const200>>,<<Const200>>] bias:gt
+## CHECK-DAG: Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpGtFloatSameConstant() constant_folding (after)
+## CHECK-DAG: FloatConstant 200
+## CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+## CHECK-DAG: Return [<<Const0>>]
+
+## CHECK-START: int TestCmp.$opt$CmpGtFloatSameConstant() constant_folding (after)
+## CHECK-NOT: Compare
+
+.method public static $opt$CmpGtFloatSameConstant()I
+ .registers 3
+ const v1, 200.f
+ const v2, 200.f
+ cmpg-float v0, v1, v2
+ return v0
+.end method
+
+## CHECK-START: int TestCmp.$opt$CmpLtFloatSameConstant() constant_folding (before)
+## CHECK-DAG: <<Const300:f\d+>> FloatConstant 300
+## CHECK-DAG: <<Cmp:i\d+>> Compare [<<Const300>>,<<Const300>>] bias:lt
+## CHECK-DAG: Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLtFloatSameConstant() constant_folding (after)
+## CHECK-DAG: FloatConstant 300
+## CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+## CHECK-DAG: Return [<<Const0>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLtFloatSameConstant() constant_folding (after)
+## CHECK-NOT: Compare
+
+.method public static $opt$CmpLtFloatSameConstant()I
+ .registers 3
+ const v1, 300.f
+ const v2, 300.f
+ cmpl-float v0, v1, v2
+ return v0
+.end method
+
+## CHECK-START: int TestCmp.$opt$CmpGtDoubleSameConstant() constant_folding (before)
+## CHECK-DAG: <<Const400:d\d+>> DoubleConstant 400
+## CHECK-DAG: <<Cmp:i\d+>> Compare [<<Const400>>,<<Const400>>] bias:gt
+## CHECK-DAG: Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpGtDoubleSameConstant() constant_folding (after)
+## CHECK-DAG: DoubleConstant 400
+## CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+## CHECK-DAG: Return [<<Const0>>]
+
+## CHECK-START: int TestCmp.$opt$CmpGtDoubleSameConstant() constant_folding (after)
+## CHECK-NOT: Compare
+
+.method public static $opt$CmpGtDoubleSameConstant()I
+ .registers 5
+ const-wide v1, 400.
+ const-wide v3, 400.
+ cmpg-double v0, v1, v3
+ return v0
+.end method
+
+## CHECK-START: int TestCmp.$opt$CmpLtDoubleSameConstant() constant_folding (before)
+## CHECK-DAG: <<Const500:d\d+>> DoubleConstant 500
+## CHECK-DAG: <<Cmp:i\d+>> Compare [<<Const500>>,<<Const500>>] bias:lt
+## CHECK-DAG: Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLtDoubleSameConstant() constant_folding (after)
+## CHECK-DAG: DoubleConstant 500
+## CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+## CHECK-DAG: Return [<<Const0>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLtDoubleSameConstant() constant_folding (after)
+## CHECK-NOT: Compare
+
+.method public static $opt$CmpLtDoubleSameConstant()I
+ .registers 5
+ const-wide v1, 500.
+ const-wide v3, 500.
+ cmpl-double v0, v1, v3
+ return v0
+.end method
+
+
+## CHECK-START: int TestCmp.$opt$CmpGtFloatConstantWithNaN() constant_folding (before)
+## CHECK-DAG: <<Const44:f\d+>> FloatConstant 44
+## CHECK-DAG: <<ConstNan:f\d+>> FloatConstant nan
+## CHECK-DAG: <<Cmp:i\d+>> Compare [<<Const44>>,<<ConstNan>>] bias:gt
+## CHECK-DAG: Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpGtFloatConstantWithNaN() constant_folding (after)
+## CHECK-DAG: FloatConstant 44
+## CHECK-DAG: FloatConstant nan
+## CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+## CHECK-DAG: Return [<<Const1>>]
+
+## CHECK-START: int TestCmp.$opt$CmpGtFloatConstantWithNaN() constant_folding (after)
+## CHECK-NOT: Compare
+
+.method public static $opt$CmpGtFloatConstantWithNaN()I
+ .registers 3
+ const v1, 44.f
+ const v2, NaNf
+ cmpg-float v0, v1, v2
+ return v0
+.end method
+
+## CHECK-START: int TestCmp.$opt$CmpLtFloatConstantWithNaN() constant_folding (before)
+## CHECK-DAG: <<Const44:f\d+>> FloatConstant 44
+## CHECK-DAG: <<ConstNan:f\d+>> FloatConstant nan
+## CHECK-DAG: <<Cmp:i\d+>> Compare [<<Const44>>,<<ConstNan>>] bias:lt
+## CHECK-DAG: Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLtFloatConstantWithNaN() constant_folding (after)
+## CHECK-DAG: FloatConstant 44
+## CHECK-DAG: FloatConstant nan
+## CHECK-DAG: <<ConstM1:i\d+>> IntConstant -1
+## CHECK-DAG: Return [<<ConstM1>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLtFloatConstantWithNaN() constant_folding (after)
+## CHECK-NOT: Compare
+
+.method public static $opt$CmpLtFloatConstantWithNaN()I
+ .registers 3
+ const v1, 44.f
+ const v2, NaNf
+ cmpl-float v0, v1, v2
+ return v0
+.end method
+
+## CHECK-START: int TestCmp.$opt$CmpGtDoubleConstantWithNaN() constant_folding (before)
+## CHECK-DAG: <<Const45:d\d+>> DoubleConstant 45
+## CHECK-DAG: <<ConstNan:d\d+>> DoubleConstant nan
+## CHECK-DAG: <<Cmp:i\d+>> Compare [<<Const45>>,<<ConstNan>>] bias:gt
+## CHECK-DAG: Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpGtDoubleConstantWithNaN() constant_folding (after)
+## CHECK-DAG: DoubleConstant 45
+## CHECK-DAG: DoubleConstant nan
+## CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+## CHECK-DAG: Return [<<Const1>>]
+
+## CHECK-START: int TestCmp.$opt$CmpGtDoubleConstantWithNaN() constant_folding (after)
+## CHECK-NOT: Compare
+
+.method public static $opt$CmpGtDoubleConstantWithNaN()I
+ .registers 5
+ const-wide v1, 45.
+ const-wide v3, NaN
+ cmpg-double v0, v1, v3
+ return v0
+.end method
+
+## CHECK-START: int TestCmp.$opt$CmpLtDoubleConstantWithNaN() constant_folding (before)
+## CHECK-DAG: <<Const46:d\d+>> DoubleConstant 46
+## CHECK-DAG: <<ConstNan:d\d+>> DoubleConstant nan
+## CHECK-DAG: <<Cmp:i\d+>> Compare [<<Const46>>,<<ConstNan>>] bias:lt
+## CHECK-DAG: Return [<<Cmp>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLtDoubleConstantWithNaN() constant_folding (after)
+## CHECK-DAG: DoubleConstant 46
+## CHECK-DAG: DoubleConstant nan
+## CHECK-DAG: <<ConstM1:i\d+>> IntConstant -1
+## CHECK-DAG: Return [<<ConstM1>>]
+
+## CHECK-START: int TestCmp.$opt$CmpLtDoubleConstantWithNaN() constant_folding (after)
+## CHECK-NOT: Compare
+
+.method public static $opt$CmpLtDoubleConstantWithNaN()I
+ .registers 5
+ const-wide v1, 46.
+ const-wide v3, NaN
+ cmpl-double v0, v1, v3
+ return v0
+.end method
diff --git a/test/442-checker-constant-folding/src/Main.java b/test/442-checker-constant-folding/src/Main.java
index 5479818ae7..93fe397273 100644
--- a/test/442-checker-constant-folding/src/Main.java
+++ b/test/442-checker-constant-folding/src/Main.java
@@ -14,8 +14,13 @@
* limitations under the License.
*/
+import java.lang.reflect.Method;
+
public class Main {
+ // Workaround for b/18051191.
+ class InnerClass {}
+
public static void assertFalse(boolean condition) {
if (condition) {
throw new Error();
@@ -47,6 +52,68 @@ public class Main {
}
+ // Wrappers around methods located in file TestCmp.smali.
+
+ public int smaliCmpLongConstants() throws Exception {
+ Method m = testCmp.getMethod("$opt$CmpLongConstants");
+ return (Integer)m.invoke(null);
+ }
+ public int smaliCmpGtFloatConstants() throws Exception {
+ Method m = testCmp.getMethod("$opt$CmpGtFloatConstants");
+ return (Integer)m.invoke(null);
+ }
+ public int smaliCmpLtFloatConstants() throws Exception {
+ Method m = testCmp.getMethod("$opt$CmpLtFloatConstants");
+ return (Integer)m.invoke(null);
+ }
+ public int smaliCmpGtDoubleConstants() throws Exception {
+ Method m = testCmp.getMethod("$opt$CmpGtDoubleConstants");
+ return (Integer)m.invoke(null);
+ }
+ public int smaliCmpLtDoubleConstants() throws Exception {
+ Method m = testCmp.getMethod("$opt$CmpLtDoubleConstants");
+ return (Integer)m.invoke(null);
+ }
+
+ public int smaliCmpLongSameConstant() throws Exception {
+ Method m = testCmp.getMethod("$opt$CmpLongSameConstant");
+ return (Integer)m.invoke(null);
+ }
+ public int smaliCmpGtFloatSameConstant() throws Exception {
+ Method m = testCmp.getMethod("$opt$CmpGtFloatSameConstant");
+ return (Integer)m.invoke(null);
+ }
+ public int smaliCmpLtFloatSameConstant() throws Exception {
+ Method m = testCmp.getMethod("$opt$CmpLtFloatSameConstant");
+ return (Integer)m.invoke(null);
+ }
+ public int smaliCmpGtDoubleSameConstant() throws Exception {
+ Method m = testCmp.getMethod("$opt$CmpGtDoubleSameConstant");
+ return (Integer)m.invoke(null);
+ }
+ public int smaliCmpLtDoubleSameConstant() throws Exception {
+ Method m = testCmp.getMethod("$opt$CmpLtDoubleSameConstant");
+ return (Integer)m.invoke(null);
+ }
+
+ public int smaliCmpGtFloatConstantWithNaN() throws Exception {
+ Method m = testCmp.getMethod("$opt$CmpGtFloatConstantWithNaN");
+ return (Integer)m.invoke(null);
+ }
+ public int smaliCmpLtFloatConstantWithNaN() throws Exception {
+ Method m = testCmp.getMethod("$opt$CmpLtFloatConstantWithNaN");
+ return (Integer)m.invoke(null);
+ }
+ public int smaliCmpGtDoubleConstantWithNaN() throws Exception {
+ Method m = testCmp.getMethod("$opt$CmpGtDoubleConstantWithNaN");
+ return (Integer)m.invoke(null);
+ }
+ public int smaliCmpLtDoubleConstantWithNaN() throws Exception {
+ Method m = testCmp.getMethod("$opt$CmpLtDoubleConstantWithNaN");
+ return (Integer)m.invoke(null);
+ }
+
+
/**
* Exercise constant folding on negation.
*/
@@ -89,6 +156,44 @@ public class Main {
return y;
}
+ /// CHECK-START: float Main.FloatNegation() constant_folding (before)
+ /// CHECK-DAG: <<Const42:f\d+>> FloatConstant 42
+ /// CHECK-DAG: <<Neg:f\d+>> Neg [<<Const42>>]
+ /// CHECK-DAG: Return [<<Neg>>]
+
+ /// CHECK-START: float Main.FloatNegation() constant_folding (after)
+ /// CHECK-DAG: <<ConstN42:f\d+>> FloatConstant -42
+ /// CHECK-DAG: Return [<<ConstN42>>]
+
+ /// CHECK-START: float Main.FloatNegation() constant_folding (after)
+ /// CHECK-NOT: Neg
+
+ public static float FloatNegation() {
+ float x, y;
+ x = 42F;
+ y = -x;
+ return y;
+ }
+
+ /// CHECK-START: double Main.DoubleNegation() constant_folding (before)
+ /// CHECK-DAG: <<Const42:d\d+>> DoubleConstant 42
+ /// CHECK-DAG: <<Neg:d\d+>> Neg [<<Const42>>]
+ /// CHECK-DAG: Return [<<Neg>>]
+
+ /// CHECK-START: double Main.DoubleNegation() constant_folding (after)
+ /// CHECK-DAG: <<ConstN42:d\d+>> DoubleConstant -42
+ /// CHECK-DAG: Return [<<ConstN42>>]
+
+ /// CHECK-START: double Main.DoubleNegation() constant_folding (after)
+ /// CHECK-NOT: Neg
+
+ public static double DoubleNegation() {
+ double x, y;
+ x = 42D;
+ y = -x;
+ return y;
+ }
+
/**
* Exercise constant folding on addition.
@@ -166,6 +271,48 @@ public class Main {
return c;
}
+ /// CHECK-START: float Main.FloatAddition() constant_folding (before)
+ /// CHECK-DAG: <<Const1:f\d+>> FloatConstant 1
+ /// CHECK-DAG: <<Const2:f\d+>> FloatConstant 2
+ /// CHECK-DAG: <<Add:f\d+>> Add [<<Const1>>,<<Const2>>]
+ /// CHECK-DAG: Return [<<Add>>]
+
+ /// CHECK-START: float Main.FloatAddition() constant_folding (after)
+ /// CHECK-DAG: <<Const3:f\d+>> FloatConstant 3
+ /// CHECK-DAG: Return [<<Const3>>]
+
+ /// CHECK-START: float Main.FloatAddition() constant_folding (after)
+ /// CHECK-NOT: Add
+
+ public static float FloatAddition() {
+ float a, b, c;
+ a = 1F;
+ b = 2F;
+ c = a + b;
+ return c;
+ }
+
+ /// CHECK-START: double Main.DoubleAddition() constant_folding (before)
+ /// CHECK-DAG: <<Const1:d\d+>> DoubleConstant 1
+ /// CHECK-DAG: <<Const2:d\d+>> DoubleConstant 2
+ /// CHECK-DAG: <<Add:d\d+>> Add [<<Const1>>,<<Const2>>]
+ /// CHECK-DAG: Return [<<Add>>]
+
+ /// CHECK-START: double Main.DoubleAddition() constant_folding (after)
+ /// CHECK-DAG: <<Const3:d\d+>> DoubleConstant 3
+ /// CHECK-DAG: Return [<<Const3>>]
+
+ /// CHECK-START: double Main.DoubleAddition() constant_folding (after)
+ /// CHECK-NOT: Add
+
+ public static double DoubleAddition() {
+ double a, b, c;
+ a = 1D;
+ b = 2D;
+ c = a + b;
+ return c;
+ }
+
/**
* Exercise constant folding on subtraction.
@@ -213,6 +360,48 @@ public class Main {
return c;
}
+ /// CHECK-START: float Main.FloatSubtraction() constant_folding (before)
+ /// CHECK-DAG: <<Const6:f\d+>> FloatConstant 6
+ /// CHECK-DAG: <<Const2:f\d+>> FloatConstant 2
+ /// CHECK-DAG: <<Sub:f\d+>> Sub [<<Const6>>,<<Const2>>]
+ /// CHECK-DAG: Return [<<Sub>>]
+
+ /// CHECK-START: float Main.FloatSubtraction() constant_folding (after)
+ /// CHECK-DAG: <<Const4:f\d+>> FloatConstant 4
+ /// CHECK-DAG: Return [<<Const4>>]
+
+ /// CHECK-START: float Main.FloatSubtraction() constant_folding (after)
+ /// CHECK-NOT: Sub
+
+ public static float FloatSubtraction() {
+ float a, b, c;
+ a = 6F;
+ b = 2F;
+ c = a - b;
+ return c;
+ }
+
+ /// CHECK-START: double Main.DoubleSubtraction() constant_folding (before)
+ /// CHECK-DAG: <<Const6:d\d+>> DoubleConstant 6
+ /// CHECK-DAG: <<Const2:d\d+>> DoubleConstant 2
+ /// CHECK-DAG: <<Sub:d\d+>> Sub [<<Const6>>,<<Const2>>]
+ /// CHECK-DAG: Return [<<Sub>>]
+
+ /// CHECK-START: double Main.DoubleSubtraction() constant_folding (after)
+ /// CHECK-DAG: <<Const4:d\d+>> DoubleConstant 4
+ /// CHECK-DAG: Return [<<Const4>>]
+
+ /// CHECK-START: double Main.DoubleSubtraction() constant_folding (after)
+ /// CHECK-NOT: Sub
+
+ public static double DoubleSubtraction() {
+ double a, b, c;
+ a = 6D;
+ b = 2D;
+ c = a - b;
+ return c;
+ }
+
/**
* Exercise constant folding on multiplication.
@@ -260,6 +449,48 @@ public class Main {
return c;
}
+ /// CHECK-START: float Main.FloatMultiplication() constant_folding (before)
+ /// CHECK-DAG: <<Const7:f\d+>> FloatConstant 7
+ /// CHECK-DAG: <<Const3:f\d+>> FloatConstant 3
+ /// CHECK-DAG: <<Mul:f\d+>> Mul [<<Const7>>,<<Const3>>]
+ /// CHECK-DAG: Return [<<Mul>>]
+
+ /// CHECK-START: float Main.FloatMultiplication() constant_folding (after)
+ /// CHECK-DAG: <<Const21:f\d+>> FloatConstant 21
+ /// CHECK-DAG: Return [<<Const21>>]
+
+ /// CHECK-START: float Main.FloatMultiplication() constant_folding (after)
+ /// CHECK-NOT: Mul
+
+ public static float FloatMultiplication() {
+ float a, b, c;
+ a = 7F;
+ b = 3F;
+ c = a * b;
+ return c;
+ }
+
+ /// CHECK-START: double Main.DoubleMultiplication() constant_folding (before)
+ /// CHECK-DAG: <<Const7:d\d+>> DoubleConstant 7
+ /// CHECK-DAG: <<Const3:d\d+>> DoubleConstant 3
+ /// CHECK-DAG: <<Mul:d\d+>> Mul [<<Const7>>,<<Const3>>]
+ /// CHECK-DAG: Return [<<Mul>>]
+
+ /// CHECK-START: double Main.DoubleMultiplication() constant_folding (after)
+ /// CHECK-DAG: <<Const21:d\d+>> DoubleConstant 21
+ /// CHECK-DAG: Return [<<Const21>>]
+
+ /// CHECK-START: double Main.DoubleMultiplication() constant_folding (after)
+ /// CHECK-NOT: Mul
+
+ public static double DoubleMultiplication() {
+ double a, b, c;
+ a = 7D;
+ b = 3D;
+ c = a * b;
+ return c;
+ }
+
/**
* Exercise constant folding on division.
@@ -311,6 +542,48 @@ public class Main {
return c;
}
+ /// CHECK-START: float Main.FloatDivision() constant_folding (before)
+ /// CHECK-DAG: <<Const8:f\d+>> FloatConstant 8
+ /// CHECK-DAG: <<Const2P5:f\d+>> FloatConstant 2.5
+ /// CHECK-DAG: <<Div:f\d+>> Div [<<Const8>>,<<Const2P5>>]
+ /// CHECK-DAG: Return [<<Div>>]
+
+ /// CHECK-START: float Main.FloatDivision() constant_folding (after)
+ /// CHECK-DAG: <<Const3P2:f\d+>> FloatConstant 3.2
+ /// CHECK-DAG: Return [<<Const3P2>>]
+
+ /// CHECK-START: float Main.FloatDivision() constant_folding (after)
+ /// CHECK-NOT: Div
+
+ public static float FloatDivision() {
+ float a, b, c;
+ a = 8F;
+ b = 2.5F;
+ c = a / b;
+ return c;
+ }
+
+ /// CHECK-START: double Main.DoubleDivision() constant_folding (before)
+ /// CHECK-DAG: <<Const8:d\d+>> DoubleConstant 8
+ /// CHECK-DAG: <<Const2P5:d\d+>> DoubleConstant 2.5
+ /// CHECK-DAG: <<Div:d\d+>> Div [<<Const8>>,<<Const2P5>>]
+ /// CHECK-DAG: Return [<<Div>>]
+
+ /// CHECK-START: double Main.DoubleDivision() constant_folding (after)
+ /// CHECK-DAG: <<Const3P2:d\d+>> DoubleConstant 3.2
+ /// CHECK-DAG: Return [<<Const3P2>>]
+
+ /// CHECK-START: double Main.DoubleDivision() constant_folding (after)
+ /// CHECK-NOT: Div
+
+ public static double DoubleDivision() {
+ double a, b, c;
+ a = 8D;
+ b = 2.5D;
+ c = a / b;
+ return c;
+ }
+
/**
* Exercise constant folding on remainder.
@@ -362,6 +635,48 @@ public class Main {
return c;
}
+ /// CHECK-START: float Main.FloatRemainder() constant_folding (before)
+ /// CHECK-DAG: <<Const8:f\d+>> FloatConstant 8
+ /// CHECK-DAG: <<Const2P5:f\d+>> FloatConstant 2.5
+ /// CHECK-DAG: <<Rem:f\d+>> Rem [<<Const8>>,<<Const2P5>>]
+ /// CHECK-DAG: Return [<<Rem>>]
+
+ /// CHECK-START: float Main.FloatRemainder() constant_folding (after)
+ /// CHECK-DAG: <<Const0P5:f\d+>> FloatConstant 0.5
+ /// CHECK-DAG: Return [<<Const0P5>>]
+
+ /// CHECK-START: float Main.FloatRemainder() constant_folding (after)
+ /// CHECK-NOT: Rem
+
+ public static float FloatRemainder() {
+ float a, b, c;
+ a = 8F;
+ b = 2.5F;
+ c = a % b;
+ return c;
+ }
+
+ /// CHECK-START: double Main.DoubleRemainder() constant_folding (before)
+ /// CHECK-DAG: <<Const8:d\d+>> DoubleConstant 8
+ /// CHECK-DAG: <<Const2P5:d\d+>> DoubleConstant 2.5
+ /// CHECK-DAG: <<Rem:d\d+>> Rem [<<Const8>>,<<Const2P5>>]
+ /// CHECK-DAG: Return [<<Rem>>]
+
+ /// CHECK-START: double Main.DoubleRemainder() constant_folding (after)
+ /// CHECK-DAG: <<Const0P5:d\d+>> DoubleConstant 0.5
+ /// CHECK-DAG: Return [<<Const0P5>>]
+
+ /// CHECK-START: double Main.DoubleRemainder() constant_folding (after)
+ /// CHECK-NOT: Rem
+
+ public static double DoubleRemainder() {
+ double a, b, c;
+ a = 8D;
+ b = 2.5D;
+ c = a % b;
+ return c;
+ }
+
/**
* Exercise constant folding on left shift.
@@ -1197,25 +1512,37 @@ public class Main {
}
- public static void main(String[] args) {
+ public static void main(String[] args) throws Exception {
assertIntEquals(-42, IntNegation());
assertLongEquals(-42L, LongNegation());
+ assertFloatEquals(-42F, FloatNegation());
+ assertDoubleEquals(-42D, DoubleNegation());
assertIntEquals(3, IntAddition1());
assertIntEquals(14, IntAddition2());
assertLongEquals(3L, LongAddition());
+ assertFloatEquals(3F, FloatAddition());
+ assertDoubleEquals(3D, DoubleAddition());
assertIntEquals(4, IntSubtraction());
assertLongEquals(4L, LongSubtraction());
+ assertFloatEquals(4F, FloatSubtraction());
+ assertDoubleEquals(4D, DoubleSubtraction());
assertIntEquals(21, IntMultiplication());
assertLongEquals(21L, LongMultiplication());
+ assertFloatEquals(21F, FloatMultiplication());
+ assertDoubleEquals(21D, DoubleMultiplication());
assertIntEquals(2, IntDivision());
assertLongEquals(2L, LongDivision());
+ assertFloatEquals(3.2F, FloatDivision());
+ assertDoubleEquals(3.2D, DoubleDivision());
assertIntEquals(2, IntRemainder());
assertLongEquals(2L, LongRemainder());
+ assertFloatEquals(0.5F, FloatRemainder());
+ assertDoubleEquals(0.5D, DoubleRemainder());
assertIntEquals(4, ShlIntLong());
assertLongEquals(12L, ShlLongInt());
@@ -1259,6 +1586,24 @@ public class Main {
assertFalse(CmpFloatGreaterThanNaN(arbitrary));
assertFalse(CmpDoubleLessThanNaN(arbitrary));
+ Main main = new Main();
+ assertIntEquals(1, main.smaliCmpLongConstants());
+ assertIntEquals(-1, main.smaliCmpGtFloatConstants());
+ assertIntEquals(-1, main.smaliCmpLtFloatConstants());
+ assertIntEquals(-1, main.smaliCmpGtDoubleConstants());
+ assertIntEquals(-1, main.smaliCmpLtDoubleConstants());
+
+ assertIntEquals(0, main.smaliCmpLongSameConstant());
+ assertIntEquals(0, main.smaliCmpGtFloatSameConstant());
+ assertIntEquals(0, main.smaliCmpLtFloatSameConstant());
+ assertIntEquals(0, main.smaliCmpGtDoubleSameConstant());
+ assertIntEquals(0, main.smaliCmpLtDoubleSameConstant());
+
+ assertIntEquals(1, main.smaliCmpGtFloatConstantWithNaN());
+ assertIntEquals(-1, main.smaliCmpLtFloatConstantWithNaN());
+ assertIntEquals(1, main.smaliCmpGtDoubleConstantWithNaN());
+ assertIntEquals(-1, main.smaliCmpLtDoubleConstantWithNaN());
+
assertIntEquals(33, ReturnInt33());
assertIntEquals(2147483647, ReturnIntMax());
assertIntEquals(0, ReturnInt0());
@@ -1275,4 +1620,10 @@ public class Main {
assertDoubleEquals(34, ReturnDouble34());
assertDoubleEquals(99.25, ReturnDouble99P25());
}
+
+ Main() throws ClassNotFoundException {
+ testCmp = Class.forName("TestCmp");
+ }
+
+ private Class<?> testCmp;
}
diff --git a/test/449-checker-bce/src/Main.java b/test/449-checker-bce/src/Main.java
index 31bb94cb8c..32bbc5b61d 100644
--- a/test/449-checker-bce/src/Main.java
+++ b/test/449-checker-bce/src/Main.java
@@ -391,6 +391,36 @@ public class Main {
array[base + 1] = 1;
}
+ /// CHECK-START: void Main.constantIndexing10(int[], int) BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+
+ /// CHECK-START: void Main.constantIndexing10(int[], int) BCE (after)
+ /// CHECK: Deoptimize
+ /// CHECK: Deoptimize
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+
+ static void constantIndexing10(int[] array, int base) {
+ // Offset hidden in incremented base.
+ array[base] = 1;
+ array[++base] = 2;
+ array[++base] = 3;
+ array[++base] = 4;
+ }
+
static void runAllConstantIndices() {
int[] a1 = { 0 };
int[] a6 = { 0, 0, 0, 0, 0, 0 };
@@ -502,6 +532,12 @@ public class Main {
a6[3] != 3 || a6[4] != 40 || a6[5] != 10) {
System.out.println("constant indices 9 failed!");
}
+
+ constantIndexing10(a6, 0);
+ if (a6[0] != 1 || a6[1] != 2 || a6[2] != 3 ||
+ a6[3] != 4 || a6[4] != 40 || a6[5] != 10) {
+ System.out.println("constant indices 10 failed!");
+ }
}
// A helper into which the actual throwing function should be inlined.
diff --git a/test/529-checker-unresolved/build b/test/529-checker-unresolved/build
index 8c3c4f8952..d85035b669 100644
--- a/test/529-checker-unresolved/build
+++ b/test/529-checker-unresolved/build
@@ -29,14 +29,12 @@ mv classes/UnresolvedInterface.class classes-ex
mv classes/UnresolvedSuperClass.class classes-ex
if [ ${USE_JACK} = "true" ]; then
- # Create .jack files from classes generated with javac.
- ${JILL} classes --output classes.jack
- ${JILL} classes-ex --output classes-ex.jack
+ jar cf classes.jill.jar -C classes .
+ jar cf classes-ex.jill.jar -C classes-ex .
- # Create DEX files from .jack files.
- ${JACK} --import classes.jack --output-dex .
+ ${JACK} --import classes.jill.jar --output-dex .
zip $TEST_NAME.jar classes.dex
- ${JACK} --import classes-ex.jack --output-dex .
+ ${JACK} --import classes-ex.jill.jar --output-dex .
zip ${TEST_NAME}-ex.jar classes.dex
else
if [ ${NEED_DEX} = "true" ]; then
diff --git a/test/566-checker-codegen-select/src/Main.java b/test/566-checker-codegen-select/src/Main.java
index 3a1b3fcf85..e215ab0309 100644
--- a/test/566-checker-codegen-select/src/Main.java
+++ b/test/566-checker-codegen-select/src/Main.java
@@ -20,13 +20,6 @@ public class Main {
/// CHECK: <<Cond:z\d+>> LessThanOrEqual [{{j\d+}},{{j\d+}}]
/// CHECK-NEXT: Select [{{j\d+}},{{j\d+}},<<Cond>>]
- // Condition must be materialized on X86 because it would need too many
- // registers otherwise.
- /// CHECK-START-X86: long Main.$noinline$longSelect(long) disassembly (after)
- /// CHECK: LessThanOrEqual
- /// CHECK-NEXT: cmp
- /// CHECK: Select
-
public long $noinline$longSelect(long param) {
if (doThrow) { throw new Error(); }
long val_true = longB;
diff --git a/test/570-checker-osr/osr.cc b/test/570-checker-osr/osr.cc
index 4c58b39319..09e97ea751 100644
--- a/test/570-checker-osr/osr.cc
+++ b/test/570-checker-osr/osr.cc
@@ -41,7 +41,8 @@ class OsrVisitor : public StackVisitor {
(m_name.compare("$noinline$returnDouble") == 0) ||
(m_name.compare("$noinline$returnLong") == 0) ||
(m_name.compare("$noinline$deopt") == 0) ||
- (m_name.compare("$noinline$inlineCache") == 0)) {
+ (m_name.compare("$noinline$inlineCache") == 0) ||
+ (m_name.compare("$noinline$stackOverflow") == 0)) {
const OatQuickMethodHeader* header =
Runtime::Current()->GetJit()->GetCodeCache()->LookupOsrMethodHeader(m);
if (header != nullptr && header == GetCurrentOatQuickMethodHeader()) {
@@ -91,7 +92,8 @@ class ProfilingInfoVisitor : public StackVisitor {
ArtMethod* m = GetMethod();
std::string m_name(m->GetName());
- if (m_name.compare("$noinline$inlineCache") == 0) {
+ if ((m_name.compare("$noinline$inlineCache") == 0) ||
+ (m_name.compare("$noinline$stackOverflow") == 0)) {
ProfilingInfo::Create(Thread::Current(), m, /* retry_allocation */ true);
return false;
}
@@ -119,7 +121,8 @@ class OsrCheckVisitor : public StackVisitor {
std::string m_name(m->GetName());
jit::Jit* jit = Runtime::Current()->GetJit();
- if (m_name.compare("$noinline$inlineCache") == 0 && jit != nullptr) {
+ if ((m_name.compare("$noinline$inlineCache") == 0) ||
+ (m_name.compare("$noinline$stackOverflow") == 0)) {
while (jit->GetCodeCache()->LookupOsrMethodHeader(m) == nullptr) {
// Sleep to yield to the compiler thread.
sleep(0);
diff --git a/test/570-checker-osr/run b/test/570-checker-osr/run
new file mode 100755
index 0000000000..24d69b4b3b
--- /dev/null
+++ b/test/570-checker-osr/run
@@ -0,0 +1,18 @@
+#!/bin/bash
+#
+# 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.
+
+# Ensure this test is not subject to code collection.
+exec ${RUN} "$@" --runtime-option -Xjitinitialsize:32M
diff --git a/test/570-checker-osr/src/Main.java b/test/570-checker-osr/src/Main.java
index 828908a582..1142d49eed 100644
--- a/test/570-checker-osr/src/Main.java
+++ b/test/570-checker-osr/src/Main.java
@@ -40,6 +40,9 @@ public class Main {
if ($noinline$inlineCache(new SubMain(), /* isSecondInvocation */ true) != SubMain.class) {
throw new Error("Unexpected return value");
}
+
+ $noinline$stackOverflow(new Main(), /* isSecondInvocation */ false);
+ $noinline$stackOverflow(new SubMain(), /* isSecondInvocation */ true);
}
public static int $noinline$returnInt() {
@@ -129,7 +132,32 @@ public class Main {
return Main.class;
}
- public static int[] array = new int[4];
+ public void otherInlineCache() {
+ return;
+ }
+
+ public static void $noinline$stackOverflow(Main m, boolean isSecondInvocation) {
+ // If we are running in non-JIT mode, or were unlucky enough to get this method
+ // already JITted, just return the expected value.
+ if (!ensureInInterpreter()) {
+ return;
+ }
+
+ // We need a ProfilingInfo object to populate the 'otherInlineCache' call.
+ ensureHasProfilingInfo();
+
+ if (isSecondInvocation) {
+ // Ensure we have an OSR code and we jump to it.
+ while (!ensureInOsrCode()) {}
+ }
+
+ for (int i = 0; i < (isSecondInvocation ? 10000000 : 1); ++i) {
+ // The first invocation of $noinline$stackOverflow will populate the inline
+ // cache with Main. The second invocation of the method, will see a SubMain
+ // and will therefore trigger deoptimization.
+ m.otherInlineCache();
+ }
+ }
public static native boolean ensureInInterpreter();
public static native boolean ensureInOsrCode();
@@ -147,4 +175,8 @@ class SubMain extends Main {
public Main inlineCache() {
return new SubMain();
}
+
+ public void otherInlineCache() {
+ return;
+ }
}
diff --git a/test/570-checker-select/src/Main.java b/test/570-checker-select/src/Main.java
index 8a4cf603af..59741d6d05 100644
--- a/test/570-checker-select/src/Main.java
+++ b/test/570-checker-select/src/Main.java
@@ -29,6 +29,11 @@ public class Main {
/// CHECK: Select [{{i\d+}},{{i\d+}},<<Cond>>]
/// CHECK: cmovnz/ne
+ /// CHECK-START-X86: int Main.BoolCond_IntVarVar(boolean, int, int) disassembly (after)
+ /// CHECK: <<Cond:z\d+>> ParameterValue
+ /// CHECK: Select [{{i\d+}},{{i\d+}},<<Cond>>]
+ /// CHECK: cmovnz/ne
+
public static int BoolCond_IntVarVar(boolean cond, int x, int y) {
return cond ? x : y;
}
@@ -46,6 +51,11 @@ public class Main {
/// CHECK: Select [{{i\d+}},{{i\d+}},<<Cond>>]
/// CHECK: cmovnz/ne
+ /// CHECK-START-X86: int Main.BoolCond_IntVarCst(boolean, int) disassembly (after)
+ /// CHECK: <<Cond:z\d+>> ParameterValue
+ /// CHECK: Select [{{i\d+}},{{i\d+}},<<Cond>>]
+ /// CHECK: cmovnz/ne
+
public static int BoolCond_IntVarCst(boolean cond, int x) {
return cond ? x : 1;
}
@@ -63,6 +73,11 @@ public class Main {
/// CHECK: Select [{{i\d+}},{{i\d+}},<<Cond>>]
/// CHECK: cmovnz/ne
+ /// CHECK-START-X86: int Main.BoolCond_IntCstVar(boolean, int) disassembly (after)
+ /// CHECK: <<Cond:z\d+>> ParameterValue
+ /// CHECK: Select [{{i\d+}},{{i\d+}},<<Cond>>]
+ /// CHECK: cmovnz/ne
+
public static int BoolCond_IntCstVar(boolean cond, int y) {
return cond ? 1 : y;
}
@@ -80,6 +95,12 @@ public class Main {
/// CHECK: Select [{{j\d+}},{{j\d+}},<<Cond>>]
/// CHECK: cmovnz/neq
+ /// CHECK-START-X86: long Main.BoolCond_LongVarVar(boolean, long, long) disassembly (after)
+ /// CHECK: <<Cond:z\d+>> ParameterValue
+ /// CHECK: Select [{{j\d+}},{{j\d+}},<<Cond>>]
+ /// CHECK: cmovnz/ne
+ /// CHECK-NEXT: cmovnz/ne
+
public static long BoolCond_LongVarVar(boolean cond, long x, long y) {
return cond ? x : y;
}
@@ -97,6 +118,12 @@ public class Main {
/// CHECK: Select [{{j\d+}},{{j\d+}},<<Cond>>]
/// CHECK: cmovnz/neq
+ /// CHECK-START-X86: long Main.BoolCond_LongVarCst(boolean, long) disassembly (after)
+ /// CHECK: <<Cond:z\d+>> ParameterValue
+ /// CHECK: Select [{{j\d+}},{{j\d+}},<<Cond>>]
+ /// CHECK: cmovnz/ne
+ /// CHECK-NEXT: cmovnz/ne
+
public static long BoolCond_LongVarCst(boolean cond, long x) {
return cond ? x : 1L;
}
@@ -114,6 +141,12 @@ public class Main {
/// CHECK: Select [{{j\d+}},{{j\d+}},<<Cond>>]
/// CHECK: cmovnz/neq
+ /// CHECK-START-X86: long Main.BoolCond_LongCstVar(boolean, long) disassembly (after)
+ /// CHECK: <<Cond:z\d+>> ParameterValue
+ /// CHECK: Select [{{j\d+}},{{j\d+}},<<Cond>>]
+ /// CHECK: cmovnz/ne
+ /// CHECK-NEXT: cmovnz/ne
+
public static long BoolCond_LongCstVar(boolean cond, long y) {
return cond ? 1L : y;
}
@@ -168,6 +201,11 @@ public class Main {
/// CHECK-NEXT: Select [{{i\d+}},{{i\d+}},<<Cond>>]
/// CHECK: cmovle/ng
+ /// CHECK-START-X86: int Main.IntNonmatCond_IntVarVar(int, int, int, int) disassembly (after)
+ /// CHECK: <<Cond:z\d+>> LessThanOrEqual [{{i\d+}},{{i\d+}}]
+ /// CHECK-NEXT: Select [{{i\d+}},{{i\d+}},<<Cond>>]
+ /// CHECK: cmovle/ng
+
public static int IntNonmatCond_IntVarVar(int a, int b, int x, int y) {
return a > b ? x : y;
}
@@ -189,6 +227,11 @@ public class Main {
/// CHECK: Select [{{i\d+}},{{i\d+}},<<Cond>>]
/// CHECK: cmovle/ng
+ /// CHECK-START-X86: int Main.IntMatCond_IntVarVar(int, int, int, int) disassembly (after)
+ /// CHECK: <<Cond:z\d+>> LessThanOrEqual [{{i\d+}},{{i\d+}}]
+ /// CHECK: Select [{{i\d+}},{{i\d+}},<<Cond>>]
+ /// CHECK: cmovle/ng
+
public static int IntMatCond_IntVarVar(int a, int b, int x, int y) {
int result = (a > b ? x : y);
return result + (a > b ? 0 : 1);
@@ -208,6 +251,12 @@ public class Main {
/// CHECK-NEXT: Select [{{j\d+}},{{j\d+}},<<Cond>>]
/// CHECK: cmovle/ngq
+ /// CHECK-START-X86: long Main.IntNonmatCond_LongVarVar(int, int, long, long) disassembly (after)
+ /// CHECK: <<Cond:z\d+>> LessThanOrEqual [{{i\d+}},{{i\d+}}]
+ /// CHECK-NEXT: Select [{{j\d+}},{{j\d+}},<<Cond>>]
+ /// CHECK: cmovle/ng
+ /// CHECK-NEXT: cmovle/ng
+
public static long IntNonmatCond_LongVarVar(int a, int b, long x, long y) {
return a > b ? x : y;
}
@@ -232,6 +281,15 @@ public class Main {
/// CHECK: Select [{{j\d+}},{{j\d+}},<<Cond>>]
/// CHECK: cmovnz/neq
+ /// CHECK-START-X86: long Main.IntMatCond_LongVarVar(int, int, long, long) disassembly (after)
+ /// CHECK: <<Cond:z\d+>> LessThanOrEqual [{{i\d+}},{{i\d+}}]
+ /// CHECK: Select [{{j\d+}},{{j\d+}},<<Cond>>]
+ /// CHECK-NEXT: cmovle/ng
+ /// CHECK-NEXT: cmovle/ng
+ /// CHECK: Select [{{j\d+}},{{j\d+}},<<Cond>>]
+ /// CHECK: cmovnz/ne
+ /// CHECK-NEXT: cmovnz/ne
+
public static long IntMatCond_LongVarVar(int a, int b, long x, long y) {
long result = (a > b ? x : y);
return result + (a > b ? 0L : 1L);
diff --git a/test/574-irreducible-and-constant-area/expected.txt b/test/574-irreducible-and-constant-area/expected.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/574-irreducible-and-constant-area/expected.txt
diff --git a/test/574-irreducible-and-constant-area/info.txt b/test/574-irreducible-and-constant-area/info.txt
new file mode 100644
index 0000000000..e957a5ae6b
--- /dev/null
+++ b/test/574-irreducible-and-constant-area/info.txt
@@ -0,0 +1,3 @@
+Regression test for intrinsics on x86, which used to wrongly assume
+a HInvokeStaticOrDirect must have a special input (does not apply for irreducible
+loops).
diff --git a/test/574-irreducible-and-constant-area/run b/test/574-irreducible-and-constant-area/run
new file mode 100755
index 0000000000..ffdbcc9cf2
--- /dev/null
+++ b/test/574-irreducible-and-constant-area/run
@@ -0,0 +1,18 @@
+#!/bin/bash
+#
+# 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.
+
+# Don't do relocation, as this affects this test.
+exec ${RUN} "$@" --no-relocate
diff --git a/test/574-irreducible-and-constant-area/smali/IrreducibleLoop.smali b/test/574-irreducible-and-constant-area/smali/IrreducibleLoop.smali
new file mode 100644
index 0000000000..d7d43466d1
--- /dev/null
+++ b/test/574-irreducible-and-constant-area/smali/IrreducibleLoop.smali
@@ -0,0 +1,35 @@
+# 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;
+
+.method public static simpleLoop(I)I
+ .registers 5
+ const/16 v0, 42
+ const/16 v1, 42
+ const-wide/high16 v2, 0x4000000000000000L
+ if-eq p0, v0, :other_loop_entry
+ :loop_entry
+ invoke-static {v1, v1}, LMain;->$inline$foo(FF)V
+ invoke-static {v2, v3, v2, v3}, LMain;->$inline$foo(DD)V
+ if-ne p0, v0, :exit
+ add-int v0, v0, v0
+ :other_loop_entry
+ add-int v0, v0, v0
+ goto :loop_entry
+ :exit
+ return v0
+.end method
diff --git a/test/574-irreducible-and-constant-area/src/Main.java b/test/574-irreducible-and-constant-area/src/Main.java
new file mode 100644
index 0000000000..3cdd92456c
--- /dev/null
+++ b/test/574-irreducible-and-constant-area/src/Main.java
@@ -0,0 +1,41 @@
+/*
+ * 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("simpleLoop", int.class);
+ Object[] arguments = { 42 };
+ m.invoke(null, arguments);
+ }
+
+ public static void $inline$foo(float a, float b) {
+ Math.abs(a);
+ Math.max(a, b);
+ Math.min(a, b);
+ }
+
+ public static void $inline$foo(double a, double b) {
+ Math.abs(a);
+ Math.max(a, b);
+ Math.min(a, b);
+ }
+}
diff --git a/test/575-checker-isnan/expected.txt b/test/575-checker-isnan/expected.txt
new file mode 100644
index 0000000000..b0aad4deb5
--- /dev/null
+++ b/test/575-checker-isnan/expected.txt
@@ -0,0 +1 @@
+passed
diff --git a/test/575-checker-isnan/info.txt b/test/575-checker-isnan/info.txt
new file mode 100644
index 0000000000..5c48a6a877
--- /dev/null
+++ b/test/575-checker-isnan/info.txt
@@ -0,0 +1 @@
+Unit test for float/double isNaN() operation.
diff --git a/test/575-checker-isnan/src/Main.java b/test/575-checker-isnan/src/Main.java
new file mode 100644
index 0000000000..cc71e5e27d
--- /dev/null
+++ b/test/575-checker-isnan/src/Main.java
@@ -0,0 +1,126 @@
+/*
+ * 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: boolean Main.isNaN32(float) instruction_simplifier (before)
+ /// CHECK-DAG: <<Result:z\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: Return [<<Result>>]
+ //
+ /// CHECK-START: boolean Main.isNaN32(float) instruction_simplifier (after)
+ /// CHECK-DAG: <<Result:z\d+>> NotEqual
+ /// CHECK-DAG: Return [<<Result>>]
+ //
+ /// CHECK-START: boolean Main.isNaN32(float) instruction_simplifier (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
+ private static boolean isNaN32(float x) {
+ return Float.isNaN(x);
+ }
+
+ /// CHECK-START: boolean Main.isNaN64(double) instruction_simplifier (before)
+ /// CHECK-DAG: <<Result:z\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: Return [<<Result>>]
+ //
+ /// CHECK-START: boolean Main.isNaN64(double) instruction_simplifier (after)
+ /// CHECK-DAG: <<Result:z\d+>> NotEqual
+ /// CHECK-DAG: Return [<<Result>>]
+ //
+ /// CHECK-START: boolean Main.isNaN64(double) instruction_simplifier (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
+ private static boolean isNaN64(double x) {
+ return Double.isNaN(x);
+ }
+
+ public static void main(String args[]) {
+ // A few distinct numbers.
+ expectFalse(isNaN32(Float.NEGATIVE_INFINITY));
+ expectFalse(isNaN32(-1.0f));
+ expectFalse(isNaN32(-0.0f));
+ expectFalse(isNaN32(0.0f));
+ expectFalse(isNaN32(1.0f));
+ expectFalse(isNaN32(Float.POSITIVE_INFINITY));
+
+ // A few distinct subnormal numbers.
+ expectFalse(isNaN32(Float.intBitsToFloat(0x00400000)));
+ expectFalse(isNaN32(Float.intBitsToFloat(0x80400000)));
+ expectFalse(isNaN32(Float.intBitsToFloat(0x00000001)));
+ expectFalse(isNaN32(Float.intBitsToFloat(0x80000001)));
+
+ // A few NaN numbers.
+ expectTrue(isNaN32(Float.NaN));
+ expectTrue(isNaN32(0.0f / 0.0f));
+ expectTrue(isNaN32((float)Math.sqrt(-1.0f)));
+ float[] fvals = {
+ Float.intBitsToFloat(0x7f800001),
+ Float.intBitsToFloat(0x7fa00000),
+ Float.intBitsToFloat(0x7fc00000),
+ Float.intBitsToFloat(0x7fffffff),
+ Float.intBitsToFloat(0xff800001),
+ Float.intBitsToFloat(0xffa00000),
+ Float.intBitsToFloat(0xffc00000),
+ Float.intBitsToFloat(0xffffffff)
+ };
+ for (int i = 0; i < fvals.length; i++) {
+ expectTrue(isNaN32(fvals[i]));
+ }
+
+ // A few distinct numbers.
+ expectFalse(isNaN64(Double.NEGATIVE_INFINITY));
+ expectFalse(isNaN32(-1.0f));
+ expectFalse(isNaN64(-0.0d));
+ expectFalse(isNaN64(0.0d));
+ expectFalse(isNaN64(1.0d));
+ expectFalse(isNaN64(Double.POSITIVE_INFINITY));
+
+ // A few distinct subnormal numbers.
+ expectFalse(isNaN64(Double.longBitsToDouble(0x0008000000000000l)));
+ expectFalse(isNaN64(Double.longBitsToDouble(0x8008000000000000l)));
+ expectFalse(isNaN64(Double.longBitsToDouble(0x0000000000000001l)));
+ expectFalse(isNaN64(Double.longBitsToDouble(0x8000000000000001l)));
+
+ // A few NaN numbers.
+ expectTrue(isNaN64(Double.NaN));
+ expectTrue(isNaN64(0.0d / 0.0d));
+ expectTrue(isNaN64(Math.sqrt(-1.0d)));
+ double[] dvals = {
+ Double.longBitsToDouble(0x7ff0000000000001L),
+ Double.longBitsToDouble(0x7ff4000000000000L),
+ Double.longBitsToDouble(0x7ff8000000000000L),
+ Double.longBitsToDouble(0x7fffffffffffffffL),
+ Double.longBitsToDouble(0xfff0000000000001L),
+ Double.longBitsToDouble(0xfff4000000000000L),
+ Double.longBitsToDouble(0xfff8000000000000L),
+ Double.longBitsToDouble(0xffffffffffffffffL)
+ };
+ for (int i = 0; i < dvals.length; i++) {
+ expectTrue(isNaN64(dvals[i]));
+ }
+
+ System.out.println("passed");
+ }
+
+ private static void expectTrue(boolean value) {
+ if (!value) {
+ throw new Error("Expected True");
+ }
+ }
+
+ private static void expectFalse(boolean value) {
+ if (value) {
+ throw new Error("Expected False");
+ }
+ }
+}
diff --git a/test/575-checker-string-init-alias/expected.txt b/test/575-checker-string-init-alias/expected.txt
new file mode 100644
index 0000000000..6a5618ebc6
--- /dev/null
+++ b/test/575-checker-string-init-alias/expected.txt
@@ -0,0 +1 @@
+JNI_OnLoad called
diff --git a/test/575-checker-string-init-alias/info.txt b/test/575-checker-string-init-alias/info.txt
new file mode 100644
index 0000000000..a91ea645e7
--- /dev/null
+++ b/test/575-checker-string-init-alias/info.txt
@@ -0,0 +1,2 @@
+Test for the String.<init> change and deoptimization: make
+sure the compiler knows how to handle dex aliases.
diff --git a/test/575-checker-string-init-alias/smali/TestCase.smali b/test/575-checker-string-init-alias/smali/TestCase.smali
new file mode 100644
index 0000000000..ff04b278a4
--- /dev/null
+++ b/test/575-checker-string-init-alias/smali/TestCase.smali
@@ -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.
+
+.class public LTestCase;
+
+.super Ljava/lang/Object;
+
+.field public static staticField:Ljava/lang/String;
+
+## CHECK-START: void TestCase.testNoAlias(int[], java.lang.String) register (after)
+## CHECK: <<Null:l\d+>> NullConstant
+## CHECK: Deoptimize env:[[<<Null>>,{{.*]]}}
+## CHECK: InvokeStaticOrDirect method_name:java.lang.String.<init>
+.method public static testNoAlias([ILjava/lang/String;)V
+ .registers 6
+ const v1, 0
+ const v2, 1
+ new-instance v0, Ljava/lang/String;
+
+ # Will deoptimize.
+ aget v3, p0, v1
+
+ # Check that we're being executed by the interpreter.
+ invoke-static {}, LMain;->assertIsInterpreted()V
+
+ invoke-direct {v0, p1}, Ljava/lang/String;-><init>(Ljava/lang/String;)V
+
+ sput-object v0, LTestCase;->staticField:Ljava/lang/String;
+
+ # Will throw AIOOBE.
+ aget v3, p0, v2
+
+ return-void
+.end method
+
+## CHECK-START: void TestCase.testAlias(int[], java.lang.String) register (after)
+## CHECK: <<New:l\d+>> NewInstance
+## CHECK: Deoptimize env:[[<<New>>,<<New>>,{{.*]]}}
+## CHECK: InvokeStaticOrDirect method_name:java.lang.String.<init>
+.method public static testAlias([ILjava/lang/String;)V
+ .registers 7
+ const v2, 0
+ const v3, 1
+ new-instance v0, Ljava/lang/String;
+ move-object v1, v0
+
+ # Will deoptimize.
+ aget v4, p0, v2
+
+ # Check that we're being executed by the interpreter.
+ invoke-static {}, LMain;->assertIsInterpreted()V
+
+ invoke-direct {v1, p1}, Ljava/lang/String;-><init>(Ljava/lang/String;)V
+
+ sput-object v1, LTestCase;->staticField:Ljava/lang/String;
+
+ # Will throw AIOOBE.
+ aget v4, p0, v3
+
+ return-void
+.end method
diff --git a/test/575-checker-string-init-alias/src/Main.java b/test/575-checker-string-init-alias/src/Main.java
new file mode 100644
index 0000000000..1ab320748a
--- /dev/null
+++ b/test/575-checker-string-init-alias/src/Main.java
@@ -0,0 +1,68 @@
+/*
+ * 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.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+
+public class Main {
+ // Workaround for b/18051191.
+ class Inner {}
+
+ public static native void assertIsInterpreted();
+
+ private static void assertEqual(String expected, String actual) {
+ if (!expected.equals(actual)) {
+ throw new Error("Assertion failed: " + expected + " != " + actual);
+ }
+ }
+
+ public static void main(String[] args) throws Throwable {
+ System.loadLibrary(args[0]);
+ Class<?> c = Class.forName("TestCase");
+ int[] array = new int[1];
+
+ {
+ Method m = c.getMethod("testNoAlias", int[].class, String.class);
+ try {
+ m.invoke(null, new Object[] { array , "foo" });
+ throw new Error("Expected AIOOBE");
+ } catch (InvocationTargetException e) {
+ if (!(e.getCause() instanceof ArrayIndexOutOfBoundsException)) {
+ throw new Error("Expected AIOOBE");
+ }
+ // Ignore
+ }
+ Field field = c.getField("staticField");
+ assertEqual("foo", (String)field.get(null));
+ }
+
+ {
+ Method m = c.getMethod("testAlias", int[].class, String.class);
+ try {
+ m.invoke(null, new Object[] { array, "bar" });
+ throw new Error("Expected AIOOBE");
+ } catch (InvocationTargetException e) {
+ if (!(e.getCause() instanceof ArrayIndexOutOfBoundsException)) {
+ throw new Error("Expected AIOOBE");
+ }
+ // Ignore
+ }
+ Field field = c.getField("staticField");
+ assertEqual("bar", (String)field.get(null));
+ }
+ }
+}
diff --git a/test/576-polymorphic-inlining/expected.txt b/test/576-polymorphic-inlining/expected.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/576-polymorphic-inlining/expected.txt
diff --git a/test/576-polymorphic-inlining/info.txt b/test/576-polymorphic-inlining/info.txt
new file mode 100644
index 0000000000..b3ef0c8fba
--- /dev/null
+++ b/test/576-polymorphic-inlining/info.txt
@@ -0,0 +1 @@
+Test for polymorphic inlining.
diff --git a/test/576-polymorphic-inlining/src/Main.java b/test/576-polymorphic-inlining/src/Main.java
new file mode 100644
index 0000000000..d8d09aff87
--- /dev/null
+++ b/test/576-polymorphic-inlining/src/Main.java
@@ -0,0 +1,103 @@
+/*
+ * 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 {
+ public static void main(String[] args) {
+ for (int i = 0; i < 20000; ++i) {
+ $noinline$testVoid(new Main());
+ $noinline$testVoid(new SubMain());
+ $noinline$testVoid(new SubSubMain());
+
+ $noinline$testWithReturnValue(new Main());
+ $noinline$testWithReturnValue(new SubMain());
+ $noinline$testWithReturnValue(new SubSubMain());
+
+ $noinline$testWithBackEdge(new Main());
+ $noinline$testWithBackEdge(new SubMain());
+ $noinline$testWithBackEdge(new SubSubMain());
+ }
+ }
+
+ public static void assertIdentical(Object expected, Object actual) {
+ if (expected != actual) {
+ throw new Error("Expected " + expected + ", got " + actual);
+ }
+ }
+
+ public static void $noinline$testVoid(Main m) {
+ if (doThrow) throw new Error("");
+ m.willInlineVoid();
+ m.willOnlyInlineForMainVoid();
+ }
+
+ public static void $noinline$testWithReturnValue(Main m) {
+ if (doThrow) throw new Error("");
+ assertIdentical(m.getClass(), m.willInlineWithReturnValue());
+ assertIdentical(m.getClass(), m.willOnlyInlineForMainWithReturnValue());
+ }
+
+ public static void $noinline$testWithBackEdge(Main m) {
+ if (doThrow) throw new Error("");
+ for (int i = 0; i < 10; ++i) {
+ m.willInlineVoid();
+ }
+ for (int i = 0; i < 10; ++i) {
+ m.willOnlyInlineForMainVoid();
+ }
+ }
+
+ public void willInlineVoid() {
+ }
+
+ public void willOnlyInlineForMainVoid() {
+ }
+
+ public Class willInlineWithReturnValue() {
+ return Main.class;
+ }
+
+ public Class willOnlyInlineForMainWithReturnValue() {
+ return Main.class;
+ }
+ public static boolean doThrow;
+}
+
+class SubMain extends Main {
+ public void willOnlyInlineForMainVoid() {
+ if (doThrow) throw new Error("");
+ }
+
+ public void willInlineVoid() {
+ }
+
+ public Class willInlineWithReturnValue() {
+ return SubMain.class;
+ }
+
+ public Class willOnlyInlineForMainWithReturnValue() {
+ return SubMain.class;
+ }
+}
+
+class SubSubMain extends SubMain {
+ public Class willInlineWithReturnValue() {
+ return SubSubMain.class;
+ }
+
+ public Class willOnlyInlineForMainWithReturnValue() {
+ return SubSubMain.class;
+ }
+}
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index b3560b634b..364be59919 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -42,8 +42,7 @@ TEST_ART_RUN_TEST_ORDERONLY_DEPENDENCIES :=
ifeq ($(ANDROID_COMPILE_WITH_JACK),true)
TEST_ART_RUN_TEST_DEPENDENCIES += \
- $(JACK) \
- $(JILL_JAR)
+ $(JACK)
TEST_ART_RUN_TEST_ORDERONLY_DEPENDENCIES += setup-jack-server
endif
@@ -72,8 +71,8 @@ $$(dmart_target): $(TEST_ART_RUN_TEST_DEPENDENCIES) $(TARGET_JACK_CLASSPATH_DEPE
DXMERGER=$(abspath $(HOST_OUT_EXECUTABLES)/dexmerger) \
JACK_VERSION=$(JACK_DEFAULT_VERSION) \
JACK=$(abspath $(JACK)) \
+ JACK_VERSION=$(JACK_DEFAULT_VERSION) \
JACK_CLASSPATH=$(TARGET_JACK_CLASSPATH) \
- JILL_JAR=$(abspath $(JILL_JAR)) \
$(LOCAL_PATH)/run-test $$(PRIVATE_RUN_TEST_OPTIONS) --output-path $$(abspath $$(dir $$@)) $(1)
$(hide) touch $$@
@@ -962,8 +961,8 @@ $$(run_test_rule_name): $(TEST_ART_RUN_TEST_DEPENDENCIES) $(HOST_OUT_EXECUTABLES
DXMERGER=$(abspath $(HOST_OUT_EXECUTABLES)/dexmerger) \
JACK_VERSION=$(JACK_DEFAULT_VERSION) \
JACK=$(abspath $(JACK)) \
+ JACK_VERSION=$(JACK_DEFAULT_VERSION) \
JACK_CLASSPATH=$$(PRIVATE_JACK_CLASSPATH) \
- JILL_JAR=$(abspath $(JILL_JAR)) \
art/test/run-test $$(PRIVATE_RUN_TEST_OPTIONS) $(12) \
&& $$(call ART_TEST_PASSED,$$@) || $$(call ART_TEST_FAILED,$$@)
$$(hide) (echo $(MAKECMDGOALS) | grep -q $$@ && \
diff --git a/test/run-test b/test/run-test
index faa597e1ca..f1875d71a5 100755
--- a/test/run-test
+++ b/test/run-test
@@ -88,13 +88,7 @@ if [ -z "$JACK_CLASSPATH" ]; then
export JACK_CLASSPATH="${OUT_DIR:-$ANDROID_BUILD_TOP/out}/host/common/obj/JAVA_LIBRARIES/core-libart-hostdex_intermediates/classes.jack:${OUT_DIR:-$ANDROID_BUILD_TOP/out}/host/common/obj/JAVA_LIBRARIES/core-oj-hostdex_intermediates/classes.jack"
fi
-# If JILL_JAR is not set, assume it is located in the prebuilts directory.
-if [ -z "$JILL_JAR" ]; then
- export JILL_JAR="$ANDROID_BUILD_TOP/prebuilts/sdk/tools/jill.jar"
-fi
-
export JACK="$JACK -g -cp $JACK_CLASSPATH"
-export JILL="java -jar $JILL_JAR"
info="info.txt"
build="build"