8335059: Consider renaming ClassLoaderData::keep_alive

Reviewed-by: dholmes, stefank
This commit is contained in:
Coleen Phillimore 2024-08-02 11:47:26 +00:00
parent a89b525189
commit 328a0533b2
10 changed files with 42 additions and 41 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2024, 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
@ -375,7 +375,7 @@ void BarrierSetAssembler::c2i_entry_barrier(MacroAssembler* masm) {
__ load_method_holder_cld(rscratch1, rmethod);
// Is it a strong CLD?
__ ldrw(rscratch2, Address(rscratch1, ClassLoaderData::keep_alive_offset()));
__ ldrw(rscratch2, Address(rscratch1, ClassLoaderData::keep_alive_ref_count_offset()));
__ cbnz(rscratch2, method_live);
// Is it a weak but alive CLD?

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2022 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -238,7 +238,7 @@ void BarrierSetAssembler::c2i_entry_barrier(MacroAssembler *masm, Register tmp1,
__ ld(tmp1_class_loader_data, in_bytes(InstanceKlass::class_loader_data_offset()), tmp1);
// Fast path: If class loader is strong, the holder cannot be unloaded.
__ lwz(tmp2, in_bytes(ClassLoaderData::keep_alive_offset()), tmp1_class_loader_data);
__ lwz(tmp2, in_bytes(ClassLoaderData::keep_alive_ref_count_offset()), tmp1_class_loader_data);
__ cmpdi(CCR0, tmp2, 0);
__ bne(CCR0, skip_barrier);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -326,7 +326,7 @@ void BarrierSetAssembler::c2i_entry_barrier(MacroAssembler* masm) {
__ load_method_holder_cld(t0, xmethod);
// Is it a strong CLD?
__ lwu(t1, Address(t0, ClassLoaderData::keep_alive_offset()));
__ lwu(t1, Address(t0, ClassLoaderData::keep_alive_ref_count_offset()));
__ bnez(t1, method_live);
// Is it a weak but alive CLD?

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2024, 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
@ -423,7 +423,7 @@ void BarrierSetAssembler::c2i_entry_barrier(MacroAssembler* masm) {
__ load_method_holder_cld(tmp1, rbx);
// Is it a strong CLD?
__ cmpl(Address(tmp1, ClassLoaderData::keep_alive_offset()), 0);
__ cmpl(Address(tmp1, ClassLoaderData::keep_alive_ref_count_offset()), 0);
__ jcc(Assembler::greater, method_live);
// Is it a weak but alive CLD?

View File

@ -141,7 +141,7 @@ ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool has_class_mirror_ho
// A non-strong hidden class loader data doesn't have anything to keep
// it from being unloaded during parsing of the non-strong hidden class.
// The null-class-loader should always be kept alive.
_keep_alive((has_class_mirror_holder || h_class_loader.is_null()) ? 1 : 0),
_keep_alive_ref_count((has_class_mirror_holder || h_class_loader.is_null()) ? 1 : 0),
_claim(0),
_handles(),
_klasses(nullptr), _packages(nullptr), _modules(nullptr), _unnamed_module(nullptr), _dictionary(nullptr),
@ -345,26 +345,26 @@ void ClassLoaderData::demote_strong_roots() {
// while the class is being parsed, and if the class appears on the module fixup list.
// Due to the uniqueness that no other class shares the hidden class' name or
// ClassLoaderData, no other non-GC thread has knowledge of the hidden class while
// it is being defined, therefore _keep_alive is not volatile or atomic.
void ClassLoaderData::inc_keep_alive() {
// it is being defined, therefore _keep_alive_ref_count is not volatile or atomic.
void ClassLoaderData::inc_keep_alive_ref_count() {
if (has_class_mirror_holder()) {
assert(_keep_alive > 0, "Invalid keep alive increment count");
_keep_alive++;
assert(_keep_alive_ref_count > 0, "Invalid keep alive increment count");
_keep_alive_ref_count++;
}
}
void ClassLoaderData::dec_keep_alive() {
void ClassLoaderData::dec_keep_alive_ref_count() {
if (has_class_mirror_holder()) {
assert(_keep_alive > 0, "Invalid keep alive decrement count");
if (_keep_alive == 1) {
// When the keep_alive counter is 1, the oop handle area is a strong root,
assert(_keep_alive_ref_count > 0, "Invalid keep alive decrement count");
if (_keep_alive_ref_count == 1) {
// When the keep_alive_ref_count counter is 1, the oop handle area is a strong root,
// acting as input to the GC tracing. Such strong roots are part of the
// snapshot-at-the-beginning, and can not just be pulled out from the
// system when concurrent GCs are running at the same time, without
// invoking the right barriers.
demote_strong_roots();
}
_keep_alive--;
_keep_alive_ref_count--;
}
}
@ -680,8 +680,8 @@ oop ClassLoaderData::holder_no_keepalive() const {
// Unloading support
bool ClassLoaderData::is_alive() const {
bool alive = keep_alive() // null class loader and incomplete non-strong hidden class.
|| (_holder.peek() != nullptr); // and not cleaned by the GC weak handle processing.
bool alive = (_keep_alive_ref_count > 0) // null class loader and incomplete non-strong hidden class.
|| (_holder.peek() != nullptr); // and not cleaned by the GC weak handle processing.
return alive;
}
@ -1009,7 +1009,7 @@ void ClassLoaderData::print_on(outputStream* out) const {
out->print_cr(" - unloading %s", _unloading ? "true" : "false");
out->print_cr(" - class mirror holder %s", _has_class_mirror_holder ? "true" : "false");
out->print_cr(" - modified oops %s", _modified_oops ? "true" : "false");
out->print_cr(" - keep alive %d", _keep_alive);
out->print_cr(" - _keep_alive_ref_count %d", _keep_alive_ref_count);
out->print (" - claim ");
switch(_claim) {
case _claim_none: out->print_cr("none"); break;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2024, 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
@ -125,10 +125,10 @@ class ClassLoaderData : public CHeapObj<mtClass> {
// Remembered sets support for the oops in the class loader data.
bool _modified_oops; // Card Table Equivalent
int _keep_alive; // if this CLD is kept alive.
// Used for non-strong hidden classes and the
// boot class loader. _keep_alive does not need to be volatile or
// atomic since there is one unique CLD per non-strong hidden class.
int _keep_alive_ref_count; // if this CLD should not be considered eligible for unloading.
// Used for non-strong hidden classes and the
// boot class loader. _keep_alive_ref_count does not need to be volatile or
// atomic since there is one unique CLD per non-strong hidden class.
volatile int _claim; // non-zero if claimed, for example during GC traces.
// To avoid applying oop closure more than once.
@ -205,12 +205,14 @@ private:
bool has_modified_oops() { return _modified_oops; }
oop holder_no_keepalive() const;
// Resolving the holder keeps this CLD alive for the current GC cycle.
oop holder() const;
void keep_alive() const { (void)holder(); }
void classes_do(void f(Klass* const));
private:
bool keep_alive() const { return _keep_alive > 0; }
int keep_alive_ref_count() const { return _keep_alive_ref_count; }
void loaded_classes_do(KlassClosure* klass_closure);
void classes_do(void f(InstanceKlass*));
@ -302,9 +304,10 @@ private:
return _unloading;
}
// Used to refcount a non-strong hidden class's s CLD in order to indicate their aliveness.
void inc_keep_alive();
void dec_keep_alive();
// Used to refcount a non-strong hidden class's CLD in order to force its aliveness during
// loading, when gc tracing may not find this CLD alive through the holder.
void inc_keep_alive_ref_count();
void dec_keep_alive_ref_count();
void initialize_holder(Handle holder);
@ -335,8 +338,8 @@ private:
bool modules_defined() { return (_modules != nullptr); }
// Offsets
static ByteSize holder_offset() { return byte_offset_of(ClassLoaderData, _holder); }
static ByteSize keep_alive_offset() { return byte_offset_of(ClassLoaderData, _keep_alive); }
static ByteSize holder_offset() { return byte_offset_of(ClassLoaderData, _holder); }
static ByteSize keep_alive_ref_count_offset() { return byte_offset_of(ClassLoaderData, _keep_alive_ref_count); }
// Loaded class dictionary
Dictionary* dictionary() const { return _dictionary; }

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2024, 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
@ -201,7 +201,7 @@ void ClassLoaderDataGraph::cld_do(CLDClosure* cl) {
void ClassLoaderDataGraph::roots_cld_do(CLDClosure* strong, CLDClosure* weak) {
assert_is_safepoint_or_gc();
for (ClassLoaderData* cld = Atomic::load_acquire(&_head); cld != nullptr; cld = cld->next()) {
CLDClosure* closure = cld->keep_alive() ? strong : weak;
CLDClosure* closure = (cld->keep_alive_ref_count() > 0) ? strong : weak;
if (closure != nullptr) {
closure->do_cld(cld);
}
@ -309,8 +309,7 @@ void ClassLoaderDataGraph::modules_do_keepalive(void f(ModuleEntry*)) {
assert_locked_or_safepoint(Module_lock);
ClassLoaderDataGraphIterator iter;
while (ClassLoaderData* cld = iter.get_next()) {
// Keep the holder alive.
(void)cld->holder();
cld->keep_alive();
cld->modules_do(f);
}
}
@ -334,8 +333,7 @@ void ClassLoaderDataGraph::packages_do(void f(PackageEntry*)) {
void ClassLoaderDataGraph::loaded_classes_do_keepalive(KlassClosure* klass_closure) {
ClassLoaderDataGraphIterator iter;
while (ClassLoaderData* cld = iter.get_next()) {
// Keep the holder alive.
(void)cld->holder();
cld->keep_alive();
cld->loaded_classes_do(klass_closure);
}
}

View File

@ -963,7 +963,7 @@ void java_lang_Class::set_mirror_module_field(JavaThread* current, Klass* k, Han
// Keep list of classes needing java.base module fixup
if (!ModuleEntryTable::javabase_defined()) {
assert(k->java_mirror() != nullptr, "Class's mirror is null");
k->class_loader_data()->inc_keep_alive();
k->class_loader_data()->inc_keep_alive_ref_count();
assert(fixup_module_field_list() != nullptr, "fixup_module_field_list not initialized");
fixup_module_field_list()->push(k);
} else {

View File

@ -705,7 +705,7 @@ void ModuleEntryTable::patch_javabase_entries(JavaThread* current, Handle module
{
java_lang_Class::fixup_module_field(k, module_handle);
}
k->class_loader_data()->dec_keep_alive();
k->class_loader_data()->dec_keep_alive_ref_count();
}
delete java_lang_Class::fixup_module_field_list();

View File

@ -1032,7 +1032,7 @@ static jclass jvm_lookup_define_class(jclass lookup, const char *name,
// The hidden class loader data has been artificially been kept alive to
// this point. The mirror and any instances of this class have to keep
// it alive afterwards.
ik->class_loader_data()->dec_keep_alive();
ik->class_loader_data()->dec_keep_alive_ref_count();
if (is_nestmate && log_is_enabled(Debug, class, nestmates)) {
ModuleEntry* module = ik->module();