diff src/share/vm/oops/instanceMirrorKlass.cpp @ 13438:ad72068ac41e

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
author sjohanss
date Tue, 10 Dec 2013 10:31:00 +0100
parents 55a0da3d420b
children de6a9e811145
line wrap: on
line diff
--- a/src/share/vm/oops/instanceMirrorKlass.cpp	Mon Dec 09 08:20:45 2013 +0100
+++ b/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),                                     \