Skip to content

Commit 8338947

Browse files
committed
Passing method and parameter types from Library$Handler#invoke to
Function#invoke. This saves costs for map and reflection lookups.
1 parent a960d1b commit 8338947

File tree

3 files changed

+21
-6
lines changed

3 files changed

+21
-6
lines changed

CHANGES.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
<<<<<<< a960d1bc7339830853e2346b49c5ae8024421f3b
12
NOTE: as of JNA 4.0, JNA is now dual-licensed under LGPL and ASL (see LICENSE).
23

34
NOTE: JNI native support is typically incompatible between minor versions, and almost always incompatible between major versions.
@@ -24,6 +25,7 @@ Features
2425
* [#350](https://github.com/twall/jna/pull/350): Added `jnacontrib.x11.api.X.Window.getSubwindows` - [@rm5248](https://github.com/rm5248).
2526
* Improved `contrib/msoffice` sample - [@wolftobias](https://github.com/wolftobias).
2627
* [#352](https://github.com/twall/jna/pull/352): Performance improvements due to reduced locking in `com.sun.jna.Library$Handler` and fewer vararg checks in `com.sun.jna.Function` - [@Boereck](https://github.com/Boereck).
28+
* [#353](https://github.com/twall/jna/pull/353): Performance improvements by improved collaboration between `com.sun.jna.Library$Handler` and `com.sun.jna.Function` - [@Boereck](https://github.com/Boereck).
2729
* [#357](https://github.com/twall/jna/pull/357): Added `com.sun.jna.platform.win32.Kernel32.SetSystemTime` - [@lgoldstein](https://github.com/lgoldstein), [@thomasjoulin](https://github.com/thomasjoulin).
2830
* [#365](https://github.com/twall/jna/pull/365): Added `com.sun.jna.platform.win32.Kernel32.GetComputerNameEx` support - [@lgoldstein](https://github.com/lgoldstein).
2931
* [#368](https://github.com/twall/jna/pull/368): Added `com.sun.jna.platform.win32.Kernel32.VirtualQueryEx`, `com.sun.jna.platform.win32.WinNT.MEMORY_BASIC_INFORMATION` and `MEM_COMMIT`, `MEM_FREE`, `MEM_RESERVE`, `MEM_IMAGE`, `MEM_MAPPED`, `MEM_PRIVATE` constants - [@apsk](https://github.com/apsk).
@@ -774,4 +776,4 @@ Bug Fixes
774776
* Ensure native libraries are only loaded once until released
775777
* Properly handle NULL when the return value is a Structure
776778
* Proper conversion to wchar_t on linux
777-
* Copy full length of Java strings to C strings instead of stopping when a NUL character is encountered
779+
* Copy full length of Java strings to C strings instead of stopping when a NUL character is encountered

src/com/sun/jna/Function.java

+11-2
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,17 @@ public Object invoke(Class returnType, Object[] inArgs) {
272272
* native result as an Object.
273273
*/
274274
public Object invoke(Class returnType, Object[] inArgs, Map options) {
275+
Method invokingMethod = (Method)options.get(OPTION_INVOKING_METHOD);
276+
Class[] paramTypes = invokingMethod != null ? invokingMethod.getParameterTypes() : null;
277+
return invoke(invokingMethod, paramTypes, returnType, inArgs, options);
278+
}
279+
280+
/** Invoke the native function with the given arguments, returning the
281+
* native result as an Object. This method can be called if invoking method and parameter
282+
* types are already at hand. When calling {@link Function#invoke(Class, Object[], Map)},
283+
* the method has to be in the options under key {@link Function#OPTION_INVOKING_METHOD}.
284+
*/
285+
Object invoke(Method invokingMethod, Class[] paramTypes, Class returnType, Object[] inArgs, Map options) {
275286
// Clone the argument array to obtain a scratch space for modified
276287
// types/values
277288
Object[] args = { };
@@ -285,8 +296,6 @@ public Object invoke(Class returnType, Object[] inArgs, Map options) {
285296

286297
TypeMapper mapper =
287298
(TypeMapper)options.get(Library.OPTION_TYPE_MAPPER);
288-
Method invokingMethod = (Method)options.get(OPTION_INVOKING_METHOD);
289-
Class[] paramTypes = invokingMethod != null ? invokingMethod.getParameterTypes() : null;
290299
boolean allowObjects = Boolean.TRUE.equals(options.get(Library.OPTION_ALLOW_OBJECTS));
291300
boolean isVarArgs = args.length > 0 && invokingMethod != null ? isVarArgs(invokingMethod) : false;
292301
for (int i=0; i < args.length; i++) {

src/com/sun/jna/Library.java

+7-3
Original file line numberDiff line numberDiff line change
@@ -167,18 +167,20 @@ public Class getInterfaceClass() {
167167
*/
168168
private static final class FunctionInfo {
169169

170-
FunctionInfo(InvocationHandler handler, Function function, boolean isVarArgs, Map options) {
170+
FunctionInfo(InvocationHandler handler, Function function, Class[] parameterTypes, boolean isVarArgs, Map options) {
171171
super();
172172
this.handler = handler;
173173
this.function = function;
174174
this.isVarArgs = isVarArgs;
175175
this.options = options;
176+
this.parameterTypes = parameterTypes;
176177
}
177178

178179
final InvocationHandler handler;
179180
final Function function;
180181
final boolean isVarArgs;
181182
final Map options;
183+
final Class[] parameterTypes;
182184
}
183185

184186
public Object invoke(Object proxy, Method method, Object[] inArgs)
@@ -211,14 +213,16 @@ else if (OBJECT_EQUALS.equals(method)) {
211213
handler = invocationMapper.getInvocationHandler(nativeLibrary, method);
212214
}
213215
Function function = null;
216+
Class[] parameterTypes = null;
214217
Map options = null;
215218
if (handler == null) {
216219
// Find the function to invoke
217220
function = nativeLibrary.getFunction(method.getName(), method);
221+
parameterTypes = method.getParameterTypes();
218222
options = new HashMap(this.options);
219223
options.put(Function.OPTION_INVOKING_METHOD, method);
220224
}
221-
f = new FunctionInfo(handler, function, isVarArgs, options);
225+
f = new FunctionInfo(handler, function, parameterTypes, isVarArgs, options);
222226
functions.put(method, f);
223227
}
224228
}
@@ -229,7 +233,7 @@ else if (OBJECT_EQUALS.equals(method)) {
229233
if (f.handler != null) {
230234
return f.handler.invoke(proxy, method, inArgs);
231235
}
232-
return f.function.invoke(method.getReturnType(), inArgs, f.options);
236+
return f.function.invoke(method, f.parameterTypes, method.getReturnType(), inArgs, f.options);
233237
}
234238
}
235239
}

0 commit comments

Comments
 (0)