Tue, 26 Nov 2013 14:35:38 +0100
8027675: Full collections with Serial slower in JDK 8 compared to 7u40
Summary: Reduced the number of calls to follow_class_loader and instead marked and pushed the klass holder directly. Also removed unneeded calls to adjust_klass.
Reviewed-by: coleenp, jmasa, mgerdin, tschatzl
1.1 --- a/src/share/vm/gc_implementation/shared/markSweep.cpp Fri Nov 22 13:42:46 2013 -0800 1.2 +++ b/src/share/vm/gc_implementation/shared/markSweep.cpp Tue Nov 26 14:35:38 2013 +0100 1.3 @@ -66,29 +66,10 @@ 1.4 klass->oops_do(&MarkSweep::adjust_pointer_closure); 1.5 } 1.6 1.7 -void MarkSweep::follow_klass(Klass* klass) { 1.8 - ClassLoaderData* cld = klass->class_loader_data(); 1.9 - // The actual processing of the klass is done when we 1.10 - // traverse the list of Klasses in the class loader data. 1.11 - MarkSweep::follow_class_loader(cld); 1.12 -} 1.13 - 1.14 -void MarkSweep::adjust_klass(Klass* klass) { 1.15 - ClassLoaderData* cld = klass->class_loader_data(); 1.16 - // The actual processing of the klass is done when we 1.17 - // traverse the list of Klasses in the class loader data. 1.18 - MarkSweep::adjust_class_loader(cld); 1.19 -} 1.20 - 1.21 void MarkSweep::follow_class_loader(ClassLoaderData* cld) { 1.22 cld->oops_do(&MarkSweep::mark_and_push_closure, &MarkSweep::follow_klass_closure, true); 1.23 } 1.24 1.25 -void MarkSweep::adjust_class_loader(ClassLoaderData* cld) { 1.26 - cld->oops_do(&MarkSweep::adjust_pointer_closure, &MarkSweep::adjust_klass_closure, true); 1.27 -} 1.28 - 1.29 - 1.30 void MarkSweep::follow_stack() { 1.31 do { 1.32 while (!_marking_stack.is_empty()) {
2.1 --- a/src/share/vm/gc_implementation/shared/markSweep.hpp Fri Nov 22 13:42:46 2013 -0800 2.2 +++ b/src/share/vm/gc_implementation/shared/markSweep.hpp Tue Nov 26 14:35:38 2013 +0100 2.3 @@ -172,10 +172,8 @@ 2.4 static void follow_stack(); // Empty marking stack. 2.5 2.6 static void follow_klass(Klass* klass); 2.7 - static void adjust_klass(Klass* klass); 2.8 2.9 static void follow_class_loader(ClassLoaderData* cld); 2.10 - static void adjust_class_loader(ClassLoaderData* cld); 2.11 2.12 static void preserve_mark(oop p, markOop mark); 2.13 // Save the mark word so it can be restored later
3.1 --- a/src/share/vm/gc_implementation/shared/markSweep.inline.hpp Fri Nov 22 13:42:46 2013 -0800 3.2 +++ b/src/share/vm/gc_implementation/shared/markSweep.inline.hpp Tue Nov 26 14:35:38 2013 +0100 3.3 @@ -44,6 +44,11 @@ 3.4 } 3.5 } 3.6 3.7 +inline void MarkSweep::follow_klass(Klass* klass) { 3.8 + oop op = klass->klass_holder(); 3.9 + MarkSweep::mark_and_push(&op); 3.10 +} 3.11 + 3.12 template <class T> inline void MarkSweep::follow_root(T* p) { 3.13 assert(!Universe::heap()->is_in_reserved(p), 3.14 "roots shouldn't be things within the heap");
4.1 --- a/src/share/vm/oops/instanceKlass.cpp Fri Nov 22 13:42:46 2013 -0800 4.2 +++ b/src/share/vm/oops/instanceKlass.cpp Tue Nov 26 14:35:38 2013 +0100 4.3 @@ -2157,7 +2157,6 @@ 4.4 obj, \ 4.5 MarkSweep::adjust_pointer(p), \ 4.6 assert_is_in) 4.7 - MarkSweep::adjust_klass(obj->klass()); 4.8 return size; 4.9 } 4.10
5.1 --- a/src/share/vm/oops/instanceMirrorKlass.cpp Fri Nov 22 13:42:46 2013 -0800 5.2 +++ b/src/share/vm/oops/instanceMirrorKlass.cpp Tue Nov 26 14:35:38 2013 +0100 5.3 @@ -155,7 +155,13 @@ 5.4 // Follow the klass field in the mirror. 5.5 Klass* klass = java_lang_Class::as_Klass(obj); 5.6 if (klass != NULL) { 5.7 - MarkSweep::follow_klass(klass); 5.8 + // For anonymous classes we need to handle the class loader data, 5.9 + // otherwise it won't be claimed and can be unloaded. 5.10 + if (klass->oop_is_instance() && InstanceKlass::cast(klass)->is_anonymous()) { 5.11 + MarkSweep::follow_class_loader(klass->class_loader_data()); 5.12 + } else { 5.13 + MarkSweep::follow_klass(klass); 5.14 + } 5.15 } else { 5.16 // If klass is NULL then this a mirror for a primitive type. 5.17 // We don't have to follow them, since they are handled as strong 5.18 @@ -196,17 +202,6 @@ 5.19 int size = oop_size(obj); 5.20 InstanceKlass::oop_adjust_pointers(obj); 5.21 5.22 - // Follow the klass field in the mirror. 5.23 - Klass* klass = java_lang_Class::as_Klass(obj); 5.24 - if (klass != NULL) { 5.25 - MarkSweep::adjust_klass(klass); 5.26 - } else { 5.27 - // If klass is NULL then this a mirror for a primitive type. 5.28 - // We don't have to follow them, since they are handled as strong 5.29 - // roots in Universe::oops_do. 5.30 - assert(java_lang_Class::is_primitive(obj), "Sanity check"); 5.31 - } 5.32 - 5.33 InstanceMirrorKlass_OOP_ITERATE( \ 5.34 start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \ 5.35 MarkSweep::adjust_pointer(p), \
6.1 --- a/src/share/vm/oops/objArrayKlass.cpp Fri Nov 22 13:42:46 2013 -0800 6.2 +++ b/src/share/vm/oops/objArrayKlass.cpp Tue Nov 26 14:35:38 2013 +0100 6.3 @@ -569,7 +569,6 @@ 6.4 // Get size before changing pointers. 6.5 // Don't call size() or oop_size() since that is a virtual call. 6.6 int size = a->object_size(); 6.7 - MarkSweep::adjust_klass(a->klass()); 6.8 ObjArrayKlass_OOP_ITERATE(a, p, MarkSweep::adjust_pointer(p)) 6.9 return size; 6.10 }