[lworld] Handling of missing ValueTypes attributes

Tobias Hartmann tobias.hartmann at oracle.com
Fri Jul 13 09:45:39 UTC 2018

Hi Karen,

On 11.07.2018 21:42, Karen Kinnear wrote:
>     2a. flattening in containers - flattenable fields and array - require check of value type vs.
> ACTUAL loaded type
>           - this is easy, we preload types

Yes, no issues here.

>     2b. JIT scalarization of field access - must be an ACTUAL value type and must be flattenable
>        This will only work for fields that the JIT’d caller believes are value types, the declarer
> believes are value types and the declarer does an ACTUAL check
>        Need caller-callee agreement for a JIT’d caller.

I don't understand what you mean by caller/callee in the context of a field access?
Also, I'm not sure what you mean by "scalarization of field access"?

If compiled code loads a value type from a field (no matter if the field is flattenable or not), it
will scalarize the value type if it's not null (i.e., pass it on in registers or on the stack). This
relies on the fact that at compile time, the field type is loaded if it's a value type.

>     2c. JIT calling convention - scalarization of arguments
>        Need either the caller-callee in agreement if both compiled OR
>        For caller calls by reference, adapter that can scalarize arguments it knows are ACTUAL value
> types
>        Today adaptor is created at callee link time, so we explicitly load types in local methods in
> the ValueTypes attribute so they can be scalarized

Yes, but we don't support that for LW1 because there are still lots of other issues to sort out
before we can re-enable -XX:+ValueTypePassFieldsAsArgs (for example, the issue with lambda forms and
linkTo* calls).

>      2d. JIT returning a value type
>         I do not know our plans for value type return optimizations.

The plan is to re-enable -XX:+ValueTypeReturnedAsFields for lworld once we have sorted out the
calling convention issues.

>         The adaptor for returns are stored off of the return type, so they know the ACTUAL value.

Returns do not use any adapters but we do some kind of handshaking between the caller and the callee
to make sure that they agree on the type (see page 26/27 of [1]).

>         In general we can check caller-callee consistency so we can be in agreement about whether a
> type is a value type.
>         The exception is the JavaCalls::call_helper path used by Reflection, jni (and others internally)
>             - I assume we will always return a reference here (I have not studied the details yet,
> so I don’t know where that is handled)

I'm not sure about the reflection/jni case but the short answer would be "we don't support
scalarization of the return value for LW1". And I don't see any problems with the current code.

> Details:
> 1. MethodHandles - invocation and field access always goes through LinkResolver at this point.
> There are two exceptions here:
>     - one is when the MethodHandle creation does NOT pass in the calling class information
>       - in that case there is no check for caller-callee consistency, we need to look at this
> independently
>     - one is invokespecial indirect superclass (ACC_SUPER) which performs selection in the java code.
>        - That is a rathole I won’t follow here - we should fix that anyway - multiple potential
> approaches.
> 2. Reflection:
>    optimized reflection generates bytecodes, so goes through bytecode path, so goes through
> LinkResolver.
>    initial reflection calls JavaCalls::call->JavaCalls::call_helper
> 3. JNI:
>    also goes through JavaCalls::call_helper
> JavaCalls::call_helper calls call_stub to invoke the entry_point which is:
>    normally: method->from_interpreted_entry
>    debug: method->interpreter_entry
> For argument passing, my assumption is that we are ok with the JavaCalls::call_helper path because
> it always passes by reference
> and uses the callee adapter from interpreter which knows the declared value types that can be
> scalarized. So the same adaptor that works for
> interpreted code works for call_helper where the caller always assumes everything is a reference and
> passes by reference.
> JIT folks - does this work in practice?

Yes, that seems reasonable but it's very hard to figure this all out by code inspection. I think
what we need is more tests to find bugs and/or gain confidence in our current design/implementation.

That said, current JIT optimizations do not rely on the value types attribute but of course there
might be bugs or implicit assumptions that do not hold.

However, Ioi's optimization (8206140) relies on the fact that an interpreted callee always knows
when it's returning null for a value type (and can then deoptimize the compiled caller). It seems
that the attribute consistency checks cannot guarantee that but I need to take a closer look.

My take on this is to defer all optimizations that rely on the consistency checks to after we got
these right (and it's okay if that is after LW1).

Best regards,

[1] http://cr.openjdk.java.net/~thartmann/talks/2018-Value_Types_Compiler_Offsite.pdf

More information about the valhalla-dev mailing list