On Fri, 21 Apr 2023 18:25:32 GMT, Jorn Vernee <jver...@openjdk.org> 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

Reply via email to