LambdaMetafactory requires full privilege access, but doesn't seem to actually restrict functionality

Remi Forax forax at univ-mlv.fr
Thu Jan 13 15:05:03 UTC 2022



----- Original Message -----
> From: "Steven Schlansker" <stevenschlansker at gmail.com>
> To: "core-libs-dev" <core-libs-dev at openjdk.java.net>
> Sent: Wednesday, January 12, 2022 9:56:30 PM
> Subject: LambdaMetafactory requires full privilege access, but doesn't seem to actually restrict functionality

> Hi core-libs-dev,
> 
> I am maintaining a module for the popular Jackson JSON library that attempts to
> simplify code-generation code without losing performance.
> Long ago, it was a huge win to code-generate custom getter / setter / field
> accessors rather than use core reflection. Now, the gap is closing a lot with
> MethodHandles, but there still seems to be some benefit.
> 
> The previous approach used for code generation relied on the CGLib + ASM
> libraries, which as I am sure you know leads to horrible-to-maintain code since
> you essentially write bytecode directly.

I don't see the issue here, writing bytecodes in not that hard :)

> Feature development basically stopped because writing out long chains of
> `visitVarInsn(ASTORE, 3)` and the like scares off most contributors, myself
> included.

yes, sadly known issue, generating assembly code even a highlevel one like the Java byetcode by hands require a niche knowledge which sadly is rarely teached at university anymore (and let's not talked about bootcamp).  

> 
> As an experiment, I started to port the custom class generation logic to use
> LambdaMetafactory. The idea is to use the factory to generate `Function<Bean,
> T>` getter and `BiConsumer<Bean, T>` setter implementations.

If you want to make the serailization/deserialization to JSON fast you will mostly battle two things,
 - polymorphic call site, a call that can call some many different implementations that the VM will not try to inline,
   usually the trick is to just have one of such call to take care of the different kind of objects.
 - boxing, that kind of code tends to abstract over any values, but boxing means allocation if there is no inlining.  

For me, it means that you want two specialized codes, the decoder that switches over the keys and call the correct setter and the encoder that calls the getters in sequence.

Trying to abstract over getters and setters is a step too far because you loose the benefit to write a code specific to a peculiar class.

I suppose you try to use the method handles directly with invokeExact() if you are able to remove the boxing
or with invoke() if not ?

Because it's not clear to me why you want to use the LambdaMetafactory ?

[...]

> 
> I'm also curious for any feedback on the overall approach of using the
> Metafactory, perhaps I am way off in the weeds, and should just trust
> MethodHandles to perform well if you use invokeExact :) JMH does seem to show
> some benefit though especially with Graal compiler.
> 
> Thanks a bunch for any thoughts,
> Steven Schlansker

Rémi


More information about the core-libs-dev mailing list