The CDS static dump calls os::init_random(0x12345678). This modifies a global state and may affect the behavior of other VM components in subtle ways.
================
https://github.com/openjdk/jdk/blob/2063bb8ffabd6096f547ec6da979cfcf68a56ba3/src/hotspot/share/cds/metaspaceShared.cpp#L499-L517
void VM_PopulateDumpSharedSpace::doit() {
...
// Initialize random for updating the hash of symbols
os::init_random(0x12345678);
https://github.com/openjdk/jdk/blob/2063bb8ffabd6096f547ec6da979cfcf68a56ba3/src/hotspot/share/oops/symbol.cpp#L75-L81
void Symbol::update_identity_hash() {
// This is called at a safepoint during dumping of a static CDS archive. The caller should have
// called os::init_random() with a deterministic seed and then iterate all archived Symbols in
// a deterministic order.
assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
_hash_and_refcount = pack_hash_and_refcount((short)os::random(), PERM_REFCOUNT);
}
================
Proposal:
All CDS needs is a deterministic sequence of random numbers to be used by Symbol::update_identity_hash(). We can copy the logic in os::random() but maintain our own seed. Also, this is called in a single thread so no cmpxchg is needed:
int os::random() {
// Make updating the random seed thread safe.
while (true) {
unsigned int seed = _rand_seed;
unsigned int rand = next_random(seed);
if (Atomic::cmpxchg(&_rand_seed, seed, rand, memory_order_relaxed) == seed) {
return static_cast<int>(rand);
}
}
}
static unsigned int _cds_symbol_seed = 0x12345678;
int cds_symbol_random() {
_cds_symbol_seed = os::next_random(_cds_symbol_seed);
return static_cast<int>(_cds_symbol_seed);
}
================
https://github.com/openjdk/jdk/blob/2063bb8ffabd6096f547ec6da979cfcf68a56ba3/src/hotspot/share/cds/metaspaceShared.cpp#L499-L517
void VM_PopulateDumpSharedSpace::doit() {
...
// Initialize random for updating the hash of symbols
os::init_random(0x12345678);
https://github.com/openjdk/jdk/blob/2063bb8ffabd6096f547ec6da979cfcf68a56ba3/src/hotspot/share/oops/symbol.cpp#L75-L81
void Symbol::update_identity_hash() {
// This is called at a safepoint during dumping of a static CDS archive. The caller should have
// called os::init_random() with a deterministic seed and then iterate all archived Symbols in
// a deterministic order.
assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
_hash_and_refcount = pack_hash_and_refcount((short)os::random(), PERM_REFCOUNT);
}
================
Proposal:
All CDS needs is a deterministic sequence of random numbers to be used by Symbol::update_identity_hash(). We can copy the logic in os::random() but maintain our own seed. Also, this is called in a single thread so no cmpxchg is needed:
int os::random() {
// Make updating the random seed thread safe.
while (true) {
unsigned int seed = _rand_seed;
unsigned int rand = next_random(seed);
if (Atomic::cmpxchg(&_rand_seed, seed, rand, memory_order_relaxed) == seed) {
return static_cast<int>(rand);
}
}
}
static unsigned int _cds_symbol_seed = 0x12345678;
int cds_symbol_random() {
_cds_symbol_seed = os::next_random(_cds_symbol_seed);
return static_cast<int>(_cds_symbol_seed);
}
- relates to
-
JDK-8330027 Identity hashes of archived objects must be based on a reproducible random seed
-
- Resolved
-
-
JDK-8323556 CDS archive space addresses should be randomized with ArchiveRelocationMode=1
-
- Closed
-