summaryrefslogtreecommitdiff
path: root/test/496-checker-inlining-class-loader
diff options
context:
space:
mode:
author Wojciech Staszkiewicz <staszkiewicz@google.com> 2016-09-19 10:06:09 -0700
committer Wojciech Staszkiewicz <staszkiewicz@google.com> 2016-09-19 15:33:15 -0700
commitca57c409b947bdd4642374ae8d7366e14b2a836e (patch)
tree44f85e41cd4dfe1aa57018f14bc762a234758105 /test/496-checker-inlining-class-loader
parent7d26164308e9eab5c596a19b841e4ab1c27828a8 (diff)
Shorten long test names
Long Android.run-test.mk targets cause testing framework to misbehave. Issues occur in no-prebuild mode when --output-path parameter generated by the make system is too long. When this happens oat generation fails silently in oat_file_assistant.cc during creation of empty vdex and oat files. Creation fails because file names, which are as long as absolute path to source dex file, are longer than 255 characters Linux file name limit. Because oat generation fails silently affected tests pass even though they were effectively ran in interpreter mode, instead of intended default mode. This CL shortens test names to be at most 35 characters. This helps make the tests more reliable. Test: m test-art-run-test Bug: 31597671 Change-Id: Ic68408ae0c98ffca0c64ca4f5535f4e683a296f0
Diffstat (limited to 'test/496-checker-inlining-class-loader')
-rw-r--r--test/496-checker-inlining-class-loader/expected.txt4
-rw-r--r--test/496-checker-inlining-class-loader/info.txt2
-rw-r--r--test/496-checker-inlining-class-loader/src/FirstSeenByMyClassLoader.java26
-rw-r--r--test/496-checker-inlining-class-loader/src/Main.java131
4 files changed, 163 insertions, 0 deletions
diff --git a/test/496-checker-inlining-class-loader/expected.txt b/test/496-checker-inlining-class-loader/expected.txt
new file mode 100644
index 0000000000..312c28f8b0
--- /dev/null
+++ b/test/496-checker-inlining-class-loader/expected.txt
@@ -0,0 +1,4 @@
+Request for LoadedByMyClassLoader
+Request for FirstSeenByMyClassLoader
+In between the two calls.
+In $noinline$bar
diff --git a/test/496-checker-inlining-class-loader/info.txt b/test/496-checker-inlining-class-loader/info.txt
new file mode 100644
index 0000000000..aa4b256207
--- /dev/null
+++ b/test/496-checker-inlining-class-loader/info.txt
@@ -0,0 +1,2 @@
+Regression test to ensure compilers preserve JLS
+semantics of class loading.
diff --git a/test/496-checker-inlining-class-loader/src/FirstSeenByMyClassLoader.java b/test/496-checker-inlining-class-loader/src/FirstSeenByMyClassLoader.java
new file mode 100644
index 0000000000..e97b4e3391
--- /dev/null
+++ b/test/496-checker-inlining-class-loader/src/FirstSeenByMyClassLoader.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015 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 FirstSeenByMyClassLoader {
+ public static void $inline$bar() {
+ }
+
+ public static void $noinline$bar() {
+ try {
+ System.out.println("In $noinline$bar");
+ } catch (Throwable t) { /* Ignore */ }
+ }
+}
diff --git a/test/496-checker-inlining-class-loader/src/Main.java b/test/496-checker-inlining-class-loader/src/Main.java
new file mode 100644
index 0000000000..15d4dc07bc
--- /dev/null
+++ b/test/496-checker-inlining-class-loader/src/Main.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2015 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.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+class MyClassLoader extends ClassLoader {
+ MyClassLoader() throws Exception {
+ super(MyClassLoader.class.getClassLoader());
+
+ // Some magic to get access to the pathList field of BaseDexClassLoader.
+ ClassLoader loader = getClass().getClassLoader();
+ Class<?> baseDexClassLoader = loader.getClass().getSuperclass();
+ Field f = baseDexClassLoader.getDeclaredField("pathList");
+ f.setAccessible(true);
+ Object pathList = f.get(loader);
+
+ // Some magic to get access to the dexField field of pathList.
+ // Need to make a copy of the dex elements since we don't want an app image with pre-resolved
+ // things.
+ f = pathList.getClass().getDeclaredField("dexElements");
+ f.setAccessible(true);
+ Object[] dexElements = (Object[]) f.get(pathList);
+ f = dexElements[0].getClass().getDeclaredField("dexFile");
+ f.setAccessible(true);
+ for (Object element : dexElements) {
+ Object dexFile = f.get(element);
+ // Make copy.
+ Field fileNameField = dexFile.getClass().getDeclaredField("mFileName");
+ fileNameField.setAccessible(true);
+ dexFiles.add(dexFile.getClass().getDeclaredConstructor(String.class).newInstance(
+ fileNameField.get(dexFile)));
+ }
+ }
+
+ ArrayList<Object> dexFiles = new ArrayList<Object>();
+ Field dexFileField;
+
+ protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException {
+ // Other classes may also get loaded, ignore those.
+ if (className.equals("LoadedByMyClassLoader") || className.equals("FirstSeenByMyClassLoader")) {
+ System.out.println("Request for " + className);
+ }
+
+ // We're only going to handle LoadedByMyClassLoader.
+ if (className != "LoadedByMyClassLoader") {
+ return getParent().loadClass(className);
+ }
+
+ // Mimic what DexPathList.findClass is doing.
+ try {
+ for (Object dexFile : dexFiles) {
+ Method method = dexFile.getClass().getDeclaredMethod(
+ "loadClassBinaryName", String.class, ClassLoader.class, List.class);
+
+ if (dexFile != null) {
+ Class<?> clazz = (Class<?>)method.invoke(dexFile, className, this, null);
+ if (clazz != null) {
+ return clazz;
+ }
+ }
+ }
+ } catch (Exception e) { /* Ignore */ }
+ return null;
+ }
+}
+
+class LoadedByMyClassLoader {
+ /// CHECK-START: void LoadedByMyClassLoader.bar() inliner (before)
+ /// CHECK: LoadClass
+ /// CHECK-NEXT: ClinitCheck
+ /// CHECK-NEXT: InvokeStaticOrDirect
+ /// CHECK-NEXT: LoadClass
+ /// CHECK-NEXT: ClinitCheck
+ /// CHECK-NEXT: StaticFieldGet
+ /// CHECK-NEXT: LoadString
+ /// CHECK-NEXT: NullCheck
+ /// CHECK-NEXT: InvokeVirtual
+
+ /// CHECK-START: void LoadedByMyClassLoader.bar() inliner (after)
+ /// CHECK: LoadClass
+ /// CHECK-NEXT: ClinitCheck
+ /* We inlined FirstSeenByMyClassLoader.$inline$bar */
+ /// CHECK-NEXT: LoadClass
+ /// CHECK-NEXT: ClinitCheck
+ /// CHECK-NEXT: StaticFieldGet
+ /// CHECK-NEXT: LoadString
+ /// CHECK-NEXT: NullCheck
+ /// CHECK-NEXT: InvokeVirtual
+
+ /// CHECK-START: void LoadedByMyClassLoader.bar() register (before)
+ /* Load and initialize FirstSeenByMyClassLoader */
+ /// CHECK: LoadClass gen_clinit_check:true
+ /* Load and initialize System */
+ // There may be MipsComputeBaseMethodAddress here.
+ /// CHECK: LoadClass gen_clinit_check:true
+ /// CHECK-NEXT: StaticFieldGet
+ // There may be HArmDexCacheArraysBase or HX86ComputeBaseMethodAddress here.
+ /// CHECK: LoadString
+ /// CHECK-NEXT: NullCheck
+ /// CHECK-NEXT: InvokeVirtual
+ public static void bar() {
+ FirstSeenByMyClassLoader.$inline$bar();
+ System.out.println("In between the two calls.");
+ FirstSeenByMyClassLoader.$noinline$bar();
+ }
+}
+
+public class Main {
+ public static void main(String[] args) throws Exception {
+ MyClassLoader o = new MyClassLoader();
+ Class<?> foo = o.loadClass("LoadedByMyClassLoader");
+ Method m = foo.getDeclaredMethod("bar");
+ m.invoke(null);
+ }
+}