Skip to content

Compact layout updates for jdk.internal.misc.Unsafe - #23301

Merged
hangshao0 merged 1 commit into
eclipse-openj9:masterfrom
theresa-m:compact_layout_unsafe
Apr 8, 2026
Merged

Compact layout updates for jdk.internal.misc.Unsafe#23301
hangshao0 merged 1 commit into
eclipse-openj9:masterfrom
theresa-m:compact_layout_unsafe

Conversation

@theresa-m

@theresa-m theresa-m commented Feb 3, 2026

Copy link
Copy Markdown
Contributor
  • Add a new compiler flag COMPACT_LAYOUT for Java changes. This flag is disabled by default.
  • Update compareAndExchangeByte/Boolean/Char/Short
  • Update getByte/Boolean/Char/Short
  • Update putByte/Boolean/Char/Short

Related: #21251

Depends on: eclipse-omr/omr#8133

I have confirmed locally that the Valhalla functional tests that do not rely on the JIT are passing. The tests in functional/UnsafeTest pass as well using -Xint.

@theresa-m theresa-m added comp:vm project:valhalla Used to track Project Valhalla related work labels Feb 3, 2026
@theresa-m
theresa-m force-pushed the compact_layout_unsafe branch 4 times, most recently from 32cfb6e to 80edf79 Compare February 3, 2026 20:46
@theresa-m
theresa-m force-pushed the compact_layout_unsafe branch from 80edf79 to ed01eb7 Compare February 18, 2026 16:29
@theresa-m
theresa-m marked this pull request as ready for review February 18, 2026 18:32
Comment thread jcl/src/java.base/share/classes/jdk/internal/misc/Unsafe.java
Comment thread jcl/src/java.base/share/classes/jdk/internal/misc/Unsafe.java Outdated
@theresa-m
theresa-m force-pushed the compact_layout_unsafe branch from ed01eb7 to ccbab69 Compare February 19, 2026 20:55
Comment thread jcl/src/java.base/share/classes/jdk/internal/misc/Unsafe.java
Comment thread runtime/oti/UnsafeAPI.hpp
* @return the value stored in the object field before the update
*/
VMINLINE U_8
inlineMixedObjectCompareAndExchangeU8(J9VMThread *vmThread, j9object_t destObject, UDATA destOffset, U_8 compareValue, U_8 swapValue, bool isVolatile = false)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the rest of barrier code seems to be under the build flag, but not here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are existing J9VM_OPT_VALHALLA_COMPACT_LAYOUTS flags for these methods at line 620 and 952.

@theresa-m
theresa-m marked this pull request as draft March 17, 2026 14:43
@theresa-m
theresa-m force-pushed the compact_layout_unsafe branch 2 times, most recently from 777c68a to 8fcf4bc Compare March 17, 2026 16:40
@theresa-m
theresa-m marked this pull request as ready for review March 17, 2026 16:40
@theresa-m
theresa-m requested a review from hangshao0 March 17, 2026 16:40

TR::Node *TR_J9InlinerPolicy::createUnsafeAddressWithOffset(TR::Node *unsafeCall)
{
#if defined(J9VM_OPT_VALHALLA_COMPACT_LAYOUTS)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hzongaro fyi this method is causing a compilation error since the new J9_SUN_FIELD_OFFSET_MASK are 64 bits.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this result in a build-time compilation error (from the C++ compiler) or a compilation failure/crash for the JIT compiler?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It results in a build time error.

openj9/runtime/compiler/optimizer/InlinerTempForJ9.cpp:552:42: error: implicit conversion from 'unsigned long' to 'int32_t' (aka 'int') changes value from 4611686018427387903 to -1 [-Werror,-Wconstant-conversion]
            TR::Node::iconst(unsafeCall, ~(J9_SUN_FIELD_OFFSET_MASK))));
            ~~                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess with the original value for J9_SUN_FIELD_OFFSET_MASK, it would work in both 32-bit and 64-bit modes. The JIT doesn't usually conditionally compile out sections based on whether the target is 32-bit or 64-bit, so I don't want to suggest using conditional compilation here. May I suggest trying to cast the J9_SUN_FIELD_OFFSET_MASK to an int32_t in the call to TR::Node::iconst?

