JDK-8237976 : Add VM options to control field layout algorithms
  • Type: CSR
  • Component: hotspot
  • Sub-Component: runtime
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 15
  • Submitted: 2020-01-28
  • Updated: 2024-04-18
  • Resolved: 2020-02-10
Related Reports
CSR :  
Relates :  
Description
Summary
-------

Add new VM options `UseEmptySlotsInSupers` and `UseNewFieldLayout` to control the new algorithm computing field layouts.

Problem
-------

First issue

The new algorithm to compute field layouts performs more optimizations than the previous algorithm. 

One of these optimizations is to allocate fields of a class in the unused slots of its super classes. This optimization provides better data density but can cause issues in two cases:

  1 - allocating a field in the unused slots of a super-class breaks a property of the old algorithm which always allocated field of a class *after* the fields of its direct super class. This property was not written anywhere, but was exploited by some code (CI, JVMCI and deoptimization had to be modified because they were relying on this property). It is possible that tools from the Java ecosystem rely on this property too, and by consequence, could break because of the new layout,

  2 - even if the JVMS doesn't provide any guarantee about the layout of fields, some users might absolutely want that fields of a given class are allocated together (for instance, to be in the same cache line). This property was naturally provided by the old algorithm but it is not the default behavior of the new algorithm.

The second optimization allows the allocation of subclass fields directly after the last field of the direct super-class, instead of aligning the first field of the subclass on a heapOopSize boundary as the old code does.

Second issue:

The old code to compute field layouts has been stable for so long that people used some of its properties as it they were behavior guaranteed by the JVM. The new code tries to be as compatible as possible with the behavior of the old code, but some of its properties could have been missed (because they are not written anywhere).

Solution
--------

It is a bad coding practice to rely on unspecified behaviors of the JVM like the fields layout, however, to avoid breaking existing applications and tools relying on the current field layouts, the JVM should provide a way to disable aggressive optimizations during field allocations, in order to continue to use the same field layouts as today.

The number of unspecified behaviors of field layout being currently exploited is unknown, and disabling the aggressive optimizations might not be sufficient to reproduce the same field layouts with the new code as they were with the old code. The changeset for JDK-8237767 doesn't remove the old code. A VM option should allow users to still use the old code during a transition period (see timeframe below), until the old is eventually removed.

Note that there's no guarantee that such unspecified behaviors of the old code will be back-ported in the new code before the old code is removed.

Specification
-------------

`UseEmptySlotsInSupers` is a new product VM option, with type boolean and a default value of true, which would disable new optimizations during field layout computations, in order to produce the same layouts as the old code. This option would be supported on the long term with the new code.

`UseNewFieldLayout` is a new pre-deprecated product VM option, with a type boolean and a default value of true, which would allow users to still use the old code instead of the new code, in case some unknown differences in behavior between the old and the new code impact them. This option is pre-deprecated because the plan is to remove the old code at some point. The current plan is to have this option pre-deprecated in JDK 15, to make it obsolete in JDK 16 when the old code is removed (before JDK 17, the next LTS release). 

Webrev:
http://cr.openjdk.java.net/~fparain/jdk_layout/webrev.09c/index.html

Comments
Retroactively approving this request which was inappropriately pushed before the CSR review was complete. Please write a release note for this change.
10-02-2020

Timeline has been updated according to David's feedback.
06-02-2020

> The current plan is to have this option pre-deprecated in JDK 15, to make it obsolete in JKDK 16, and to remove it when the old code is removed in JDK 17 (next LTS release). Code removal occurs when a flag is obsoleted, not when it expires, so the above timeline needs to be updated according to whether the intent is to remove the old code in 16 or 17. I thought it was intended to remove in 16 hence the immediate deprecation in 15. Thanks.
03-02-2020

Proposal has been updated to use two product flags, one of which is now immediately deprecated in 15. This is a special transitional flag.
03-02-2020

I agree that [~dholmes]'s concerns are well-founded.
30-01-2020

I don't agree that the flag to use the old behaviour should be a diagnostic option. We have had issues in the past where customers will not run the JVM in production with diagnostic flags enabled. If customers may encounter problems that require the old behaviour then we need a way to disable it in product mode and we need a migration path for those customers.
29-01-2020