changeset 2057:b03260081e9b

7006113: G1: Initialize ReferenceProcessor::_is_alive_non_header field Summary: Initialize the _is_alive_non_header field of G1's reference processor with an instance of the G1CMIsAliveClosure. This will stop adding reference objects with live referents to the discovered reference lists unnecessarily. Reviewed-by: tonyp, ysr, jwilhelm, brutisso
author johnc
date Fri, 17 Dec 2010 11:26:53 -0800
parents 36eef023306f
children 74ee0db180fa
files src/share/vm/gc_implementation/g1/concurrentMark.cpp src/share/vm/gc_implementation/g1/concurrentMark.hpp src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
diffstat 4 files changed, 42 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Thu Dec 16 09:14:34 2010 -0800
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Fri Dec 17 11:26:53 2010 -0800
@@ -1825,23 +1825,11 @@
   }
 }
 
-
-class G1CMIsAliveClosure: public BoolObjectClosure {
-  G1CollectedHeap* _g1;
- public:
-  G1CMIsAliveClosure(G1CollectedHeap* g1) :
-    _g1(g1)
-  {}
-
-  void do_object(oop obj) {
-    assert(false, "not to be invoked");
-  }
-  bool do_object_b(oop obj) {
-    HeapWord* addr = (HeapWord*)obj;
-    return addr != NULL &&
-           (!_g1->is_in_g1_reserved(addr) || !_g1->is_obj_ill(obj));
-  }
-};
+bool G1CMIsAliveClosure::do_object_b(oop obj) {
+  HeapWord* addr = (HeapWord*)obj;
+  return addr != NULL &&
+         (!_g1->is_in_g1_reserved(addr) || !_g1->is_obj_ill(obj));
+}
 
 class G1CMKeepAliveClosure: public OopClosure {
   G1CollectedHeap* _g1;
@@ -1896,16 +1884,15 @@
   rp->setup_policy(clear_all_soft_refs);
   assert(_markStack.isEmpty(), "mark stack should be empty");
 
-  G1CMIsAliveClosure   g1IsAliveClosure  (g1h);
-  G1CMKeepAliveClosure g1KeepAliveClosure(g1h, this, nextMarkBitMap());
+  G1CMIsAliveClosure   g1_is_alive(g1h);
+  G1CMKeepAliveClosure g1_keep_alive(g1h, this, nextMarkBitMap());
   G1CMDrainMarkingStackClosure
-    g1DrainMarkingStackClosure(nextMarkBitMap(), &_markStack,
-                               &g1KeepAliveClosure);
+    g1_drain_mark_stack(nextMarkBitMap(), &_markStack, &g1_keep_alive);
 
   // XXXYYY  Also: copy the parallel ref processing code from CMS.
-  rp->process_discovered_references(&g1IsAliveClosure,
-                                    &g1KeepAliveClosure,
-                                    &g1DrainMarkingStackClosure,
+  rp->process_discovered_references(&g1_is_alive,
+                                    &g1_keep_alive,
+                                    &g1_drain_mark_stack,
                                     NULL);
   assert(_markStack.overflow() || _markStack.isEmpty(),
          "mark stack should be empty (unless it overflowed)");
@@ -1918,8 +1905,8 @@
   assert(!rp->discovery_enabled(), "should have been disabled");
 
   // Now clean up stale oops in SymbolTable and StringTable
-  SymbolTable::unlink(&g1IsAliveClosure);
-  StringTable::unlink(&g1IsAliveClosure);
+  SymbolTable::unlink(&g1_is_alive);
+  StringTable::unlink(&g1_is_alive);
 }
 
 void ConcurrentMark::swapMarkBitMaps() {
--- a/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Thu Dec 16 09:14:34 2010 -0800
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Fri Dec 17 11:26:53 2010 -0800
@@ -33,6 +33,25 @@
 typedef GenericTaskQueue<oop>            CMTaskQueue;
 typedef GenericTaskQueueSet<CMTaskQueue> CMTaskQueueSet;
 
+// Closure used by CM during concurrent reference discovery
+// and reference processing (during remarking) to determine
+// if a particular object is alive. It is primarily used
+// to determine if referents of discovered reference objects
+// are alive. An instance is also embedded into the
+// reference processor as the _is_alive_non_header field
+class G1CMIsAliveClosure: public BoolObjectClosure {
+  G1CollectedHeap* _g1;
+ public:
+  G1CMIsAliveClosure(G1CollectedHeap* g1) :
+    _g1(g1)
+  {}
+
+  void do_object(oop obj) {
+    ShouldNotCallThis();
+  }
+  bool do_object_b(oop obj);
+};
+
 // A generic CM bit map.  This is essentially a wrapper around the BitMap
 // class, with one bit per (1<<_shifter) HeapWords.
 
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Thu Dec 16 09:14:34 2010 -0800
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Fri Dec 17 11:26:53 2010 -0800
@@ -1768,6 +1768,7 @@
   _g1_policy(policy_),
   _dirty_card_queue_set(false),
   _into_cset_dirty_card_queue_set(false),
+  _is_alive_closure(this),
   _ref_processor(NULL),
   _process_strong_tasks(new SubTasksDone(G1H_PS_NumElements)),
   _bot_shared(NULL),
@@ -2061,7 +2062,8 @@
                                          mr,    // span
                                          false, // Reference discovery is not atomic
                                          true,  // mt_discovery
-                                         NULL,  // is alive closure: need to fill this in for efficiency
+                                         &_is_alive_closure, // is alive closure
+                                                             // for efficiency
                                          ParallelGCThreads,
                                          ParallelRefProcEnabled,
                                          true); // Setting next fields of discovered
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Thu Dec 16 09:14:34 2010 -0800
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Fri Dec 17 11:26:53 2010 -0800
@@ -849,6 +849,12 @@
   void print_gc_alloc_regions();
 #endif // !PRODUCT
 
+  // Instance of the concurrent mark is_alive closure for embedding
+  // into the reference processor as the is_alive_non_header. This
+  // prevents unnecessary additions to the discovered lists during
+  // concurrent discovery.
+  G1CMIsAliveClosure _is_alive_closure;
+
   // ("Weak") Reference processing support
   ReferenceProcessor* _ref_processor;
 
@@ -893,7 +899,7 @@
   // specified by the policy object.
   jint initialize();
 
-  void ref_processing_init();
+  virtual void ref_processing_init();
 
   void set_par_threads(int t) {
     SharedHeap::set_par_threads(t);