#else /* defined(J9VM_OPT_VALHALLA_COMPACT_LAYOUTS) */
    if (comp()->target().is64Bit()) {
        TR::Node *constNode = TR::Node::lconst(unsafeCall, ~(J9_SUN_FIELD_OFFSET_MASK));
        return TR::Node::create(TR::aladd, 2, unsafeCall->getChild(1),
            TR::Node::create(TR::land, 2, unsafeCall->getChild(2), constNode));
    }

    return TR::Node::create(TR::aiadd, 2, unsafeCall->getChild(1),
        TR::Node::create(TR::iand, 2, TR::Node::create(TR::l2i, 1, unsafeCall->getChild(2)),
            TR::Node::iconst(unsafeCall, ~((int32_t) J9_SUN_FIELD_OFFSET_MASK))));
#endif /* defined(J9VM_OPT_VALHALLA_COMPACT_LAYOUTS) */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may be moving the tags to the high bits (of a long offset), so we should not assume that the value is 32 bit.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may be moving the tags to the high bits (of a long offset), so we should not assume that the value is 32 bit.

Ah, sorry - I was thinking the tag values would still be less than 2^32 in 32-bit mode. However, this is masking off the tag values for use in an address calculation, so I think it would be safe to consider only the low-order 32 bits of the mask value.

Now that I look at it more closely, I see the case under defined(J9VM_OPT_VALHALLA_COMPACT_LAYOUTS) is the same as the 64-bit mode non-compact layout version, so I think it would be safe to remove that entire #if defined block and leave the method as it originally was, except casting the value in the call to TR::Node:iconst to an int32_t, and then perhaps add a comment pointing out that even if the tag bits are in the high-order 32 bits, only the low order 32 bits participate in the address calculation for 32 bit targets, so it’s safe to cast the complemented mask value to a uint32_t.

Perhaps too it would be better to use (int32_t) (~(J9_SUN_FIELD_OFFSET_MASK)) rather than ~((int32_t) J9_SUN_FIELD_OFFSET_MASK) as I originally suggested.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, the constant may be explicitly declared as a U_64 if we move the bits. The current assumption that the bits are encoded in the offset will no longer be correct on 32-bit (only the low 32 bits are the offset, and tha tag bits are in the high 32 bits).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I've added your suggestion

Comment thread jcl/src/java.base/share/classes/jdk/internal/misc/Unsafe.java
Comment thread jcl/src/java.base/share/classes/jdk/internal/misc/Unsafe.java Outdated
Comment thread runtime/oti/j9consts.h
Comment thread runtime/oti/j9consts.h Outdated
@theresa-m
theresa-m force-pushed the compact_layout_unsafe branch from 8fcf4bc to ec38209 Compare March 17, 2026 20:19
@theresa-m
theresa-m requested a review from hangshao0 March 17, 2026 20:19
Comment thread jcl/src/java.base/share/classes/jdk/internal/misc/Unsafe.java Outdated
Comment thread runtime/oti/j9consts.h Outdated
@theresa-m
theresa-m force-pushed the compact_layout_unsafe branch 2 times, most recently from 05b6a85 to 8cd7062 Compare March 24, 2026 16:41
@theresa-m
theresa-m force-pushed the compact_layout_unsafe branch 3 times, most recently from 066f053 to 1e897ca Compare March 26, 2026 15:01
@theresa-m
theresa-m marked this pull request as ready for review March 26, 2026 15:01
@theresa-m

Copy link
Copy Markdown
Contributor Author

This compiles on win32 now http://vmfarm.rtp.raleigh.ibm.com/build_info.php?build_id=114779

@hzongaro hzongaro left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JIT compiler-related changes look good to me. Thanks!

@gacholio

Copy link
Copy Markdown
Contributor

I will look at this tomorrow.

@hangshao0

Copy link
Copy Markdown
Contributor

@amicic This is waiting for your approval.

- Add a new compiler flag COMPACT_LAYOUT for Java changes. This
flag is disabled by default.
- Update Unsafe compareAndExchangeByte/Boolean/Char/Short
- Update Unsafe getByte/Boolean/Char/Short
- Update Unsafe putByte/Boolean/Char/Short
- Move static offset flags from least significant bits to most significant bits
of U_64 and adjust variable types from UDATA to U_64

