8028993: Full collections with ParallelScavenge slower in JDK 8 compared to 7u40
Summary: Reducing the number of calls to follow_class_loader to speed up the marking phase. Also removed some unnecessary calls to adjust_klass.
Reviewed-by: stefank, jmasa, mgerdin
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Mon Dec 09 08:20:45 2013 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Tue Dec 10 10:31:00 2013 +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:
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp Mon Dec 09 08:20:45 2013 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp Tue Dec 10 10:31:00 2013 +0100
@@ -1200,13 +1200,10 @@
T* p);
template <class T> 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 <class T>
inline void PSParallelCompact::KeepAliveClosure::do_oop_work(T* p) {
mark_and_push(_compaction_manager, p);
--- a/hotspot/src/share/vm/oops/instanceClassLoaderKlass.cpp Mon Dec 09 08:20:45 2013 +0100
+++ b/hotspot/src/share/vm/oops/instanceClassLoaderKlass.cpp Tue Dec 10 10:31:00 2013 +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
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Mon Dec 09 08:20:45 2013 +0100
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Tue Dec 10 10:31:00 2013 +0100
@@ -2199,7 +2199,6 @@
obj, \
PSParallelCompact::adjust_pointer(p), \
assert_is_in)
- obj->update_header(cm);
return size;
}
--- a/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp Mon Dec 09 08:20:45 2013 +0100
+++ b/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp Tue Dec 10 10:31:00 2013 +0100
@@ -155,8 +155,13 @@
// Follow the klass field in the mirror.
Klass* klass = java_lang_Class::as_Klass(obj);
if (klass != NULL) {
- // For anonymous classes we need to handle the class loader data,
- // otherwise it won't be claimed and can be unloaded.
+ // An anonymous class doesn't have its own class loader, so the call
+ // to follow_klass will mark and push its java mirror instead of the
+ // class loader. When handling the java mirror for an anonymous class
+ // we need to make sure its class loader data is claimed, this is done
+ // by calling follow_class_loader explicitly. For non-anonymous classes
+ // the call to follow_class_loader is made when the class loader itself
+ // is handled.
if (klass->oop_is_instance() && InstanceKlass::cast(klass)->is_anonymous()) {
MarkSweep::follow_class_loader(klass->class_loader_data());
} else {
@@ -183,7 +188,18 @@
// Follow the klass field in the mirror.
Klass* klass = java_lang_Class::as_Klass(obj);
if (klass != NULL) {
- PSParallelCompact::follow_klass(cm, klass);
+ // An anonymous class doesn't have its own class loader, so the call
+ // to follow_klass will mark and push its java mirror instead of the
+ // class loader. When handling the java mirror for an anonymous class
+ // we need to make sure its class loader data is claimed, this is done
+ // by calling follow_class_loader explicitly. For non-anonymous classes
+ // the call to follow_class_loader is made when the class loader itself
+ // is handled.
+ 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 +348,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), \
--- a/hotspot/src/share/vm/oops/objArrayKlass.cpp Mon Dec 09 08:20:45 2013 +0100
+++ b/hotspot/src/share/vm/oops/objArrayKlass.cpp Tue Dec 10 10:31:00 2013 +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;
}
--- a/hotspot/src/share/vm/oops/oop.hpp Mon Dec 09 08:20:45 2013 +0100
+++ b/hotspot/src/share/vm/oops/oop.hpp Tue Dec 10 10:31:00 2013 +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);
--- a/hotspot/src/share/vm/oops/oop.pcgc.inline.hpp Mon Dec 09 08:20:45 2013 +0100
+++ b/hotspot/src/share/vm/oops/oop.pcgc.inline.hpp Tue Dec 10 10:31:00 2013 +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