[foreign] RFR 8210757: Add binder support for direct native invocation strategy
Jorn Vernee
jbvernee at xs4all.nl
Sat Sep 15 00:04:58 UTC 2018
Maurizio Cimadamore schreef op 2018-09-14 20:04:
> Hi,
> as mentioned in [1], this patch adds binder support for the so called
> 'direct' invocation scheme, which allows for greater native invocation
> downcall/upcall performances by means of specialized adapters. The
> core idea, also described in [1], is to define adapters of the kind:
>
> invokeNative_V_DDDDD
> invokeNative_V_JDDDD
> invokeNative_V_JJDDD
> invokeNative_V_JJJDD
> invokeNative_V_JJJJD
> invokeNative_V_JJJJJ
>
> Where long arguments come before double arguments (and do this for
> each arity e.g. <=5).
>
> If all arguments are passed in register, then this reordering doesn't
> affect behavior, and greatly limits the number of permutations to be
> supported/generated.
On windows the story seems to be more difficult then I initially
thought. On SysV, if you have a C function like this:
void f(long l, double d);
`l` will be passed in the first integer register, and `d` will be passed
in the first float/vector register. But on windows, `d` will be passed
in the **second** float/vector register, and if there was a another
integer argument it would be passed in the third integer register [1].
This becomes worse with varargs, which requires floats to be passed in
both the integer and float/vector registers.
So I don't think reordering parameters will work on windows, since the
parameter index dictates which register it uses. However, you should be
able to still use the downcall-with-shuffling strategy (though I don't
have that working yet for mixed argument classes).
> The downcall part (java to native) is relative straightforward: the
> directNativeInvoker.cpp file defines a bunch of native entry points,
> one per shape, which cast the input address to a function pointer of
> the desired shape, and then call it:
>
> jlong NI_invokeNative_J_JD(JNIEnv *env, jobject _unused, jlong addr,
> jlong arg0, jdouble arg1) {
> return ((jlong (*)(jlong, jdouble))addr)(arg0, arg1);
> }
As an optimization here, I think you should make the function address
the last argument, since that prevents having to shuffle the other
arguments between registers before calling the function [2]
> * we need to setup a framework in which new invocation strategies can
> be plugged in - note that we now have essentially 4 cases:
>
> { NativeInvoker, UpcallHandler } x { Universal, Direct }
>
> When the code wants e.g. a NativeInvoker, it asks for one to the
> NativeInvoker::of factory (UpcallHandler work in a similar way); this
> factory will attempt to go down the fast path - if an error occurs
> when computing the fast path, the call will fallback to the universal
> (slow) path.
This sounds like a great idea!
Jorn
[1] :
https://docs.microsoft.com/en-us/cpp/build/parameter-passing?view=vs-2017#example-of-argument-passing-3---mixed-ints-and-floats
[2] : https://godbolt.org/z/JjPJca
More information about the panama-dev
mailing list