Skip to content

Commit

Permalink
Passing method and parameter types from Library$Handler#invoke to
Browse files Browse the repository at this point in the history
Function#invoke. This saves costs for map and reflection lookups.
  • Loading branch information
Boereck committed Oct 12, 2014
1 parent 4616cfb commit 3aa6ea4
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 5 deletions.
13 changes: 11 additions & 2 deletions src/com/sun/jna/Function.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 = { };
Expand All @@ -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++) {
Expand Down
10 changes: 7 additions & 3 deletions src/com/sun/jna/Library.java
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
}
}
Expand All @@ -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);
}
}
}

0 comments on commit 3aa6ea4

Please sign in to comment.