# HG changeset patch # User johnc # Date 1292614013 28800 # Node ID b03260081e9bae5a109752871b338b37daa69bb5 # Parent 36eef023306ffbe5ababf11e091eebb6a1509804 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 diff -r 36eef023306f -r b03260081e9b src/share/vm/gc_implementation/g1/concurrentMark.cpp --- 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() { diff -r 36eef023306f -r b03260081e9b src/share/vm/gc_implementation/g1/concurrentMark.hpp --- 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 CMTaskQueue; typedef GenericTaskQueueSet 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. diff -r 36eef023306f -r b03260081e9b src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- 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 diff -r 36eef023306f -r b03260081e9b src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp --- 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);