-
Bug
-
Resolution: Fixed
-
P3
-
None
-
None
Consider the following function:
```
int printf(const char *format, ...);
```
For this function, jextract generates this:
```
public static int printf(MemorySegment format, Object... x1) { ... }
```
That is a method with a varargs parameter list. Internally, this is supported using RuntimeHelper's VarargsInvoker machinery:
https://github.com/openjdk/jextract/blob/master/src/main/resources/org/openjdk/jextract/impl/resources/RuntimeHelper.java.template#L101
This class is used to create a method handle which is re-linked on each invocation, based on the types of the actual arguments provided by the caller.
This approach has two issues:
* performance-wise, it is not optimal: if the same call shape is invoked multiple times, there will still be an expensive re-linking process;
* there is no way for the varargs invoker machinery to fully disambiguate between structs and pointers. And, even if there was a way, it would still be not possible, given a struct instance, to infer its layout. For this reason, varargs invoker only really can pass segments by reference.
A possible improvement on this strategy would be to emit the following:
```
interface printfInvoker {
void apply(MemorySegment format, Object... args);
}
static printfInvoker printf(MemoryLayout... variadicLayouts) { ... } // new primitive
static void printf(MemorySegment segment, Object... args) { ... }
```
That is, for each variadic method, jextract could generate an "invoker" interface, plus a factory that takes a bunch of variadic layouts and creates an invoker for that specialized shape.
Then, we could also generate a friendly wrapper which still infers layouts from variadic arguments (using same limited approach as today), which is then used to create a new invoker, and call it on the spot.
```
int printf(const char *format, ...);
```
For this function, jextract generates this:
```
public static int printf(MemorySegment format, Object... x1) { ... }
```
That is a method with a varargs parameter list. Internally, this is supported using RuntimeHelper's VarargsInvoker machinery:
https://github.com/openjdk/jextract/blob/master/src/main/resources/org/openjdk/jextract/impl/resources/RuntimeHelper.java.template#L101
This class is used to create a method handle which is re-linked on each invocation, based on the types of the actual arguments provided by the caller.
This approach has two issues:
* performance-wise, it is not optimal: if the same call shape is invoked multiple times, there will still be an expensive re-linking process;
* there is no way for the varargs invoker machinery to fully disambiguate between structs and pointers. And, even if there was a way, it would still be not possible, given a struct instance, to infer its layout. For this reason, varargs invoker only really can pass segments by reference.
A possible improvement on this strategy would be to emit the following:
```
interface printfInvoker {
void apply(MemorySegment format, Object... args);
}
static printfInvoker printf(MemoryLayout... variadicLayouts) { ... } // new primitive
static void printf(MemorySegment segment, Object... args) { ... }
```
That is, for each variadic method, jextract could generate an "invoker" interface, plus a factory that takes a bunch of variadic layouts and creates an invoker for that specialized shape.
Then, we could also generate a friendly wrapper which still infers layouts from variadic arguments (using same limited approach as today), which is then used to create a new invoker, and call it on the spot.
- duplicates
-
CODETOOLS-7903301 VarargsInvoker should use variadic layouts
-
- Closed
-