On Wed, 2 Aug 2023 12:35:50 GMT, Yasumasa Suenaga <ysuen...@openjdk.org> wrote:

> I guess you suggested that ArgumentShuffle in HotSpot moves into 
> DowncallLinker, right?

No, ArgumentShuffle should stay inside HotSpot. We can not do all the shuffling 
on the Java side. We can only eliminate some of the register moves that are 
needed by re-ordering the arguments on the Java side.

For instance, if you look at the comment in `assembler_x86.hpp`, where we 
define `j_rarg*` Register constants, you'll see this:


//        |-------------------------------------------------------|
//        | c_rarg0   c_rarg1  c_rarg2 c_rarg3 c_rarg4 c_rarg5    |
//        |-------------------------------------------------------|
//        | rcx       rdx      r8      r9      rdi*    rsi*       | windows (* 
not a c_rarg)
//        | rdi       rsi      rdx     rcx     r8      r9         | 
solaris/linux
//        |-------------------------------------------------------|
//        | j_rarg5   j_rarg0  j_rarg1 j_rarg2 j_rarg3 j_rarg4    |
//        |-------------------------------------------------------|


i.e. all the registers in the Java calling convention are 'off by one' compared 
to the native calling convention. This makes sense for JNI since we need to 
prepend the JNIEnv* to the start of the argument list, but it doesn't make 
sense for Panama.

Let's say we have a native function taking five `long`s. On Linux/x64 the 
VMStorage[] for the arguments (the one we use when creating the 
NativeEntryPoint inside DowncallLinker) would be:

    [rdi, rsi, rdx, rcx, r8, r9]

i.e. the first argument we pass on the Java side gets moved (by the downcall 
stub) into `rdi`, the second into `rsi`, etc. This doesn't match the incoming 
registers of the Java calling convention, where the first argument is passed 
passing in `rsi`, the second is passed in `rdx`, etc. (i.e. off-by-one).

We can simply re-arrange the entries in the `VMStorage[]` to match the order of 
registers in the Java calling convention:

    [rsi, rdx, rcx, r8, r9, rdi]
    
i.e. the argument that should go into `rdi` is passed in the fifth position 
instead. Since now the registers for each argument match the Java calling 
convention, the downcall stub doesn't need to do any shuffling! (I'm being very 
hand-wavey here. Figuring out how to correctly do the re-ordering is the hard 
part of this).

Ok, but now the arguments we pass to the downcall stub are going to go in the 
wrong registers as well :( So, to compensate for that, we have to also re-order 
the incoming argument values on the Java side so that each argument will 
correspond to it's original register again. To do that, we just need to pass 
the first argument in the fifth position as well, and shift arguments 1-4 
forward by one spot.

Make sense?

-------------

PR Comment: https://git.openjdk.org/jdk/pull/15089#issuecomment-1662302891

Reply via email to