EG help please with getting to LW1 re: Value Types Consistency Checking

Tobi Ajila Tobi_Ajila at ca.ibm.com
Fri Jul 6 15:38:56 UTC 2018


I would like to propose an alternative strategy, one that would effectively
provide the same consistency checks outlined in
http://cr.openjdk.java.net/~acorn/value-types-consistency-checking-details.pdf
 without requiring eager loading of value types (VT) in the return/args of
methods during the preparation phase. This is born out of our experience
with PackedObjects which took a very similar approach to the ValueTypes
attribute.

This proposal makes use of the existing ValueTypes attribute. In addition,
it requires that each classloader keeps a registry of ‘expected’ VTs.

Proposal
--------------------------
The following steps occur in the loading phase:

1. Prior to loading the current class each type in the ValueTypes attribute
is checked see if it is loaded. If it is, the type must be a VT or ICCE is
thrown. Otherwise, the type is registered with the initiating classloaders
expected VT registry (EVTR).

2. Pre-loading of ACC_FLATTENABLE instance fields follow the same rules as
the ones specified in Karen's proposal.

3. Prior to loading the current class, if the current class is a VT it must
be in the classloader's EVTR or ICCE is thrown. If the current class is not
a VT and does appear in the EVTR, ICCE is thrown.

In link phase prior to preparation:
- Same as Karen's static field rules, "static fields declared with the
ACC_FLATTENABLE flag set have their type pre-loaded..."

In preparation phase:
- Same as Karen's method overriding rules, "any method overriding needs to
perform value type consistency checking between declarer of the overridden
method ..."

At resolution time:
- Same as Karen’s CONSTANT_Class, field and method resolution rules
---------------------------

The benefit of this approach is that as soon as anyone believes a class is
a VT, it must be loaded as a VT or it fails. As a result, there is no
inconsistency of loaded VTs. This proposal doesn't guard against cases
where a class was not expecting a method return/arg type to be a VT but
then later on turned out to be a VT when it was resolved. However, I think
don’t think Karen’s proposal offered these guarantees either.

> Some aspects of the implementation complexity that we have identified so
far:
> a) At method resolution time, if there is a mismatch in value type
consistency
> between the declaring class and the actual type in the signature, then
there
> is also a mismatch in all classes that have overridden the current
method.
> This is particularly painful with default methods in interfaces.

With this proposal the only possible inconsistency here is:
Method has a return/arg type that is believed to not be a VT but turns out
to be a VT. In this case any compiled code is doing pass by reference
calling convention which works for both VT and non-VT types.

> b) We need to ensure that we catch all method resolution, through all of
the
> alternate accessor paths, including MethodHandles, VarHandles,
Reflection, JNI,
> so that we catch both the specification and implementation changes.

All these cases are covered with the class loading consistency checks
(EVTR).

> c) Our favorite, invokespecial ACC_SUPER, needs special handling, since
it
> performs selection which is not based on overriding, but based on
virtually
> re-resolving.

same as above

> e) If we modify the specification to allow eager loading, and save errors
> to throw at method resolution, we need to work through the JVMS question
> of which errors would be saved (e.g. OOME, SOE might be thrown as part of
> the implementation vs. saving LinkageError), as well as designing a new
> implementation mechanism to repeat exceptions relative to signatures used
> for method resolution.

This wouldn’t be required in this proposal

> d) Pass by value calling convention optimizations depend on loading the
> actual type. Loading of the parameter types on first method resolution
> implies that if the caller is compiled, the caller method requires
> deoptimization/recompilation to pass arguments by value for future calls,
> which is a performance cost.

Typically, a method is run a few times before it is compiled (perhaps I’m
making implementation assumptions?). At this stage, the return/arg types
are either loaded or they are always null. This seems to suggest that
deoptimization/recompilation scenario would not be a common occurrence.


--Tobi

> From: Karen Kinnear <karen.kinnear at oracle.com>
> To: valhalla-spec-experts <valhalla-spec-experts at openjdk.java.net>
> Date: 2018/06/26 10:32 AM
> Subject: EG help please with getting to LW1 re: Value Types
> Consistency Checking
> Sent by: "valhalla-spec-experts" <valhalla-spec-experts-
> bounces at openjdk.java.net>
>
> Summary: Could we please allow eager loading for value types in the
> locally declared method signatures
> prior to preparation  for LW1?
>
> Without that we seriously risk being able to offer an LW1 early
> access binary for the JVMLS.
> We believe it is more important to get this into people’s hands for
> experimentation and feedback than
> to delay the eager loading at this time.
>
> Details:
> At our EG discussion on June 20, 2018, we discussed the proposal for
> Value Types Consistency checking
> at http://cr.openjdk.java.net/~acorn/value-types-consistency-
> checking-details.pdf
>
> Part of the proposal for checking value type consistency relative to
> the actual type
> was for locally declared methods. The proposal was to check the
> value types in arguments/return type
> before preparation of the declaring class.
>
> During the meeting, there was a request to explore whether we could
either:
> 1)  delay checking the value type consistency until an attempt to
> resolve the method for invocation, or
> 2) write the JVMS is such as way as to allow eager loading, but only
> throw an error related to the eager loading at method resolution.
>
> My understanding is that the goals of this are two-fold:
> 1) if the method is never called, the rest of the code will continue to
run
> 2) reduce eager loading
>
> We have started this investigation, and there is non-trivial
> complexity in implementing either of these approaches,
> and we would like more time to explore how to make this possible,
> after making LW1 available.
>
> Some aspects of the implementation complexity that we have identified so
far:
> a) At method resolution time, if there is a mismatch in value type
> consistency between the declaring class and the actual
> type in the signature, then there is also a mismatch in all classes
> that have overridden the current method. This is particularly
> painful with default methods in interfaces.
> b) We need to ensure that we catch all method resolution, through
> all of the alternate accessor paths, including MethodHandles, VarHandles,
> Reflection, JNI, so that we catch both the specification and
> implementation changes.
> c) Our favorite, invokespecial ACC_SUPER, needs special handling,
> since it performs selection which is not based on overriding, but
> based on virtually re-resolving.
> d) Pass by value calling convention optimizations depend on loading
> the actual type. Loading of the parameter types on first method
> resolution implies that if the caller is compiled, the caller method
> requires deoptimization/recompilation to pass arguments by value for
> future calls, which is a performance cost.
> e) If we modify the specification to allow eager loading, and save
> errors to throw at method resolution, we need to work through the
> JVMS question of which errors would be saved (e.g. OOME, SOE might
> be thrown as part of the implementation vs. saving LinkageError), as
> well as designing a new implementation mechanism to repeat
> exceptions relative to signatures used for method resolution.
>
> thanks,
> Karen


More information about the valhalla-spec-observers mailing list