Thanks Remi,
I strongly agree. In fact, with the ability to implement multiple
methods in an invoke proxy (presumably through passing a list of name
and handle pairs, and the impl method descriptors are stored in
handles' method types), we can allow implementing any number of
interfaces (even ones with language-wise conflicting methods like
String getValue() and Long getValue()) and perform better
initialization-time verifications (compared to invocation handlers,
where users often forget to implement object methods and the proxy
breaks only when it is sent into a hash set)

My current vision is a proxy factory method that takes a list of
interfaces and a list of method implementations, each represented by a
pair of name and method handle. However, I don't know well about
native compilation, so I wonder if this structure would serve native
optimization well, or if it has any other drawbacks. Please enlighten
me.

On Wed, Aug 25, 2021 at 5:22 AM Remi Forax <fo...@univ-mlv.fr> wrote:
>
> ----- Original Message -----
> > From: "-" <liangchenb...@gmail.com>
> > To: "Brian Goetz" <brian.go...@oracle.com>, "core-libs-dev" 
> > <core-libs-dev@openjdk.java.net>
> > Sent: Lundi 23 Août 2021 08:34:17
> > Subject: Re: Implementing MethodHandleProxies#asInterfaceInstance with 
> > hidden classes
>
> > Thanks for the quick reply!
> >
> > The main drawback, API wise, with LMF is that it does not accept
> > non-direct method handles [1], while the MHP is able accept any method
> > handle, such as native ones from JEP 389 [2]. LMF also lacks the
> > ability to restore a method handle from a wrapper instance. Using LMF
> > also requires user discretion on which methods to implement, and the
> > lookup's required privileges may change too. In general, MHP would be
> > more runtime-oriented and transient compared to LMF.
> >
> > I am inclined toward a separate bytecode generation implementation for
> > the improved MHP asInterfaceInstance, somewhat similar to what's in
> > JEP 416's implementation [3]. The extra bridges for all compatible
> > methods, accessors to backing method handle/interface, potential to
> > expand to abstract classes, different hidden class modes would reduce
> > the commonalities between the two implementations and make
> > refactorings on LMF to support these MHP functionalities costly.
>
> In my opinion, what is missing is a java.lang.invoke.Proxy, the equivalent of 
> java.lang.reflect.Proxy but using defineHiddenClass + a bootstrap method + 
> method handles instead of the InvocationHandler + j.l.r.Method. With that, 
> implementing java.lang.invoke.MethodHandleProxies on top of of 
> java.lang.invoke.Proxy is just a matter of wiring.
>
> As you said, there is a need for a more dynamic version of the 
> LambdaMetafactory.
> I believe it should work with any interfaces not only functional interfaces.
> This would avoid statically typed langages like Kotlin or Scala, or injection 
> frameworks like Weld, Spring or Guice to generate a lot of proxy classes and 
> it should be straightforward enough so static compilers like graal native 
> image or Android d8 can generate the proxy classes at compile time to support 
> "native" compilation (the same way lambdas are currently supported).
> So we get best of both worlds, efficient dynamic proxies at runtime AND 
> supports of "native" compilation.
>
> Rémi
>
> >
> > [1]
> > https://github.com/openjdk/jdk/blob/b690f29699180149d33b6a83de10697790587a87/src/java.base/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java#L141
> > [2] https://openjdk.java.net/jeps/389#The-C-linker
> > [3]
> > https://github.com/openjdk/jdk/blob/cff856f9df89293cbc8f2f1e977148cd6ece4f85/src/java.base/share/classes/jdk/internal/reflect/ClassByteBuilder.java
> >
> >
> > On Sun, Aug 22, 2021 at 9:26 PM Brian Goetz <brian.go...@oracle.com> wrote:
> >>
> >> This was an early attempt at the functionality provided by 
> >> LambdaMetafactory.
> >> It could probably be reimplemented on top of that, but probably could be
> >> deprecated in favor of LMF as well.
> >>
> >> Sent from my iPad
> >>
> >> > On Aug 22, 2021, at 10:08 PM, liangchenb...@gmail.com wrote:
> >> >
> >> > Currently, java.lang.invoke.MethodHandleProxies#asInterfaceInstance [1] 
> >> > is
> >> > implemented with java.lang.reflect.Proxy. After looking at its public 
> >> > API,
> >> > including Javadoc, it seems that MethodHandleProxies would benefit from a
> >> > hidden class implementation without changing its public API definition
> >> > (including Javadocs).
> >> >
> >> > Recently, there is JEP 416 [2] for reimplementing reflection based on
> >> > method handles. This implementation utilizes hidden classes with method
> >> > handles passed in classdata and retrieved to condy, which allows generic
> >> > method handles (beyond regular constable ones) to be optimized in method
> >> > calls. Similarly, for MethodHandleProxies, hidden classes allow the
> >> > implementations to detach from classloaders and be freely recyclable; 
> >> > they
> >> > can use class data to store the adapted method handles (which can
> >> > significantly speed up invocations); and it can allow it to support
> >> > implementing single-abstract-method abstract classes in the future (as
> >> > discussed in its Javadoc) as well, with only minor tweaks.
> >> >
> >> > Does this sound feasible? I want to ensure it is a good idea before any
> >> > implementation is attempted. If there is any issue with this vision, 
> >> > please
> >> > don't hesitate to point it out. Feel free to comment, too! If this looks
> >> > good, I hope an issue can be created for it.
> >> >
> >> > Best
> >> >
> >> > [1]
> >> > https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/lang/invoke/MethodHandleProxies.html
> > > > [2] https://openjdk.java.net/jeps/416

Reply via email to