Updated SoV documents

Tobias Hartmann tobias.hartmann at oracle.com
Mon Mar 30 14:49:51 UTC 2020


Hi Brian,

On 30.03.20 15:52, Brian Goetz wrote:
> By “scalarization in the scope of a method”, you mean ordinary field hoisting?  Since that is an optimization we do routinely for final fields, 

No, I'm basically talking about what C2's -XX:+EliminateAllocations does today for very limited
cases of non-escaping object allocations (that's what we call "scalar replacement"). Instead of
trying to figure out if an allocation is necessary and the object needs to be passed/accessed via an
indirection through a pointer, we use the fact that inline types don't have identity, i.e. can never
escape, avoid allocations and just pass the fields in registers or on the native stack. This avoids
allocation overhead, memory accesses (including barriers) and helps all kinds of later optimizations
like constant folding.

While this might sound trivial, it's not and it's *much* more powerful than what we do today for
final fields or non-escaping object allocations. In fact, final fields do not help EA at all because
the holder object still has identity.

Here's a simple example on pages 21-22:
http://cr.openjdk.java.net/~thartmann/talks/2018-Value_Types_Compiler_Offsite.pdf

For method 'computePOJO', C2 emits an allocation for 'Complex' because due to control flow, Escape
Analysis is not able to determine that the 'c' is non-escaping (even though the constructor is fully
inlined). As a result, the generated assembly is non-optimal and contains allocations + memory accesses.

On the other hand, C2 generates optimal code for 'computeValueType' because without any analysis,
'Complex' is known to be non-escaping and can be "scalar replaced". The code contains no allocations
and no memory accesses, just some operations on registers.

> I had assumed that it was only scalarization at method boundaries the was important and new here?

No, not at all. For the JIT, the main benefit of inline types is that we don't need to rely on
traditional Escape Analysis which is very limited (in fact, we don't even apply Escape Analysis to
inline types because they they don't have identity and therefore can not escape). Scalarization at
method boundaries is just the cream topping.

> There’s also a small error about ref-default inline classes; the ref projection has to be called C, not C$ref, for binary compatibility purposes.

Okay, makes sense.

> Basically, better escape analysis is the primary one.  If we can prove non-nullity (or confidently speculate on it), I would assume then we can recover the scalarization optimizations, but I understand we haven’t done this (and may not.)  

We actually do this already in the scope of a method (and it's inlinees). If we can prove or
speculate on non-nullity, we apply the same optimizations to C$ref that would be applied to C$val. I
wouldn't call this "better escape analysis" though because there is no escape analysis involved.

However, we don't do this beyond call boundaries (details are explained in [1]).

You are saying "can routinely optimize layout" but I don't see how we could do this for the
reference projections?

Best regards,
Tobias

[1] https://mail.openjdk.java.net/pipermail/valhalla-dev/2019-December/006668.html



More information about the valhalla-dev mailing list