Compact layout updates for jdk.internal.misc.Unsafe - #23301
Conversation
32cfb6e to
80edf79
Compare
80edf79 to
ed01eb7
Compare
ed01eb7 to
ccbab69
Compare
| * @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) |
There was a problem hiding this comment.
the rest of barrier code seems to be under the build flag, but not here
There was a problem hiding this comment.
There are existing J9VM_OPT_VALHALLA_COMPACT_LAYOUTS flags for these methods at line 620 and 952.
777c68a to
8fcf4bc
Compare
|
|
||
| TR::Node *TR_J9InlinerPolicy::createUnsafeAddressWithOffset(TR::Node *unsafeCall) | ||
| { | ||
| #if defined(J9VM_OPT_VALHALLA_COMPACT_LAYOUTS) |
There was a problem hiding this comment.
@hzongaro fyi this method is causing a compilation error since the new J9_SUN_FIELD_OFFSET_MASK are 64 bits.
There was a problem hiding this comment.
Does this result in a build-time compilation error (from the C++ compiler) or a compilation failure/crash for the JIT compiler?
There was a problem hiding this comment.
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))));
~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~
There was a problem hiding this comment.
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) */
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
Thanks, I've added your suggestion
8fcf4bc to
ec38209
Compare
05b6a85 to
8cd7062
Compare
066f053 to
1e897ca
Compare
|
This compiles on win32 now http://vmfarm.rtp.raleigh.ibm.com/build_info.php?build_id=114779 |
hzongaro
left a comment
There was a problem hiding this comment.
JIT compiler-related changes look good to me. Thanks!
|
I will look at this tomorrow. |
|
@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>
1e897ca to
f7987c3
Compare
|
Jenkins test sanity.functional,extended alinuxval jdknext |
|
jenkins compile win,win32 jdk8 |
|
jenkins test sanity.functional,extended zlinux jdk21 |
|
|
||
| #if defined(J9VM_OPT_VALHALLA_COMPACT_LAYOUTS) | ||
| /** | ||
| * Performs an atomic compare-and-exchange on a byte field of a mixed object |
There was a problem hiding this comment.
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) |
| return result; | ||
| #else /* J9VM_GC_ALWAYS_CALL_OBJECT_ACCESS_BARRIER */ | ||
| #error unsupported barrier | ||
| #endif /* J9VM_GC_ALWAYS_CALL_OBJECT_ACCESS_BARRIER */ |
There was a problem hiding this comment.
Mismatched comments (they should repeat the if condition, i.e. defined(J9VM_GC_ALWAYS_CALL_OBJECT_ACCESS_BARRIER) || defined(J9VM_GC_COMBINATION_SPEC)).
| offset = fieldID->offset; | ||
| offset |= J9_SUN_STATIC_FIELD_OFFSET_TAG; |
There was a problem hiding this comment.
There are several similar changes: Why?
There was a problem hiding this comment.
I thought it would be easier to debug if something went wrong with changing the value of these flags.
There was a problem hiding this comment.
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.
| /* 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) { |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
Mismatched types (several places):
U_64 offset = *(U_64 *)(_sp + 1);Signed-off-by: Theresa Mammarella <Theresa.T.Mammarella@ibm.com>
Signed-off-by: Theresa Mammarella <Theresa.T.Mammarella@ibm.com>
Signed-off-by: Theresa Mammarella <Theresa.T.Mammarella@ibm.com>
Address additional review comments from #23301
This reverts commit e3b1a77.
Signed-off-by: Theresa Mammarella <Theresa.T.Mammarella@ibm.com>
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.