7043987: 3/3 JVMTI FollowReferences is slow
authordcubed
Thu, 23 Jun 2011 20:31:43 -0700
changeset 10228 e5e1539de725
parent 10227 6582884d0484
child 10229 7b358d5def21
7043987: 3/3 JVMTI FollowReferences is slow Summary: VM_HeapWalkOperation::doit() should only reset mark bits when necessary. Reviewed-by: dsamersoff, ysr, dholmes, dcubed Contributed-by: ashok.srinivasa.murthy@oracle.com
hotspot/src/share/vm/prims/jvmtiTagMap.cpp
--- a/hotspot/src/share/vm/prims/jvmtiTagMap.cpp	Sat Jun 18 13:32:27 2011 +0400
+++ b/hotspot/src/share/vm/prims/jvmtiTagMap.cpp	Thu Jun 23 20:31:43 2011 -0700
@@ -1647,6 +1647,7 @@
   // saved headers
   static GrowableArray<oop>* _saved_oop_stack;
   static GrowableArray<markOop>* _saved_mark_stack;
+  static bool _needs_reset;                  // do we need to reset mark bits?
 
  public:
   static void init();                       // initialize
@@ -1654,10 +1655,14 @@
 
   static inline void mark(oop o);           // mark an object
   static inline bool visited(oop o);        // check if object has been visited
+
+  static inline bool needs_reset()            { return _needs_reset; }
+  static inline void set_needs_reset(bool v)  { _needs_reset = v; }
 };
 
 GrowableArray<oop>* ObjectMarker::_saved_oop_stack = NULL;
 GrowableArray<markOop>* ObjectMarker::_saved_mark_stack = NULL;
+bool ObjectMarker::_needs_reset = true;  // need to reset mark bits by default
 
 // initialize ObjectMarker - prepares for object marking
 void ObjectMarker::init() {
@@ -1680,7 +1685,13 @@
   // iterate over all objects and restore the mark bits to
   // their initial value
   RestoreMarksClosure blk;
-  Universe::heap()->object_iterate(&blk);
+  if (needs_reset()) {
+    Universe::heap()->object_iterate(&blk);
+  } else {
+    // We don't need to reset mark bits on this call, but reset the
+    // flag to the default for the next call.
+    set_needs_reset(true);
+  }
 
   // When sharing is enabled we need to restore the headers of the objects
   // in the readwrite space too.
@@ -3235,8 +3246,16 @@
 
   // the heap walk starts with an initial object or the heap roots
   if (initial_object().is_null()) {
+    // If either collect_stack_roots() or collect_simple_roots()
+    // returns false at this point, then there are no mark bits
+    // to reset.
+    ObjectMarker::set_needs_reset(false);
+
     if (!collect_simple_roots()) return;
     if (!collect_stack_roots()) return;
+
+    // no early return so enable heap traversal to reset the mark bits
+    ObjectMarker::set_needs_reset(true);
   } else {
     visit_stack()->push(initial_object()());
   }