On 2017-11-02 23:13, John Rose wrote:
On Nov 2, 2017, at 3:00 PM, Christoph Dreis
<[email protected] <mailto:[email protected]>> wrote:
Thanks for the clarification. Actually the more important concern was
to get rid of unnecessary allocations that the cloning inside
Executable.getParameterTypes() is producing. As Claes mentioned
experience and experiments show that JIT's escaping mechanisms fail
from time to time on this one. And if you ask me it is not good
practice to rely on the compiler optimizations anyhow, but that's
maybe just me.
I do like your proposal nonetheless as an additional improvement, but
I think it won't achieve the allocation-free part I was aiming for.
Correct me if I'm wrong, please.
There are two ways it can directly achieve what you are after.
First, if the guts of the jlr.Method can cache the List and return
the same value every time. Then the legacy API point can use
List::toArray to create the legacy array values.
Second, if the guts of the jlr.Method choose to cache the Class[],
it can still return a List wrapped around the same array, each time,
as long as the List refuses modification.
Either option avoids the O(N) copying and avoids problems
with escape analysis. The second option has O(1) allocation,
the first does zero allocation.
The first option also allows constant propagation through the
List.of values, something that arrays can never do (until we
introduce frozen arrays). This bit of magic is one of several
reasons people who program with arrays should try to move
over to lists. It is enabled by the private annotation @Stable.
— John
I like the first option, and it'd be a nice extra to allow consumers to
move forward from a 90s to an early 2000s programming model. :-)
One drawback is that this would be a somewhat larger effort to a
piece of sensitive, legacy code, but my gut feeling is that by moving
over from arrays to immutable Lists we are likely to reduce risk of
certain bugs creeping in.
/Claes