# HG changeset patch # User eosterlund # Date 1536577662 -7200 # Node ID 72bdaf11dd6a8b1c607fee09b39a4293cdb0a65a # Parent d058b410af0a24fd043b2abfed045363c5c28bc1 8210233: Prepare Klass::is_loader_alive() for concurrent class unloading Reviewed-by: coleenp, pliden diff -r d058b410af0a -r 72bdaf11dd6a src/hotspot/share/classfile/classLoaderData.hpp --- a/src/hotspot/share/classfile/classLoaderData.hpp Mon Sep 10 11:24:26 2018 +0200 +++ b/src/hotspot/share/classfile/classLoaderData.hpp Mon Sep 10 13:07:42 2018 +0200 @@ -336,6 +336,8 @@ bool claimed() const { return _claimed == 1; } bool claim(); + // Computes if the CLD is alive or not. This is safe to call in concurrent + // contexts. bool is_alive() const; // Accessors @@ -377,6 +379,9 @@ inline oop class_loader() const; // Returns true if this class loader data is for a loader going away. + // Note that this is only safe after the GC has computed if the CLD is + // unloading or not. In concurrent contexts where there are no such + // guarantees, is_alive() should be used instead. bool is_unloading() const { assert(!(is_the_null_class_loader_data() && _unloading), "The null class loader can never be unloaded"); return _unloading; diff -r d058b410af0a -r 72bdaf11dd6a src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp --- a/src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp Mon Sep 10 11:24:26 2018 +0200 +++ b/src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp Mon Sep 10 13:07:42 2018 +0200 @@ -470,7 +470,7 @@ void do_cld (ClassLoaderData* cld) { // We do not display unloading loaders, for now. - if (cld->is_unloading()) { + if (!cld->is_alive()) { return; } diff -r d058b410af0a -r 72bdaf11dd6a src/hotspot/share/oops/klass.hpp --- a/src/hotspot/share/oops/klass.hpp Mon Sep 10 11:24:26 2018 +0200 +++ b/src/hotspot/share/oops/klass.hpp Mon Sep 10 13:07:42 2018 +0200 @@ -656,8 +656,9 @@ virtual MetaspaceObj::Type type() const { return ClassType; } // Iff the class loader (or mirror for unsafe anonymous classes) is alive the - // Klass is considered alive. Has already been marked as unloading. - bool is_loader_alive() const { return !class_loader_data()->is_unloading(); } + // Klass is considered alive. This is safe to call before the CLD is marked as + // unloading, and hence during concurrent class unloading. + bool is_loader_alive() const { return class_loader_data()->is_alive(); } // Load the klass's holder as a phantom. This is useful when a weak Klass // pointer has been "peeked" and then must be kept alive before it may