On Wed, 16 Sep 2026 14:34:57 GMT, Frederic Parain <[email protected]> wrote:
>> src/java.base/share/classes/java/lang/runtime/ValueObjectMethods.java line >> 176: >> >>> 174: // to enable caching. The identity hash of the value class >>> distinguishes >>> 175: // different value classes and is easy for the compiler to >>> fetch. >>> 176: return (result & 0x7fffffff) == 0 ? typeHash : result; >> >> We need to check if the hash that will be retrieved later is null or not, >> but between this return and the storage, the hash is masked to fit in the >> cache of the mark word, which is at most 31 bits. So, 0x80_00_00_00 will >> also be cut into a 0 hash. >> >> I made this masking here in a quick and dirty way: it assumes we will keep >> 31 bits, which I think it wrong at least on 32 bits architectures (if I >> understand the comments about the mark word correctly). Yet, I didn't manage >> to get the mask from the VM as we do in Mark.java. So, this is to be fixed >> by somebody who knows this side of JDK better than me. >> >> If we omit the masking here (and we do `result == 0`), then the test >> `test/hotspot/jtreg/compiler/valhalla/valuetypes/TestHashcodeFastPath.java` >> fails. Specifically the first instance of the assert >> >> Asserts.assertNE(h(would_have_zero_hashcode1), 0); >> >> since it actually runs fully in the interpreter (`h` is excluded and the >> enclosing method is marked with `@Run`, so not compiled). >> >> Another option is not to do the filtering here, but somewhere around >> https://github.com/openjdk/jdk/blob/e45a4e7a8514c1193e2ff92ead04630d93a760ec/src/hotspot/share/prims/jvm.cpp#L815 >> in the caller, where we are in the C++ world and accessing the mask is easy >> (but there, getting `System.identityHashCode(type)` is harder). > > Here's the markword format given in markWord.hpp: > > // Bit-format of an object header (most significant first, big endian layout > below): > // > // 32 bits: > // -------- > // hash:25 age:4 self-fwd:1 lock:2 > // > // 64 bits (without compact headers): > // ---------------------------------- > // unused:22 hash:31 valhalla:4 age:4 self-fwd:1 lock:2 > // > // 64 bits (with compact headers): > // ------------------------------- > // klass:22 hash:31 valhalla:4 age:4 self-fwd:1 lock:2 Related relevant code include: - where we set the hash in the markword: https://github.com/openjdk/jdk/blob/ea04454135e2e431d3518261dc0e68064d8f4a5b/src/hotspot/share/prims/jvm.cpp#L827-L828 - the code doing it: https://github.com/openjdk/jdk/blob/ea04454135e2e431d3518261dc0e68064d8f4a5b/src/hotspot/share/oops/markWord.hpp#L297-L301 - the code getting the hash: https://github.com/openjdk/jdk/blob/ea04454135e2e431d3518261dc0e68064d8f4a5b/src/hotspot/share/oops/markWord.hpp#L269-L272 Basically, it's just masking and shifting. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/32660#discussion_r4027925966
