Today LayoutKind serves multiple purposes in the code: 1) Describe the layout of a value field [REFERENCE, *_FLAT] 2) Describe the layout of a field, flat layout not applicable or flat layout [UNKNOWN, *_FLAT] 3) Describe the layout of a value payload [BUFFERED, *_FLAT] 4) Describe uninitialized values for (1-3) [UNKNOWN]
A surprising (to me) amount of code lands in (2). This leads to us having to be careful around the values that are invalid to use at the various locations in the code. I want to make it so that it is easier to know that you are passing around valid values and that we catch early if we start to use uninitialized values. So, I propose that we convert `LayoutKind` to only hold the flat layouts and then we add a couple of wrapper classes that support the optionality of holding a flat layout. Code that is guaranteed to operate on flat layouts will be using the `FlatLayout` class. Code that may operate on a flat layout will be using the `OptionalFlatLayout` class, which can be queried to see if it holds a `FlatLayout` or not. `OptionalFlatLayout` adds an extra `_is_flat` boolean that is used to discriminate if the `FlatLayout` is active or not. Often code already had an `_is_flat` field, and for those the existing flatness field has been superseded by the one in `OptionalFlatLayout`. Some classes already have their own, other way to decide if we are dealing with a flat layout. For those I've introduced a scaled-down version, called `FlatLayoutSlot`, where the existence of a `FlatLayout` is determined by the surrounding code's "is flat" discriminator. Code that is using `OptionalFlatLayout` fields can create it to hold a flat layout, create it to represent a non-flat situation, and create it marked as "uninitialized". It might be that the code doesn't yet know how to initialize it, or the code might only use it under certain conditions. To make sure that we don't try to query uninitialized OptionalFlatLayouts, asserts have been added to all layout queries. Other things to look for in the patch: * The implementation and construction of `ArrayDescription` has been simplified. * I've decoupled the LayoutKind enumeration values from the "layout value" passed around via Unsafe (and MethodHandle). See FlatLayoutEncoding. * Serviceability code has some restructuring around the construction of objects to make sure that they can be initialized properly in the initializer list. * `JvmtiFlatTagMapKey` has been renamed to `JvmtiValueTagMapKey`. While making this conversion it was found that they don't always hold flat values. They are flat when they are installed in the table, but they can hold buffered objects when doing lookups. Testing: * I've run HotSpot tier1, Valhalla, and JVMTI/heap dumping tests on my local machine. More thorough testing will follow. --------- - [x] I confirm that I make this contribution in accordance with the [OpenJDK Interim AI Policy](https://openjdk.org/legal/ai). ------------- Commit messages: - Make LayoutKind flat-only Changes: https://git.openjdk.org/jdk/pull/33283/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=33283&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8394161 Stats: 1028 lines in 42 files changed: 460 ins; 178 del; 390 mod Patch: https://git.openjdk.org/jdk/pull/33283.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/33283/head:pull/33283 PR: https://git.openjdk.org/jdk/pull/33283
