summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/021-string2/expected.txt4
-rw-r--r--test/021-string2/src/Main.java25
-rw-r--r--test/137-cfi/cfi.cc4
-rw-r--r--test/141-class-unload/expected.txt1
-rw-r--r--test/141-class-unload/jni_unload.cc14
-rw-r--r--test/141-class-unload/src/Main.java12
-rw-r--r--test/153-reference-stress/expected.txt1
-rw-r--r--test/153-reference-stress/info.txt1
-rw-r--r--test/153-reference-stress/src/Main.java73
-rw-r--r--test/530-checker-loops3/src/Main.java85
-rw-r--r--test/530-checker-loops4/src/Main.java28
-rw-r--r--test/552-checker-sharpening/src/Main.java23
-rw-r--r--test/616-cha-regression-proxy-method/expected.txt1
-rw-r--r--test/616-cha-regression-proxy-method/info.txt1
-rw-r--r--test/616-cha-regression-proxy-method/src/Main.java131
-rw-r--r--test/616-cha/run (renamed from test/Android.arm_vixl.mk)10
-rw-r--r--test/616-cha/src/Main.java9
-rw-r--r--test/618-checker-induction/src/Main.java123
-rw-r--r--test/623-checker-loop-regressions/src/Main.java87
-rw-r--r--test/624-checker-stringops/src/Main.java16
-rw-r--r--test/626-checker-arm64-scratch-register/expected.txt1
-rw-r--r--test/626-checker-arm64-scratch-register/info.txt2
-rw-r--r--test/626-checker-arm64-scratch-register/src/Main.java298
-rw-r--r--test/628-vdex/run2
-rw-r--r--test/630-safecast-array/expected.txt0
-rw-r--r--test/630-safecast-array/info.txt3
-rw-r--r--test/630-safecast-array/smali/Main.smali33
-rw-r--r--test/706-jit-skip-compilation/expected.txt1
-rw-r--r--test/706-jit-skip-compilation/info.txt4
-rw-r--r--test/706-jit-skip-compilation/run19
-rw-r--r--test/706-jit-skip-compilation/smali/errclass.smali34
-rw-r--r--test/706-jit-skip-compilation/src/Main.java57
-rw-r--r--test/911-get-stack-trace/expected.txt358
-rw-r--r--test/911-get-stack-trace/src/Main.java15
-rw-r--r--test/911-get-stack-trace/stack_trace.cc78
-rw-r--r--test/913-heaps/expected.txt16
-rw-r--r--test/913-heaps/heaps.cc7
-rwxr-xr-xtest/917-fields-transformation/build17
-rw-r--r--test/917-fields-transformation/expected.txt12
-rw-r--r--test/917-fields-transformation/info.txt1
-rwxr-xr-xtest/917-fields-transformation/run43
-rw-r--r--test/917-fields-transformation/src/Main.java80
-rw-r--r--test/917-fields-transformation/src/Transform.java29
-rw-r--r--test/Android.run-test.mk65
-rw-r--r--test/ErroneousA/ErroneousA.java17
-rw-r--r--test/ErroneousB/ErroneousB.java20
-rw-r--r--test/common/runtime_state.cc24
-rwxr-xr-xtest/etc/run-test-jar15
-rw-r--r--test/ti-agent/common_load.cc1
49 files changed, 1643 insertions, 258 deletions
diff --git a/test/021-string2/expected.txt b/test/021-string2/expected.txt
index a9c6eb87bd..f269c7cf3e 100644
--- a/test/021-string2/expected.txt
+++ b/test/021-string2/expected.txt
@@ -1,2 +1,6 @@
Got expected npe
OK
+ true true true true
+ true true true true
+ true true true true
+ true true true true
diff --git a/test/021-string2/src/Main.java b/test/021-string2/src/Main.java
index 51351e1835..df0a3ddf48 100644
--- a/test/021-string2/src/Main.java
+++ b/test/021-string2/src/Main.java
@@ -92,6 +92,31 @@ public class Main {
testCompareToAndEquals();
testIndexOf();
+
+ String s0_0 = "\u0000";
+ String s0_1 = new String(s0_0);
+ String s0_2 = new String(new char[] { '\u0000' });
+ String s0_3 = s0_0 + "";
+ System.out.println(
+ " " + $noinline$equals(s0_0, s0_0) +
+ " " + $noinline$equals(s0_0, s0_1) +
+ " " + $noinline$equals(s0_0, s0_2) +
+ " " + $noinline$equals(s0_0, s0_3));
+ System.out.println(
+ " " + $noinline$equals(s0_1, s0_0) +
+ " " + $noinline$equals(s0_1, s0_1) +
+ " " + $noinline$equals(s0_1, s0_2) +
+ " " + $noinline$equals(s0_1, s0_3));
+ System.out.println(
+ " " + $noinline$equals(s0_2, s0_0) +
+ " " + $noinline$equals(s0_2, s0_1) +
+ " " + $noinline$equals(s0_2, s0_2) +
+ " " + $noinline$equals(s0_2, s0_3));
+ System.out.println(
+ " " + $noinline$equals(s0_3, s0_0) +
+ " " + $noinline$equals(s0_3, s0_1) +
+ " " + $noinline$equals(s0_3, s0_2) +
+ " " + $noinline$equals(s0_3, s0_3));
}
public static void testCompareToAndEquals() {
diff --git a/test/137-cfi/cfi.cc b/test/137-cfi/cfi.cc
index 113b35f98d..3b237f40ff 100644
--- a/test/137-cfi/cfi.cc
+++ b/test/137-cfi/cfi.cc
@@ -25,11 +25,11 @@
#include "jni.h"
+#include "android-base/stringprintf.h"
#include <backtrace/Backtrace.h>
#include "base/logging.h"
#include "base/macros.h"
-#include "base/stringprintf.h"
#include "gc/heap.h"
#include "gc/space/image_space.h"
#include "oat_file.h"
@@ -91,7 +91,7 @@ static bool CheckStack(Backtrace* bt, const std::vector<std::string>& seq) {
static void MoreErrorInfo(pid_t pid, bool sig_quit_on_fail) {
printf("Secondary pid is %d\n", pid);
- PrintFileToLog(StringPrintf("/proc/%d/maps", pid), ::android::base::ERROR);
+ PrintFileToLog(android::base::StringPrintf("/proc/%d/maps", pid), ::android::base::ERROR);
if (sig_quit_on_fail) {
int res = kill(pid, SIGQUIT);
diff --git a/test/141-class-unload/expected.txt b/test/141-class-unload/expected.txt
index 0a03ecb3a4..a1c5fa8a2f 100644
--- a/test/141-class-unload/expected.txt
+++ b/test/141-class-unload/expected.txt
@@ -20,5 +20,6 @@ null
JNI_OnLoad called
class null false test
JNI_OnUnload called
+JNI_OnLoad called
Number of loaded unload-ex maps 0
Too small false
diff --git a/test/141-class-unload/jni_unload.cc b/test/141-class-unload/jni_unload.cc
index bbbb0a6036..9b7e171a95 100644
--- a/test/141-class-unload/jni_unload.cc
+++ b/test/141-class-unload/jni_unload.cc
@@ -32,5 +32,19 @@ extern "C" JNIEXPORT void JNICALL Java_IntHolder_waitForCompilation(JNIEnv*, jcl
}
}
+extern "C" JNIEXPORT void JNICALL Java_Main_stopJit(JNIEnv*, jclass) {
+ jit::Jit* jit = Runtime::Current()->GetJit();
+ if (jit != nullptr) {
+ jit->Stop();
+ }
+}
+
+extern "C" JNIEXPORT void JNICALL Java_Main_startJit(JNIEnv*, jclass) {
+ jit::Jit* jit = Runtime::Current()->GetJit();
+ if (jit != nullptr) {
+ jit->Start();
+ }
+}
+
} // namespace
} // namespace art
diff --git a/test/141-class-unload/src/Main.java b/test/141-class-unload/src/Main.java
index 2a6e9442e8..595c70d0f6 100644
--- a/test/141-class-unload/src/Main.java
+++ b/test/141-class-unload/src/Main.java
@@ -55,11 +55,15 @@ public class Main {
}
private static void testOatFilesUnloaded(int pid) throws Exception {
+ System.loadLibrary(nativeLibraryName);
+ // Stop the JIT to ensure its threads and work queue are not keeping classes
+ // artifically alive.
+ stopJit();
+ Runtime.getRuntime().gc();
+ System.runFinalization();
BufferedReader reader = new BufferedReader(new FileReader ("/proc/" + pid + "/maps"));
String line;
int count = 0;
- Runtime.getRuntime().gc();
- System.runFinalization();
while ((line = reader.readLine()) != null) {
if (line.contains("@141-class-unload-ex.jar")) {
System.out.println(line);
@@ -67,6 +71,7 @@ public class Main {
}
}
System.out.println("Number of loaded unload-ex maps " + count);
+ startJit();
}
private static void stressTest(Constructor<?> constructor) throws Exception {
@@ -229,4 +234,7 @@ public class Main {
private static int getPid() throws Exception {
return Integer.parseInt(new File("/proc/self").getCanonicalFile().getName());
}
+
+ public static native void stopJit();
+ public static native void startJit();
}
diff --git a/test/153-reference-stress/expected.txt b/test/153-reference-stress/expected.txt
new file mode 100644
index 0000000000..7ef22e9a43
--- /dev/null
+++ b/test/153-reference-stress/expected.txt
@@ -0,0 +1 @@
+PASS
diff --git a/test/153-reference-stress/info.txt b/test/153-reference-stress/info.txt
new file mode 100644
index 0000000000..6bc00404ab
--- /dev/null
+++ b/test/153-reference-stress/info.txt
@@ -0,0 +1 @@
+Tests java.lang.ref.Reference.get() and GC running in parallel.
diff --git a/test/153-reference-stress/src/Main.java b/test/153-reference-stress/src/Main.java
new file mode 100644
index 0000000000..fc6f9ccb35
--- /dev/null
+++ b/test/153-reference-stress/src/Main.java
@@ -0,0 +1,73 @@
+/*
+ * 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.ref.WeakReference;
+
+public class Main {
+ static final int numWeakReferences = 16 * 1024;
+ static WeakReference[] weakReferences = new WeakReference[numWeakReferences];
+ static volatile boolean done = false;
+ static Object keepAlive;
+
+ public static void main(String[] args) throws Exception {
+ // Try to call Reference.get repeatedly while the GC is running.
+ Thread gcThread = new GcThread();
+ Thread[] readerThread = new ReaderThread[4];
+ for (int i = 0; i < readerThread.length; ++i) {
+ readerThread[i] = new ReaderThread();
+ }
+ gcThread.start();
+ for (int i = 0; i < readerThread.length; ++i) {
+ readerThread[i].start();
+ }
+ gcThread.join();
+ for (int i = 0; i < readerThread.length; ++i) {
+ readerThread[i].join();
+ }
+ System.out.println("PASS");
+ }
+
+ static class GcThread extends Thread {
+ GcThread() {
+ Object temp = new Object();
+ for (int j = 0; j < weakReferences.length; ++j) {
+ weakReferences[j] = new WeakReference(temp);
+ }
+ }
+ public void run() {
+ for (int i = 0; i < 1000; ++i) {
+ Object o = new Object();
+ for (int j = 0; j < weakReferences.length; ++j) {
+ weakReferences[j] = new WeakReference(o);
+ }
+ }
+ done = true;
+ }
+ }
+
+ static class ReaderThread extends Thread {
+ public void run() {
+ while (!done) {
+ for (int j = 0; j < weakReferences.length; ++j) {
+ keepAlive = weakReferences[j].get();
+ }
+ for (int j = 0; j < weakReferences.length; ++j) {
+ weakReferences[j].clear();
+ }
+ }
+ }
+ }
+}
diff --git a/test/530-checker-loops3/src/Main.java b/test/530-checker-loops3/src/Main.java
index 209786a113..dfc4a5f98f 100644
--- a/test/530-checker-loops3/src/Main.java
+++ b/test/530-checker-loops3/src/Main.java
@@ -235,6 +235,59 @@ public class Main {
}
}
+ /// CHECK-START: void Main.shortBound1(int[], short) BCE (before)
+ /// CHECK-DAG: BoundsCheck loop:{{B\d+}}
+ //
+ /// CHECK-START: void Main.shortBound1(int[], short) BCE (after)
+ /// CHECK-DAG: Deoptimize loop:none
+ /// CHECK-DAG: Deoptimize loop:none
+ /// CHECK-DAG: Deoptimize loop:none
+ /// CHECK-NOT: Deoptimize
+ //
+ /// CHECK-START: void Main.shortBound1(int[], short) BCE (after)
+ /// CHECK-NOT: BoundsCheck
+ public static void shortBound1(int[] array, short s) {
+ // Lower precision bound will appear in deopt arithmetic
+ // and follows normal implicit widening conversion.
+ for (int i = 0; i < s; i++) {
+ array[i] = 222;
+ }
+ }
+
+ /// CHECK-START: void Main.shortBound2(int[], short) BCE (before)
+ /// CHECK-DAG: BoundsCheck loop:{{B\d+}}
+ //
+ /// CHECK-START: void Main.shortBound2(int[], short) BCE (after)
+ /// CHECK-DAG: Deoptimize loop:none
+ /// CHECK-DAG: Deoptimize loop:none
+ /// CHECK-DAG: Deoptimize loop:none
+ /// CHECK-NOT: Deoptimize
+ //
+ /// CHECK-START: void Main.shortBound2(int[], short) BCE (after)
+ /// CHECK-NOT: BoundsCheck
+ public static void shortBound2(int[] array, short s) {
+ // Lower precision bound will appear in deopt arithmetic
+ // and follows normal implicit widening conversion.
+ for (int i = 0; s > i; i++) {
+ array[i] = 444;
+ }
+ }
+
+ /// CHECK-START: void Main.narrowingFromLong(int[], int) BCE (before)
+ /// CHECK-DAG: BoundsCheck loop:{{B\d+}}
+ //
+ /// CHECK-START: void Main.narrowingFromLong(int[], int) BCE (after)
+ /// CHECK-DAG: BoundsCheck loop:{{B\d+}}
+ public static void narrowingFromLong(int[] array, int n) {
+ // Parallel induction in long precision that is narrowed provides type
+ // conversion challenges for BCE in deopt arithmetic when combined
+ // with the int loop induction. Therefore, currently skipped.
+ long l = 0;
+ for (int i = 0; i < n; i++, l++) {
+ array[(int)l] = 888;
+ }
+ }
+
//
// Verifier.
//
@@ -316,6 +369,38 @@ public class Main {
} catch (ArrayIndexOutOfBoundsException e) {
}
+ shortBound1(a, (short)a.length);
+ for (int i = 0; i < a.length; i++) {
+ expectEquals(222, a[i]);
+ }
+ shortBound2(a, (short)a.length);
+ for (int i = 0; i < a.length; i++) {
+ expectEquals(444, a[i]);
+ }
+
+ try {
+ shortBound1(a, (short)(a.length + 1));
+ throw new Error("Should throw AIOOBE");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ }
+ for (int i = 0; i < a.length; i++) {
+ expectEquals(222, a[i]);
+ }
+
+ try {
+ shortBound2(a, (short)(a.length + 1));
+ throw new Error("Should throw AIOOBE");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ }
+ for (int i = 0; i < a.length; i++) {
+ expectEquals(444, a[i]);
+ }
+
+ narrowingFromLong(a, a.length);
+ for (int i = 0; i < a.length; i++) {
+ expectEquals(888, a[i]);
+ }
+
System.out.println("passed");
}
diff --git a/test/530-checker-loops4/src/Main.java b/test/530-checker-loops4/src/Main.java
index 7d3d7d9bfe..91af1f4ee9 100644
--- a/test/530-checker-loops4/src/Main.java
+++ b/test/530-checker-loops4/src/Main.java
@@ -96,7 +96,29 @@ public class Main {
/// CHECK-NOT: Phi
public static int geo4(int a) {
for (int i = 0; i < 10; i++) {
- a %= 7;
+ a %= 7; // a wrap-around induction
+ }
+ return a;
+ }
+
+ /// CHECK-START: int Main.geo5() loop_optimization (before)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Shr loop:<<Loop>>
+ //
+ /// CHECK-START: int Main.geo5() loop_optimization (after)
+ /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 loop:none
+ /// CHECK-DAG: <<Int1:i\d+>> IntConstant 2147483647 loop:none
+ /// CHECK-DAG: <<Int2:i\d+>> IntConstant 1024 loop:none
+ /// CHECK-DAG: <<Div:i\d+>> Div [<<Int1>>,<<Int2>>] loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Div>>,<<Zero>>] loop:none
+ /// CHECK-DAG: Return [<<Add>>] loop:none
+ //
+ /// CHECK-START: int Main.geo5() loop_optimization (after)
+ /// CHECK-NOT: Phi
+ public static int geo5() {
+ int a = 0x7fffffff;
+ for (int i = 0; i < 10; i++) {
+ a >>= 1;
}
return a;
}
@@ -186,7 +208,7 @@ public class Main {
int r = 0;
for (int i = 0; i < 100; i++) { // a converges to 0
r += x[a];
- a %= 5;
+ a %= 5; // a wrap-around induction
}
return r;
}
@@ -305,6 +327,8 @@ public class Main {
expectEquals(i % 7, geo4(i));
}
+ expectEquals(0x1fffff, geo5());
+
expectEquals(34, geo1BCE());
expectEquals(36, geo2BCE());
expectEquals(131, geo3BCE());
diff --git a/test/552-checker-sharpening/src/Main.java b/test/552-checker-sharpening/src/Main.java
index 9e475ab9be..fe6ff13628 100644
--- a/test/552-checker-sharpening/src/Main.java
+++ b/test/552-checker-sharpening/src/Main.java
@@ -55,6 +55,9 @@ public class Main {
/// CHECK-NOT: MipsDexCacheArraysBase
/// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
+ /// CHECK-START-MIPS64: int Main.testSimple(int) sharpening (after)
+ /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
+
/// CHECK-START-X86: int Main.testSimple(int) sharpening (after)
/// CHECK-NOT: X86ComputeBaseMethodAddress
/// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
@@ -96,6 +99,10 @@ public class Main {
/// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
/// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
+ /// CHECK-START-MIPS64: int Main.testDiamond(boolean, int) sharpening (after)
+ /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
+ /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
+
/// CHECK-START-X86: int Main.testDiamond(boolean, int) sharpening (after)
/// CHECK-NOT: X86ComputeBaseMethodAddress
/// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
@@ -274,6 +281,11 @@ public class Main {
// TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress.
/// CHECK: LoadString load_kind:{{BootImageAddress|BssEntry|DexCacheViaMethod}}
+ /// CHECK-START-MIPS64: java.lang.String Main.$noinline$getBootImageString() sharpening (after)
+ // Note: load kind depends on PIC/non-PIC
+ // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress.
+ /// CHECK: LoadString load_kind:{{BootImageAddress|BssEntry|DexCacheViaMethod}}
+
public static String $noinline$getBootImageString() {
// Prevent inlining to avoid the string comparison being optimized away.
if (doThrow) { throw new Error(); }
@@ -303,6 +315,9 @@ public class Main {
/// CHECK-START-MIPS: java.lang.String Main.$noinline$getNonBootImageString() sharpening (after)
/// CHECK: LoadString load_kind:BssEntry
+ /// CHECK-START-MIPS64: java.lang.String Main.$noinline$getNonBootImageString() sharpening (after)
+ /// CHECK: LoadString load_kind:BssEntry
+
public static String $noinline$getNonBootImageString() {
// Prevent inlining to avoid the string comparison being optimized away.
if (doThrow) { throw new Error(); }
@@ -338,6 +353,11 @@ public class Main {
// TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress.
/// CHECK: LoadClass load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}} class_name:java.lang.String
+ /// CHECK-START-MIPS64: java.lang.Class Main.$noinline$getStringClass() sharpening (after)
+ // Note: load kind depends on PIC/non-PIC
+ // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress.
+ /// CHECK: LoadClass load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}} class_name:java.lang.String
+
public static Class<?> $noinline$getStringClass() {
// Prevent inlining to avoid the string comparison being optimized away.
if (doThrow) { throw new Error(); }
@@ -375,6 +395,9 @@ public class Main {
/// CHECK-DAG: MipsDexCacheArraysBase
/// CHECK-DAG: LoadClass load_kind:DexCachePcRelative class_name:Other
+ /// CHECK-START-MIPS64: java.lang.Class Main.$noinline$getOtherClass() sharpening (after)
+ /// CHECK: LoadClass load_kind:DexCachePcRelative class_name:Other
+
public static Class<?> $noinline$getOtherClass() {
// Prevent inlining to avoid the string comparison being optimized away.
if (doThrow) { throw new Error(); }
diff --git a/test/616-cha-regression-proxy-method/expected.txt b/test/616-cha-regression-proxy-method/expected.txt
new file mode 100644
index 0000000000..6a5618ebc6
--- /dev/null
+++ b/test/616-cha-regression-proxy-method/expected.txt
@@ -0,0 +1 @@
+JNI_OnLoad called
diff --git a/test/616-cha-regression-proxy-method/info.txt b/test/616-cha-regression-proxy-method/info.txt
new file mode 100644
index 0000000000..386a07f398
--- /dev/null
+++ b/test/616-cha-regression-proxy-method/info.txt
@@ -0,0 +1 @@
+Regression test for Class Hierarchy Analysis (CHA) on visiting proxy method frame.
diff --git a/test/616-cha-regression-proxy-method/src/Main.java b/test/616-cha-regression-proxy-method/src/Main.java
new file mode 100644
index 0000000000..19c92be006
--- /dev/null
+++ b/test/616-cha-regression-proxy-method/src/Main.java
@@ -0,0 +1,131 @@
+/*
+ * 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.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+class Main1 {
+ void foo(int i) {
+ if (i != 1) {
+ printError("error1");
+ }
+ }
+
+ void printError(String msg) {
+ System.out.println(msg);
+ }
+}
+
+class Main2 extends Main1 {
+ void foo(int i) {
+ if (i != 2) {
+ printError("error2");
+ }
+ }
+}
+
+class Proxied implements Runnable {
+ public void run() {
+ synchronized(Main.class) {
+ Main.sOtherThreadStarted = true;
+ // Wait for Main2 to be linked and deoptimization is triggered.
+ try {
+ Main.class.wait();
+ } catch (Exception e) {
+ }
+ }
+ }
+}
+
+class MyInvocationHandler implements InvocationHandler {
+ private final Proxied proxied;
+
+ public MyInvocationHandler(Proxied proxied) {
+ this.proxied = proxied;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ return method.invoke(proxied, args);
+ }
+}
+
+public class Main {
+ static Main1 sMain1;
+ static Main1 sMain2;
+ static volatile boolean sOtherThreadStarted;
+
+ // sMain1.foo() will be always be Main1.foo() before Main2 is loaded/linked.
+ // So sMain1.foo() can be devirtualized to Main1.foo() and be inlined.
+ // After Dummy.createMain2() which links in Main2, live testOverride() on stack
+ // should be deoptimized.
+ static void testOverride() {
+ sMain1.foo(sMain1.getClass() == Main1.class ? 1 : 2);
+
+ // Wait for the other thread to start.
+ while (!sOtherThreadStarted);
+ // Create an Main2 instance and assign it to sMain2.
+ // sMain1 is kept the same.
+ sMain2 = Dummy.createMain2();
+ // Wake up the other thread.
+ synchronized(Main.class) {
+ Main.class.notify();
+ }
+
+ // There should be a deoptimization here right after Main2 is linked by
+ // calling Dummy.createMain2(), even though sMain1 didn't change.
+ // The behavior here would be different if inline-cache is used, which
+ // doesn't deoptimize since sMain1 still hits the type cache.
+ sMain1.foo(sMain1.getClass() == Main1.class ? 1 : 2);
+ if (sMain2 != null) {
+ sMain2.foo(sMain2.getClass() == Main1.class ? 1 : 2);
+ }
+ }
+
+ // Test scenarios under which CHA-based devirtualization happens,
+ // and class loading that overrides a method can invalidate compiled code.
+ // Also create a proxy method such that a proxy method's frame is visited
+ // during stack walking.
+ public static void main(String[] args) {
+ System.loadLibrary(args[0]);
+ // sMain1 is an instance of Main1. Main2 hasn't bee loaded yet.
+ sMain1 = new Main1();
+
+ // Create another thread that calls a proxy method.
+ new Thread() {
+ public void run() {
+ Runnable proxy = (Runnable)Proxy.newProxyInstance(
+ Proxied.class.getClassLoader(),
+ new Class[] { Runnable.class },
+ new MyInvocationHandler(new Proxied()));
+ proxy.run();
+ }
+ }.start();
+
+ ensureJitCompiled(Main.class, "testOverride");
+ // This will create Main2 instance in the middle of testOverride().
+ testOverride();
+ }
+
+ private static native void ensureJitCompiled(Class<?> itf, String method_name);
+}
+
+// Put createMain2() in another class to avoid class loading due to verifier.
+class Dummy {
+ static Main1 createMain2() {
+ return new Main2();
+ }
+}
diff --git a/test/Android.arm_vixl.mk b/test/616-cha/run
index c89eb4a1d8..9c64c7dc66 100644
--- a/test/Android.arm_vixl.mk
+++ b/test/616-cha/run
@@ -1,3 +1,4 @@
+#!/bin/bash
#
# Copyright (C) 2016 The Android Open Source Project
#
@@ -5,16 +6,13 @@
# 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
+# 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.
-#
-# Known broken tests for the ARM VIXL backend.
-TEST_ART_BROKEN_OPTIMIZING_ARM_VIXL_RUN_TESTS := \
- 562-checker-no-intermediate \
- 624-checker-stringops \
+# Run without an app image to prevent the classes to be loaded at startup.
+exec ${RUN} "${@}" --no-app-image
diff --git a/test/616-cha/src/Main.java b/test/616-cha/src/Main.java
index 787318dd67..b6179449df 100644
--- a/test/616-cha/src/Main.java
+++ b/test/616-cha/src/Main.java
@@ -179,7 +179,7 @@ public class Main {
}
}
- // Test scanerios under which CHA-based devirtualization happens,
+ // Test scenarios under which CHA-based devirtualization happens,
// and class loading that overrides a method can invalidate compiled code.
// Also test pure non-overriding case, which is more for checking generated
// code form.
@@ -206,11 +206,6 @@ public class Main {
// sMain1 is an instance of Main1. Main2 hasn't bee loaded yet.
sMain1 = new Main1();
- // Loop enough to get testOverride() JITed.
- for (int i=0; i<100; i++) {
- testOverride(false, false, false);
- }
-
ensureJitCompiled(Main.class, "testOverride");
testOverride(false, false, true);
@@ -244,7 +239,7 @@ public class Main {
private static native boolean hasSingleImplementation(Class<?> clazz, String method_name);
}
-// Do it in another class to avoid class loading due to verifier.
+// Put createMain2() in another class to avoid class loading due to verifier.
class Dummy {
static Main1 createMain2() {
return new Main2();
diff --git a/test/618-checker-induction/src/Main.java b/test/618-checker-induction/src/Main.java
index 87a69b25c4..ad3ff448d0 100644
--- a/test/618-checker-induction/src/Main.java
+++ b/test/618-checker-induction/src/Main.java
@@ -248,6 +248,33 @@ public class Main {
return closed; // only needs last value
}
+ /// CHECK-START: int Main.closedFormInductionTrivialIf() loop_optimization (before)
+ /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: Select loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: Return [<<Phi1>>] loop:none
+ //
+ /// CHECK-START: int Main.closedFormInductionTrivialIf() loop_optimization (after)
+ /// CHECK-NOT: Phi
+ /// CHECK-NOT: Select
+ //
+ /// CHECK-START: int Main.closedFormInductionTrivialIf() instruction_simplifier$after_bce (after)
+ /// CHECK-DAG: <<Int:i\d+>> IntConstant 81 loop:none
+ /// CHECK-DAG: Return [<<Int>>] loop:none
+ static int closedFormInductionTrivialIf() {
+ int closed = 11;
+ for (int i = 0; i < 10; i++) {
+ // Trivial if becomes trivial select at HIR level.
+ // Make sure this is still recognized as induction.
+ if (i < 5) {
+ closed += 7;
+ } else {
+ closed += 7;
+ }
+ }
+ return closed; // only needs last value
+ }
+
/// CHECK-START: int Main.closedFormNested() loop_optimization (before)
/// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none
/// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop1>> outer_loop:none
@@ -438,6 +465,20 @@ public class Main {
return i;
}
+ // TODO: handle as closed/empty eventually?
+ static int mainIndexShort1(short s) {
+ int i = 0;
+ for (i = 0; i < s; i++) { }
+ return i;
+ }
+
+ // TODO: handle as closed/empty eventually?
+ static int mainIndexShort2(short s) {
+ int i = 0;
+ for (i = 0; s > i; i++) { }
+ return i;
+ }
+
/// CHECK-START: int Main.periodicReturnedN(int) loop_optimization (before)
/// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
/// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
@@ -666,6 +707,75 @@ public class Main {
return x;
}
+ /// CHECK-START: float Main.periodicFloat10() loop_optimization (before)
+ /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Phi2:f\d+>> Phi loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Phi3:f\d+>> Phi loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Phi4:f\d+>> Phi loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: Return [<<Phi2>>] loop:none
+ //
+ /// CHECK-START: float Main.periodicFloat10() loop_optimization (after)
+ /// CHECK-NOT: Phi
+ //
+ /// CHECK-START: float Main.periodicFloat10() loop_optimization (after)
+ /// CHECK-DAG: <<Float:f\d+>> FloatConstant 2 loop:none
+ /// CHECK-DAG: Return [<<Float>>] loop:none
+ private static float periodicFloat10() {
+ float r = 4.5f;
+ float s = 2.0f;
+ float t = -1.0f;
+ for (int i = 0; i < 10; i++) {
+ float tmp = t; t = r; r = s; s = tmp;
+ }
+ return r;
+ }
+
+ /// CHECK-START: float Main.periodicFloat11() loop_optimization (before)
+ /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Phi2:f\d+>> Phi loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Phi3:f\d+>> Phi loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Phi4:f\d+>> Phi loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: Return [<<Phi2>>] loop:none
+ //
+ /// CHECK-START: float Main.periodicFloat11() loop_optimization (after)
+ /// CHECK-NOT: Phi
+ //
+ /// CHECK-START: float Main.periodicFloat11() loop_optimization (after)
+ /// CHECK-DAG: <<Float:f\d+>> FloatConstant -1 loop:none
+ /// CHECK-DAG: Return [<<Float>>] loop:none
+ private static float periodicFloat11() {
+ float r = 4.5f;
+ float s = 2.0f;
+ float t = -1.0f;
+ for (int i = 0; i < 11; i++) {
+ float tmp = t; t = r; r = s; s = tmp;
+ }
+ return r;
+ }
+
+ /// CHECK-START: float Main.periodicFloat12() loop_optimization (before)
+ /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Phi2:f\d+>> Phi loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Phi3:f\d+>> Phi loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Phi4:f\d+>> Phi loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: Return [<<Phi2>>] loop:none
+ //
+ /// CHECK-START: float Main.periodicFloat12() loop_optimization (after)
+ /// CHECK-NOT: Phi
+ //
+ /// CHECK-START: float Main.periodicFloat12() loop_optimization (after)
+ /// CHECK-DAG: <<Float:f\d+>> FloatConstant 4.5 loop:none
+ /// CHECK-DAG: Return [<<Float>>] loop:none
+ private static float periodicFloat12() {
+ float r = 4.5f;
+ float s = 2.0f;
+ float t = -1.0f;
+ for (int i = 0; i < 12; i++) {
+ float tmp = t; t = r; r = s; s = tmp;
+ }
+ return r;
+ }
+
private static int exceptionExitBeforeAdd() {
int k = 0;
try {
@@ -732,6 +842,7 @@ public class Main {
expectEquals(12395, closedFormInductionUp());
expectEquals(12295, closedFormInductionInAndDown(12345));
+ expectEquals(81, closedFormInductionTrivialIf());
expectEquals(10 * 10, closedFormNested());
expectEquals(12345 + 17 * 23 * 7, closedFormNestedAlt());
for (int n = -4; n < 10; n++) {
@@ -751,6 +862,8 @@ public class Main {
for (int n = -4; n < 4; n++) {
int tc = (n <= 0) ? 0 : n;
expectEquals(tc, mainIndexReturnedN(n));
+ expectEquals(tc, mainIndexShort1((short) n));
+ expectEquals(tc, mainIndexShort2((short) n));
expectEquals(tc & 1, periodicReturnedN(n));
expectEquals((tc * (tc + 1)) / 2, getSumN(n));
}
@@ -775,6 +888,10 @@ public class Main {
expectEquals(!even, periodicBoolIdiom3N(false, n));
}
+ expectEquals( 2.0f, periodicFloat10());
+ expectEquals(-1.0f, periodicFloat11());
+ expectEquals( 4.5f, periodicFloat12());
+
expectEquals(100, exceptionExitBeforeAdd());
expectEquals(100, exceptionExitAfterAdd());
a = null;
@@ -787,6 +904,12 @@ public class Main {
System.out.println("passed");
}
+ private static void expectEquals(float expected, float result) {
+ if (expected != result) {
+ throw new Error("Expected: " + expected + ", found: " + result);
+ }
+ }
+
private static void expectEquals(int expected, int result) {
if (expected != result) {
throw new Error("Expected: " + expected + ", found: " + result);
diff --git a/test/623-checker-loop-regressions/src/Main.java b/test/623-checker-loop-regressions/src/Main.java
index ce5bda1393..7cc0b8b652 100644
--- a/test/623-checker-loop-regressions/src/Main.java
+++ b/test/623-checker-loop-regressions/src/Main.java
@@ -82,6 +82,88 @@ public class Main {
return 0;
}
+ // Regression test for b/33774618: transfer operations involving
+ // narrowing linear induction should be done correctly.
+ //
+ /// CHECK-START: int Main.transferNarrowWrap() loop_optimization (before)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START: int Main.transferNarrowWrap() loop_optimization (after)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
+ static int transferNarrowWrap() {
+ short x = 0;
+ int w = 10;
+ int v = 3;
+ for (int i = 0; i < 10; i++) {
+ v = w + 1; // transfer on wrap-around
+ w = x; // wrap-around
+ x += 2; // narrowing linear
+ }
+ return v;
+ }
+
+ // Regression test for b/33774618: transfer operations involving
+ // narrowing linear induction should be done correctly
+ // (currently rejected, could be improved).
+ //
+ /// CHECK-START: int Main.polynomialShort() loop_optimization (before)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START: int Main.polynomialShort() loop_optimization (after)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
+ static int polynomialShort() {
+ int x = 0;
+ for (short i = 0; i < 10; i++) {
+ x = x - i; // polynomial on narrowing linear
+ }
+ return x;
+ }
+
+ // Regression test for b/33774618: transfer operations involving
+ // narrowing linear induction should be done correctly
+ // (currently rejected, could be improved).
+ //
+ /// CHECK-START: int Main.polynomialIntFromLong() loop_optimization (before)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START: int Main.polynomialIntFromLong() loop_optimization (after)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
+ static int polynomialIntFromLong() {
+ int x = 0;
+ for (long i = 0; i < 10; i++) {
+ x = x - (int) i; // polynomial on narrowing linear
+ }
+ return x;
+ }
+
+ /// CHECK-START: int Main.polynomialInt() loop_optimization (before)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START: int Main.polynomialInt() loop_optimization (after)
+ /// CHECK-NOT: Phi
+ //
+ /// CHECK-START: int Main.polynomialInt() instruction_simplifier$after_bce (after)
+ /// CHECK-DAG: <<Int:i\d+>> IntConstant -45 loop:none
+ /// CHECK-DAG: Return [<<Int>>] loop:none
+ static int polynomialInt() {
+ int x = 0;
+ for (int i = 0; i < 10; i++) {
+ x = x - i;
+ }
+ return x;
+ }
+
public static void main(String[] args) {
expectEquals(10, earlyExitFirst(-1));
for (int i = 0; i <= 10; i++) {
@@ -98,6 +180,11 @@ public class Main {
expectEquals(2, earlyExitNested());
+ expectEquals(17, transferNarrowWrap());
+ expectEquals(-45, polynomialShort());
+ expectEquals(-45, polynomialIntFromLong());
+ expectEquals(-45, polynomialInt());
+
System.out.println("passed");
}
diff --git a/test/624-checker-stringops/src/Main.java b/test/624-checker-stringops/src/Main.java
index d965e3ffce..75b782e8c0 100644
--- a/test/624-checker-stringops/src/Main.java
+++ b/test/624-checker-stringops/src/Main.java
@@ -258,6 +258,20 @@ public class Main {
return b.length();
}
+ // Regression b/33656359: StringBuffer x is passed to constructor of String
+ // (this caused old code to crash due to missing nullptr check).
+ //
+ /// CHECK-START: void Main.doesNothing() instruction_simplifier (before)
+ /// CHECK-DAG: InvokeVirtual intrinsic:StringBufferToString
+ //
+ /// CHECK-START: void Main.doesNothing() instruction_simplifier (after)
+ /// CHECK-DAG: InvokeVirtual intrinsic:StringBufferToString
+ static void doesNothing() {
+ StringBuffer x = new StringBuffer();
+ String y = new String(x);
+ x.toString();
+ }
+
public static void main(String[] args) {
expectEquals(1865, liveIndexOf());
expectEquals(29, deadIndexOf());
@@ -281,6 +295,8 @@ public class Main {
expectEquals(0, bufferDeadLoop());
expectEquals(0, builderDeadLoop());
+ doesNothing();
+
System.out.println("passed");
}
diff --git a/test/626-checker-arm64-scratch-register/expected.txt b/test/626-checker-arm64-scratch-register/expected.txt
new file mode 100644
index 0000000000..b0aad4deb5
--- /dev/null
+++ b/test/626-checker-arm64-scratch-register/expected.txt
@@ -0,0 +1 @@
+passed
diff --git a/test/626-checker-arm64-scratch-register/info.txt b/test/626-checker-arm64-scratch-register/info.txt
new file mode 100644
index 0000000000..847213119f
--- /dev/null
+++ b/test/626-checker-arm64-scratch-register/info.txt
@@ -0,0 +1,2 @@
+Regression test checking that the ARM64 scratch register pool is not
+exhausted during moves between stack slots (b/32545705).
diff --git a/test/626-checker-arm64-scratch-register/src/Main.java b/test/626-checker-arm64-scratch-register/src/Main.java
new file mode 100644
index 0000000000..aa211be33c
--- /dev/null
+++ b/test/626-checker-arm64-scratch-register/src/Main.java
@@ -0,0 +1,298 @@
+/*
+ * 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 {
+
+ boolean b00;
+ boolean b01;
+ boolean b02;
+ boolean b03;
+ boolean b04;
+ boolean b05;
+ boolean b06;
+ boolean b07;
+ boolean b08;
+ boolean b09;
+ boolean b10;
+ boolean b11;
+ boolean b12;
+ boolean b13;
+ boolean b14;
+ boolean b15;
+ boolean b16;
+ boolean b17;
+ boolean b18;
+ boolean b19;
+ boolean b20;
+ boolean b21;
+ boolean b22;
+ boolean b23;
+ boolean b24;
+ boolean b25;
+ boolean b26;
+ boolean b27;
+ boolean b28;
+ boolean b29;
+ boolean b30;
+ boolean b31;
+ boolean b32;
+ boolean b33;
+ boolean b34;
+ boolean b35;
+ boolean b36;
+
+ boolean conditionA;
+ boolean conditionB;
+ boolean conditionC;
+
+ /// CHECK-START-ARM64: void Main.test() register (after)
+ /// CHECK: begin_block
+ /// CHECK: name "B0"
+ /// CHECK: <<This:l\d+>> ParameterValue
+ /// CHECK: end_block
+ /// CHECK: begin_block
+ /// CHECK: successors "<<ThenBlock:B\d+>>" "<<ElseBlock:B\d+>>"
+ /// CHECK: <<CondB:z\d+>> InstanceFieldGet [<<This>>] field_name:Main.conditionB
+ /// CHECK: If [<<CondB>>]
+ /// CHECK: end_block
+ /// CHECK: begin_block
+ /// CHECK: name "<<ElseBlock>>"
+ /// CHECK: ParallelMove moves:[#100->d17,32(sp)->d1,36(sp)->d2,d17->d3,d3->d4,d4->d5,d5->d6,d6->d7,d7->d18,d18->d19,d19->d20,d20->d21,d21->d22,d22->d23,d23->d10,d10->d11,d11->d12,24(sp)->d13,28(sp)->d14,d14->16(sp),d12->20(sp),d13->24(sp),d1->28(sp),d2->32(sp),16(sp)->36(sp),20(sp)->40(sp)]
+ /// CHECK: end_block
+
+ /// CHECK-START-ARM64: void Main.test() disassembly (after)
+ /// CHECK: begin_block
+ /// CHECK: name "B0"
+ /// CHECK: <<This:l\d+>> ParameterValue
+ /// CHECK: end_block
+ /// CHECK: begin_block
+ /// CHECK: successors "<<ThenBlock:B\d+>>" "<<ElseBlock:B\d+>>"
+ /// CHECK: <<CondB:z\d+>> InstanceFieldGet [<<This>>] field_name:Main.conditionB
+ /// CHECK: If [<<CondB>>]
+ /// CHECK: end_block
+ /// CHECK: begin_block
+ /// CHECK: name "<<ElseBlock>>"
+ /// CHECK: ParallelMove moves:[invalid->invalid,invalid->invalid,invalid->invalid,invalid->invalid,invalid->invalid,invalid->invalid,invalid->invalid,invalid->invalid,invalid->invalid,invalid->invalid,invalid->invalid,invalid->invalid,invalid->invalid,invalid->invalid,invalid->invalid,invalid->invalid,invalid->invalid,invalid->invalid,invalid->invalid,invalid->invalid,invalid->invalid,invalid->invalid,invalid->invalid,invalid->invalid,invalid->invalid,invalid->invalid]
+ /// CHECK: fmov d31, d2
+ /// CHECK: ldr s2, [sp, #36]
+ /// CHECK: ldr w16, [sp, #16]
+ /// CHECK: str w16, [sp, #36]
+ /// CHECK: str s14, [sp, #16]
+ /// CHECK: ldr s14, [sp, #28]
+ /// CHECK: str s1, [sp, #28]
+ /// CHECK: ldr s1, [sp, #32]
+ /// CHECK: str s31, [sp, #32]
+ /// CHECK: ldr w16, [sp, #20]
+ /// CHECK: str w16, [sp, #40]
+ /// CHECK: str s12, [sp, #20]
+ /// CHECK: fmov d12, d11
+ /// CHECK: fmov d11, d10
+ /// CHECK: fmov d10, d23
+ /// CHECK: fmov d23, d22
+ /// CHECK: fmov d22, d21
+ /// CHECK: fmov d21, d20
+ /// CHECK: fmov d20, d19
+ /// CHECK: fmov d19, d18
+ /// CHECK: fmov d18, d7
+ /// CHECK: fmov d7, d6
+ /// CHECK: fmov d6, d5
+ /// CHECK: fmov d5, d4
+ /// CHECK: fmov d4, d3
+ /// CHECK: fmov d3, d17
+ /// CHECK: fmov d17, d13
+ /// CHECK: ldr s13, [sp, #24]
+ /// CHECK: str s17, [sp, #24]
+ /// CHECK: ldr s17, pc+{{\d+}} (addr {{0x[0-9a-f]+}}) (100)
+ /// CHECK: end_block
+
+ public void test() {
+ String r = "";
+
+ // For the purpose of this regression test, the order of
+ // definition of these float variable matters. Likewise with the
+ // order of the instructions where these variables are used below.
+ // Reordering these lines make make the original (b/32545705)
+ // issue vanish.
+ float f17 = b17 ? 0.0f : 1.0f;
+ float f16 = b16 ? 0.0f : 1.0f;
+ float f18 = b18 ? 0.0f : 1.0f;
+ float f19 = b19 ? 0.0f : 1.0f;
+ float f20 = b20 ? 0.0f : 1.0f;
+ float f21 = b21 ? 0.0f : 1.0f;
+ float f15 = b15 ? 0.0f : 1.0f;
+ float f00 = b00 ? 0.0f : 1.0f;
+ float f22 = b22 ? 0.0f : 1.0f;
+ float f23 = b23 ? 0.0f : 1.0f;
+ float f24 = b24 ? 0.0f : 1.0f;
+ float f25 = b25 ? 0.0f : 1.0f;
+ float f26 = b26 ? 0.0f : 1.0f;
+ float f27 = b27 ? 0.0f : 1.0f;
+ float f29 = b29 ? 0.0f : 1.0f;
+ float f28 = b28 ? 0.0f : 1.0f;
+ float f01 = b01 ? 0.0f : 1.0f;
+ float f02 = b02 ? 0.0f : 1.0f;
+ float f03 = b03 ? 0.0f : 1.0f;
+ float f04 = b04 ? 0.0f : 1.0f;
+ float f05 = b05 ? 0.0f : 1.0f;
+ float f07 = b07 ? 0.0f : 1.0f;
+ float f06 = b06 ? 0.0f : 1.0f;
+ float f30 = b30 ? 0.0f : 1.0f;
+ float f31 = b31 ? 0.0f : 1.0f;
+ float f32 = b32 ? 0.0f : 1.0f;
+ float f33 = b33 ? 0.0f : 1.0f;
+ float f34 = b34 ? 0.0f : 1.0f;
+ float f36 = b36 ? 0.0f : 1.0f;
+ float f35 = b35 ? 0.0f : 1.0f;
+ float f08 = b08 ? 0.0f : 1.0f;
+ float f09 = b09 ? 0.0f : 1.0f;
+ float f10 = b10 ? 0.0f : 1.0f;
+ float f11 = b11 ? 0.0f : 1.0f;
+ float f12 = b12 ? 0.0f : 1.0f;
+ float f14 = b14 ? 0.0f : 1.0f;
+ float f13 = b13 ? 0.0f : 1.0f;
+
+ if (conditionA) {
+ f16 /= 1000.0f;
+ f17 /= 1000.0f;
+ f18 /= 1000.0f;
+ f19 /= 1000.0f;
+ f20 /= 1000.0f;
+ f21 /= 1000.0f;
+ f15 /= 1000.0f;
+ f08 /= 1000.0f;
+ f09 /= 1000.0f;
+ f10 /= 1000.0f;
+ f11 /= 1000.0f;
+ f12 /= 1000.0f;
+ f30 /= 1000.0f;
+ f31 /= 1000.0f;
+ f32 /= 1000.0f;
+ f33 /= 1000.0f;
+ f34 /= 1000.0f;
+ f01 /= 1000.0f;
+ f02 /= 1000.0f;
+ f03 /= 1000.0f;
+ f04 /= 1000.0f;
+ f05 /= 1000.0f;
+ f23 /= 1000.0f;
+ f24 /= 1000.0f;
+ f25 /= 1000.0f;
+ f26 /= 1000.0f;
+ f27 /= 1000.0f;
+ f22 /= 1000.0f;
+ f00 /= 1000.0f;
+ f14 /= 1000.0f;
+ f13 /= 1000.0f;
+ f36 /= 1000.0f;
+ f35 /= 1000.0f;
+ f07 /= 1000.0f;
+ f06 /= 1000.0f;
+ f29 /= 1000.0f;
+ f28 /= 1000.0f;
+ }
+ // The parallel move that used to exhaust the ARM64 parallel move
+ // resolver's scratch register pool (provided by VIXL) was in the
+ // "else" branch of the following condition generated by ART's
+ // compiler.
+ if (conditionB) {
+ f16 /= 100.0f;
+ f17 /= 100.0f;
+ f18 /= 100.0f;
+ f19 /= 100.0f;
+ f20 /= 100.0f;
+ f21 /= 100.0f;
+ f15 /= 100.0f;
+ f08 /= 100.0f;
+ f09 /= 100.0f;
+ f10 /= 100.0f;
+ f11 /= 100.0f;
+ f12 /= 100.0f;
+ f30 /= 100.0f;
+ f31 /= 100.0f;
+ f32 /= 100.0f;
+ f33 /= 100.0f;
+ f34 /= 100.0f;
+ f01 /= 100.0f;
+ f02 /= 100.0f;
+ f03 /= 100.0f;
+ f04 /= 100.0f;
+ f05 /= 100.0f;
+ f23 /= 100.0f;
+ f24 /= 100.0f;
+ f25 /= 100.0f;
+ f26 /= 100.0f;
+ f27 /= 100.0f;
+ f22 /= 100.0f;
+ f00 /= 100.0f;
+ f14 /= 100.0f;
+ f13 /= 100.0f;
+ f36 /= 100.0f;
+ f35 /= 100.0f;
+ f07 /= 100.0f;
+ f06 /= 100.0f;
+ f29 /= 100.0f;
+ f28 /= 100.0f;
+ }
+ if (conditionC) {
+ f16 /= 12.0f;
+ f17 /= 12.0f;
+ f18 /= 12.0f;
+ f19 /= 12.0f;
+ f20 /= 12.0f;
+ f21 /= 12.0f;
+ f15 /= 12.0f;
+ f08 /= 12.0f;
+ f09 /= 12.0f;
+ f10 /= 12.0f;
+ f11 /= 12.0f;
+ f12 /= 12.0f;
+ f30 /= 12.0f;
+ f31 /= 12.0f;
+ f32 /= 12.0f;
+ f33 /= 12.0f;
+ f34 /= 12.0f;
+ f01 /= 12.0f;
+ f02 /= 12.0f;
+ f03 /= 12.0f;
+ f04 /= 12.0f;
+ f05 /= 12.0f;
+ f23 /= 12.0f;
+ f24 /= 12.0f;
+ f25 /= 12.0f;
+ f26 /= 12.0f;
+ f27 /= 12.0f;
+ f22 /= 12.0f;
+ f00 /= 12.0f;
+ f14 /= 12.0f;
+ f13 /= 12.0f;
+ f36 /= 12.0f;
+ f35 /= 12.0f;
+ f07 /= 12.0f;
+ f06 /= 12.0f;
+ f29 /= 12.0f;
+ f28 /= 12.0f;
+ }
+ float s = 0.0f;
+ s = ((float) Math.round(100.0f * s)) / 100.0f;
+ String res = s + r;
+ }
+
+ public static void main(String[] args) {
+ Main main = new Main();
+ main.test();
+ System.out.println("passed");
+ }
+}
diff --git a/test/628-vdex/run b/test/628-vdex/run
index f1b0a95f64..4cbcea3b7e 100644
--- a/test/628-vdex/run
+++ b/test/628-vdex/run
@@ -14,4 +14,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-exec ${RUN} --vdex "${@}"
+exec ${RUN} -Xcompiler-option --compiler-filter=verify-profile --vdex "${@}"
diff --git a/test/630-safecast-array/expected.txt b/test/630-safecast-array/expected.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/630-safecast-array/expected.txt
diff --git a/test/630-safecast-array/info.txt b/test/630-safecast-array/info.txt
new file mode 100644
index 0000000000..e10516784e
--- /dev/null
+++ b/test/630-safecast-array/info.txt
@@ -0,0 +1,3 @@
+Regression test for vdex, which used to crash in AddAssignability
+called by the dex2dex compiler, not anticipating arrays of primitive
+type.
diff --git a/test/630-safecast-array/smali/Main.smali b/test/630-safecast-array/smali/Main.smali
new file mode 100644
index 0000000000..a50f37ccbc
--- /dev/null
+++ b/test/630-safecast-array/smali/Main.smali
@@ -0,0 +1,33 @@
+# 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 LMain;
+.super Ljava/lang/Object;
+
+.method public static main([Ljava/lang/String;)V
+.registers 1
+ return-void
+.end method
+
+.method public static testPrimitiveDestination([Ljava/lang/String;)V
+.registers 1
+ check-cast p0, [B
+ return-void
+.end method
+
+.method public static testPrimitiveSource([B)V
+.registers 1
+ check-cast p0, [Ljava/lang/String;
+ return-void
+.end method
diff --git a/test/706-jit-skip-compilation/expected.txt b/test/706-jit-skip-compilation/expected.txt
new file mode 100644
index 0000000000..6a5618ebc6
--- /dev/null
+++ b/test/706-jit-skip-compilation/expected.txt
@@ -0,0 +1 @@
+JNI_OnLoad called
diff --git a/test/706-jit-skip-compilation/info.txt b/test/706-jit-skip-compilation/info.txt
new file mode 100644
index 0000000000..e9ef86bfb3
--- /dev/null
+++ b/test/706-jit-skip-compilation/info.txt
@@ -0,0 +1,4 @@
+Regression test for the JIT crashing when compiling a method with invalid
+dead dex code. For not compilable methods we don't gather samples and we don't
+trigger JIT compilation. However kAccDontBotherCompile is not persisted in the
+oat file and so we may end up compiling a method which we shouldn't.
diff --git a/test/706-jit-skip-compilation/run b/test/706-jit-skip-compilation/run
new file mode 100644
index 0000000000..6c5720a099
--- /dev/null
+++ b/test/706-jit-skip-compilation/run
@@ -0,0 +1,19 @@
+#!/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.
+
+# Run without the app image, otherwise the verification results will be cached
+# in the ArtMethod of the image and the test will be skewed.
+exec ${RUN} "${@}" --no-app-image
diff --git a/test/706-jit-skip-compilation/smali/errclass.smali b/test/706-jit-skip-compilation/smali/errclass.smali
new file mode 100644
index 0000000000..410504cb2f
--- /dev/null
+++ b/test/706-jit-skip-compilation/smali/errclass.smali
@@ -0,0 +1,34 @@
+# 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 LErrClass;
+
+.super Ljava/lang/Object;
+
+.method public static errMethod()J
+ .registers 8
+ const/4 v0, 0x0
+ const/4 v3, 0x0
+ aget v1, v0, v3 # v0 is null, this will alays throw and the invalid code
+ # below will not be verified.
+ move v3, v4
+ move-wide/from16 v6, v2 # should trigger a verification error if verified as
+ # v3 is a single register but used as a pair here.
+ return v6
+.end method
+
+# Add a field to work around demerger bug b/18051191.
+# Failure to verify dex file '...': Offset(552) should be zero when size is zero for field-ids.
+.field private a:I
diff --git a/test/706-jit-skip-compilation/src/Main.java b/test/706-jit-skip-compilation/src/Main.java
new file mode 100644
index 0000000000..aa847248d6
--- /dev/null
+++ b/test/706-jit-skip-compilation/src/Main.java
@@ -0,0 +1,57 @@
+/*
+ * 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.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public class Main {
+ public static void main(String[] args) throws Exception {
+ System.loadLibrary(args[0]);
+ Class<?> c = Class.forName("ErrClass");
+ Method m = c.getMethod("errMethod");
+
+ // Print the counter before invokes. The golden file expects this to be 0.
+ int hotnessCounter = getHotnessCounter(c, "errMethod");
+ if (hotnessCounter != 0) {
+ throw new RuntimeException("Unexpected hotnessCounter: " + hotnessCounter);
+ }
+
+ // Loop enough to make sure the interpreter reports invocations count.
+ long result = 0;
+ for (int i = 0; i < 10000; i++) {
+ try {
+ result += (Long)m.invoke(null);
+ hotnessCounter = getHotnessCounter(c, "errMethod");
+ if (hotnessCounter != 0) {
+ throw new RuntimeException(
+ "Unexpected hotnessCounter: " + hotnessCounter);
+ }
+
+ } catch (InvocationTargetException e) {
+ if (!(e.getCause() instanceof NullPointerException)) {
+ throw e;
+ }
+ }
+ }
+
+ // Not compilable methods should not increase their hotness counter.
+ if (hotnessCounter != 0) {
+ throw new RuntimeException("Unexpected hotnessCounter: " + hotnessCounter);
+ }
+ }
+
+ public static native int getHotnessCounter(Class cls, String method_name);
+}
diff --git a/test/911-get-stack-trace/expected.txt b/test/911-get-stack-trace/expected.txt
index 20bab7814e..f8c97ce475 100644
--- a/test/911-get-stack-trace/expected.txt
+++ b/test/911-get-stack-trace/expected.txt
@@ -3,206 +3,206 @@
###################
From top
---------
- getStackTrace (Ljava/lang/Thread;II)[Ljava/lang/String;
- print (Ljava/lang/Thread;II)V
- printOrWait (IILMain$ControlData;)V
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- doTest ()V
- main ([Ljava/lang/String;)V
----------
- print (Ljava/lang/Thread;II)V
- printOrWait (IILMain$ControlData;)V
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- doTest ()V
- main ([Ljava/lang/String;)V
----------
- getStackTrace (Ljava/lang/Thread;II)[Ljava/lang/String;
- print (Ljava/lang/Thread;II)V
- printOrWait (IILMain$ControlData;)V
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
----------
- printOrWait (IILMain$ControlData;)V
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
+ getStackTrace (Ljava/lang/Thread;II)[[Ljava/lang/String; -1 -2
+ print (Ljava/lang/Thread;II)V 0 124
+ printOrWait (IILMain$ControlData;)V 6 151
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ doTest ()V 38 34
+ main ([Ljava/lang/String;)V 6 24
+---------
+ print (Ljava/lang/Thread;II)V 0 124
+ printOrWait (IILMain$ControlData;)V 6 151
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ doTest ()V 42 35
+ main ([Ljava/lang/String;)V 6 24
+---------
+ getStackTrace (Ljava/lang/Thread;II)[[Ljava/lang/String; -1 -2
+ print (Ljava/lang/Thread;II)V 0 124
+ printOrWait (IILMain$ControlData;)V 6 151
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+---------
+ printOrWait (IILMain$ControlData;)V 6 151
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
From bottom
---------
- main ([Ljava/lang/String;)V
+ main ([Ljava/lang/String;)V 6 24
---------
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- doTest ()V
- main ([Ljava/lang/String;)V
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ doTest ()V 65 41
+ main ([Ljava/lang/String;)V 6 24
---------
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
################################
### Other thread (suspended) ###
################################
From top
---------
- wait ()V
- printOrWait (IILMain$ControlData;)V
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- run ()V
----------
- printOrWait (IILMain$ControlData;)V
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- run ()V
----------
- wait ()V
- printOrWait (IILMain$ControlData;)V
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
----------
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
+ wait ()V -1 -2
+ printOrWait (IILMain$ControlData;)V 24 157
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ run ()V 4 54
+---------
+ printOrWait (IILMain$ControlData;)V 24 157
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ run ()V 4 54
+---------
+ wait ()V -1 -2
+ printOrWait (IILMain$ControlData;)V 24 157
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+---------
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
From bottom
---------
- run ()V
+ run ()V 4 54
---------
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- run ()V
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ run ()V 4 54
---------
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
###########################
### Other thread (live) ###
###########################
From top
---------
- printOrWait (IILMain$ControlData;)V
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- run ()V
----------
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- run ()V
----------
- printOrWait (IILMain$ControlData;)V
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
----------
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
+ printOrWait (IILMain$ControlData;)V 44 164
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ run ()V 4 88
+---------
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ run ()V 4 88
+---------
+ printOrWait (IILMain$ControlData;)V 44 164
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+---------
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
From bottom
---------
- run ()V
+ run ()V 4 88
---------
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- run ()V
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ run ()V 4 88
---------
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
- foo (IIILMain$ControlData;)I
- baz (IIILMain$ControlData;)Ljava/lang/Object;
- bar (IIILMain$ControlData;)J
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
diff --git a/test/911-get-stack-trace/src/Main.java b/test/911-get-stack-trace/src/Main.java
index df4501d338..722bee8056 100644
--- a/test/911-get-stack-trace/src/Main.java
+++ b/test/911-get-stack-trace/src/Main.java
@@ -109,13 +109,14 @@ public class Main {
t.join();
}
- public static void print(String[] stack) {
+ public static void print(String[][] stack) {
System.out.println("---------");
- for (int i = 0; i < stack.length; i += 2) {
- System.out.print(' ');
- System.out.print(stack[i]);
- System.out.print(' ');
- System.out.println(stack[i + 1]);
+ for (String[] stackElement : stack) {
+ for (String part : stackElement) {
+ System.out.print(' ');
+ System.out.print(part);
+ }
+ System.out.println();
}
}
@@ -174,5 +175,5 @@ public class Main {
volatile boolean stop = false;
}
- public static native String[] getStackTrace(Thread thread, int start, int max);
+ public static native String[][] getStackTrace(Thread thread, int start, int max);
}
diff --git a/test/911-get-stack-trace/stack_trace.cc b/test/911-get-stack-trace/stack_trace.cc
index e7d9380469..57f6a927ea 100644
--- a/test/911-get-stack-trace/stack_trace.cc
+++ b/test/911-get-stack-trace/stack_trace.cc
@@ -16,10 +16,14 @@
#include "stack_trace.h"
+#include <inttypes.h>
#include <memory>
#include <stdio.h>
+#include "android-base/stringprintf.h"
+
#include "base/logging.h"
+#include "base/macros.h"
#include "jni.h"
#include "openjdkjvmti/jvmti.h"
#include "ScopedLocalRef.h"
@@ -29,6 +33,25 @@
namespace art {
namespace Test911GetStackTrace {
+using android::base::StringPrintf;
+
+static jint FindLineNumber(jint line_number_count,
+ jvmtiLineNumberEntry* line_number_table,
+ jlocation location) {
+ if (line_number_table == nullptr) {
+ return -2;
+ }
+
+ jint line_number = -1;
+ for (jint i = 0; i != line_number_count; ++i) {
+ if (line_number_table[i].start_location > location) {
+ return line_number;
+ }
+ line_number = line_number_table[i].line_number;
+ }
+ return line_number;
+}
+
extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getStackTrace(
JNIEnv* env, jclass klass ATTRIBUTE_UNUSED, jthread thread, jint start, jint max) {
std::unique_ptr<jvmtiFrameInfo[]> frames(new jvmtiFrameInfo[max]);
@@ -44,8 +67,7 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getStackTrace(
}
}
- auto callback = [&](jint i) -> jstring {
- size_t method_index = static_cast<size_t>(i) / 2;
+ auto callback = [&](jint method_index) -> jobjectArray {
char* name;
char* sig;
char* gen;
@@ -58,13 +80,47 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getStackTrace(
return nullptr;
}
}
- jstring callback_result;
- if (i % 2 == 0) {
- callback_result = name == nullptr ? nullptr : env->NewStringUTF(name);
- } else {
- callback_result = sig == nullptr ? nullptr : env->NewStringUTF(sig);
+
+ jint line_number_count;
+ jvmtiLineNumberEntry* line_number_table;
+ {
+ jvmtiError line_result = jvmti_env->GetLineNumberTable(frames[method_index].method,
+ &line_number_count,
+ &line_number_table);
+ if (line_result != JVMTI_ERROR_NONE) {
+ // Accept absent info and native method errors.
+ if (line_result != JVMTI_ERROR_ABSENT_INFORMATION &&
+ line_result != JVMTI_ERROR_NATIVE_METHOD) {
+ char* err;
+ jvmti_env->GetErrorName(line_result, &err);
+ printf("Failure running GetLineNumberTable: %s\n", err);
+ return nullptr;
+ }
+ line_number_table = nullptr;
+ line_number_count = 0;
+ }
}
+ auto inner_callback = [&](jint component_index) -> jstring {
+ switch (component_index) {
+ case 0:
+ return (name == nullptr) ? nullptr : env->NewStringUTF(name);
+ case 1:
+ return (sig == nullptr) ? nullptr : env->NewStringUTF(sig);
+ case 2:
+ return env->NewStringUTF(StringPrintf("%" PRId64, frames[method_index].location).c_str());
+ case 3: {
+ jint line_number = FindLineNumber(line_number_count,
+ line_number_table,
+ frames[method_index].location);
+ return env->NewStringUTF(StringPrintf("%d", line_number).c_str());
+ }
+ }
+ LOG(FATAL) << "Unreachable";
+ UNREACHABLE();
+ };
+ jobjectArray inner_array = CreateObjectArray(env, 4, "java/lang/String", inner_callback);
+
if (name != nullptr) {
jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(name));
}
@@ -74,9 +130,13 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getStackTrace(
if (gen != nullptr) {
jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(gen));
}
- return callback_result;
+ if (line_number_table != nullptr) {
+ jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(line_number_table));
+ }
+
+ return inner_array;
};
- return CreateObjectArray(env, 2 * count, "java/lang/String", callback);
+ return CreateObjectArray(env, count, "[Ljava/lang/String;", callback);
}
// Don't do anything
diff --git a/test/913-heaps/expected.txt b/test/913-heaps/expected.txt
index e5fa53f207..7522a659f2 100644
--- a/test/913-heaps/expected.txt
+++ b/test/913-heaps/expected.txt
@@ -5,12 +5,12 @@ root@root --(stack-local[id=1,tag=3000,depth=3,method=doFollowReferencesTest,vre
root@root --(thread)--> 3000@0 [size=132, length=-1]
0@0 --(array-element@0)--> 1@1000 [size=16, length=-1]
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
-1002@0 --(interface)--> 2001@0 [size=132, length=-1]
+1002@0 --(interface)--> 2001@0 [size=124, length=-1]
1002@0 --(superclass)--> 1001@0 [size=123, length=-1]
1@1000 --(class)--> 1000@0 [size=123, length=-1]
1@1000 --(field@12)--> 3@1001 [size=24, length=-1]
1@1000 --(field@8)--> 2@1000 [size=16, length=-1]
-2001@0 --(interface)--> 2000@0 [size=132, length=-1]
+2001@0 --(interface)--> 2000@0 [size=124, length=-1]
2@1000 --(class)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@16)--> 4@1000 [size=16, length=-1]
@@ -22,12 +22,12 @@ root@root --(thread)--> 3000@0 [size=132, length=-1]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
-1002@0 --(interface)--> 2001@0 [size=132, length=-1]
+1002@0 --(interface)--> 2001@0 [size=124, length=-1]
1002@0 --(superclass)--> 1001@0 [size=123, length=-1]
1@1000 --(class)--> 1000@0 [size=123, length=-1]
1@1000 --(field@12)--> 3@1001 [size=24, length=-1]
1@1000 --(field@8)--> 2@1000 [size=16, length=-1]
-2001@0 --(interface)--> 2000@0 [size=132, length=-1]
+2001@0 --(interface)--> 2000@0 [size=124, length=-1]
2@1000 --(class)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@16)--> 4@1000 [size=16, length=-1]
@@ -46,12 +46,12 @@ root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestRoot
root@root --(thread)--> 1@1000 [size=16, length=-1]
root@root --(thread)--> 3000@0 [size=132, length=-1]
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
-1002@0 --(interface)--> 2001@0 [size=132, length=-1]
+1002@0 --(interface)--> 2001@0 [size=124, length=-1]
1002@0 --(superclass)--> 1001@0 [size=123, length=-1]
1@1000 --(class)--> 1000@0 [size=123, length=-1]
1@1000 --(field@12)--> 3@1001 [size=24, length=-1]
1@1000 --(field@8)--> 2@1000 [size=16, length=-1]
-2001@0 --(interface)--> 2000@0 [size=132, length=-1]
+2001@0 --(interface)--> 2000@0 [size=124, length=-1]
2@1000 --(class)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@16)--> 4@1000 [size=16, length=-1]
@@ -63,12 +63,12 @@ root@root --(thread)--> 3000@0 [size=132, length=-1]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
-1002@0 --(interface)--> 2001@0 [size=132, length=-1]
+1002@0 --(interface)--> 2001@0 [size=124, length=-1]
1002@0 --(superclass)--> 1001@0 [size=123, length=-1]
1@1000 --(class)--> 1000@0 [size=123, length=-1]
1@1000 --(field@12)--> 3@1001 [size=24, length=-1]
1@1000 --(field@8)--> 2@1000 [size=16, length=-1]
-2001@0 --(interface)--> 2000@0 [size=132, length=-1]
+2001@0 --(interface)--> 2000@0 [size=124, length=-1]
2@1000 --(class)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@16)--> 4@1000 [size=16, length=-1]
diff --git a/test/913-heaps/heaps.cc b/test/913-heaps/heaps.cc
index 7b00fcdcc1..49ab7dd83e 100644
--- a/test/913-heaps/heaps.cc
+++ b/test/913-heaps/heaps.cc
@@ -22,9 +22,10 @@
#include <vector>
+#include "android-base/stringprintf.h"
+
#include "base/logging.h"
#include "base/macros.h"
-#include "base/stringprintf.h"
#include "jit/jit.h"
#include "jni.h"
#include "native_stack_dump.h"
@@ -39,6 +40,8 @@
namespace art {
namespace Test913Heaps {
+using android::base::StringPrintf;
+
extern "C" JNIEXPORT void JNICALL Java_Main_forceGarbageCollection(JNIEnv* env ATTRIBUTE_UNUSED,
jclass klass ATTRIBUTE_UNUSED) {
jvmtiError ret = jvmti_env->ForceGarbageCollection();
@@ -180,7 +183,7 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_followReferences(JNIEnv* env
if (*tag_ptr >= 1000) {
// This is a class or interface, the size of which will be dependent on the architecture.
// Do not print the size, but detect known values and "normalize" for the golden file.
- if ((sizeof(void*) == 4 && size == 180) || (sizeof(void*) == 8 && size == 232)) {
+ if ((sizeof(void*) == 4 && size == 172) || (sizeof(void*) == 8 && size == 224)) {
adapted_size = 123;
}
}
diff --git a/test/917-fields-transformation/build b/test/917-fields-transformation/build
new file mode 100755
index 0000000000..898e2e54a2
--- /dev/null
+++ b/test/917-fields-transformation/build
@@ -0,0 +1,17 @@
+#!/bin/bash
+#
+# 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.
+
+./default-build "$@" --experimental agents
diff --git a/test/917-fields-transformation/expected.txt b/test/917-fields-transformation/expected.txt
new file mode 100644
index 0000000000..bcdd201113
--- /dev/null
+++ b/test/917-fields-transformation/expected.txt
@@ -0,0 +1,12 @@
+Result is Hello
+take1 is Hello
+take2 is Goodbye
+Result is start
+take1 is start
+take2 is end
+Result is Goodbye
+take1 is Hello
+take2 is Goodbye
+Result is end
+take1 is start
+take2 is end
diff --git a/test/917-fields-transformation/info.txt b/test/917-fields-transformation/info.txt
new file mode 100644
index 0000000000..4cd1bd9dbd
--- /dev/null
+++ b/test/917-fields-transformation/info.txt
@@ -0,0 +1 @@
+Tests field access after class redefinition support in the jvmti plugin.
diff --git a/test/917-fields-transformation/run b/test/917-fields-transformation/run
new file mode 100755
index 0000000000..a434b63e42
--- /dev/null
+++ b/test/917-fields-transformation/run
@@ -0,0 +1,43 @@
+#!/bin/bash
+#
+# 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.
+
+plugin=libopenjdkjvmtid.so
+agent=libtiagentd.so
+lib=tiagentd
+if [[ "$@" == *"-O"* ]]; then
+ agent=libtiagent.so
+ plugin=libopenjdkjvmti.so
+ lib=tiagent
+fi
+
+if [[ "$@" == *"--jvm"* ]]; then
+ arg="jvm"
+else
+ arg="art"
+ if [[ "$@" != *"--debuggable"* ]]; then
+ other_args=" -Xcompiler-option --debuggable "
+ else
+ other_args=""
+ fi
+fi
+
+./default-run "$@" --experimental agents \
+ --experimental runtime-plugins \
+ --runtime-option -agentpath:${agent}=917-fields-transformation,${arg} \
+ --android-runtime-option -Xplugin:${plugin} \
+ --android-runtime-option -Xfully-deoptable \
+ ${other_args} \
+ --args ${lib}
diff --git a/test/917-fields-transformation/src/Main.java b/test/917-fields-transformation/src/Main.java
new file mode 100644
index 0000000000..5378bb7a05
--- /dev/null
+++ b/test/917-fields-transformation/src/Main.java
@@ -0,0 +1,80 @@
+/*
+ * 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.util.Base64;
+public class Main {
+
+ // base64 encoded class/dex file for
+ // class Transform {
+ // public String take1;
+ // public String take2;
+ //
+ // public Transform(String a, String b) {
+ // take1 = a;
+ // take2 = b;
+ // }
+ //
+ // public String getResult() {
+ // return take2;
+ // }
+ // }
+ private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
+ "yv66vgAAADQAFwoABQARCQAEABIJAAQAEwcAFAcAFQEABXRha2UxAQASTGphdmEvbGFuZy9TdHJp" +
+ "bmc7AQAFdGFrZTIBAAY8aW5pdD4BACcoTGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJp" +
+ "bmc7KVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQAJZ2V0UmVzdWx0AQAUKClMamF2YS9sYW5n" +
+ "L1N0cmluZzsBAApTb3VyY2VGaWxlAQAOVHJhbnNmb3JtLmphdmEMAAkAFgwABgAHDAAIAAcBAAlU" +
+ "cmFuc2Zvcm0BABBqYXZhL2xhbmcvT2JqZWN0AQADKClWACAABAAFAAAAAgABAAYABwAAAAEACAAH" +
+ "AAAAAgABAAkACgABAAsAAAAzAAIAAwAAAA8qtwABKiu1AAIqLLUAA7EAAAABAAwAAAASAAQAAAAU" +
+ "AAQAFQAJABYADgAXAAEADQAOAAEACwAAAB0AAQABAAAABSq0AAOwAAAAAQAMAAAABgABAAAAGgAB" +
+ "AA8AAAACABA=");
+ private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
+ "ZGV4CjAzNQAGUTBb4jIABRlaI9rejdk7RCfyqR2kmNSkAgAAcAAAAHhWNBIAAAAAAAAAAAQCAAAM" +
+ "AAAAcAAAAAQAAACgAAAAAwAAALAAAAACAAAA1AAAAAMAAADkAAAAAQAAAPwAAACIAQAAHAEAAFwB" +
+ "AABkAQAAZwEAAHQBAACIAQAAnAEAAKwBAACvAQAAtAEAAMgBAADTAQAA2gEAAAIAAAADAAAABAAA" +
+ "AAYAAAABAAAAAgAAAAAAAAAGAAAAAwAAAAAAAAAHAAAAAwAAAFQBAAAAAAIACgAAAAAAAgALAAAA" +
+ "AAACAAAAAAAAAAAACQAAAAEAAQAAAAAAAAAAAAAAAAABAAAAAAAAAAUAAAAAAAAA8AEAAAAAAAAD" +
+ "AAMAAQAAAOEBAAAIAAAAcBACAAAAWwEAAFsCAQAOAAIAAQAAAAAA6wEAAAMAAABUEAEAEQAAAAIA" +
+ "AAACAAIABjxpbml0PgABTAALTFRyYW5zZm9ybTsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEv" +
+ "bGFuZy9TdHJpbmc7AA5UcmFuc2Zvcm0uamF2YQABVgADVkxMABJlbWl0dGVyOiBqYWNrLTQuMTkA" +
+ "CWdldFJlc3VsdAAFdGFrZTEABXRha2UyABQCAAAHDjwtLQAaAAcOAAACAQEAAQEBAIGABJwCAQG8" +
+ "AgAADQAAAAAAAAABAAAAAAAAAAEAAAAMAAAAcAAAAAIAAAAEAAAAoAAAAAMAAAADAAAAsAAAAAQA" +
+ "AAACAAAA1AAAAAUAAAADAAAA5AAAAAYAAAABAAAA/AAAAAEgAAACAAAAHAEAAAEQAAABAAAAVAEA" +
+ "AAIgAAAMAAAAXAEAAAMgAAACAAAA4QEAAAAgAAABAAAA8AEAAAAQAAABAAAABAIAAA==");
+
+ public static void main(String[] args) {
+ System.loadLibrary(args[1]);
+ doTest(new Transform("Hello", "Goodbye"),
+ new Transform("start", "end"));
+ }
+
+ private static void printTransform(Transform t) {
+ System.out.println("Result is " + t.getResult());
+ System.out.println("take1 is " + t.take1);
+ System.out.println("take2 is " + t.take2);
+ }
+ public static void doTest(Transform t1, Transform t2) {
+ printTransform(t1);
+ printTransform(t2);
+ doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
+ printTransform(t1);
+ printTransform(t2);
+ }
+
+ // Transforms the class
+ private static native void doCommonClassRedefinition(Class<?> target,
+ byte[] class_file,
+ byte[] dex_file);
+}
diff --git a/test/917-fields-transformation/src/Transform.java b/test/917-fields-transformation/src/Transform.java
new file mode 100644
index 0000000000..6fe6223776
--- /dev/null
+++ b/test/917-fields-transformation/src/Transform.java
@@ -0,0 +1,29 @@
+/*
+ * 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 Transform {
+ public String take1;
+ public String take2;
+
+ public Transform(String take1, String take2) {
+ this.take1 = take1;
+ this.take2 = take2;
+ }
+
+ public String getResult() {
+ return take1;
+ }
+}
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index 2f1ca6d295..fdd5b6009c 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -226,6 +226,12 @@ define name-to-var
$(shell echo $(1) | tr '[:lower:]' '[:upper:]' | tr '-' '_')
endef # name-to-var
+# Disable 153-reference-stress temporarily until a fix arrives. b/33389022.
+# Disable 080-oom-fragmentation due to flakes. b/33795328
+ART_TEST_RUN_TEST_SKIP += \
+ 153-reference-stress \
+ 080-oom-fragmentation
+
ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \
$(COMPILER_TYPES),$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \
$(IMAGE_TYPES), $(PICTEST_TYPES), $(DEBUGGABLE_TYPES), $(ART_TEST_RUN_TEST_SKIP), $(ALL_ADDRESS_SIZES))
@@ -280,6 +286,7 @@ TEST_ART_BROKEN_TARGET_TESTS += \
911-get-stack-trace \
912-classes \
913-heaps \
+ 917-fields-transformation \
ifneq (,$(filter target,$(TARGET_TYPES)))
ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,target,$(RUN_TYPES),$(PREBUILD_TYPES), \
@@ -492,6 +499,24 @@ ifneq (,$(filter trace stream,$(TRACE_TYPES)))
$(PICTEST_TYPES),$(DEBUGGABLE_TYPES), $(TEST_ART_BROKEN_TRACING_RUN_TESTS),$(ALL_ADDRESS_SIZES))
endif
+TEST_ART_BROKEN_TRACING_RUN_TESTS :=
+
+# These tests expect JIT compilation, which is suppressed when tracing.
+TEST_ART_BROKEN_JIT_TRACING_RUN_TESTS := \
+ 604-hot-static-interface \
+ 612-jit-dex-cache \
+ 613-inlining-dex-cache \
+ 616-cha \
+ 626-set-resolved-string \
+
+ifneq (,$(filter trace stream,$(TRACE_TYPES)))
+ ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \
+ jit,$(RELOCATE_TYPES),trace stream,$(GC_TYPES),$(JNI_TYPES),$(IMAGE_TYPES), \
+ $(PICTEST_TYPES),$(DEBUGGABLE_TYPES), $(TEST_ART_BROKEN_JIT_TRACING_RUN_TESTS),$(ALL_ADDRESS_SIZES))
+endif
+
+TEST_ART_BROKEN_JIT_TRACING_RUN_TESTS :=
+
# Known broken tests for the interpreter.
# CFI unwinding expects managed frames.
# 629 requires compilation.
@@ -514,13 +539,24 @@ TEST_ART_BROKEN_INTERPRETER_RUN_TESTS :=
# Test 906 iterates the heap filtering with different options. No instances should be created
# between those runs to be able to have precise checks.
# Test 902 hits races with the JIT compiler. b/32821077
+# Test 626-const-class-linking can deadlock with JIT. b/33567581
# Test 629 requires compilation.
+# Test 914, 915, 917, & 918 are very sensitive to the exact state of the stack,
+# including the jit-inserted runtime frames. This causes them to be somewhat
+# flaky as JIT tests. This should be fixed once b/33630159 or b/33616143 are
+# resolved but until then just disable them. Test 916 already checks this
+# feature for JIT use cases in a way that is resilient to the jit frames.
TEST_ART_BROKEN_JIT_RUN_TESTS := \
137-cfi \
+ 626-const-class-linking \
629-vdex-speed \
902-hello-transformation \
904-object-allocation \
906-iterate-heap \
+ 914-hello-obsolescence \
+ 915-obsolete-2 \
+ 917-fields-transformation \
+ 918-obsolete-fields \
ifneq (,$(filter jit,$(COMPILER_TYPES)))
ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \
@@ -544,26 +580,6 @@ ifneq (,$(filter regalloc_gc,$(COMPILER_TYPES)))
$(TEST_ART_BROKEN_OPTIMIZING_GRAPH_COLOR),$(ALL_ADDRESS_SIZES))
endif
-# Known broken tests for the ARM VIXL backend.
-# Android.arm_vixl.mk defines TEST_ART_BROKEN_OPTIMIZING_ARM_VIXL_RUN_TESTS.
-include $(LOCAL_PATH)/Android.arm_vixl.mk
-
-ifdef ART_USE_VIXL_ARM_BACKEND
- ifeq (arm,$(filter arm,$(TARGET_ARCH) $(TARGET_2ND_ARCH)))
- ifneq (,$(filter $(OPTIMIZING_COMPILER_TYPES),$(COMPILER_TYPES)))
- ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,target,$(RUN_TYPES),$(PREBUILD_TYPES), \
- $(OPTIMIZING_COMPILER_TYPES),$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \
- $(IMAGE_TYPES),$(PICTEST_TYPES),$(DEBUGGABLE_TYPES), \
- $(TEST_ART_BROKEN_OPTIMIZING_ARM_VIXL_RUN_TESTS),32)
- endif
- endif
- # TODO(VIXL): These two tests currently fail, but adding them to `ART_TEST_KNOWN_BROKEN` breaks
- # `export ART_USE_VIXL_ARM_BACKEND=true && mma -j6 test-art-target-gtest dist`
- #ART_TEST_KNOWN_BROKEN += test-art-target-gtest-dex2oat_test32
- #ART_TEST_KNOWN_BROKEN += test-art-target-gtest-image_test32
-endif
-
-
# Known broken tests for the mips32 optimizing compiler backend.
TEST_ART_BROKEN_OPTIMIZING_MIPS_RUN_TESTS := \
@@ -672,15 +688,6 @@ ifeq ($(ART_USE_READ_BARRIER),true)
endif
endif
-# Tests disabled for GSS.
-TEST_ART_BROKEN_GSS_RUN_TESTS := 080-oom-fragmentation
-ifeq ($(ART_DEFAULT_GC_TYPE),GSS)
- ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES), \
- $(PREBUILD_TYPES),$(COMPILER_TYPES),$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES), \
- $(JNI_TYPES),$(IMAGE_TYPES),$(PICTEST_TYPES),$(DEBUGGABLE_TYPES), \
- $(TEST_ART_BROKEN_GSS_RUN_TESTS),$(ALL_ADDRESS_SIZES))
-endif
-
TEST_ART_BROKEN_OPTIMIZING_READ_BARRIER_RUN_TESTS :=
TEST_ART_BROKEN_JIT_READ_BARRIER_RUN_TESTS :=
diff --git a/test/ErroneousA/ErroneousA.java b/test/ErroneousA/ErroneousA.java
new file mode 100644
index 0000000000..49da54452a
--- /dev/null
+++ b/test/ErroneousA/ErroneousA.java
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+final class FinalSuper {}
diff --git a/test/ErroneousB/ErroneousB.java b/test/ErroneousB/ErroneousB.java
new file mode 100644
index 0000000000..6c2902ab7d
--- /dev/null
+++ b/test/ErroneousB/ErroneousB.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+// Only final in first dex.
+class FinalSuper {}
+
+class Erroneous extends FinalSuper {}
diff --git a/test/common/runtime_state.cc b/test/common/runtime_state.cc
index 285f3aa541..f26e122580 100644
--- a/test/common/runtime_state.cc
+++ b/test/common/runtime_state.cc
@@ -188,4 +188,28 @@ extern "C" JNIEXPORT jboolean JNICALL Java_Main_hasSingleImplementation(JNIEnv*
return method->HasSingleImplementation();
}
+extern "C" JNIEXPORT int JNICALL Java_Main_getHotnessCounter(JNIEnv* env,
+ jclass,
+ jclass cls,
+ jstring method_name) {
+ jit::Jit* jit = Runtime::Current()->GetJit();
+ if (jit == nullptr) {
+ // The hotness counter is valid only under JIT.
+ // If we don't JIT return 0 to match test expectations.
+ return 0;
+ }
+
+ ArtMethod* method = nullptr;
+ {
+ ScopedObjectAccess soa(Thread::Current());
+
+ ScopedUtfChars chars(env, method_name);
+ CHECK(chars.c_str() != nullptr);
+ method = soa.Decode<mirror::Class>(cls)->FindDeclaredDirectMethodByName(
+ chars.c_str(), kRuntimePointerSize);
+ }
+
+ return method->GetCounter();
+}
+
} // namespace art
diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar
index f0abb442bf..566f7ba522 100755
--- a/test/etc/run-test-jar
+++ b/test/etc/run-test-jar
@@ -59,6 +59,7 @@ ARGS=""
EXTERNAL_LOG_TAGS="n" # if y respect externally set ANDROID_LOG_TAGS.
DRY_RUN="n" # if y prepare to run the test but don't run it.
TEST_VDEX="n"
+APP_IMAGE="y"
while true; do
if [ "x$1" = "x--quiet" ]; then
@@ -132,6 +133,9 @@ while true; do
elif [ "x$1" = "x--prebuild" ]; then
PREBUILD="y"
shift
+ elif [ "x$1" = "x--no-app-image" ]; then
+ APP_IMAGE="n"
+ shift
elif [ "x$1" = "x--strip-dex" ]; then
STRIP_DEX="y"
shift
@@ -369,8 +373,8 @@ fi
if [ "$JIT" = "y" ]; then
INT_OPTS="-Xusejit:true"
if [ "$VERIFY" = "y" ] ; then
- INT_OPTS="${INT_OPTS} -Xcompiler-option --compiler-filter=verify-at-runtime"
- COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=verify-at-runtime"
+ INT_OPTS="${INT_OPTS} -Xcompiler-option --compiler-filter=interpret-only"
+ COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=interpret-only"
else
INT_OPTS="${INT_OPTS} -Xcompiler-option --compiler-filter=verify-none"
COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=verify-none"
@@ -453,11 +457,14 @@ vdex_cmdline="true"
mkdir_locations="${DEX_LOCATION}/dalvik-cache/$ISA"
strip_cmdline="true"
-# Pick a base that will force the app image to get relocated.
-app_image="--base=0x4000 --app-image-file=$DEX_LOCATION/oat/$ISA/$TEST_NAME.art"
if [ "$PREBUILD" = "y" ]; then
mkdir_locations="${mkdir_locations} ${DEX_LOCATION}/oat/$ISA"
+ if [ "$APP_IMAGE" = "y" ]; then
+ # Pick a base that will force the app image to get relocated.
+ app_image="--base=0x4000 --app-image-file=$DEX_LOCATION/oat/$ISA/$TEST_NAME.art"
+ fi
+
dex2oat_cmdline="$INVOKE_WITH $ANDROID_ROOT/bin/dex2oatd \
$COMPILE_FLAGS \
--boot-image=${BOOT_IMAGE} \
diff --git a/test/ti-agent/common_load.cc b/test/ti-agent/common_load.cc
index 2795cbc25c..38861482d2 100644
--- a/test/ti-agent/common_load.cc
+++ b/test/ti-agent/common_load.cc
@@ -66,6 +66,7 @@ AgentLib agents[] = {
{ "911-get-stack-trace", Test911GetStackTrace::OnLoad, nullptr },
{ "912-classes", Test912Classes::OnLoad, nullptr },
{ "913-heaps", Test913Heaps::OnLoad, nullptr },
+ { "917-fields-transformation", common_redefine::OnLoad, nullptr },
};
static AgentLib* FindAgent(char* name) {