JDK-8323900 : Avoid calling os::init_random() in CDS static dump
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: runtime
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2024-01-17
  • Updated: 2024-04-26
  • Resolved: 2024-04-17
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 23
23 b19Fixed
Related Reports
Relates :  
Relates :  
Description
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);
}


Comments
Changeset: 2fe2f3af Author: Ioi Lam <iklam@openjdk.org> Date: 2024-04-17 05:31:39 +0000 URL: https://git.openjdk.org/jdk/commit/2fe2f3aff82f41a3b7942861e29ccbd3bcc68661
17-04-2024

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/18728 Date: 2024-04-10 16:31:08 +0000
10-04-2024