From 3aa6ea462c9468b7e77a9749aff1ef0dd52ef580 Mon Sep 17 00:00:00 2001 From: Max Bureck Date: Sun, 12 Oct 2014 18:50:33 +0200 Subject: [PATCH] Passing method and parameter types from Library$Handler#invoke to Function#invoke. This saves costs for map and reflection lookups. --- src/com/sun/jna/Function.java | 13 +++++++++++-- src/com/sun/jna/Library.java | 10 +++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/com/sun/jna/Function.java b/src/com/sun/jna/Function.java index 7bcc68c973..6a58e4d185 100644 --- a/src/com/sun/jna/Function.java +++ b/src/com/sun/jna/Function.java @@ -272,6 +272,17 @@ public Object invoke(Class returnType, Object[] inArgs) { * native result as an Object. */ public Object invoke(Class returnType, Object[] inArgs, Map options) { + Method invokingMethod = (Method)options.get(OPTION_INVOKING_METHOD); + Class[] paramTypes = invokingMethod != null ? invokingMethod.getParameterTypes() : null; + return invoke(invokingMethod, paramTypes, returnType, inArgs, options); + } + + /** Invoke the native function with the given arguments, returning the + * native result as an Object. This method can be called if invoking method and parameter + * types are already at hand. When calling {@link Function#invoke(Class, Object[], Map)}, + * the method has to be in the options under key {@link Function#OPTION_INVOKING_METHOD}. + */ + Object invoke(Method invokingMethod, Class[] paramTypes, Class returnType, Object[] inArgs, Map options) { // Clone the argument array to obtain a scratch space for modified // types/values Object[] args = { }; @@ -285,8 +296,6 @@ public Object invoke(Class returnType, Object[] inArgs, Map options) { TypeMapper mapper = (TypeMapper)options.get(Library.OPTION_TYPE_MAPPER); - Method invokingMethod = (Method)options.get(OPTION_INVOKING_METHOD); - Class[] paramTypes = invokingMethod != null ? invokingMethod.getParameterTypes() : null; boolean allowObjects = Boolean.TRUE.equals(options.get(Library.OPTION_ALLOW_OBJECTS)); boolean isVarArgs = args.length > 0 && invokingMethod != null ? isVarArgs(invokingMethod) : false; for (int i=0; i < args.length; i++) { diff --git a/src/com/sun/jna/Library.java b/src/com/sun/jna/Library.java index e4d0f5d5fc..4d9e53c3d9 100644 --- a/src/com/sun/jna/Library.java +++ b/src/com/sun/jna/Library.java @@ -167,18 +167,20 @@ public Class getInterfaceClass() { */ private static final class FunctionInfo { - FunctionInfo(InvocationHandler handler, Function function, boolean isVarArgs, Map options) { + FunctionInfo(InvocationHandler handler, Function function, Class[] parameterTypes, boolean isVarArgs, Map options) { super(); this.handler = handler; this.function = function; this.isVarArgs = isVarArgs; this.options = options; + this.parameterTypes = parameterTypes; } final InvocationHandler handler; final Function function; final boolean isVarArgs; final Map options; + final Class[] parameterTypes; } public Object invoke(Object proxy, Method method, Object[] inArgs) @@ -211,14 +213,16 @@ else if (OBJECT_EQUALS.equals(method)) { handler = invocationMapper.getInvocationHandler(nativeLibrary, method); } Function function = null; + Class[] parameterTypes = null; Map options = null; if (handler == null) { // Find the function to invoke function = nativeLibrary.getFunction(method.getName(), method); + parameterTypes = method.getParameterTypes(); options = new HashMap(this.options); options.put(Function.OPTION_INVOKING_METHOD, method); } - f = new FunctionInfo(handler, function, isVarArgs, options); + f = new FunctionInfo(handler, function, parameterTypes, isVarArgs, options); functions.put(method, f); } } @@ -229,7 +233,7 @@ else if (OBJECT_EQUALS.equals(method)) { if (f.handler != null) { return f.handler.invoke(proxy, method, inArgs); } - return f.function.invoke(method.getReturnType(), inArgs, f.options); + return f.function.invoke(method, f.parameterTypes, method.getReturnType(), inArgs, f.options); } } }