From 826b803b4da92986bfbe7fc2618c326ccb50c971 Mon Sep 17 00:00:00 2001 From: Mathieu Chartier Date: Thu, 16 Apr 2015 18:31:01 -0700 Subject: Move functionality from ArtMethod into Method Bug: 19264997 Change-Id: Ife79c469fdb09f30e3aefcfc3e0ce5ed32303fce --- libart/src/main/java/java/lang/Class.java | 153 ++------------------- .../java/java/lang/reflect/AbstractMethod.java | 98 +++++++++---- .../src/main/java/java/lang/reflect/ArtMethod.java | 99 ------------- .../main/java/java/lang/reflect/Constructor.java | 21 ++- libart/src/main/java/java/lang/reflect/Method.java | 37 ++--- libart/src/main/java/java/lang/reflect/Proxy.java | 12 +- 6 files changed, 112 insertions(+), 308 deletions(-) (limited to 'libart') diff --git a/libart/src/main/java/java/lang/Class.java b/libart/src/main/java/java/lang/Class.java index 573e753..d74fd14 100644 --- a/libart/src/main/java/java/lang/Class.java +++ b/libart/src/main/java/java/lang/Class.java @@ -532,25 +532,7 @@ public final class Class implements Serializable, AnnotatedElement, GenericDe * * @param args the types of the parameters to the constructor. */ - private Constructor getDeclaredConstructorInternal(Class[] args) { - if (directMethods != null) { - for (ArtMethod m : directMethods) { - int modifiers = m.getAccessFlags(); - if (Modifier.isStatic(modifiers)) { - // skip which is a static constructor - continue; - } - if (!Modifier.isConstructor(modifiers)) { - continue; - } - if (!ArtMethod.equalConstructorParameters(m, args)) { - continue; - } - return new Constructor(m); - } - } - return null; - } + private native Constructor getDeclaredConstructorInternal(Class[] args); /** * Returns an array containing {@code Constructor} objects for all public @@ -561,9 +543,7 @@ public final class Class implements Serializable, AnnotatedElement, GenericDe * @see #getDeclaredConstructors() */ public Constructor[] getConstructors() { - ArrayList> constructors = new ArrayList(); - getDeclaredConstructors(true, constructors); - return constructors.toArray(new Constructor[constructors.size()]); + return getDeclaredConstructorsInternal(true); } /** @@ -575,28 +555,11 @@ public final class Class implements Serializable, AnnotatedElement, GenericDe * @see #getConstructors() */ public Constructor[] getDeclaredConstructors() { - ArrayList> constructors = new ArrayList(); - getDeclaredConstructors(false, constructors); - return constructors.toArray(new Constructor[constructors.size()]); - } - - private void getDeclaredConstructors(boolean publicOnly, List> constructors) { - if (directMethods != null) { - for (ArtMethod m : directMethods) { - int modifiers = m.getAccessFlags(); - if (!publicOnly || Modifier.isPublic(modifiers)) { - if (Modifier.isStatic(modifiers)) { - // skip which is a static constructor - continue; - } - if (Modifier.isConstructor(modifiers)) { - constructors.add(new Constructor(m)); - } - } - } - } + return getDeclaredConstructorsInternal(false); } + private native Constructor[] getDeclaredConstructorsInternal(boolean publicOnly); + /** * Returns a {@code Method} object which represents the method matching the * specified name and parameter types that is declared by the class @@ -688,72 +651,7 @@ public final class Class implements Serializable, AnnotatedElement, GenericDe * @param name the method name * @param args the method's parameter types */ - private Method getDeclaredMethodInternal(String name, Class[] args) { - // Covariant return types permit the class to define multiple - // methods with the same name and parameter types. Prefer to - // return a non-synthetic method in such situations. We may - // still return a synthetic method to handle situations like - // escalated visibility. We never return miranda methods that - // were synthesized by the runtime. - int skipModifiers = Modifier.MIRANDA | Modifier.SYNTHETIC; - ArtMethod artMethodResult = null; - if (virtualMethods != null) { - for (ArtMethod m : virtualMethods) { - ArtMethod nonProxyMethod = Class.findOverriddenMethodIfProxy(m); - String methodName = ArtMethod.getMethodName(nonProxyMethod); - if (!name.equals(methodName)) { - continue; - } - if (!ArtMethod.equalMethodParameters(nonProxyMethod, args)) { - continue; - } - int modifiers = m.getAccessFlags(); - if ((modifiers & skipModifiers) == 0) { - return new Method(m); - } - if ((modifiers & Modifier.MIRANDA) == 0) { - // Remember as potential result if it's not a miranda method. - artMethodResult = m; - } - } - } - if (artMethodResult == null) { - if (directMethods != null) { - for (ArtMethod m : directMethods) { - int modifiers = m.getAccessFlags(); - if (Modifier.isConstructor(modifiers)) { - continue; - } - ArtMethod nonProxyMethod = Class.findOverriddenMethodIfProxy(m); - String methodName = ArtMethod.getMethodName(nonProxyMethod); - if (!name.equals(methodName)) { - continue; - } - if (!ArtMethod.equalMethodParameters(nonProxyMethod, args)) { - continue; - } - if ((modifiers & skipModifiers) == 0) { - return new Method(m); - } - // Direct methods cannot be miranda methods, - // so this potential result must be synthetic. - artMethodResult = m; - } - } - } - if (artMethodResult == null) { - return null; - } - return new Method(artMethodResult); - } - - /** - * Returns the overridden method if the {@code method} is a proxy method, - * otherwise returns the {@code method}. - * - * @hide - */ - public static native ArtMethod findOverriddenMethodIfProxy(ArtMethod method); + private native Method getDeclaredMethodInternal(String name, Class[] args); /** * Returns an array containing {@code Method} objects for all methods @@ -764,11 +662,7 @@ public final class Class implements Serializable, AnnotatedElement, GenericDe * @see #getMethods() */ public Method[] getDeclaredMethods() { - int initial_size = virtualMethods == null ? 0 : virtualMethods.length; - initial_size += directMethods == null ? 0 : directMethods.length; - ArrayList methods = new ArrayList(initial_size); - getDeclaredMethodsUnchecked(false, methods); - Method[] result = methods.toArray(new Method[methods.size()]); + Method[] result = getDeclaredMethodsUnchecked(false); for (Method m : result) { // Throw NoClassDefFoundError if types cannot be resolved. m.getReturnType(); @@ -786,30 +680,7 @@ public final class Class implements Serializable, AnnotatedElement, GenericDe * @param methods A list to populate with declared methods. * @hide */ - public void getDeclaredMethodsUnchecked(boolean publicOnly, List methods) { - if (virtualMethods != null) { - for (ArtMethod m : virtualMethods) { - int modifiers = m.getAccessFlags(); - if (!publicOnly || Modifier.isPublic(modifiers)) { - // Add non-miranda virtual methods. - if ((modifiers & Modifier.MIRANDA) == 0) { - methods.add(new Method(m)); - } - } - } - } - if (directMethods != null) { - for (ArtMethod m : directMethods) { - int modifiers = m.getAccessFlags(); - if (!publicOnly || Modifier.isPublic(modifiers)) { - // Add non-constructor direct/static methods. - if (!Modifier.isConstructor(modifiers)) { - methods.add(new Method(m)); - } - } - } - } - } + public native Method[] getDeclaredMethodsUnchecked(boolean publicOnly); /** * Returns an array containing {@code Method} objects for all public methods @@ -839,11 +710,11 @@ public final class Class implements Serializable, AnnotatedElement, GenericDe * superclasses, and all implemented interfaces, including overridden methods. */ private void getPublicMethodsInternal(List result) { - getDeclaredMethodsUnchecked(true, result); + Collections.addAll(result, getDeclaredMethodsUnchecked(true)); if (!isInterface()) { // Search superclasses, for interfaces don't search java.lang.Object. for (Class c = superClass; c != null; c = c.superClass) { - c.getDeclaredMethodsUnchecked(true, result); + Collections.addAll(result, c.getDeclaredMethodsUnchecked(true)); } } // Search iftable which has a flattened and uniqued list of interfaces. @@ -851,7 +722,7 @@ public final class Class implements Serializable, AnnotatedElement, GenericDe if (iftable != null) { for (int i = 0; i < iftable.length; i += 2) { Class ifc = (Class) iftable[i]; - ifc.getDeclaredMethodsUnchecked(true, result); + Collections.addAll(result, ifc.getDeclaredMethodsUnchecked(true)); } } } @@ -1529,7 +1400,7 @@ public final class Class implements Serializable, AnnotatedElement, GenericDe throw new IllegalAccessException(init + " is not accessible from " + caller); } try { - return init.newInstance(null, init.isAccessible()); + return init.newInstanceTwoFrames(); } catch (InvocationTargetException e) { SneakyThrow.sneakyThrow(e.getCause()); return null; // Unreachable. diff --git a/libart/src/main/java/java/lang/reflect/AbstractMethod.java b/libart/src/main/java/java/lang/reflect/AbstractMethod.java index 7e6491d..aa5df0c 100644 --- a/libart/src/main/java/java/lang/reflect/AbstractMethod.java +++ b/libart/src/main/java/java/lang/reflect/AbstractMethod.java @@ -39,28 +39,30 @@ import libcore.reflect.AnnotationAccess; import libcore.reflect.GenericSignatureParser; import libcore.reflect.ListOfTypes; import libcore.reflect.Types; +import libcore.util.EmptyArray; /** * This class represents an abstract method. Abstract methods are either methods or constructors. * @hide */ public abstract class AbstractMethod extends AccessibleObject { + /** Bits encoding access (e.g. public, private) as well as other runtime specific flags */ + protected int accessFlags; - /** - * Hidden to workaround b/16828157. - * @hide - */ - protected final ArtMethod artMethod; + /** The ArtMethod associated with this Method, requried for dispatching due to entrypoints */ + protected ArtMethod artMethod; - /** - * Hidden to workaround b/16828157. - * @hide - */ - protected AbstractMethod(ArtMethod artMethod) { - if (artMethod == null) { - throw new NullPointerException("artMethod == null"); - } - this.artMethod = artMethod; + /** Method's declaring class */ + protected Class declaringClass; + + /** Overriden method's declaring class (same as declaringClass unless declaringClass + * is a proxy class) */ + protected Class declaringClassOfOverriddenMethod; + + /** The method index of this method within its defining dex file */ + protected int dexMethodIndex; + + protected AbstractMethod() { } public T getAnnotation(Class annotationClass) { @@ -90,33 +92,33 @@ public abstract class AbstractMethod extends AccessibleObject { } int getModifiers() { - return fixMethodFlags(artMethod.getAccessFlags()); + return fixMethodFlags(accessFlags); } boolean isVarArgs() { - return (artMethod.getAccessFlags() & Modifier.VARARGS) != 0; + return (accessFlags & Modifier.VARARGS) != 0; } boolean isBridge() { - return (artMethod.getAccessFlags() & Modifier.BRIDGE) != 0; + return (accessFlags & Modifier.BRIDGE) != 0; } boolean isSynthetic() { - return (artMethod.getAccessFlags() & Modifier.SYNTHETIC) != 0; + return (accessFlags & Modifier.SYNTHETIC) != 0; } /** * @hide */ public final int getAccessFlags() { - return artMethod.getAccessFlags(); + return accessFlags; } /** * Returns the class that declares this constructor or method. */ Class getDeclaringClass() { - return artMethod.getDeclaringClass(); + return declaringClass; } /** @@ -125,7 +127,7 @@ public abstract class AbstractMethod extends AccessibleObject { * @hide */ public final int getDexMethodIndex() { - return artMethod.getDexMethodIndex(); + return dexMethodIndex; } /** @@ -144,7 +146,17 @@ public abstract class AbstractMethod extends AccessibleObject { * @return the parameter types */ Class[] getParameterTypes() { - return artMethod.getParameterTypes(); + Dex dex = declaringClassOfOverriddenMethod.getDex(); + short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex); + if (types.length == 0) { + return EmptyArray.CLASS; + } + Class[] parametersArray = new Class[types.length]; + for (int i = 0; i < types.length; i++) { + // Note, in the case of a Proxy the dex cache types are equal. + parametersArray[i] = declaringClassOfOverriddenMethod.getDexCacheType(dex, types[i]); + } + return parametersArray; } /** @@ -155,8 +167,10 @@ public abstract class AbstractMethod extends AccessibleObject { if (!(other instanceof AbstractMethod)) { return false; } - // exactly one instance of each member in this runtime - return this.artMethod == ((AbstractMethod) other).artMethod; + // Exactly one instance of each member in this runtime, todo, does this work for proxies? + AbstractMethod otherMethod = (AbstractMethod) other; + return this.declaringClass == otherMethod.declaringClass && + this.dexMethodIndex == otherMethod.dexMethodIndex; } String toGenericString() { @@ -195,7 +209,10 @@ public abstract class AbstractMethod extends AccessibleObject { * * @return an array of arrays of {@code Annotation} instances */ - public abstract Annotation[][] getParameterAnnotations(); + public Annotation[][] getParameterAnnotations() { + return AnnotationAccess.getParameterAnnotations( + declaringClassOfOverriddenMethod, dexMethodIndex); + } /** * Returns the constructor's signature in non-printable form. This is called @@ -252,6 +269,37 @@ public abstract class AbstractMethod extends AccessibleObject { parser.returnType, parser.formalTypeParameters); } + protected boolean equalMethodParameters(Class[] params) { + Dex dex = declaringClassOfOverriddenMethod.getDex(); + short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex); + if (types.length != params.length) { + return false; + } + for (int i = 0; i < types.length; i++) { + if (declaringClassOfOverriddenMethod.getDexCacheType(dex, types[i]) != params[i]) { + return false; + } + } + return true; + } + + protected int compareParameters(Class[] params) { + Dex dex = declaringClassOfOverriddenMethod.getDex(); + short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex); + int length = Math.min(types.length, params.length); + for (int i = 0; i < length; i++) { + Class aType = declaringClassOfOverriddenMethod.getDexCacheType(dex, types[i]); + Class bType = params[i]; + if (aType != bType) { + int comparison = aType.getName().compareTo(bType.getName()); + if (comparison != 0) { + return comparison; + } + } + } + return types.length - params.length; + } + /** * Helper for Method and Constructor for toGenericString */ diff --git a/libart/src/main/java/java/lang/reflect/ArtMethod.java b/libart/src/main/java/java/lang/reflect/ArtMethod.java index 3abcb60..84e6b48 100644 --- a/libart/src/main/java/java/lang/reflect/ArtMethod.java +++ b/libart/src/main/java/java/lang/reflect/ArtMethod.java @@ -75,103 +75,4 @@ public final class ArtMethod { /** Only created by ART directly. */ private ArtMethod() {} - - public Class getDeclaringClass() { - return declaringClass; - } - - public int getAccessFlags() { - return accessFlags; - } - - int getDexMethodIndex() { - return dexMethodIndex; - } - - public static String getMethodName(ArtMethod artMethod) { - Class declClass = artMethod.getDeclaringClass(); - Dex dex = declClass.getDex(); - int nameIndex = dex.nameIndexFromMethodIndex(artMethod.getDexMethodIndex()); - // Note, in the case of a Proxy the dex cache strings are equal. - return declClass.getDexCacheString(dex, nameIndex); - } - - /** - * Returns true if the given parameters match those of the method in the given order. - * - * @hide - */ - public static boolean equalConstructorParameters(ArtMethod artMethod, Class[] params) { - Class declClass = artMethod.getDeclaringClass(); - Dex dex = declClass.getDex(); - short[] types = dex.parameterTypeIndicesFromMethodIndex(artMethod.getDexMethodIndex()); - if (types.length != params.length) { - return false; - } - for (int i = 0; i < types.length; i++) { - if (declClass.getDexCacheType(dex, types[i]) != params[i]) { - return false; - } - } - return true; - } - - /** - * Returns true if the given parameters match those of this method in the given order. - * - * @hide - */ - public static boolean equalMethodParameters(ArtMethod artMethod, Class[] params) { - return equalConstructorParameters(artMethod, params); - } - - Class[] getParameterTypes() { - Class declClass = getDeclaringClass(); - Dex dex = declClass.getDex(); - short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex); - if (types.length == 0) { - return EmptyArray.CLASS; - } - Class[] parametersArray = new Class[types.length]; - for (int i = 0; i < types.length; i++) { - // Note, in the case of a Proxy the dex cache types are equal. - parametersArray[i] = declClass.getDexCacheType(dex, types[i]); - } - return parametersArray; - } - - Class getReturnType() { - Class declClass = getDeclaringClass(); - Dex dex = declClass.getDex(); - int returnTypeIndex = dex.returnTypeIndexFromMethodIndex(dexMethodIndex); - // Note, in the case of a Proxy the dex cache types are equal. - return declClass.getDexCacheType(dex, returnTypeIndex); - } - - /** - * Performs a comparison of the parameters to this method with the given parameters. - * - * @hide - */ - int compareParameters(Class[] params) { - Class declClass = getDeclaringClass(); - Dex dex = declClass.getDex(); - short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex); - int length = Math.min(types.length, params.length); - for (int i = 0; i < length; i++) { - Class aType = declClass.getDexCacheType(dex, types[i]); - Class bType = params[i]; - if (aType != bType) { - int comparison = aType.getName().compareTo(bType.getName()); - if (comparison != 0) { - return comparison; - } - } - } - return types.length - params.length; - } - - Annotation[][] getParameterAnnotations() { - return AnnotationAccess.getParameterAnnotations(declaringClass, dexMethodIndex); - } } diff --git a/libart/src/main/java/java/lang/reflect/Constructor.java b/libart/src/main/java/java/lang/reflect/Constructor.java index 66ae143..0e5706f 100644 --- a/libart/src/main/java/java/lang/reflect/Constructor.java +++ b/libart/src/main/java/java/lang/reflect/Constructor.java @@ -49,11 +49,7 @@ public final class Constructor extends AbstractMethod implements GenericDecla private static final Comparator ORDER_BY_SIGNATURE = null; // Unused; must match Method. - /** - * @hide - */ - public Constructor(ArtMethod artMethod) { - super(artMethod); + private Constructor() { } public Annotation[] getAnnotations() { @@ -213,7 +209,7 @@ public final class Constructor extends AbstractMethod implements GenericDecla * @return an array of arrays of {@code Annotation} instances */ public Annotation[][] getParameterAnnotations() { - return artMethod.getParameterAnnotations(); + return super.getParameterAnnotations(); } /** @@ -283,13 +279,14 @@ public final class Constructor extends AbstractMethod implements GenericDecla * * @see AccessibleObject */ - public T newInstance(Object... args) throws InstantiationException, - IllegalAccessException, IllegalArgumentException, InvocationTargetException { - return newInstance(args, isAccessible()); - } + public native T newInstance(Object... args) throws InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException; - /** @hide */ - public native T newInstance(Object[] args, boolean accessible) throws InstantiationException, + /** + * Special version that looks up two frames for access check. Used by Class.newInstance. + * @hide + */ + public native T newInstanceTwoFrames(Object... args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException; /** diff --git a/libart/src/main/java/java/lang/reflect/Method.java b/libart/src/main/java/java/lang/reflect/Method.java index c70e34e..1439a3b 100644 --- a/libart/src/main/java/java/lang/reflect/Method.java +++ b/libart/src/main/java/java/lang/reflect/Method.java @@ -57,8 +57,7 @@ public final class Method extends AbstractMethod implements GenericDeclaration, } int comparison = a.getName().compareTo(b.getName()); if (comparison == 0) { - comparison = Class.findOverriddenMethodIfProxy(a.artMethod).compareParameters( - Class.findOverriddenMethodIfProxy(b.artMethod).getParameterTypes()); + comparison = a.compareParameters(b.getParameterTypes()); if (comparison == 0) { // This is necessary for methods that have covariant return types. Class aReturnType = a.getReturnType(); @@ -77,12 +76,7 @@ public final class Method extends AbstractMethod implements GenericDeclaration, /** * @hide */ - public Method(ArtMethod artMethod) { - super(artMethod); - } - - ArtMethod getArtMethod() { - return artMethod; + private Method() { } public Annotation[] getAnnotations() { @@ -136,8 +130,9 @@ public final class Method extends AbstractMethod implements GenericDeclaration, * @return the name of this method */ @Override public String getName() { - ArtMethod nonProxyMethod = Class.findOverriddenMethodIfProxy(artMethod); - return ArtMethod.getMethodName(nonProxyMethod); + Dex dex = declaringClassOfOverriddenMethod.getDex(); + int nameIndex = dex.nameIndexFromMethodIndex(dexMethodIndex); + return declaringClassOfOverriddenMethod.getDexCacheString(dex, nameIndex); } /** @@ -172,7 +167,7 @@ public final class Method extends AbstractMethod implements GenericDeclaration, * @return the parameter types */ @Override public Class[] getParameterTypes() { - return Class.findOverriddenMethodIfProxy(artMethod).getParameterTypes(); + return super.getParameterTypes(); } /** @@ -182,9 +177,13 @@ public final class Method extends AbstractMethod implements GenericDeclaration, * @return the return type */ public Class getReturnType() { - return Class.findOverriddenMethodIfProxy(artMethod).getReturnType(); + Dex dex = declaringClassOfOverriddenMethod.getDex(); + int returnTypeIndex = dex.returnTypeIndexFromMethodIndex(dexMethodIndex); + // Note, in the case of a Proxy the dex cache types are equal. + return declaringClassOfOverriddenMethod.getDexCacheType(dex, returnTypeIndex); } + /** * {@inheritDoc} * @@ -210,10 +209,7 @@ public final class Method extends AbstractMethod implements GenericDeclaration, * @hide needed by Proxy */ boolean equalNameAndParameters(Method m) { - ArtMethod nonProxyThis = Class.findOverriddenMethodIfProxy(this.artMethod); - ArtMethod nonProxyM = Class.findOverriddenMethodIfProxy(m.artMethod); - return ArtMethod.getMethodName(nonProxyThis).equals(ArtMethod.getMethodName(nonProxyM)) && - ArtMethod.equalMethodParameters(nonProxyThis, nonProxyM.getParameterTypes()); + return getName().equals(m.getName()) && equalMethodParameters(m.getParameterTypes()); } /** @@ -313,7 +309,7 @@ public final class Method extends AbstractMethod implements GenericDeclaration, * @return an array of arrays of {@code Annotation} instances */ public Annotation[][] getParameterAnnotations() { - return Class.findOverriddenMethodIfProxy(artMethod).getParameterAnnotations(); + return super.getParameterAnnotations(); } /** @@ -370,12 +366,7 @@ public final class Method extends AbstractMethod implements GenericDeclaration, * @throws InvocationTargetException * if an exception was thrown by the invoked method */ - public Object invoke(Object receiver, Object... args) - throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { - return invoke(receiver, args, isAccessible()); - } - - private native Object invoke(Object receiver, Object[] args, boolean accessible) + public native Object invoke(Object receiver, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException; /** diff --git a/libart/src/main/java/java/lang/reflect/Proxy.java b/libart/src/main/java/java/lang/reflect/Proxy.java index e47b27b..18ad49c 100755 --- a/libart/src/main/java/java/lang/reflect/Proxy.java +++ b/libart/src/main/java/java/lang/reflect/Proxy.java @@ -166,11 +166,7 @@ public class Proxy implements Serializable { Collections.sort(methods, ORDER_BY_SIGNATURE_AND_SUBTYPE); validateReturnTypes(methods); List[]> exceptions = deduplicateAndGetExceptions(methods); - - ArtMethod[] methodsArray = new ArtMethod[methods.size()]; - for (int i = 0; i < methodsArray.length; i++) { - methodsArray[i] = methods.get(i).getArtMethod(); - } + Method[] methodsArray = methods.toArray(new Method[methods.size()]); Class[][] exceptionsArray = exceptions.toArray(new Class[exceptions.size()][]); String baseName = commonPackageName != null && !commonPackageName.isEmpty() @@ -383,7 +379,7 @@ public class Proxy implements Serializable { } private static native Class generateProxy(String name, Class[] interfaces, - ClassLoader loader, ArtMethod[] methods, + ClassLoader loader, Method[] methods, Class[][] exceptions); /* @@ -392,8 +388,8 @@ public class Proxy implements Serializable { */ private static native void constructorPrototype(InvocationHandler h); - static Object invoke(Proxy proxy, ArtMethod method, Object[] args) throws Throwable { + private static Object invoke(Proxy proxy, Method method, Object[] args) throws Throwable { InvocationHandler h = proxy.h; - return h.invoke(proxy, new Method(method), args); + return h.invoke(proxy, method, args); } } -- cgit v1.1