diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/164-resolution-trampoline-dex-cache/expected.txt | 3 | ||||
| -rw-r--r-- | test/164-resolution-trampoline-dex-cache/info.txt | 3 | ||||
| -rw-r--r-- | test/164-resolution-trampoline-dex-cache/profile | 1 | ||||
| -rw-r--r-- | test/164-resolution-trampoline-dex-cache/run | 22 | ||||
| -rw-r--r-- | test/164-resolution-trampoline-dex-cache/src-ex/MostDerived.java | 50 | ||||
| -rw-r--r-- | test/164-resolution-trampoline-dex-cache/src/Base.java | 21 | ||||
| -rw-r--r-- | test/164-resolution-trampoline-dex-cache/src/Derived.java | 18 | ||||
| -rw-r--r-- | test/164-resolution-trampoline-dex-cache/src/Main.java | 59 | ||||
| -rw-r--r-- | test/911-get-stack-trace/src/art/PrintThread.java | 2 | ||||
| -rw-r--r-- | test/912-classes/expected.txt | 2 | ||||
| -rw-r--r-- | test/912-classes/src-art/art/Test912.java | 32 | ||||
| -rw-r--r-- | test/knownfailures.json | 8 |
12 files changed, 217 insertions, 4 deletions
diff --git a/test/164-resolution-trampoline-dex-cache/expected.txt b/test/164-resolution-trampoline-dex-cache/expected.txt new file mode 100644 index 0000000000..d549cb1664 --- /dev/null +++ b/test/164-resolution-trampoline-dex-cache/expected.txt @@ -0,0 +1,3 @@ +JNI_OnLoad called +Base.foo() on MostDerived +MostDerived.test(.) done. diff --git a/test/164-resolution-trampoline-dex-cache/info.txt b/test/164-resolution-trampoline-dex-cache/info.txt new file mode 100644 index 0000000000..4e4d82ae5b --- /dev/null +++ b/test/164-resolution-trampoline-dex-cache/info.txt @@ -0,0 +1,3 @@ +Regression test for artQuickResolutionTrampoline() erroneously storing an +ArtMethod to a DexCache for a MethodId referencing a class missing from the +associated ClassTable. This discrepancy then led to a crash when JITting. diff --git a/test/164-resolution-trampoline-dex-cache/profile b/test/164-resolution-trampoline-dex-cache/profile new file mode 100644 index 0000000000..d232ff20ca --- /dev/null +++ b/test/164-resolution-trampoline-dex-cache/profile @@ -0,0 +1 @@ +LMostDerived;->test(Ljava/lang/Class;)V diff --git a/test/164-resolution-trampoline-dex-cache/run b/test/164-resolution-trampoline-dex-cache/run new file mode 100644 index 0000000000..5e77cd56ed --- /dev/null +++ b/test/164-resolution-trampoline-dex-cache/run @@ -0,0 +1,22 @@ +#!/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. + +# Use the --secondary switch to add secondary dex file to class path. +# Make sure we compile the required method using speed-profile compiler filter. +# Enable JIT through runtime option to avoid the compiler filter set by --jit. +exec ${RUN} "${@}" --secondary \ + -Xcompiler-option --compiler-filter=speed-profile --profile \ + --runtime-option -Xusejit:true diff --git a/test/164-resolution-trampoline-dex-cache/src-ex/MostDerived.java b/test/164-resolution-trampoline-dex-cache/src-ex/MostDerived.java new file mode 100644 index 0000000000..0c85528b55 --- /dev/null +++ b/test/164-resolution-trampoline-dex-cache/src-ex/MostDerived.java @@ -0,0 +1,50 @@ +/* + * 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. + */ + +public class MostDerived extends Derived { + public static void test(Class main) { + // The defining class loader of MostDerived (MDCL) is also the initiating loader of + // superclass Derived but delegates the loading to its parent class loader (PCL) which + // defines both Derived and Base. Thus Derived.class is recorded in MDCL's ClassTable + // but the Base.class is not because the Base's initiating loader is PCL. This is the + // case when loading the MostDerived class and remains the case after resolving the + // "invoke-super Derived.foo(.)" called from from MostDerived.foo(.). When that + // invoke-super is executed from AOT-compiled code, it goes through the .bss ArtMethod* + // entry and on first execution goes through the resolution method. After resolving to + // the Base.foo(.), the artQuickResolutionTrampoline() used to erroneously fill the + // Base.foo(.) entry in the MostDerived's DexCache which is wrong as the referenced + // class Base is not in the associated, i.e. MDCL's, ClassTable. + new MostDerived().foo(main); + try { + // This discrepancy then used to crash when resolving the Base.foo(.) method + // for JIT compilation of another method. + main.getDeclaredMethod("ensureJitCompiled", Class.class, String.class).invoke( + null, MostDerived.class, "bar"); + } catch (Throwable t) { + t.printStackTrace(System.out); + } + System.out.println("MostDerived.test(.) done."); + } + + public void foo(Class main) { + super.foo(main); + } + + public void bar(Class main) { + Base b = this; + b.foo(main); + } +} diff --git a/test/164-resolution-trampoline-dex-cache/src/Base.java b/test/164-resolution-trampoline-dex-cache/src/Base.java new file mode 100644 index 0000000000..d4ef78bf49 --- /dev/null +++ b/test/164-resolution-trampoline-dex-cache/src/Base.java @@ -0,0 +1,21 @@ +/* + * 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. + */ + +public class Base { + public void foo(Class main) { + System.out.println("Base.foo() on " + getClass().getName()); + } +} diff --git a/test/164-resolution-trampoline-dex-cache/src/Derived.java b/test/164-resolution-trampoline-dex-cache/src/Derived.java new file mode 100644 index 0000000000..acca9ce5af --- /dev/null +++ b/test/164-resolution-trampoline-dex-cache/src/Derived.java @@ -0,0 +1,18 @@ +/* + * 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. + */ + +public class Derived extends Base { +} diff --git a/test/164-resolution-trampoline-dex-cache/src/Main.java b/test/164-resolution-trampoline-dex-cache/src/Main.java new file mode 100644 index 0000000000..b4731ae0b6 --- /dev/null +++ b/test/164-resolution-trampoline-dex-cache/src/Main.java @@ -0,0 +1,59 @@ +/* + * 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 java.lang.reflect.Constructor; +import java.lang.reflect.Method; + +public class Main { + public static String TEST_NAME = "164-resolution-trampoline-dex-cache"; + + public static void main(String[] args) { + // Load the test JNI for ensureJitCompiled(). Note that classes Main loaded + // by other class loaders do not have the binding, so we need to pass the + // current Main.class around and call ensureJitCompiled() via reflection. + System.loadLibrary(args[0]); + try { + String dex_location = System.getenv("DEX_LOCATION"); + ClassLoader systemLoader = ClassLoader.getSystemClassLoader().getParent(); + ClassLoader baseLoader = getClassLoaderFor(dex_location, systemLoader, /* ex */ false); + ClassLoader mainLoader = getClassLoaderFor(dex_location, baseLoader, /* ex */ true); + + Class<?> tc = Class.forName("MostDerived", true, mainLoader); + Method m = tc.getDeclaredMethod("test", Class.class); + m.invoke(null, Main.class); + } catch (Throwable t) { + t.printStackTrace(System.out); + } + } + + public static ClassLoader getClassLoaderFor(String location, ClassLoader parent, boolean ex) + throws Exception { + try { + Class<?> class_loader_class = Class.forName("dalvik.system.PathClassLoader"); + Constructor<?> ctor = + class_loader_class.getConstructor(String.class, ClassLoader.class); + String path = location + "/" + TEST_NAME + (ex ? "-ex.jar" : ".jar"); + return (ClassLoader)ctor.newInstance(path, parent); + } catch (ClassNotFoundException e) { + // Running on RI. Use URLClassLoader. + String url = "file://" + location + (ex ? "/classes-ex/" : "/classes/"); + return new java.net.URLClassLoader( + new java.net.URL[] { new java.net.URL(url) }, parent); + } + } + + public static native void ensureJitCompiled(Class<?> klass, String method_name); +} diff --git a/test/911-get-stack-trace/src/art/PrintThread.java b/test/911-get-stack-trace/src/art/PrintThread.java index fee5ba00ab..d8b3cbc57e 100644 --- a/test/911-get-stack-trace/src/art/PrintThread.java +++ b/test/911-get-stack-trace/src/art/PrintThread.java @@ -42,7 +42,7 @@ public class PrintThread { // may not exist depending on the environment. public final static String IGNORE_THREAD_NAME_REGEX = "Binder:|RenderThread|hwuiTask|Jit thread pool worker|Instr:|JDWP|Profile Saver|main|" + - "queued-work-looper"; + "queued-work-looper|InstrumentationConnectionThread"; public final static Matcher IGNORE_THREADS = Pattern.compile(IGNORE_THREAD_NAME_REGEX).matcher(""); diff --git a/test/912-classes/expected.txt b/test/912-classes/expected.txt index 9dcc5f9c90..7ad5d608b7 100644 --- a/test/912-classes/expected.txt +++ b/test/912-classes/expected.txt @@ -56,7 +56,7 @@ boot <- (B) <- (A, List) boot <- 1+2 (A,B) [class A, class B, class java.lang.Object] -[37, 0] +[35, 0] B, false Load: LB; on ClassEvents diff --git a/test/912-classes/src-art/art/Test912.java b/test/912-classes/src-art/art/Test912.java index fbf8794c50..1742276bd7 100644 --- a/test/912-classes/src-art/art/Test912.java +++ b/test/912-classes/src-art/art/Test912.java @@ -19,8 +19,10 @@ package art; import java.lang.ref.Reference; import java.lang.reflect.Constructor; import java.lang.reflect.Proxy; +import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; +import java.util.Base64; import java.util.Comparator; public class Test912 { @@ -214,8 +216,34 @@ public class Test912 { } } - private static void testClassVersion() { - System.out.println(Arrays.toString(getClassVersion(Main.class))); + /** + * base64 encoded class/dex file for + * class Transform { + * public void sayHi() { + * System.out.println("Goodbye"); + * } + * } + */ + private static final byte[] DEX_BYTES = Base64.getDecoder().decode( + "ZGV4CjAzNQCLXSBQ5FiS3f16krSYZFF8xYZtFVp0GRXMAgAAcAAAAHhWNBIAAAAAAAAAACwCAAAO" + + "AAAAcAAAAAYAAACoAAAAAgAAAMAAAAABAAAA2AAAAAQAAADgAAAAAQAAAAABAACsAQAAIAEAAGIB" + + "AABqAQAAcwEAAIABAACXAQAAqwEAAL8BAADTAQAA4wEAAOYBAADqAQAA/gEAAAMCAAAMAgAAAgAA" + + "AAMAAAAEAAAABQAAAAYAAAAIAAAACAAAAAUAAAAAAAAACQAAAAUAAABcAQAABAABAAsAAAAAAAAA" + + "AAAAAAAAAAANAAAAAQABAAwAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAHAAAAAAAAAB4CAAAA" + + "AAAAAQABAAEAAAATAgAABAAAAHAQAwAAAA4AAwABAAIAAAAYAgAACQAAAGIAAAAbAQEAAABuIAIA" + + "EAAOAAAAAQAAAAMABjxpbml0PgAHR29vZGJ5ZQALTFRyYW5zZm9ybTsAFUxqYXZhL2lvL1ByaW50" + + "U3RyZWFtOwASTGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xh" + + "bmcvU3lzdGVtOwAOVHJhbnNmb3JtLmphdmEAAVYAAlZMABJlbWl0dGVyOiBqYWNrLTMuMzYAA291" + + "dAAHcHJpbnRsbgAFc2F5SGkAEQAHDgATAAcOhQAAAAEBAICABKACAQG4Ag0AAAAAAAAAAQAAAAAA" + + "AAABAAAADgAAAHAAAAACAAAABgAAAKgAAAADAAAAAgAAAMAAAAAEAAAAAQAAANgAAAAFAAAABAAA" + + "AOAAAAAGAAAAAQAAAAABAAABIAAAAgAAACABAAABEAAAAQAAAFwBAAACIAAADgAAAGIBAAADIAAA" + + "AgAAABMCAAAAIAAAAQAAAB4CAAAAEAAAAQAAACwCAAA="); + private static void testClassVersion() throws Exception { + Class<?> class_loader_class = Class.forName("dalvik.system.InMemoryDexClassLoader"); + Constructor<?> ctor = class_loader_class.getConstructor(ByteBuffer.class, ClassLoader.class); + Class target = ((ClassLoader)ctor.newInstance( + ByteBuffer.wrap(DEX_BYTES), Test912.class.getClassLoader())).loadClass("Transform"); + System.out.println(Arrays.toString(getClassVersion(target))); } private static void testClassEvents() throws Exception { diff --git a/test/knownfailures.json b/test/knownfailures.json index 69421de325..a2502e69e0 100644 --- a/test/knownfailures.json +++ b/test/knownfailures.json @@ -105,6 +105,14 @@ "description": ["This test sometimes runs out of memory initializing the boot classpath."] }, { + "tests": "164-resolution-trampoline-dex-cache", + "variant": "interp-ac | interpreter", + "description": ["This test requires AOT mixed with JIT and enables the JIT by the ", + "runtime option -Xusejit:true. This conflicts with -Xint passed for ", + "interpreter configurations (interp-ac | interpreter). The 'jit' ", + "configuration succeeds even though it does not test anything useful."] + }, + { "tests": ["908-gc-start-finish", "913-heaps"], "variant": "gcstress", |