mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-09 21:19:38 +00:00
8335059: Consider renaming ClassLoaderData::keep_alive
Reviewed-by: dholmes, stefank
This commit is contained in:
parent
a89b525189
commit
328a0533b2
@ -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?
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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?
|
||||
|
||||
@ -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?
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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; }
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user