On Fri, 21 Apr 2023 18:25:32 GMT, Jorn Vernee <[email protected]> wrote:
> Implement captureCallState support for upcall stubs.
>
> The method handle of an upcall stub linked with this linker option has an
> additional leading memory segment parameter into which the capture state
> (e.g. errno) should be written. After returning from Java, this value is then
> actually written to the corresponding execution state.
src/java.base/share/classes/jdk/internal/foreign/abi/SharedUtils.java line 177:
> 175: // should appear before the IMR segment parameter
> 176: target = swapArguments(target, 0, 1);
> 177: }
e.g.
target = (MemorySegment, MemorySegment, ...) MemorySegment
^ IMR segment ^ CCS segment
These should be swapped, since the binding recipe for the capture state segment
comes before the binding recipe for the IMR segment, since the former is
inserted as a leading parameter in CallingSequenceBuilder::build, after a
particular CallArranger inserts the IMR segment parameter.
src/java.base/share/classes/jdk/internal/foreign/abi/SharedUtils.java line 192:
> 190: public static UpcallStubFactory arrangeUpcallHelper(boolean
> isInMemoryReturn, boolean dropReturn,
> 191: ABIDescriptor
> abi, CallingSequence callingSequence) {
> 192: MethodType targetType = callingSequence.calleeMethodType();
Previously this was using the a method type which was derived from the
FunctionDescriptor. Since that corresponds to the native side, it didn't
contain the return buffer. But, since the return buffer isn't passed on to the
user, that worked out since the type would match the type of the target method
handle.
However, if we are capturing call state, we need to pass on the capture state
segment to the user, so the target type has an additional leading MS parameter.
To make that work, I've switched to using the calleeMethodType here, which
contains both the return buffer and capture state parameters, and then I filter
out the return buffer below.
This also avoids having to do the fake adaptation, which turned a method type
returning a struct into a method type which excepts a pointer into which the
return value should be written: `(...) -> MemorySegment` into `(MemorySegment,
...) -> void/MemorySegment)`. The callee method type is already in the latter
form.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/13588#discussion_r1174070167
PR Review Comment: https://git.openjdk.org/jdk/pull/13588#discussion_r1174060551