8377712: ConstantPool of WeakReferenceKey is not deterministic in CDS archive

Reviewed-by: liach, kvn
This commit is contained in:
Ioi Lam 2026-02-19 05:24:08 +00:00
parent 7d2b6ed892
commit 33c9f20bef
4 changed files with 41 additions and 3 deletions

View File

@ -1148,7 +1148,7 @@ void AOTMetaspace::dump_static_archive_impl(StaticArchiveBuilder& builder, TRAPS
if (CDSConfig::is_dumping_full_module_graph()) {
ClassLoaderDataShared::ensure_module_entry_tables_exist();
ClassLoaderDataShared::build_tables(CHECK);
HeapShared::reset_archived_object_states(CHECK);
HeapShared::prepare_for_archiving(CHECK);
}
AOTReferenceObjSupport::initialize(CHECK);

View File

@ -247,6 +247,28 @@ void HeapShared::reset_archived_object_states(TRAPS) {
reset_states(boot_loader(), CHECK);
}
void HeapShared::ensure_determinism(TRAPS) {
TempNewSymbol class_name = SymbolTable::new_symbol("jdk/internal/util/WeakReferenceKey");
TempNewSymbol method_name = SymbolTable::new_symbol("ensureDeterministicAOTCache");
Klass* weak_ref_key_class = SystemDictionary::resolve_or_fail(class_name, true, CHECK);
precond(weak_ref_key_class != nullptr);
log_debug(aot)("Calling WeakReferenceKey::ensureDeterministicAOTCache(Object.class)");
JavaValue result(T_BOOLEAN);
JavaCalls::call_static(&result,
weak_ref_key_class,
method_name,
vmSymbols::void_boolean_signature(),
CHECK);
assert(result.get_jboolean() == false, "sanity");
}
void HeapShared::prepare_for_archiving(TRAPS) {
reset_archived_object_states(CHECK);
ensure_determinism(CHECK);
}
HeapShared::ArchivedObjectCache* HeapShared::_archived_object_cache = nullptr;
bool HeapShared::is_archived_heap_in_use() {

View File

@ -382,8 +382,10 @@ private:
static bool walk_one_object(PendingOopStack* stack, int level, KlassSubGraphInfo* subgraph_info,
oop orig_obj, oop referrer);
public:
static void reset_archived_object_states(TRAPS);
static void ensure_determinism(TRAPS);
public:
static void prepare_for_archiving(TRAPS);
static void create_archived_object_cache() {
_archived_object_cache =
new (mtClass)ArchivedObjectCache(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -88,4 +88,18 @@ final class WeakReferenceKey<T> extends WeakReference<T> implements ReferenceKey
public String toString() {
return this.getClass().getCanonicalName() + "#" + System.identityHashCode(this);
}
// WeakReferenceKey.equals() is usually executed in the AOT assembly phase. However,
// in some rare occasions, it's not executed (due to peculiarity of hash code and
// memory addressing??). As a result, the constant pool entries used by
// equals() are not resolved.
//
// The JVM calls ensureDeterministicAOTCache() during the AOT assembly phase to ensure
// that the constant pool entries used by equals() are resolved, so that the
// the JDK's default CDS archives have deterministic contents.
private static boolean ensureDeterministicAOTCache() {
WeakReferenceKey<String> k1 = new WeakReferenceKey<>("1", null);
WeakReferenceKey<String> k2 = new WeakReferenceKey<>("2", null);
return k1.equals(k2);
}
}