Integrated: 7903437: Improve translation strategy for function pointers
Maurizio Cimadamore
mcimadamore at openjdk.org
Fri Feb 17 23:57:45 UTC 2023
On Fri, 17 Feb 2023 15:32:53 GMT, Maurizio Cimadamore <mcimadamore at openjdk.org> wrote:
> The current translation stragegy for function pointers is not very efficient. Every time a lambda expression is turned into an upcall stub, a new method handle lookup is performed, which is quite a slow operation.
>
> This patch improves the translation strategy so that the lookup is only performed once. For instance, considering the following `typedef`:
>
>
> typedef void (*cb)(int, int);
>
>
> jextract will generate the following functional interface:
>
>
> import static java.lang.foreign.ValueLayout.*;
> /**
> * {@snippet :
> * void (*cb)(int,int);
> * }
> */
> public interface cb {
>
> void apply(int _x0, int _x1);
> static MemorySegment allocate(cb fi, Arena scope) {
> return RuntimeHelper.upcallStub(constants$0.cb_UP$MH, fi, constants$0.cb$FUNC, scope);
> }
> static cb ofAddress(MemorySegment addr, Arena arena) {
> MemorySegment symbol = addr.reinterpret(arena.scope(), null);
> return (int __x0, int __x1) -> {
> try {
> constants$0.cb_DOWN$MH.invokeExact(symbol, __x0, __x1);
> } catch (Throwable ex$) {
> throw new AssertionError("should not reach here", ex$);
> }
> };
> }
> }
>
>
> Where the constants are defined as follows:
>
>
> static final FunctionDescriptor cb$FUNC = FunctionDescriptor.ofVoid(
> Constants$root.C_INT$LAYOUT,
> Constants$root.C_INT$LAYOUT
> );
>
> static final FunctionDescriptor cb_UP$FUNC = FunctionDescriptor.ofVoid(
> Constants$root.C_INT$LAYOUT,
> Constants$root.C_INT$LAYOUT
> );
>
> static final MethodHandle cb_UP$MH = RuntimeHelper.upcallHandle(cb.class, "apply", constants$0.cb_UP$FUNC);
>
> static final FunctionDescriptor cb_DOWN$FUNC = FunctionDescriptor.ofVoid(
> Constants$root.C_INT$LAYOUT,
> Constants$root.C_INT$LAYOUT
> );
>
> static final MethodHandle cb_DOWN$MH = RuntimeHelper.downcallHandle(
> constants$0.cb_DOWN$FUNC
> );
>
>
> And, where `RuntimeHelper::upcallHandler` is defined as follows:
>
>
> static MethodHandle upcallHandle(Class<?> fi, String name, FunctionDescriptor fdesc) {
> try {
> return MH_LOOKUP.findVirtual(fi, name, fdesc.toMethodType());
> } catch (Throwable ex) {
> throw new AssertionError(ex);
> }
> }
>
>
> This allows to perform the method handle lookup only once. This means that when creating an upcall stub, we only have to `bind` the functional interface instance to the method handle, and then create an upcall stub with the resulting handle. Both operations should be fast after the first time, because of caching.
This pull request has now been integrated.
Changeset: dfafbbe7
Author: Maurizio Cimadamore <mcimadamore at openjdk.org>
URL: https://git.openjdk.org/jextract/commit/dfafbbe7d6ab3c190dae5519236bef718fd10755
Stats: 41 lines in 4 files changed: 28 ins; 2 del; 11 mod
7903437: Improve translation strategy for function pointers
Reviewed-by: jvernee
-------------
PR: https://git.openjdk.org/jextract/pull/109
More information about the jextract-dev
mailing list