diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/496-checker-inlining-and-class-loader/src/Main.java | 3 | ||||
| -rw-r--r-- | test/552-checker-sharpening/src/Main.java | 79 | ||||
| -rw-r--r-- | test/613-inlining-dex-cache/expected.txt | 1 | ||||
| -rw-r--r-- | test/613-inlining-dex-cache/info.txt | 2 | ||||
| -rw-r--r-- | test/613-inlining-dex-cache/run | 20 | ||||
| -rw-r--r-- | test/613-inlining-dex-cache/src-ex/B.java | 18 | ||||
| -rw-r--r-- | test/613-inlining-dex-cache/src-ex/LoadedByAppClassLoader.java | 22 | ||||
| -rw-r--r-- | test/613-inlining-dex-cache/src/B.java | 20 | ||||
| -rw-r--r-- | test/613-inlining-dex-cache/src/Main.java | 85 |
9 files changed, 246 insertions, 4 deletions
diff --git a/test/496-checker-inlining-and-class-loader/src/Main.java b/test/496-checker-inlining-and-class-loader/src/Main.java index 8de6318664..78e8a40399 100644 --- a/test/496-checker-inlining-and-class-loader/src/Main.java +++ b/test/496-checker-inlining-and-class-loader/src/Main.java @@ -107,7 +107,8 @@ class LoadedByMyClassLoader { /* Load and initialize FirstSeenByMyClassLoader */ /// CHECK: LoadClass gen_clinit_check:true /* Load and initialize System */ - /// CHECK-NEXT: LoadClass gen_clinit_check:true + // There may be MipsComputeBaseMethodAddress here. + /// CHECK: LoadClass gen_clinit_check:true /// CHECK-NEXT: StaticFieldGet // There may be HArmDexCacheArraysBase or HX86ComputeBaseMethodAddress here. /// CHECK: LoadString diff --git a/test/552-checker-sharpening/src/Main.java b/test/552-checker-sharpening/src/Main.java index 09a77ed285..2232ff43d2 100644 --- a/test/552-checker-sharpening/src/Main.java +++ b/test/552-checker-sharpening/src/Main.java @@ -51,6 +51,10 @@ public class Main { /// CHECK-START-ARM64: int Main.testSimple(int) sharpening (after) /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative + /// CHECK-START-MIPS: int Main.testSimple(int) sharpening (after) + /// CHECK-NOT: MipsDexCacheArraysBase + /// 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 @@ -62,6 +66,10 @@ public class Main { /// CHECK: ArmDexCacheArraysBase /// CHECK-NOT: ArmDexCacheArraysBase + /// CHECK-START-MIPS: int Main.testSimple(int) dex_cache_array_fixups_mips (after) + /// CHECK: MipsDexCacheArraysBase + /// CHECK-NOT: MipsDexCacheArraysBase + /// CHECK-START-X86: int Main.testSimple(int) pc_relative_fixups_x86 (after) /// CHECK: X86ComputeBaseMethodAddress /// CHECK-NOT: X86ComputeBaseMethodAddress @@ -83,6 +91,11 @@ public class Main { /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative + /// CHECK-START-MIPS: int Main.testDiamond(boolean, int) sharpening (after) + /// CHECK-NOT: MipsDexCacheArraysBase + /// 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 @@ -100,6 +113,14 @@ public class Main { /// CHECK: ArmDexCacheArraysBase /// CHECK-NEXT: If + /// CHECK-START-MIPS: int Main.testDiamond(boolean, int) dex_cache_array_fixups_mips (after) + /// CHECK: MipsDexCacheArraysBase + /// CHECK-NOT: MipsDexCacheArraysBase + + /// CHECK-START-MIPS: int Main.testDiamond(boolean, int) dex_cache_array_fixups_mips (after) + /// CHECK: MipsDexCacheArraysBase + /// CHECK-NEXT: If + /// CHECK-START-X86: int Main.testDiamond(boolean, int) pc_relative_fixups_x86 (after) /// CHECK: X86ComputeBaseMethodAddress /// CHECK-NOT: X86ComputeBaseMethodAddress @@ -110,7 +131,7 @@ public class Main { public static int testDiamond(boolean negate, int x) { // These calls should use PC-relative dex cache array loads to retrieve the target method. - // PC-relative bases used by X86 and ARM should be pulled before the If. + // PC-relative bases used by ARM, MIPS and X86 should be pulled before the If. if (negate) { return $noinline$foo(-x); } else { @@ -154,8 +175,26 @@ public class Main { /// CHECK: begin_block /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative + /// CHECK-START-MIPS: int Main.testLoop(int[], int) dex_cache_array_fixups_mips (before) + /// CHECK-NOT: MipsDexCacheArraysBase + + /// CHECK-START-MIPS: int Main.testLoop(int[], int) dex_cache_array_fixups_mips (after) + /// CHECK: MipsDexCacheArraysBase + /// CHECK-NOT: MipsDexCacheArraysBase + + /// CHECK-START-MIPS: int Main.testLoop(int[], int) dex_cache_array_fixups_mips (after) + /// CHECK: InvokeStaticOrDirect + /// CHECK-NOT: InvokeStaticOrDirect + + /// CHECK-START-MIPS: int Main.testLoop(int[], int) dex_cache_array_fixups_mips (after) + /// CHECK: ArrayLength + /// CHECK-NEXT: MipsDexCacheArraysBase + /// CHECK-NEXT: Goto + /// CHECK: begin_block + /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative + public static int testLoop(int[] array, int x) { - // PC-relative bases used by X86 and ARM should be pulled before the loop. + // PC-relative bases used by ARM, MIPS and X86 should be pulled before the loop. for (int i : array) { x += $noinline$foo(i); } @@ -182,8 +221,18 @@ public class Main { /// CHECK-NEXT: ArmDexCacheArraysBase /// CHECK-NEXT: Goto + /// CHECK-START-MIPS: int Main.testLoopWithDiamond(int[], boolean, int) dex_cache_array_fixups_mips (before) + /// CHECK-NOT: MipsDexCacheArraysBase + + /// CHECK-START-MIPS: int Main.testLoopWithDiamond(int[], boolean, int) dex_cache_array_fixups_mips (after) + /// CHECK: If + /// CHECK: begin_block + /// CHECK: ArrayLength + /// CHECK-NEXT: MipsDexCacheArraysBase + /// CHECK-NEXT: Goto + public static int testLoopWithDiamond(int[] array, boolean negate, int x) { - // PC-relative bases used by X86 and ARM should be pulled before the loop + // PC-relative bases used by ARM, MIPS and X86 should be pulled before the loop // but not outside the if. if (array != null) { for (int i : array) { @@ -220,6 +269,11 @@ public class Main { // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress. /// CHECK: LoadString load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}} + /// CHECK-START-MIPS: 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|DexCachePcRelative|DexCacheViaMethod}} + public static String $noinline$getBootImageString() { // Prevent inlining to avoid the string comparison being optimized away. if (doThrow) { throw new Error(); } @@ -250,6 +304,13 @@ public class Main { /// CHECK-START-ARM64: java.lang.String Main.$noinline$getNonBootImageString() sharpening (after) /// CHECK: LoadString load_kind:DexCachePcRelative + /// CHECK-START-MIPS: java.lang.String Main.$noinline$getNonBootImageString() sharpening (after) + /// CHECK: LoadString load_kind:DexCachePcRelative + + /// CHECK-START-MIPS: java.lang.String Main.$noinline$getNonBootImageString() dex_cache_array_fixups_mips (after) + /// CHECK-DAG: MipsDexCacheArraysBase + /// CHECK-DAG: LoadString load_kind:DexCachePcRelative + public static String $noinline$getNonBootImageString() { // Prevent inlining to avoid the string comparison being optimized away. if (doThrow) { throw new Error(); } @@ -280,6 +341,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-MIPS: 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(); } @@ -310,6 +376,13 @@ public class Main { /// CHECK-START-ARM64: java.lang.Class Main.$noinline$getOtherClass() sharpening (after) /// CHECK: LoadClass load_kind:DexCachePcRelative class_name:Other + /// CHECK-START-MIPS: java.lang.Class Main.$noinline$getOtherClass() sharpening (after) + /// CHECK: LoadClass load_kind:DexCachePcRelative class_name:Other + + /// CHECK-START-MIPS: java.lang.Class Main.$noinline$getOtherClass() dex_cache_array_fixups_mips (after) + /// CHECK-DAG: MipsDexCacheArraysBase + /// CHECK-DAG: 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/613-inlining-dex-cache/expected.txt b/test/613-inlining-dex-cache/expected.txt new file mode 100644 index 0000000000..6a5618ebc6 --- /dev/null +++ b/test/613-inlining-dex-cache/expected.txt @@ -0,0 +1 @@ +JNI_OnLoad called diff --git a/test/613-inlining-dex-cache/info.txt b/test/613-inlining-dex-cache/info.txt new file mode 100644 index 0000000000..e80f642f3e --- /dev/null +++ b/test/613-inlining-dex-cache/info.txt @@ -0,0 +1,2 @@ +Regression test for the JIT compiler which used to +wrongly update the dex cache of a class loader. diff --git a/test/613-inlining-dex-cache/run b/test/613-inlining-dex-cache/run new file mode 100644 index 0000000000..9c1e7aa95c --- /dev/null +++ b/test/613-inlining-dex-cache/run @@ -0,0 +1,20 @@ +#!/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. + +flags="$@" +# We need the dex files pre-verified to avoid running the verifier +# at runtime which will update the dex cache. +exec ${RUN} ${flags/verify-at-runtime/interpret-only} diff --git a/test/613-inlining-dex-cache/src-ex/B.java b/test/613-inlining-dex-cache/src-ex/B.java new file mode 100644 index 0000000000..4da9a1da6b --- /dev/null +++ b/test/613-inlining-dex-cache/src-ex/B.java @@ -0,0 +1,18 @@ +/* + * 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 B { +} diff --git a/test/613-inlining-dex-cache/src-ex/LoadedByAppClassLoader.java b/test/613-inlining-dex-cache/src-ex/LoadedByAppClassLoader.java new file mode 100644 index 0000000000..f4e0f1019a --- /dev/null +++ b/test/613-inlining-dex-cache/src-ex/LoadedByAppClassLoader.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class LoadedByAppClassLoader { + public static void letMeInlineYou() { + // We used to pass the wrong class loader when trying to inline 'Main.foo'. + Main.foo(null); + } +} diff --git a/test/613-inlining-dex-cache/src/B.java b/test/613-inlining-dex-cache/src/B.java new file mode 100644 index 0000000000..6e7e55d430 --- /dev/null +++ b/test/613-inlining-dex-cache/src/B.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. + */ + +public class B { + public void foo() { + } +} diff --git a/test/613-inlining-dex-cache/src/Main.java b/test/613-inlining-dex-cache/src/Main.java new file mode 100644 index 0000000000..31ab1d2bfa --- /dev/null +++ b/test/613-inlining-dex-cache/src/Main.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; + +import dalvik.system.PathClassLoader; + +// ClassLoader not delegating for non java. packages. +class DelegateLastPathClassLoader extends PathClassLoader { + + public DelegateLastPathClassLoader(String dexPath, ClassLoader parent) { + super(dexPath, parent); + } + + @Override + protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { + if (!name.startsWith("java.")) { + try { + return findClass(name); + } catch (ClassNotFoundException ignore) { + // Ignore and fall through to parent class loader. + } + } + return super.loadClass(name, resolve); + } +} + +public class Main { + + public static void main(String[] args) throws Exception { + System.loadLibrary(args[0]); + final String DEX_FILE = System.getenv("DEX_LOCATION") + "/613-inlining-dex-cache-ex.jar"; + ClassLoader loader = new DelegateLastPathClassLoader(DEX_FILE, Main.class.getClassLoader()); + Class cls = loader.loadClass("LoadedByAppClassLoader"); + Method m = cls.getDeclaredMethod("letMeInlineYou"); + // Invoke the method enough times to get JITted. + for (int i = 0; i < 10000; ++i) { + m.invoke(null); + } + ensureJitCompiled(cls, "letMeInlineYou"); + ClassLoader bLoader = areYouB(); + if (bLoader != Main.class.getClassLoader()) { + throw new Error("Wrong class loader"); + } + } + + public static void foo(Main o) { + // LoadedByAppClassLoader.letMeInlineYou will try to inline this + // method but used to pass the wrong class loader. As a result, + // the lookup of B.foo was updating the dex cache with the other + // class loader's B class. + if (o != null) { + o.myField.foo(); + } + } + + public B myField; + + public static ClassLoader areYouB() { + return OtherClass.getB().getClassLoader(); + } + + public static native void ensureJitCompiled(Class cls, String method_name); +} + +class OtherClass { + public static Class getB() { + // This used to return the B class of another class loader. + return B.class; + } +} |