[lworld] RFR: [lworld] C2: Support abstract value class fields

Christian Hagedorn chagedorn at openjdk.org
Wed Sep 4 10:55:36 UTC 2024


This patch adds support for abstract value class fields. To make it work, it required fixes in various places. The two main things to change was to account for fields in abstract value classes when collecting/accessing all fields which was not expected before and updating the way we handle larvals.

## Updated Larval Handling
### Previous Larval Initialization
Before this change, larvals were always updated inside a single concrete value class constructor. It could have been done directly:

new MyValue -> MyValue.<init> (initialization here) -> Object.<init>

or by first delegating to another value type constructor inside the same value class which does the initiliazation:

new MyValue -> MyValue.<init> -> MyValue.<init> (initialization here) -> Object.<init>

It was not possible to distribute the initialization of an inline type to multiple constructors (i.e. at value class constructor cannot do a partial initialization).

Therefore, we could just detect any call from a value class constructor to an abstract constructor or the `Object` constructor with the same receiver and then mark the inline type as non-larval since it's completely initialized before calling the super constructor (abstract classes and `Object.<init>` cannot modify the inline type anymore). The only thing required after the call was to detect if we actually inlined another constructor with the same receiver within the same concrete value class. If that's the case, we need to update the exit map to propagate the initialized receiver to the caller.

This now changes: With fields in abstract value classes, a larval is not completely initialized after the concrete value class constructor is complete. We therefore needed to find a new way to ensure the correct initialization of larvals.

### New Larval Initialization with Fields in Abstract Classes
#### Problems
- A larval _could_ be fully initialized after calling the concrete value class constructor. But we could also have a situation where we still need to initialize a field in an abstract value class. Therefore, we cannot eagerly mark an inline type as non-larval once the concrete value class constructor is completed nor when an abstract value class constructor is completed (there could be multiple).
- The currently parsed method only has the map/JVM state from the direct caller. We therefore cannot simply detect the call to the `Object.<init>()` call at the end of chained value class constructor calls and then propagate the update to all the callers.

#### Solution
We therefore decided to only process larvals after the constructor call by looking at the just called method (regardless of whether is was inlined or not). If it was another concrete value class constructor, an abstract constructor or `Object.<init>` with the same receiver, then we know that after the call, the inline type is fully initialized. We only now mark it as non-larval and update the maps to propagate the update.

#### Other Fixes
I also needed to update other places where we update the receiver and the maps which often just checked if the holder class is a value type. This does not work anymore and needs to be updated (abstract value classes are not marked as inline type klasses).

#### Details
For more details, I refer to the code comments added in the patch for the various cases.

## Testing
I've copied the existing `TestValueConstructor` tests and created versions with abstract classes and added some new tests. The patch passed tier1-4 + stress except for one test failure in the stress testing: `TestNullableInlineTypes::test80()` failed with the very same assert and the same flags as `TestNullableInlineTypes::test81()` which was already disabled and tracked by [JDK-8325632](https://bugs.openjdk.org/browse/JDK-8325632). This suggests that it is most likely the same issue but triggered differently. To move forward with this patch, I also disabled `test80()`. We can get back to this later.

-------------

Commit messages:
 - disable helper method
 - [lworld] C2: Support abstract value class fields

Changes: https://git.openjdk.org/valhalla/pull/1236/files
  Webrev: https://webrevs.openjdk.org/?repo=valhalla&pr=1236&range=00
  Stats: 1370 lines in 13 files changed: 1247 ins; 24 del; 99 mod
  Patch: https://git.openjdk.org/valhalla/pull/1236.diff
  Fetch: git fetch https://git.openjdk.org/valhalla.git pull/1236/head:pull/1236

PR: https://git.openjdk.org/valhalla/pull/1236


More information about the valhalla-dev mailing list