Feedback / query on jextract for Windows 10
Duncan Gittins
duncan.gittins at gmail.com
Fri Jan 29 10:53:49 UTC 2021
Thanks for the explanation, I had not appreciated the requirement that
MH/VH must be final/static which rules out the type of lazy initialise I
expected to find in the --source output, and similar to how I've set up
the downcallHandle requests in my own code. I don't call into native
code often enough to notice that my calls may be slower later on, and I
don't plan to explore too many more of the monster Windows headers files
that raise this issue.
Previously I asked: "will the --source option be maintained in future
releases?". I should have clarified my intention by adding "to be 100%
same as the .class generation?". Based on your comments it sounds that
100% compatibility is unlikely for some time - without VM improvements
your suggested - but it helpful to know the option will be kept and they
may converge at some point.
Duncan
On 28/01/2021 22:05, Maurizio Cimadamore wrote:
> On Sat, 2021-01-23 at 18:34 +0000, Duncan Gittins wrote:
>> Have you considered changing the generated code to use lazy
>> Supplier<MethodHandle> instead of MethodHandle to ensure only
>> required
>> handles are created on-demand?
> I realize that I have not answered to this question in full, as we were
> attempting to diagnose if there was an issue.
>
> Why not using Supplier<...> in the source generation scheme? The issue
> has to do with constant-ness. For Hotspot to be able to optimize
> VarHandle and MethodHandle access, said VarHandles and MethodHandles
> have to be declared in _final_ _static_ variables. This doesn't leave a
> lot of room in terms of laziness. If we switched to some more dynamic
> approach (e.g. use a supplier, or dynamically assign elements into a
> static Object array) we would lose the constant-ness property, and
> var/method handle access would become slow.
>
> The only idiom which allows for lazy constant initialization in Java,
> w/o changes to the language, is something like this:
>
> ```
> static class ValueHolder {
> final static MethodHandle x = ...
> }
>
> MethodHandle get_x() {
> return ValueHolder.x;
> }
> ```
>
> This approach is fully lazy: the `x` constant is only initialized when
> the `get_x` method is called, because the constant is defined in its
> own holder class, and that holder class is only referenced by the
> getter method. So this is both lazy, and constant-friendly.
>
> But there is, as I'm sure you have noted, a big drawback of this
> approach: it basically requires one class holder per constant value
> (ok, in the jextract case we could probably optimize a little by
> putting - with some redundancy - all constants related to e.g. the same
> native function in the same class, but still).
>
> So, unless we want to generate an enormous number of classes, this
> approach to achieve true laziness is not really feasible, as it comes
> with a static footprint tag which is simply prohibitive in most cases.
> That's why, to preserve constant-ness, we have sacrificed laziness when
> jextract runs in `source` mode (but not when running in `class` mode,
> since in that case we can take advantage of extra VM features that are
> only available at the bytecode level).
>
> I hope this helps.
>
> CheersMaurizio
>
>
More information about the panama-dev
mailing list