On Mon, 1 May 2023 21:00:40 GMT, John R Rose <jr...@openjdk.org> wrote:

> I think you could do this by having the HC have a final non-static field for 
> each required MH (one per overload point); each os an asType adaptation of 
> the original MH. The actual code of each HC implementation method would be a 
> single invokeVirtual of a strongly typed MH::invokeExact call. This is the 
> code shape in the current PR (see the createTemplate method) except that I am 
> saying that the MH in question should come from getfield not ldc/condy.

This was the implementation up to 
[953fcc9f](https://git.openjdk.org/jdk/pull/13197/files/953fcc9fdb4bb80389c770b585d5f9b4d3936947)
 (webrev 0). It had an invocation performance of 2ns/op as opposed to Proxy's 
6ns/op, but the condy implementation has 0.41ns/op.

I indeed can move the argument validation (with a jdk.internal object instance, 
will add to wrapperInstanceType and wrapperInstanceTarget to avoid method 
clashes) and marker interface into jdk.internal.access.invoke package and 
export it to the HC's module (thanks to mandy for the patch). And moving 
`asType` to the constructor is viable too; we just need to propagate the thrown 
`WrongMethodTypeException` to the caller.

So assuming the methodhandle-in-field approach has good performance, we will 
probably generate something like:

package jdk.MHProxy5;
import sun.invoke.empty.Empty;
import sun.invoke.WrapperInstance;
//...
final /*synthetic*/ class Iface$MHProxy implements Iface, WrapperInstance {
    final MethodHandle originalMh, mh1, mh2, ...;
    // no access worries, in a non-open module, users cannot call
    Iface$MHProxy(MethodHandle originalMh, MethodHandle mh) {
        this.originalMh = originalMh; // possibly didn't bind caller
        this.mh1 = mh.asType(/*ldc MethodType */);
        //...
    }
    // Iface implementations
    public R singleMethod(P0 p0, ...) { try { return mh1.invokeExact(p0, ...); 
/* explicit descriptor */ } catch ... (rethrow, wrap throw)
    // ...
    // WrapperInstance implementations
    public Class<?> wrapperType(Empty empty) { return Iface$MHProxy.class; } // 
unused Empty parameter prevents method clash
    public MethodHandle wrapperTarget(Empty empty) {return originalMh;}
}


For proxy code, I think they look up the set of interfaces and generate one 
class in one module for each set, which is close to the single-class + module 
implementation outlined above.

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

PR Comment: https://git.openjdk.org/jdk/pull/13197#issuecomment-1530438142

Reply via email to