diff options
Diffstat (limited to 'test')
23 files changed, 145 insertions, 569 deletions
diff --git a/test/616-cha-interface-default/expected.txt b/test/157-void-class/expected.txt index 6a5618ebc6..3f61c0b5b0 100644 --- a/test/616-cha-interface-default/expected.txt +++ b/test/157-void-class/expected.txt @@ -1 +1,2 @@ JNI_OnLoad called +void.class = void diff --git a/test/157-void-class/info.txt b/test/157-void-class/info.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/157-void-class/info.txt diff --git a/test/616-cha-interface/run b/test/157-void-class/run index d8b4f0d26c..59e852c8cd 100644..100755 --- a/test/616-cha-interface/run +++ b/test/157-void-class/run @@ -14,5 +14,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Run without an app image to prevent the classes to be loaded at startup. -exec ${RUN} "${@}" --no-app-image +# Let the test build its own core image with --no-image and use verify-profile, +# so that the compiler does not try to initialize classes. This leaves the +# java.lang.Void compile-time verified but uninitialized. +./default-run "$@" --no-image \ + --runtime-option -Ximage-compiler-option \ + --runtime-option --compiler-filter=verify-profile diff --git a/test/157-void-class/src/Main.java b/test/157-void-class/src/Main.java new file mode 100644 index 0000000000..322b705f1d --- /dev/null +++ b/test/157-void-class/src/Main.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2017 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 libcore.util.EmptyArray; + +public class Main { + public static void main(String[] args) { + try { + // Check if we're running dalvik or RI. + Class<?> class_loader_class = Class.forName("dalvik.system.PathClassLoader"); + System.loadLibrary(args[0]); + } catch (ClassNotFoundException e) { + usingRI = true; + // Add expected JNI_OnLoad log line to match expected.txt. + System.out.println("JNI_OnLoad called"); + } + try { + // Initialize all classes needed for old java.lang.Void.TYPE initialization. + Runnable.class.getMethod("run", EmptyArray.CLASS).getReturnType(); + } catch (Exception e) { + throw new Error(e); + } + // Clear the resolved types of the ojluni dex file to make sure there is no entry + // for "V", i.e. void. + clearResolvedTypes(Integer.class); + // With java.lang.Void being compile-time verified but uninitialized, initialize + // it now. Previously, this would indirectly initialize TYPE with the current, + // i.e. zero-initialized, value of TYPE. The only thing that could prevent the + // series of calls leading to this was a cache hit in Class.getDexCacheType() + // which we have prevented by clearing the cache above. + Class<?> voidClass = void.class; + System.out.println("void.class = " + voidClass); + } + + public static void clearResolvedTypes(Class<?> c) { + if (!usingRI) { + nativeClearResolvedTypes(c); + } + } + + public static native void nativeClearResolvedTypes(Class<?> c); + + static boolean usingRI = false; +} diff --git a/test/536-checker-intrinsic-optimization/src/Main.java b/test/536-checker-intrinsic-optimization/src/Main.java index 52f3f84406..e395e283e0 100644 --- a/test/536-checker-intrinsic-optimization/src/Main.java +++ b/test/536-checker-intrinsic-optimization/src/Main.java @@ -330,6 +330,21 @@ public class Main { // Terminate the scope for the CHECK-NOT search at the reference or length comparison, // whichever comes first. /// CHECK: cmp {{w.*,}} {{w.*|#.*}} + + /// CHECK-START-MIPS: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after) + /// CHECK: InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals + /// CHECK-NOT: beq r0, + /// CHECK-NOT: beqz + /// CHECK-NOT: beqzc + // Terminate the scope for the CHECK-NOT search at the class field or length comparison, + // whichever comes first. + /// CHECK: lw + + /// CHECK-START-MIPS64: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after) + /// CHECK: InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals + /// CHECK-NOT: beqzc + // Terminate the scope for the CHECK-NOT search at the reference comparison. + /// CHECK: beqc public static boolean stringArgumentNotNull(Object obj) { obj.getClass(); return "foo".equals(obj); @@ -384,6 +399,22 @@ public class Main { /// CHECK-NOT: ldr {{w\d+}}, [{{x\d+}}] /// CHECK-NOT: ldr {{w\d+}}, [{{x\d+}}, #0] /// CHECK: cmp {{w\d+}}, {{w\d+|#.*}} + + // Test is brittle as it depends on the class offset being 0. + /// CHECK-START-MIPS: boolean Main.stringArgumentIsString() disassembly (after) + /// CHECK: InvokeVirtual intrinsic:StringEquals + /// CHECK: beq{{(zc)?}} + // Check that we don't try to compare the classes. + /// CHECK-NOT: lw {{r\d+}}, +0({{r\d+}}) + /// CHECK: bne{{c?}} + + // Test is brittle as it depends on the class offset being 0. + /// CHECK-START-MIPS64: boolean Main.stringArgumentIsString() disassembly (after) + /// CHECK: InvokeVirtual intrinsic:StringEquals + /// CHECK: beqzc + // Check that we don't try to compare the classes. + /// CHECK-NOT: lw {{r\d+}}, +0({{r\d+}}) + /// CHECK: bnec public static boolean stringArgumentIsString() { return "foo".equals(myString); } diff --git a/test/616-cha-abstract/src/Main.java b/test/616-cha-abstract/src/Main.java index b33f575dec..e1d7db170d 100644 --- a/test/616-cha-abstract/src/Main.java +++ b/test/616-cha-abstract/src/Main.java @@ -39,8 +39,8 @@ class Main2 extends Main1 { } public class Main { - static Base sMain1; - static Base sMain2; + static Main1 sMain1; + static Main1 sMain2; static boolean sIsOptimizing = true; static boolean sHasJIT = true; diff --git a/test/616-cha-interface-default/info.txt b/test/616-cha-interface-default/info.txt deleted file mode 100644 index 1fd330afd4..0000000000 --- a/test/616-cha-interface-default/info.txt +++ /dev/null @@ -1 +0,0 @@ -Test for Class Hierarchy Analysis (CHA) on interface method. diff --git a/test/616-cha-interface-default/run b/test/616-cha-interface-default/run deleted file mode 100644 index d8b4f0d26c..0000000000 --- a/test/616-cha-interface-default/run +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2017 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 an app image to prevent the classes to be loaded at startup. -exec ${RUN} "${@}" --no-app-image diff --git a/test/616-cha-interface-default/src/Main.java b/test/616-cha-interface-default/src/Main.java deleted file mode 100644 index 81895b00ac..0000000000 --- a/test/616-cha-interface-default/src/Main.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -interface Base { - default public void foo(int i) { - if (i != 1) { - printError("error1"); - } - } - - default void printError(String msg) { - System.out.println(msg); - } -} - -class Main1 implements Base { -} - -class Main2 extends Main1 { - public void bar() {} -} - -class Main3 implements Base { - public void foo(int i) { - if (i != 3) { - printError("error3"); - } - } -} - -public class Main { - static Base sMain1; - static Base sMain2; - static Base sMain3; - - static boolean sIsOptimizing = true; - static boolean sHasJIT = true; - static volatile boolean sOtherThreadStarted; - - private static void assertSingleImplementation(Class<?> clazz, String method_name, boolean b) { - if (hasSingleImplementation(clazz, method_name) != b) { - System.out.println(clazz + "." + method_name + - " doesn't have single implementation value of " + b); - } - } - - static int getValue(Class<?> cls) { - if (cls == Main1.class || cls == Main2.class) { - return 1; - } - return 3; - } - - // sMain1.foo()/sMain2.foo() will be always be Base.foo() before Main3 is loaded/linked. - // So sMain1.foo() can be devirtualized to Base.foo() and be inlined. - // After Dummy.createMain3() which links in Main3, live testImplement() on stack - // should be deoptimized. - static void testImplement(boolean createMain3, boolean wait, boolean setHasJIT) { - if (setHasJIT) { - if (isInterpreted()) { - sHasJIT = false; - } - return; - } - - if (createMain3 && (sIsOptimizing || sHasJIT)) { - assertIsManaged(); - } - - sMain1.foo(getValue(sMain1.getClass())); - sMain2.foo(getValue(sMain2.getClass())); - - if (createMain3) { - // Wait for the other thread to start. - while (!sOtherThreadStarted); - // Create an Main2 instance and assign it to sMain2. - // sMain1 is kept the same. - sMain3 = Dummy.createMain3(); - // Wake up the other thread. - synchronized(Main.class) { - Main.class.notify(); - } - } else if (wait) { - // This is the other thread. - synchronized(Main.class) { - sOtherThreadStarted = true; - // Wait for Main2 to be linked and deoptimization is triggered. - try { - Main.class.wait(); - } catch (Exception e) { - } - } - } - - // There should be a deoptimization here right after Main3 is linked by - // calling Dummy.createMain3(), 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(getValue(sMain1.getClass())); - if ((createMain3 || wait) && sHasJIT && !sIsOptimizing) { - // This method should be deoptimized right after Main3 is created. - assertIsInterpreted(); - } - - if (sMain3 != null) { - sMain3.foo(getValue(sMain3.getClass())); - } - } - - // Test scenarios under which CHA-based devirtualization happens, - // and class loading that implements a method can invalidate compiled code. - public static void main(String[] args) { - System.loadLibrary(args[0]); - - if (isInterpreted()) { - sIsOptimizing = false; - } - - // sMain1 is an instance of Main1. - // sMain2 is an instance of Main2. - // Neither Main1 nor Main2 override default method Base.foo(). - // Main3 hasn't bee loaded yet. - sMain1 = new Main1(); - sMain2 = new Main2(); - - ensureJitCompiled(Main.class, "testImplement"); - testImplement(false, false, true); - - if (sHasJIT && !sIsOptimizing) { - assertSingleImplementation(Base.class, "foo", true); - assertSingleImplementation(Main1.class, "foo", true); - } else { - // Main3 is verified ahead-of-time so it's linked in already. - } - - // Create another thread that also calls sMain1.foo(). - // Try to test suspend and deopt another thread. - new Thread() { - public void run() { - testImplement(false, true, false); - } - }.start(); - - // This will create Main3 instance in the middle of testImplement(). - testImplement(true, false, false); - assertSingleImplementation(Base.class, "foo", false); - assertSingleImplementation(Main1.class, "foo", true); - assertSingleImplementation(sMain3.getClass(), "foo", true); - } - - private static native void ensureJitCompiled(Class<?> itf, String method_name); - private static native void assertIsInterpreted(); - private static native void assertIsManaged(); - private static native boolean isInterpreted(); - private static native boolean hasSingleImplementation(Class<?> clazz, String method_name); -} - -// Put createMain3() in another class to avoid class loading due to verifier. -class Dummy { - static Base createMain3() { - return new Main3(); - } -} diff --git a/test/616-cha-interface/expected.txt b/test/616-cha-interface/expected.txt deleted file mode 100644 index 6a5618ebc6..0000000000 --- a/test/616-cha-interface/expected.txt +++ /dev/null @@ -1 +0,0 @@ -JNI_OnLoad called diff --git a/test/616-cha-interface/info.txt b/test/616-cha-interface/info.txt deleted file mode 100644 index 1fd330afd4..0000000000 --- a/test/616-cha-interface/info.txt +++ /dev/null @@ -1 +0,0 @@ -Test for Class Hierarchy Analysis (CHA) on interface method. diff --git a/test/616-cha-interface/src/Main.java b/test/616-cha-interface/src/Main.java deleted file mode 100644 index aee6a95aa8..0000000000 --- a/test/616-cha-interface/src/Main.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -interface Base { - void foo(int i); -} - -class Main1 implements Base { - public void foo(int i) { - if (i != 1) { - printError("error1"); - } - } - - void printError(String msg) { - System.out.println(msg); - } -} - -class Main2 extends Main1 { - public void foo(int i) { - if (i != 2) { - printError("error2"); - } - } -} - -public class Main { - static Base sMain1; - static Base sMain2; - - static boolean sIsOptimizing = true; - static boolean sHasJIT = true; - static volatile boolean sOtherThreadStarted; - - private static void assertSingleImplementation(Class<?> clazz, String method_name, boolean b) { - if (hasSingleImplementation(clazz, method_name) != b) { - System.out.println(clazz + "." + method_name + - " doesn't have single implementation value of " + b); - } - } - - // 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 testImplement() on stack - // should be deoptimized. - static void testImplement(boolean createMain2, boolean wait, boolean setHasJIT) { - if (setHasJIT) { - if (isInterpreted()) { - sHasJIT = false; - } - return; - } - - if (createMain2 && (sIsOptimizing || sHasJIT)) { - assertIsManaged(); - } - - sMain1.foo(sMain1.getClass() == Main1.class ? 1 : 2); - - if (createMain2) { - // 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(); - } - } else if (wait) { - // This is the other thread. - synchronized(Main.class) { - sOtherThreadStarted = true; - // Wait for Main2 to be linked and deoptimization is triggered. - try { - Main.class.wait(); - } catch (Exception e) { - } - } - } - - // 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 ((createMain2 || wait) && sHasJIT && !sIsOptimizing) { - // This method should be deoptimized right after Main2 is created. - assertIsInterpreted(); - } - - 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. - public static void main(String[] args) { - System.loadLibrary(args[0]); - - if (isInterpreted()) { - sIsOptimizing = false; - } - - // sMain1 is an instance of Main1. Main2 hasn't bee loaded yet. - sMain1 = new Main1(); - - ensureJitCompiled(Main.class, "testImplement"); - testImplement(false, false, true); - - if (sHasJIT && !sIsOptimizing) { - assertSingleImplementation(Base.class, "foo", true); - assertSingleImplementation(Main1.class, "foo", true); - } else { - // Main2 is verified ahead-of-time so it's linked in already. - } - - // Create another thread that also calls sMain1.foo(). - // Try to test suspend and deopt another thread. - new Thread() { - public void run() { - testImplement(false, true, false); - } - }.start(); - - // This will create Main2 instance in the middle of testImplement(). - testImplement(true, false, false); - assertSingleImplementation(Base.class, "foo", false); - assertSingleImplementation(Main1.class, "foo", false); - } - - private static native void ensureJitCompiled(Class<?> itf, String method_name); - private static native void assertIsInterpreted(); - private static native void assertIsManaged(); - private static native boolean isInterpreted(); - private static native boolean hasSingleImplementation(Class<?> clazz, 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/616-cha-miranda/expected.txt b/test/616-cha-miranda/expected.txt deleted file mode 100644 index 6a5618ebc6..0000000000 --- a/test/616-cha-miranda/expected.txt +++ /dev/null @@ -1 +0,0 @@ -JNI_OnLoad called diff --git a/test/616-cha-miranda/info.txt b/test/616-cha-miranda/info.txt deleted file mode 100644 index c46f33f613..0000000000 --- a/test/616-cha-miranda/info.txt +++ /dev/null @@ -1 +0,0 @@ -Test for Class Hierarchy Analysis (CHA) on miranda method. diff --git a/test/616-cha-miranda/run b/test/616-cha-miranda/run deleted file mode 100644 index d8b4f0d26c..0000000000 --- a/test/616-cha-miranda/run +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2017 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 an app image to prevent the classes to be loaded at startup. -exec ${RUN} "${@}" --no-app-image diff --git a/test/616-cha-miranda/src/Main.java b/test/616-cha-miranda/src/Main.java deleted file mode 100644 index e548482eb3..0000000000 --- a/test/616-cha-miranda/src/Main.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -interface Iface { - public void foo(int i); -} - -abstract class Base implements Iface { - // Iface.foo(int) will be added as a miranda method. - - void printError(String msg) { - System.out.println(msg); - } -} - -class Main1 extends Base { - public void foo(int i) { - if (i != 1) { - printError("error1"); - } - } -} - -class Main2 extends Main1 { - public void foo(int i) { - if (i != 2) { - printError("error2"); - } - } -} - -public class Main { - static Base sMain1; - static Base sMain2; - - static boolean sIsOptimizing = true; - static boolean sHasJIT = true; - static volatile boolean sOtherThreadStarted; - - private static void assertSingleImplementation(Class<?> clazz, String method_name, boolean b) { - if (hasSingleImplementation(clazz, method_name) != b) { - System.out.println(clazz + "." + method_name + - " doesn't have single implementation value of " + b); - } - } - - // 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(boolean createMain2, boolean wait, boolean setHasJIT) { - if (setHasJIT) { - if (isInterpreted()) { - sHasJIT = false; - } - return; - } - - if (createMain2 && (sIsOptimizing || sHasJIT)) { - assertIsManaged(); - } - - sMain1.foo(sMain1.getClass() == Main1.class ? 1 : 2); - - if (createMain2) { - // 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(); - } - } else if (wait) { - // This is the other thread. - synchronized(Main.class) { - sOtherThreadStarted = true; - // Wait for Main2 to be linked and deoptimization is triggered. - try { - Main.class.wait(); - } catch (Exception e) { - } - } - } - - // 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 ((createMain2 || wait) && sHasJIT && !sIsOptimizing) { - // This method should be deoptimized right after Main2 is created. - assertIsInterpreted(); - } - - 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. - public static void main(String[] args) { - System.loadLibrary(args[0]); - - if (isInterpreted()) { - sIsOptimizing = false; - } - - // sMain1 is an instance of Main1. Main2 hasn't bee loaded yet. - sMain1 = new Main1(); - - ensureJitCompiled(Main.class, "testOverride"); - testOverride(false, false, true); - - if (sHasJIT && !sIsOptimizing) { - assertSingleImplementation(Base.class, "foo", true); - assertSingleImplementation(Main1.class, "foo", true); - } else { - // Main2 is verified ahead-of-time so it's linked in already. - } - - // Create another thread that also calls sMain1.foo(). - // Try to test suspend and deopt another thread. - new Thread() { - public void run() { - testOverride(false, true, false); - } - }.start(); - - // This will create Main2 instance in the middle of testOverride(). - testOverride(true, false, false); - assertSingleImplementation(Base.class, "foo", false); - assertSingleImplementation(Main1.class, "foo", false); - } - - private static native void ensureJitCompiled(Class<?> itf, String method_name); - private static native void assertIsInterpreted(); - private static native void assertIsManaged(); - private static native boolean isInterpreted(); - private static native boolean hasSingleImplementation(Class<?> clazz, 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/913-heaps/expected.txt b/test/913-heaps/expected.txt index 46805d7272..c96edef903 100644 --- a/test/913-heaps/expected.txt +++ b/test/913-heaps/expected.txt @@ -79,8 +79,9 @@ root@root --(thread)--> 3000@0 [size=132, length=-1] 5@1002 --(field@28)--> 1@1000 [size=16, length=-1] 6@1000 --(class)--> 1000@0 [size=123, length=-1] --- -[1@0 (32, 'HelloWorld')] +[1@0 (32, 'HelloWorld'), 2@0 (16, '')] 2 +3 2@0 (15, 3xB '010203') 3@0 (16, 2xC '41005a00') 8@0 (32, 2xD '0000000000000000000000000000f03f') @@ -128,7 +129,6 @@ root@root --(thread)--> 1@1000 [size=16, length=-1] ---- untagged objects root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestNonRoot,vreg=13,location= 32])--> 1@1000 [size=16, length=-1] root@root --(stack-local[id=1,tag=3000,depth=3,method=doFollowReferencesTest,vreg=1,location= 28])--> 3000@0 [size=132, length=-1] -root@root --(system-class)--> 2@0 [size=32, length=-1] 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] @@ -170,7 +170,6 @@ root@root --(jni-local[id=1,tag=3000,depth=0,method=followReferences])--> 1@1000 root@root --(stack-local[id=1,tag=3000,depth=1,method=doFollowReferencesTestImpl,vreg=13,location= 10])--> 1@1000 [size=16, length=-1] root@root --(stack-local[id=1,tag=3000,depth=1,method=doFollowReferencesTestImpl,vreg=5,location= 10])--> 1@1000 [size=16, length=-1] root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestRoot,vreg=4,location= 19])--> 1@1000 [size=16, length=-1] -root@root --(system-class)--> 2@0 [size=32, length=-1] 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] @@ -209,7 +208,6 @@ root@root --(thread)--> 3000@0 [size=132, length=-1] --- ---- tagged classes root@root --(stack-local[id=1,tag=3000,depth=3,method=doFollowReferencesTest,vreg=1,location= 28])--> 3000@0 [size=132, length=-1] -root@root --(system-class)--> 2@0 [size=32, 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=124, length=-1] @@ -233,7 +231,6 @@ root@root --(thread)--> 3000@0 [size=132, length=-1] 5@1002 --(class)--> 1002@0 [size=123, length=-1] 6@1000 --(class)--> 1000@0 [size=123, length=-1] --- -root@root --(system-class)--> 2@0 [size=32, 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=124, length=-1] diff --git a/test/913-heaps/src/Main.java b/test/913-heaps/src/Main.java index df89f347e0..14ee2687ec 100644 --- a/test/913-heaps/src/Main.java +++ b/test/913-heaps/src/Main.java @@ -25,9 +25,19 @@ public class Main { doTest(); new TestConfig().doFollowReferencesTest(); + Runtime.getRuntime().gc(); + Runtime.getRuntime().gc(); + doStringTest(); + + Runtime.getRuntime().gc(); + Runtime.getRuntime().gc(); + doPrimitiveArrayTest(); + Runtime.getRuntime().gc(); + Runtime.getRuntime().gc(); + // Test klass filter. System.out.println("--- klass ---"); new TestConfig(A.class, 0).doFollowReferencesTest(); @@ -53,14 +63,18 @@ public class Main { } public static void doStringTest() throws Exception { - final String str = "HelloWorld"; + final String str = new String("HelloWorld"); + final String str2 = new String(""); Object o = new Object() { String s = str; + String s2 = str2; }; setTag(str, 1); + setTag(str2, 2); System.out.println(Arrays.toString(followReferencesString(o))); System.out.println(getTag(str)); + System.out.println(getTag(str2)); } public static void doPrimitiveArrayTest() throws Exception { diff --git a/test/common/runtime_state.cc b/test/common/runtime_state.cc index a841f9e6a2..c7a57cefb6 100644 --- a/test/common/runtime_state.cc +++ b/test/common/runtime_state.cc @@ -180,6 +180,9 @@ extern "C" JNIEXPORT void JNICALL Java_Main_ensureJitCompiled(JNIEnv* env, } jit::JitCodeCache* code_cache = jit->GetCodeCache(); + // Update the code cache to make sure the JIT code does not get deleted. + // Note: this will apply to all JIT compilations. + code_cache->SetGarbageCollectCode(false); while (true) { const void* pc = method->GetEntryPointFromQuickCompiledCode(); if (code_cache->ContainsPc(pc)) { diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar index f3d4332009..99926aa9a3 100755 --- a/test/etc/run-test-jar +++ b/test/etc/run-test-jar @@ -371,6 +371,22 @@ fi if [ "$HAVE_IMAGE" = "n" ]; then + if [ "${HOST}" = "y" ]; then + framework="${ANDROID_HOST_OUT}/framework" + bpath_suffix="-hostdex" + else + framework="${ANDROID_ROOT}/framework" + bpath_suffix="" + fi + # TODO If the target was compiled WITH_DEXPREOPT=true then these tests will + # fail since these jar files will be stripped. + bpath="${framework}/core-libart${bpath_suffix}.jar" + bpath="${bpath}:${framework}/core-oj${bpath_suffix}.jar" + bpath="${bpath}:${framework}/conscrypt${bpath_suffix}.jar" + bpath="${bpath}:${framework}/okhttp${bpath_suffix}.jar" + bpath="${bpath}:${framework}/bouncycastle${bpath_suffix}.jar" + # Pass down the bootclasspath + FLAGS="${FLAGS} -Xbootclasspath:${bpath}" # Add 5 minutes to give some time to generate the boot image. TIME_OUT_VALUE=$((${TIME_OUT_VALUE} + 300)) DALVIKVM_BOOT_OPT="-Ximage:/system/non-existant/core.art" diff --git a/test/run-test b/test/run-test index 6134a14696..7d3d813da0 100755 --- a/test/run-test +++ b/test/run-test @@ -530,22 +530,6 @@ if [ "$have_image" = "no" ]; then err_echo "--no-image is only supported on the art runtime" exit 1 fi - if [ "$target_mode" = "no" ]; then - framework="${ANDROID_HOST_OUT}/framework" - bpath_suffix="-hostdex" - else - framework="${android_root}/framework" - bpath_suffix="" - fi - # TODO If the target was compiled WITH_DEXPREOPT=true then these tests will - # fail since these jar files will be stripped. - bpath="${framework}/core-libart${bpath_suffix}.jar" - bpath="${bpath}:${framework}/core-oj${bpath_suffix}.jar" - bpath="${bpath}:${framework}/conscrypt${bpath_suffix}.jar" - bpath="${bpath}:${framework}/okhttp${bpath_suffix}.jar" - bpath="${bpath}:${framework}/bouncycastle${bpath_suffix}.jar" - # Pass down the bootclasspath - run_args="${run_args} --runtime-option -Xbootclasspath:${bpath}" run_args="${run_args} --no-image" fi diff --git a/test/testrunner/env.py b/test/testrunner/env.py index 4336d7772f..ed4b4a9f3e 100644 --- a/test/testrunner/env.py +++ b/test/testrunner/env.py @@ -178,6 +178,8 @@ ART_TEST_WITH_STRACE = getEnvBoolean('ART_TEST_DEBUG_GC', False) EXTRA_DISABLED_TESTS = set(env.get("ART_TEST_RUN_TEST_SKIP", "").split()) +ART_TEST_RUN_TEST_BUILD = getEnvBoolean('ART_TEST_RUN_TEST_BUILD', False) + TARGET_2ND_ARCH = get_build_var('TARGET_2ND_ARCH') TARGET_ARCH = get_build_var('TARGET_ARCH') if TARGET_2ND_ARCH: diff --git a/test/testrunner/testrunner.py b/test/testrunner/testrunner.py index c22b0be9f4..9c8d3b870c 100755 --- a/test/testrunner/testrunner.py +++ b/test/testrunner/testrunner.py @@ -704,7 +704,6 @@ def parse_test_name(test_name): return {match.group(12)} raise ValueError(test_name + " is not a valid test") - def parse_option(): global verbose global dry_run @@ -726,7 +725,15 @@ def parse_option(): parser.add_argument('--dry-run', action='store_true', dest='dry_run') parser.add_argument("--skip", action="append", dest="skips", default=[], help="Skip the given test in all circumstances.") - parser.add_argument('-b', '--build-dependencies', action='store_true', dest='build') + parser.add_argument('--no-build-dependencies', + action='store_false', dest='build', + help="Don't build dependencies under any circumstances. This is the " + + "behavior if ART_TEST_RUN_TEST_ALWAYS_BUILD is not set to 'true'.") + parser.add_argument('-b', '--build-dependencies', + action='store_true', dest='build', + help="Build dependencies under all circumstances. By default we will " + + "not build dependencies unless ART_TEST_RUN_TEST_BUILD=true.") + parser.set_defaults(build = env.ART_TEST_RUN_TEST_BUILD) parser.add_argument('--gdb', action='store_true', dest='gdb') parser.add_argument('--gdb-arg', dest='gdb_arg') @@ -804,8 +811,7 @@ def parse_option(): if options.dry_run: dry_run = True verbose = True - if options.build: - build = True + build = options.build if options.gdb: n_thread = 1 gdb = True |