diff options
Diffstat (limited to 'test')
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) { |