--- old/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp 2013-12-09 10:11:59.951607095 +0100 +++ new/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp 2013-12-09 10:11:59.863607738 +0100 @@ -2433,20 +2433,6 @@ _gc_tracer.report_object_count_after_gc(is_alive_closure()); } -void PSParallelCompact::follow_klass(ParCompactionManager* cm, Klass* klass) { - ClassLoaderData* cld = klass->class_loader_data(); - // The actual processing of the klass is done when we - // traverse the list of Klasses in the class loader data. - PSParallelCompact::follow_class_loader(cm, cld); -} - -void PSParallelCompact::adjust_klass(ParCompactionManager* cm, Klass* klass) { - ClassLoaderData* cld = klass->class_loader_data(); - // The actual processing of the klass is done when we - // traverse the list of Klasses in the class loader data. - PSParallelCompact::adjust_class_loader(cm, cld); -} - void PSParallelCompact::follow_class_loader(ParCompactionManager* cm, ClassLoaderData* cld) { PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm); @@ -2455,13 +2441,6 @@ cld->oops_do(&mark_and_push_closure, &follow_klass_closure, true); } -void PSParallelCompact::adjust_class_loader(ParCompactionManager* cm, - ClassLoaderData* cld) { - cld->oops_do(PSParallelCompact::adjust_pointer_closure(), - PSParallelCompact::adjust_klass_closure(), - true); -} - // This should be moved to the shared markSweep code! class PSAlwaysTrueClosure: public BoolObjectClosure { public: --- old/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp 2013-12-09 10:12:00.311604469 +0100 +++ new/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp 2013-12-09 10:12:00.223605112 +0100 @@ -1200,13 +1200,10 @@ T* p); template static inline void adjust_pointer(T* p); - static void follow_klass(ParCompactionManager* cm, Klass* klass); - static void adjust_klass(ParCompactionManager* cm, Klass* klass); + static inline void follow_klass(ParCompactionManager* cm, Klass* klass); static void follow_class_loader(ParCompactionManager* cm, ClassLoaderData* klass); - static void adjust_class_loader(ParCompactionManager* cm, - ClassLoaderData* klass); // Compaction support. // Return true if p is in the range [beg_addr, end_addr). @@ -1380,6 +1377,11 @@ } } +inline void PSParallelCompact::follow_klass(ParCompactionManager* cm, Klass* klass) { + oop holder = klass->klass_holder(); + PSParallelCompact::mark_and_push(cm, &holder); +} + template inline void PSParallelCompact::KeepAliveClosure::do_oop_work(T* p) { mark_and_push(_compaction_manager, p); --- old/src/share/vm/oops/instanceClassLoaderKlass.cpp 2013-12-09 10:12:00.639602078 +0100 +++ new/src/share/vm/oops/instanceClassLoaderKlass.cpp 2013-12-09 10:12:00.555602690 +0100 @@ -150,10 +150,6 @@ int InstanceClassLoaderKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { InstanceKlass::oop_update_pointers(cm, obj); - ClassLoaderData * const loader_data = java_lang_ClassLoader::loader_data(obj); - if (loader_data != NULL) { - PSParallelCompact::adjust_class_loader(cm, loader_data); - } return size_helper(); } #endif // INCLUDE_ALL_GCS --- old/src/share/vm/oops/instanceKlass.cpp 2013-12-09 10:12:00.959599743 +0100 +++ new/src/share/vm/oops/instanceKlass.cpp 2013-12-09 10:12:00.871600384 +0100 @@ -2176,7 +2176,6 @@ obj, \ PSParallelCompact::adjust_pointer(p), \ assert_is_in) - obj->update_header(cm); return size; } --- old/src/share/vm/oops/instanceMirrorKlass.cpp 2013-12-09 10:12:01.311597176 +0100 +++ new/src/share/vm/oops/instanceMirrorKlass.cpp 2013-12-09 10:12:01.227597787 +0100 @@ -183,7 +183,13 @@ // Follow the klass field in the mirror. Klass* klass = java_lang_Class::as_Klass(obj); if (klass != NULL) { - PSParallelCompact::follow_klass(cm, klass); + // For anonymous classes we need to handle the class loader data, + // otherwise it won't be claimed and can be unloaded. + if (klass->oop_is_instance() && InstanceKlass::cast(klass)->is_anonymous()) { + PSParallelCompact::follow_class_loader(cm, klass->class_loader_data()); + } else { + PSParallelCompact::follow_klass(cm, klass); + } } else { // If klass is NULL then this a mirror for a primitive type. // We don't have to follow them, since they are handled as strong @@ -332,17 +338,6 @@ int size = oop_size(obj); InstanceKlass::oop_update_pointers(cm, obj); - // Follow the klass field in the mirror. - Klass* klass = java_lang_Class::as_Klass(obj); - if (klass != NULL) { - PSParallelCompact::adjust_klass(cm, klass); - } else { - // If klass is NULL then this a mirror for a primitive type. - // We don't have to follow them, since they are handled as strong - // roots in Universe::oops_do. - assert(java_lang_Class::is_primitive(obj), "Sanity check"); - } - InstanceMirrorKlass_OOP_ITERATE( \ start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),\ PSParallelCompact::adjust_pointer(p), \ --- old/src/share/vm/oops/objArrayKlass.cpp 2013-12-09 10:12:01.631594842 +0100 +++ new/src/share/vm/oops/objArrayKlass.cpp 2013-12-09 10:12:01.543595483 +0100 @@ -587,7 +587,6 @@ assert (obj->is_objArray(), "obj must be obj array"); objArrayOop a = objArrayOop(obj); int size = a->object_size(); - a->update_header(cm); ObjArrayKlass_OOP_ITERATE(a, p, PSParallelCompact::adjust_pointer(p)) return size; } --- old/src/share/vm/oops/oop.hpp 2013-12-09 10:12:01.951592507 +0100 +++ new/src/share/vm/oops/oop.hpp 2013-12-09 10:12:01.867593119 +0100 @@ -328,11 +328,6 @@ // return the size of this oop. This is used by the MarkSweep collector. int adjust_pointers(); -#if INCLUDE_ALL_GCS - // Parallel old - void update_header(ParCompactionManager* cm); -#endif // INCLUDE_ALL_GCS - // mark-sweep support void follow_body(int begin, int end); --- old/src/share/vm/oops/oop.pcgc.inline.hpp 2013-12-09 10:12:02.271590173 +0100 +++ new/src/share/vm/oops/oop.pcgc.inline.hpp 2013-12-09 10:12:02.183590815 +0100 @@ -80,8 +80,4 @@ return forwardee(); } -inline void oopDesc::update_header(ParCompactionManager* cm) { - PSParallelCompact::adjust_klass(cm, klass()); -} - #endif // SHARE_VM_OOPS_OOP_PCGC_INLINE_HPP