RFR: 8253495: CDS generates non-deterministic output [v2]
Ioi Lam
iklam at openjdk.java.net
Thu Mar 10 19:29:43 UTC 2022
On Thu, 10 Mar 2022 13:51:56 GMT, Magnus Ihse Bursie <ihse at openjdk.org> wrote:
>> Ioi Lam has updated the pull request incrementally with one additional commit since the last revision:
>>
>> Fixed zero build
>
> I think he already did. I'm quoting:
>
>> However, the CDS archive also contains a heap dump, which includes Java HashMaps. If I allow those 3 Java threads to start, some HashMaps in the module graph will have unstable ordering. I think the reason is concurrent thread execution causes unstable assignment of the identity_hash for objects in the heap dump.
> @magicus I think we need @iklam to weigh in here and explain exactly what the "heap dump" consists of and how not running those threads affects its contents. Presently the heap dump is potentially different on each run, IIUC, only due to the order of its contents, not the contents themselves.
CDS doesn't dump the entire Java heap. Instead, it dumps only a selected portion of the Java heap. For example, the module graph. The contents of the dumped objects are always the same, except that the identity hashcode may be different if multiple threads are executed. The identity hashcode is computed here, and its value is "sticky" to the first thread that tries to get the hashcode for an object.
static inline intptr_t get_next_hash(Thread* current, oop obj) {
intptr_t value = 0;
if (hashCode == 0) {
...
} else if (hashCode == 4) {
...
} else { // default hashCode is 5:
// Marsaglia's xor-shift scheme with thread-specific state
// This is probably the best overall implementation -- we'll
// likely make this the default in future releases.
unsigned t = current->_hashStateX;
t ^= (t << 11);
current->_hashStateX = current->_hashStateY;
current->_hashStateY = current->_hashStateZ;
current->_hashStateZ = current->_hashStateW;
unsigned v = current->_hashStateW;
v = (v ^ (v >> 19)) ^ (t ^ (t >> 8));
current->_hashStateW = v;
value = v;
}
So, when the main Java thread tries to store an object `O` into a hashtable inside the module graph, if the hashcode of `O` has already been computed by a non-main thread, then the module graph will have unstable contents.
-------------
PR: https://git.openjdk.java.net/jdk/pull/7748
More information about the build-dev
mailing list