Fri, 17 Dec 2010 11:26:53 -0800
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
1.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp Thu Dec 16 09:14:34 2010 -0800 1.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp Fri Dec 17 11:26:53 2010 -0800 1.3 @@ -1825,23 +1825,11 @@ 1.4 } 1.5 } 1.6 1.7 - 1.8 -class G1CMIsAliveClosure: public BoolObjectClosure { 1.9 - G1CollectedHeap* _g1; 1.10 - public: 1.11 - G1CMIsAliveClosure(G1CollectedHeap* g1) : 1.12 - _g1(g1) 1.13 - {} 1.14 - 1.15 - void do_object(oop obj) { 1.16 - assert(false, "not to be invoked"); 1.17 - } 1.18 - bool do_object_b(oop obj) { 1.19 - HeapWord* addr = (HeapWord*)obj; 1.20 - return addr != NULL && 1.21 - (!_g1->is_in_g1_reserved(addr) || !_g1->is_obj_ill(obj)); 1.22 - } 1.23 -}; 1.24 +bool G1CMIsAliveClosure::do_object_b(oop obj) { 1.25 + HeapWord* addr = (HeapWord*)obj; 1.26 + return addr != NULL && 1.27 + (!_g1->is_in_g1_reserved(addr) || !_g1->is_obj_ill(obj)); 1.28 +} 1.29 1.30 class G1CMKeepAliveClosure: public OopClosure { 1.31 G1CollectedHeap* _g1; 1.32 @@ -1896,16 +1884,15 @@ 1.33 rp->setup_policy(clear_all_soft_refs); 1.34 assert(_markStack.isEmpty(), "mark stack should be empty"); 1.35 1.36 - G1CMIsAliveClosure g1IsAliveClosure (g1h); 1.37 - G1CMKeepAliveClosure g1KeepAliveClosure(g1h, this, nextMarkBitMap()); 1.38 + G1CMIsAliveClosure g1_is_alive(g1h); 1.39 + G1CMKeepAliveClosure g1_keep_alive(g1h, this, nextMarkBitMap()); 1.40 G1CMDrainMarkingStackClosure 1.41 - g1DrainMarkingStackClosure(nextMarkBitMap(), &_markStack, 1.42 - &g1KeepAliveClosure); 1.43 + g1_drain_mark_stack(nextMarkBitMap(), &_markStack, &g1_keep_alive); 1.44 1.45 // XXXYYY Also: copy the parallel ref processing code from CMS. 1.46 - rp->process_discovered_references(&g1IsAliveClosure, 1.47 - &g1KeepAliveClosure, 1.48 - &g1DrainMarkingStackClosure, 1.49 + rp->process_discovered_references(&g1_is_alive, 1.50 + &g1_keep_alive, 1.51 + &g1_drain_mark_stack, 1.52 NULL); 1.53 assert(_markStack.overflow() || _markStack.isEmpty(), 1.54 "mark stack should be empty (unless it overflowed)"); 1.55 @@ -1918,8 +1905,8 @@ 1.56 assert(!rp->discovery_enabled(), "should have been disabled"); 1.57 1.58 // Now clean up stale oops in SymbolTable and StringTable 1.59 - SymbolTable::unlink(&g1IsAliveClosure); 1.60 - StringTable::unlink(&g1IsAliveClosure); 1.61 + SymbolTable::unlink(&g1_is_alive); 1.62 + StringTable::unlink(&g1_is_alive); 1.63 } 1.64 1.65 void ConcurrentMark::swapMarkBitMaps() {
2.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.hpp Thu Dec 16 09:14:34 2010 -0800 2.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.hpp Fri Dec 17 11:26:53 2010 -0800 2.3 @@ -33,6 +33,25 @@ 2.4 typedef GenericTaskQueue<oop> CMTaskQueue; 2.5 typedef GenericTaskQueueSet<CMTaskQueue> CMTaskQueueSet; 2.6 2.7 +// Closure used by CM during concurrent reference discovery 2.8 +// and reference processing (during remarking) to determine 2.9 +// if a particular object is alive. It is primarily used 2.10 +// to determine if referents of discovered reference objects 2.11 +// are alive. An instance is also embedded into the 2.12 +// reference processor as the _is_alive_non_header field 2.13 +class G1CMIsAliveClosure: public BoolObjectClosure { 2.14 + G1CollectedHeap* _g1; 2.15 + public: 2.16 + G1CMIsAliveClosure(G1CollectedHeap* g1) : 2.17 + _g1(g1) 2.18 + {} 2.19 + 2.20 + void do_object(oop obj) { 2.21 + ShouldNotCallThis(); 2.22 + } 2.23 + bool do_object_b(oop obj); 2.24 +}; 2.25 + 2.26 // A generic CM bit map. This is essentially a wrapper around the BitMap 2.27 // class, with one bit per (1<<_shifter) HeapWords. 2.28
3.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Dec 16 09:14:34 2010 -0800 3.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Dec 17 11:26:53 2010 -0800 3.3 @@ -1768,6 +1768,7 @@ 3.4 _g1_policy(policy_), 3.5 _dirty_card_queue_set(false), 3.6 _into_cset_dirty_card_queue_set(false), 3.7 + _is_alive_closure(this), 3.8 _ref_processor(NULL), 3.9 _process_strong_tasks(new SubTasksDone(G1H_PS_NumElements)), 3.10 _bot_shared(NULL), 3.11 @@ -2061,7 +2062,8 @@ 3.12 mr, // span 3.13 false, // Reference discovery is not atomic 3.14 true, // mt_discovery 3.15 - NULL, // is alive closure: need to fill this in for efficiency 3.16 + &_is_alive_closure, // is alive closure 3.17 + // for efficiency 3.18 ParallelGCThreads, 3.19 ParallelRefProcEnabled, 3.20 true); // Setting next fields of discovered
4.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Dec 16 09:14:34 2010 -0800 4.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Fri Dec 17 11:26:53 2010 -0800 4.3 @@ -849,6 +849,12 @@ 4.4 void print_gc_alloc_regions(); 4.5 #endif // !PRODUCT 4.6 4.7 + // Instance of the concurrent mark is_alive closure for embedding 4.8 + // into the reference processor as the is_alive_non_header. This 4.9 + // prevents unnecessary additions to the discovered lists during 4.10 + // concurrent discovery. 4.11 + G1CMIsAliveClosure _is_alive_closure; 4.12 + 4.13 // ("Weak") Reference processing support 4.14 ReferenceProcessor* _ref_processor; 4.15 4.16 @@ -893,7 +899,7 @@ 4.17 // specified by the policy object. 4.18 jint initialize(); 4.19 4.20 - void ref_processing_init(); 4.21 + virtual void ref_processing_init(); 4.22 4.23 void set_par_threads(int t) { 4.24 SharedHeap::set_par_threads(t);