diff options
Diffstat (limited to 'test/496-checker-inlining-and-class-loader/src')
| -rw-r--r-- | test/496-checker-inlining-and-class-loader/src/Main.java | 125 |
1 files changed, 125 insertions, 0 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 new file mode 100644 index 0000000000..f6d0b41a58 --- /dev/null +++ b/test/496-checker-inlining-and-class-loader/src/Main.java @@ -0,0 +1,125 @@ +/* + * 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.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. + f = pathList.getClass().getDeclaredField("dexElements"); + f.setAccessible(true); + dexElements = (Object[]) f.get(pathList); + dexFileField = dexElements[0].getClass().getDeclaredField("dexFile"); + dexFileField.setAccessible(true); + } + + Object[] dexElements; + Field dexFileField; + + protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException { + 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 element : dexElements) { + Object dex = dexFileField.get(element); + Method method = dex.getClass().getDeclaredMethod( + "loadClassBinaryName", String.class, ClassLoader.class, List.class); + + if (dex != null) { + Class clazz = (Class)method.invoke(dex, 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 Main.$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 Main */ + /// CHECK: LoadClass gen_clinit_check:true + /* Load and initialize System */ + /// CHECK-NEXT: LoadClass gen_clinit_check:true + /// CHECK-NEXT: StaticFieldGet + /// CHECK-NEXT: LoadString + /// CHECK-NEXT: NullCheck + /// CHECK-NEXT: InvokeVirtual + public static void bar() { + Main.$inline$bar(); + System.out.println("In between the two calls."); + Main.$noinline$bar(); + } +} + +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); + } + + public static void $inline$bar() { + } + + public static void $noinline$bar() { + try { + System.out.println("In $noinline$bar"); + } catch (Throwable t) { /* Ignore */ } + } +} |