Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/hotspot/share/ci/ciInstanceKlass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ ciInstanceKlass::ciInstanceKlass(Klass* k) :
// by the GC but need to be strong roots if reachable from a current compilation.
// InstanceKlass are created for both weak and strong metadata. Ensuring this metadata
// alive covers the cases where there are weak roots without performance cost.
oop holder = ik->holder_phantom();
oop holder = ik->klass_holder();
if (ik->is_anonymous()) {
// Though ciInstanceKlass records class loader oop, it's not enough to keep
// VM anonymous classes alive (loader == NULL). Klass holder should be used instead.
Expand Down
9 changes: 9 additions & 0 deletions src/hotspot/share/classfile/classLoaderData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,15 @@ oop ClassLoaderData::holder_phantom() const {
}
}

// Let the GC read the holder without keeping it alive.
oop ClassLoaderData::holder_no_keepalive() const {
if (!_holder.is_null()) { // NULL class_loader
return _holder.peek();
} else {
return NULL;
}
}

// Unloading support
bool ClassLoaderData::is_alive() const {
bool alive = keep_alive() // null class loader and incomplete anonymous klasses.
Expand Down
5 changes: 3 additions & 2 deletions src/hotspot/share/classfile/classLoaderData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,12 +287,13 @@ class ClassLoaderData : public CHeapObj<mtClass> {
void accumulate_modified_oops() { if (has_modified_oops()) _accumulated_modified_oops = true; }
void clear_accumulated_modified_oops() { _accumulated_modified_oops = false; }
bool has_accumulated_modified_oops() { return _accumulated_modified_oops; }
private:
oop holder_no_keepalive() const;
oop holder_phantom() const;

private:
void unload();
bool keep_alive() const { return _keep_alive > 0; }

oop holder_phantom() const;
void classes_do(void f(Klass* const));
void loaded_classes_do(KlassClosure* klass_closure);
void classes_do(void f(InstanceKlass*));
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/classfile/classLoaderData.inline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

inline oop ClassLoaderData::class_loader() const {
assert(!_unloading, "This oop is not available to unloading class loader data");
assert(_holder.is_null() || _holder.peek() != NULL , "This class loader data holder must be alive");
assert(_holder.is_null() || holder_no_keepalive() != NULL , "This class loader data holder must be alive");
return _class_loader.resolve();
}

Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ void G1FullGCMarker::drain_stack() {
}

inline void G1FullGCMarker::follow_klass(Klass* k) {
oop op = k->klass_holder();
oop op = k->class_loader_data()->holder_no_keepalive();
mark_and_push(&op);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ inline void ParCompactionManager::MarkAndPushClosure::do_oop(oop* p) { do_
inline void ParCompactionManager::MarkAndPushClosure::do_oop(narrowOop* p) { do_oop_work(p); }

inline void ParCompactionManager::follow_klass(Klass* klass) {
oop holder = klass->klass_holder();
oop holder = klass->class_loader_data()->holder_no_keepalive();
mark_and_push(&holder);
}

Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/gc/serial/markSweep.inline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ template <class T> inline void MarkSweep::mark_and_push(T* p) {
}

inline void MarkSweep::follow_klass(Klass* klass) {
oop op = klass->klass_holder();
oop op = klass->class_loader_data()->holder_no_keepalive();
MarkSweep::mark_and_push(&op);
}

Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@ JVMCIKlassHandle::JVMCIKlassHandle(Thread* thread, Klass* klass) {
_thread = thread;
_klass = klass;
if (klass != NULL) {
_holder = Handle(_thread, klass->holder_phantom());
_holder = Handle(_thread, klass->klass_holder());
}
}

JVMCIKlassHandle& JVMCIKlassHandle::operator=(Klass* klass) {
_klass = klass;
if (klass != NULL) {
_holder = Handle(_thread, klass->holder_phantom());
_holder = Handle(_thread, klass->klass_holder());
}
return *this;
}
Expand Down
6 changes: 0 additions & 6 deletions src/hotspot/share/oops/instanceKlass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -680,12 +680,6 @@ class InstanceKlass: public Klass {
}
}

// Oop that keeps the metadata for this class from being unloaded
// in places where the metadata is stored in other places, like nmethods
oop klass_holder() const {
return is_anonymous() ? java_mirror() : class_loader();
}

bool is_contended() const {
return (_misc_flags & _misc_is_contended) != 0;
}
Expand Down
4 changes: 0 additions & 4 deletions src/hotspot/share/oops/klass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,10 +393,6 @@ void Klass::append_to_sibling_list() {
debug_only(verify();)
}

oop Klass::holder_phantom() const {
return class_loader_data()->holder_phantom();
}

void Klass::clean_weak_klass_links(bool unloading_occurred, bool clean_alive_klasses) {
if (!ClassUnloading || !unloading_occurred) {
return;
Expand Down
11 changes: 5 additions & 6 deletions src/hotspot/share/oops/klass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,11 @@ class Klass : public Metadata {

oop class_loader() const;

virtual oop klass_holder() const { return class_loader(); }
// This loads 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
// be used safely. All uses of klass_holder need to apply the appropriate barriers,
// except during GC.
oop klass_holder() const { return class_loader_data()->holder_phantom(); }

protected:
virtual Klass* array_klass_impl(bool or_null, int rank, TRAPS);
Expand Down Expand Up @@ -657,11 +661,6 @@ class Klass : public Metadata {
// Klass is considered alive. Has already been marked as unloading.
bool is_loader_alive() const { return !class_loader_data()->is_unloading(); }

// 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
// be used safely.
oop holder_phantom() const;

static void clean_weak_klass_links(bool unloading_occurred, bool clean_alive_klasses = true);
static void clean_subklass_tree() {
clean_weak_klass_links(/*unloading_occurred*/ true , /* clean_alive_klasses */ false);
Expand Down