Signed-off-by: Theresa Mammarella <Theresa.T.Mammarella@ibm.com>
@theresa-m
theresa-m force-pushed the compact_layout_unsafe branch from 1e897ca to f7987c3 Compare April 6, 2026 14:04
@hangshao0

Copy link
Copy Markdown
Contributor

Jenkins test sanity.functional,extended alinuxval jdknext

@hangshao0

Copy link
Copy Markdown
Contributor

jenkins compile win,win32 jdk8

@hangshao0

Copy link
Copy Markdown
Contributor

jenkins test sanity.functional,extended zlinux jdk21

@hangshao0
hangshao0 merged commit c9bd78f into eclipse-openj9:master Apr 8, 2026
12 checks passed
Comment thread jcl/jpp_configuration.xml
Comment thread runtime/compiler/optimizer/InlinerTempForJ9.cpp

#if defined(J9VM_OPT_VALHALLA_COMPACT_LAYOUTS)
/**
* Performs an atomic compare-and-exchange on a byte field of a mixed object

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing period; also line 2183.

{
#if defined(J9VM_GC_ALWAYS_CALL_OBJECT_ACCESS_BARRIER)
return vmThread->javaVM->memoryManagerFunctions->j9gc_objaccess_mixedObjectCompareAndExchangeByte(vmThread, destObject, destOffset, compareValue, swapValue);
#elif defined(J9VM_GC_COMBINATION_SPEC)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing comment.

return result;
#else /* J9VM_GC_ALWAYS_CALL_OBJECT_ACCESS_BARRIER */
#error unsupported barrier
#endif /* J9VM_GC_ALWAYS_CALL_OBJECT_ACCESS_BARRIER */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mismatched comments (they should repeat the if condition, i.e. defined(J9VM_GC_ALWAYS_CALL_OBJECT_ACCESS_BARRIER) || defined(J9VM_GC_COMBINATION_SPEC)).

Comment on lines +721 to +722
offset = fieldID->offset;
offset |= J9_SUN_STATIC_FIELD_OFFSET_TAG;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are several similar changes: Why?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought it would be easier to debug if something went wrong with changing the value of these flags.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A compiler may (hopefully will) elide the first assignment, effectively yielding the same code as for the old code, so debugging should be a similar experience either way.

Comment thread runtime/oti/UnsafeAPI.hpp
/* Aligned array access */
UDATA index = convertOffsetToIndex(currentThread, offset, logElementSize);
result = objectAccessBarrier->inlineIndexableObjectCompareAndExchangeU8(currentThread, object, index, compareValue, swapValue, true);
} else if (offset & J9_SUN_STATIC_FIELD_OFFSET_TAG) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should use J9_ARE_ANY_BITS_SET().

{
U_8 value = (U_8)*(I_32*)_sp;
UDATA offset = (UDATA)*(I_64*)(_sp + 1);
U_64 offset = *(I_64*)(_sp + 1);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mismatched types (several places):

		U_64 offset = *(U_64 *)(_sp + 1);

theresa-m added a commit to theresa-m/openj9 that referenced this pull request Apr 9, 2026
Signed-off-by: Theresa Mammarella <Theresa.T.Mammarella@ibm.com>
theresa-m added a commit to theresa-m/openj9 that referenced this pull request Apr 9, 2026
Signed-off-by: Theresa Mammarella <Theresa.T.Mammarella@ibm.com>
theresa-m added a commit to theresa-m/openj9 that referenced this pull request Apr 10, 2026
Signed-off-by: Theresa Mammarella <Theresa.T.Mammarella@ibm.com>
@github-project-automation github-project-automation Bot moved this from TODO: VM to Done in Valhalla L-World Apr 13, 2026
keithc-ca added a commit that referenced this pull request Apr 13, 2026
Address additional review comments from #23301
theresa-m added a commit to theresa-m/openj9 that referenced this pull request Apr 14, 2026
dev-koan pushed a commit to dev-koan/openj9 that referenced this pull request May 27, 2026
Signed-off-by: Theresa Mammarella <Theresa.T.Mammarella@ibm.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp:vm project:valhalla Used to track Project Valhalla related work

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants