On Wed, 2 Sep 2026 18:40:00 GMT, Chen Liang <[email protected]> wrote:

> The identity hash code of value objects currently can produce 0. A zero value 
> is usually not anticipated for System.identityHashCode calls unless the 
> argument is null; the 0 hash also cannot be cached. Thus, we should move away 
> from the 0 hash.
> 
> ---------
> - [x] I confirm that I make this contribution in accordance with the [OpenJDK 
> Interim AI Policy](https://openjdk.org/legal/ai).

We need a dedicated runtime test.

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).

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

PR Review: https://git.openjdk.org/jdk/pull/32660#pullrequestreview-5175938242
PR Review Comment: https://git.openjdk.org/jdk/pull/32660#discussion_r3986793267

Reply via email to