diff options
Diffstat (limited to 'test/497-inlining-and-class-loader')
| -rw-r--r-- | test/497-inlining-and-class-loader/clear_dex_cache.cc | 10 | ||||
| -rw-r--r-- | test/497-inlining-and-class-loader/src/Level1.java | 12 | ||||
| -rw-r--r-- | test/497-inlining-and-class-loader/src/Main.java | 198 |
3 files changed, 110 insertions, 110 deletions
diff --git a/test/497-inlining-and-class-loader/clear_dex_cache.cc b/test/497-inlining-and-class-loader/clear_dex_cache.cc index 36ec4eb65c..ddbcef59c8 100644 --- a/test/497-inlining-and-class-loader/clear_dex_cache.cc +++ b/test/497-inlining-and-class-loader/clear_dex_cache.cc @@ -34,7 +34,7 @@ extern "C" JNIEXPORT jobject JNICALL Java_Main_cloneResolvedMethods(JNIEnv* env, ScopedObjectAccess soa(Thread::Current()); ObjPtr<mirror::DexCache> dex_cache = soa.Decode<mirror::Class>(cls)->GetDexCache(); size_t num_methods = dex_cache->NumResolvedMethods(); - mirror::MethodDexCacheType* methods = dex_cache->GetResolvedMethods(); + auto* methods = dex_cache->GetResolvedMethods(); CHECK_EQ(num_methods != 0u, methods != nullptr); if (num_methods == 0u) { return nullptr; @@ -48,7 +48,7 @@ extern "C" JNIEXPORT jobject JNICALL Java_Main_cloneResolvedMethods(JNIEnv* env, CHECK(array != nullptr); ObjPtr<mirror::Array> decoded_array = soa.Decode<mirror::Array>(array); for (size_t i = 0; i != num_methods; ++i) { - auto pair = mirror::DexCache::GetNativePair(methods, i); + auto pair = methods->GetNativePair(i); uint32_t index = pair.index; ArtMethod* method = pair.object; if (sizeof(void*) == 4) { @@ -69,7 +69,7 @@ extern "C" JNIEXPORT void JNICALL Java_Main_restoreResolvedMethods( ScopedObjectAccess soa(Thread::Current()); ObjPtr<mirror::DexCache> dex_cache = soa.Decode<mirror::Class>(cls)->GetDexCache(); size_t num_methods = dex_cache->NumResolvedMethods(); - mirror::MethodDexCacheType* methods = dex_cache->GetResolvedMethods(); + auto* methods = dex_cache->GetResolvedMethods(); CHECK_EQ(num_methods != 0u, methods != nullptr); ObjPtr<mirror::Array> old = soa.Decode<mirror::Array>(old_cache); CHECK_EQ(methods != nullptr, old != nullptr); @@ -86,8 +86,8 @@ extern "C" JNIEXPORT void JNICALL Java_Main_restoreResolvedMethods( index = dchecked_integral_cast<uint32_t>(long_array->Get(2u * i)); method = reinterpret_cast64<ArtMethod*>(long_array->Get(2u * i + 1u)); } - mirror::MethodDexCachePair pair(method, index); - mirror::DexCache::SetNativePair(methods, i, pair); + mirror::NativeDexCachePair<ArtMethod> pair(method, index); + methods->SetNativePair(i, pair); } } diff --git a/test/497-inlining-and-class-loader/src/Level1.java b/test/497-inlining-and-class-loader/src/Level1.java index 977af8321e..18f79ceb26 100644 --- a/test/497-inlining-and-class-loader/src/Level1.java +++ b/test/497-inlining-and-class-loader/src/Level1.java @@ -15,13 +15,13 @@ */ public class Level1 { - public static void $inline$bar() { - Level2.$inline$bar(); - } + public static void $inline$bar() { + Level2.$inline$bar(); + } } class Level2 { - public static void $inline$bar() { - Main.$noinline$bar(); - } + public static void $inline$bar() { + Main.$noinline$bar(); + } } diff --git a/test/497-inlining-and-class-loader/src/Main.java b/test/497-inlining-and-class-loader/src/Main.java index 01b4bcd391..66a3f6e785 100644 --- a/test/497-inlining-and-class-loader/src/Main.java +++ b/test/497-inlining-and-class-loader/src/Main.java @@ -19,112 +19,112 @@ 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; - - static ClassLoader level1ClassLoader; - - protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException { - if (this != level1ClassLoader) { - if (className.equals("Level1")) { - return level1ClassLoader.loadClass(className); - } else if (className.equals("Level2")) { - throw new ClassNotFoundException("None of my methods require Level2!"); - } else if (!className.equals("LoadedByMyClassLoader")) { - // We're only going to handle LoadedByMyClassLoader. - return getParent().loadClass(className); - } - } else { - if (className != "Level1" && className != "Level2") { - return getParent().loadClass(className); - } + 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); } - // 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; - } + Object[] dexElements; + Field dexFileField; + + static ClassLoader level1ClassLoader; + + protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException { + if (this != level1ClassLoader) { + if (className.equals("Level1")) { + return level1ClassLoader.loadClass(className); + } else if (className.equals("Level2")) { + throw new ClassNotFoundException("None of my methods require Level2!"); + } else if (!className.equals("LoadedByMyClassLoader")) { + // We're only going to handle LoadedByMyClassLoader. + return getParent().loadClass(className); + } + } else { + if (className != "Level1" && className != "Level2") { + return getParent().loadClass(className); + } } - } - } catch (Exception e) { /* Ignore */ } - return null; - } + + // 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 { - public static void bar() { - Level1.$inline$bar(); - } + public static void bar() { + Level1.$inline$bar(); + } } class Main { - public static void main(String[] args) throws Exception { - System.loadLibrary(args[0]); - // Clone resolved methods, to restore the original version just - // before we walk the stack in $noinline$bar. - savedResolvedMethods = cloneResolvedMethods(Main.class); - - MyClassLoader o = new MyClassLoader(); - MyClassLoader.level1ClassLoader = new MyClassLoader(); - Class<?> foo = o.loadClass("LoadedByMyClassLoader"); - Method m = foo.getDeclaredMethod("bar"); - try { - m.invoke(null); - } catch (Error e) { /* Ignore */ } - } - - public static void $inline$bar() { - } - - public static void $noinline$bar() { - try { - // Be evil and clear all dex cache entries. - Field f = Class.class.getDeclaredField("dexCache"); - f.setAccessible(true); - Object dexCache = f.get(Main.class); - f = dexCache.getClass().getDeclaredField("resolvedTypes"); - f.setAccessible(true); - Object[] array = (Object[]) f.get(dexCache); - for (int i = 0; i < array.length; i++) { - array[i] = null; - } - restoreResolvedMethods(Main.class, savedResolvedMethods); - } catch (Throwable t) { /* Ignore */ } - - // This will walk the stack, trying to resolve methods in it. - // Because we cleared dex cache entries, we will have to find - // classes again, which require to use the correct class loader - // in the presence of inlining. - new Exception().printStackTrace(System.out); - } - static Object savedResolvedMethods; - - static native Object cloneResolvedMethods(Class<?> cls); - static native void restoreResolvedMethods(Class<?> cls, Object saved); + public static void main(String[] args) throws Exception { + System.loadLibrary(args[0]); + // Clone resolved methods, to restore the original version just + // before we walk the stack in $noinline$bar. + savedResolvedMethods = cloneResolvedMethods(Main.class); + + MyClassLoader o = new MyClassLoader(); + MyClassLoader.level1ClassLoader = new MyClassLoader(); + Class<?> foo = o.loadClass("LoadedByMyClassLoader"); + Method m = foo.getDeclaredMethod("bar"); + try { + m.invoke(null); + } catch (Error e) { /* Ignore */ } + } + + public static void $inline$bar() { + } + + public static void $noinline$bar() { + try { + // Be evil and clear all dex cache entries. + Field f = Class.class.getDeclaredField("dexCache"); + f.setAccessible(true); + Object dexCache = f.get(Main.class); + f = dexCache.getClass().getDeclaredField("resolvedTypes"); + f.setAccessible(true); + Object[] array = (Object[]) f.get(dexCache); + for (int i = 0; i < array.length; i++) { + array[i] = null; + } + restoreResolvedMethods(Main.class, savedResolvedMethods); + } catch (Throwable t) { /* Ignore */ } + + // This will walk the stack, trying to resolve methods in it. + // Because we cleared dex cache entries, we will have to find + // classes again, which require to use the correct class loader + // in the presence of inlining. + new Exception().printStackTrace(System.out); + } + static Object savedResolvedMethods; + + static native Object cloneResolvedMethods(Class<?> cls); + static native void restoreResolvedMethods(Class<?> cls, Object saved); } |