On 11/23/2019 6:09 PM, Brian Goetz wrote:
Thanks for the examples.
A few comments:
- A reasonable place to consider putting the bootstrap is in Proxy
itself. I am not sure that ConstantBootstraps is the right place (or
anywhere in JLI for that matter) unless Method is retrofitted to
implement Constable, which is problematic given that Methods are not
constants.
Yes, Method implementing Constable might not be the right thing, because
Method is not immutable. Adding the bootstrap method to j.l.r.Proxy is a
good alternative.
- In the department of “future things that might be applied here”
(Remi started it), this is a perfect application for lazy statics.
But we don’t have those yet.
What Remi and Mandy suggested is to pass the Method instances that we
already use to spin the bytecode to the new class, which avoids an other
round of method lookups.
While I like the idea, it relies on on future things. I will try to
write a prototype for that.
- The main benefit here is that it makes proxy creation faster.
However, given the amount of work that goes on at proxy creation
(reflection, byte code spinning, class loading), its not clear how
much of the cost is initializing the proxy class. Some benchmarking
to establish the cost benefit here would be good. (If we are spinning
the proxy at jlink time, then the benefit is probably greater.)
Overall, the translation approach seems sound but I would suggest that
we clarify the benefits a little bit before embarking.
I just finished the first prototype, which can be found at
https://gist.github.com/DasBrain/7766bedfbc8b76ba6a0ee66a54ba97ed - it
contains a patch, the javap output of a generated proxy class with and
without that patch, and the code I used to dump the proxy class. "make
run-test-tier1" passes all JDK tests with the patch. I hope this will
help the discussion a bit.
The other benefit I talked about is: It makes to code easier, because
it's less code and it's a greater locality. I know, this is hard to
measure.
Everything was spawned by a small sentence Remi wrote on this list:
A follow up should to use constant dynamic (introduce in Java 11) to
get the j.l.r.Method object instead of pre-calculating all of them in
the static init block.
The idea is that a ldc on a constant dynamic with bootstrap method
that takes a MethodHandle as parameter (as boostrap argument) can
return the corresponding Method by using Lookup.revealDirect + reflectAs.
The bootstrap method can be added to j.l.i.ConstantBootstraps
https://mail.openjdk.java.net/pipermail/core-libs-dev/2019-August/061923.html
But there were never a real discussion about the benefits yet. It's good
that we have one now.
As I am a novice JMH user, I don't trust myself to write good benchmarks
that actually measure what I want to measure, not confirm what I would
like it to be