On Mon, 9 Feb 2026 09:35:48 GMT, Axel Boldt-Christmas <[email protected]> 
wrote:

> Create a wrapper class which represents the payload of an InlineKlass object.
> 
> The current convention is to use a `void*` representing where the payload 
> starts, the `InlineKlass*` (as we do not always have a header when flattened) 
> and a `LayoutKind` (describing the payloads layout). 
> 
> I suggest we introduce something like a `ValuePayload` which encapsulate 
> these properties. As well as a hierarchy built upon these, with the proper 
> interfaces implemented.
> * ValuePayload (Any payload)
>   * RawValuePayload (Payload with holder erased)
>   * BufferedValuePayload (Payload of normal heap object)
>   * FlatValuePayload (Payload of flattened value)
>     * FlatFieldPayload (Payload of flattened field)
>     * FlatArrayPayload (Payload of flattened array element)
>    
> The goal is to both make interfaces clearer, and easier to understand. As 
> well as consolidating the implementation in one place rather than spread 
> across different subsystems. 
> 
> Each type (except RawValuePayload) also allows for the creation of a Handle, 
> (thread local, or in an OopStorage) for keeping the payload as a thread or 
> global root.
> 
> The ValuePayload class is also the interface for interacting with the Access 
> API for InlineKlass objects.
> 
> * Testing
>   * Running tier 1-4 with preview enabled
>   * Running app tests with preview enabled
>   * Running normal tier 1-5 
> 
> #### _Extra Notes:_
>  * The `OopHandle` type is there so that we can migrate the JVMTI payload 
> abstraction implementation to using this instead. (Future RFE)
>  * Some interfaces got cleaned up. Some are unused. Like the `null_payload` 
> which was superseded by the `Access::value_store_null`. C1 still uses the 
> `.null_reset` but if that dependency is removed we should be able to remove 
> that weird object all together.
>  * Simply adding the Java to VM transition deep inside the payload code 
> created a circular include dependency here. So rather than fixing that, I 
> implemented the relevant bytecodes in the BytecodeInterpreter.

Thanks for this work, it really improves this code a lot. I've left some very 
superficial comments, I plan on doing a more in-depth review pass down the line.

src/hotspot/share/gc/z/zBarrierSet.inline.hpp line 536:

> 534:   const LayoutKind lk = dst.get_layout_kind();
> 535:   assert(!LayoutKindHelper::is_null_free_flat(lk),
> 536:          "ZGC cannot handle atomic flat values");

Should this be null free instead? `LKH::is_null_free_flat` can be true for 
nonatomic values.

src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp line 1505:

> 1503:       CASE(_aaload): {
> 1504:           ARRAY_INTRO(-2);
> 1505:           if (((objArrayOop) arrObj)->is_flatArray()) {

As you said it'd be nice to clean this up at some point.

src/hotspot/share/prims/unsafe.cpp line 468:

> 466:   LayoutKind lk = (LayoutKind)layoutKind;
> 467:   FlatValuePayload payload = 
> FlatValuePayload::construct_from_parts(base, vk, offset, lk);
> 468:   payload.write(inlineOop(JNIHandles::resolve(value)), CHECK);

Maybe a stupid question but is it safe to write the payload? Could another 
thread be writing to it at the same time?

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

PR Review: 
https://git.openjdk.org/valhalla/pull/2068#pullrequestreview-3772582927
PR Review Comment: 
https://git.openjdk.org/valhalla/pull/2068#discussion_r2781937778
PR Review Comment: 
https://git.openjdk.org/valhalla/pull/2068#discussion_r2781949920
PR Review Comment: 
https://git.openjdk.org/valhalla/pull/2068#discussion_r2782568877

Reply via email to