7006113: G1: Initialize ReferenceProcessor::_is_alive_non_header field
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
This commit is contained in:
parent
771994b0dc
commit
b2fa4708ad
@ -1825,23 +1825,11 @@ void ConcurrentMark::completeCleanup() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool G1CMIsAliveClosure::do_object_b(oop obj) {
|
||||||
class G1CMIsAliveClosure: public BoolObjectClosure {
|
HeapWord* addr = (HeapWord*)obj;
|
||||||
G1CollectedHeap* _g1;
|
return addr != NULL &&
|
||||||
public:
|
(!_g1->is_in_g1_reserved(addr) || !_g1->is_obj_ill(obj));
|
||||||
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));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class G1CMKeepAliveClosure: public OopClosure {
|
class G1CMKeepAliveClosure: public OopClosure {
|
||||||
G1CollectedHeap* _g1;
|
G1CollectedHeap* _g1;
|
||||||
@ -1896,16 +1884,15 @@ void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) {
|
|||||||
rp->setup_policy(clear_all_soft_refs);
|
rp->setup_policy(clear_all_soft_refs);
|
||||||
assert(_markStack.isEmpty(), "mark stack should be empty");
|
assert(_markStack.isEmpty(), "mark stack should be empty");
|
||||||
|
|
||||||
G1CMIsAliveClosure g1IsAliveClosure (g1h);
|
G1CMIsAliveClosure g1_is_alive(g1h);
|
||||||
G1CMKeepAliveClosure g1KeepAliveClosure(g1h, this, nextMarkBitMap());
|
G1CMKeepAliveClosure g1_keep_alive(g1h, this, nextMarkBitMap());
|
||||||
G1CMDrainMarkingStackClosure
|
G1CMDrainMarkingStackClosure
|
||||||
g1DrainMarkingStackClosure(nextMarkBitMap(), &_markStack,
|
g1_drain_mark_stack(nextMarkBitMap(), &_markStack, &g1_keep_alive);
|
||||||
&g1KeepAliveClosure);
|
|
||||||
|
|
||||||
// XXXYYY Also: copy the parallel ref processing code from CMS.
|
// XXXYYY Also: copy the parallel ref processing code from CMS.
|
||||||
rp->process_discovered_references(&g1IsAliveClosure,
|
rp->process_discovered_references(&g1_is_alive,
|
||||||
&g1KeepAliveClosure,
|
&g1_keep_alive,
|
||||||
&g1DrainMarkingStackClosure,
|
&g1_drain_mark_stack,
|
||||||
NULL);
|
NULL);
|
||||||
assert(_markStack.overflow() || _markStack.isEmpty(),
|
assert(_markStack.overflow() || _markStack.isEmpty(),
|
||||||
"mark stack should be empty (unless it overflowed)");
|
"mark stack should be empty (unless it overflowed)");
|
||||||
@ -1918,8 +1905,8 @@ void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) {
|
|||||||
assert(!rp->discovery_enabled(), "should have been disabled");
|
assert(!rp->discovery_enabled(), "should have been disabled");
|
||||||
|
|
||||||
// Now clean up stale oops in SymbolTable and StringTable
|
// Now clean up stale oops in SymbolTable and StringTable
|
||||||
SymbolTable::unlink(&g1IsAliveClosure);
|
SymbolTable::unlink(&g1_is_alive);
|
||||||
StringTable::unlink(&g1IsAliveClosure);
|
StringTable::unlink(&g1_is_alive);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConcurrentMark::swapMarkBitMaps() {
|
void ConcurrentMark::swapMarkBitMaps() {
|
||||||
|
@ -33,6 +33,25 @@ class CMTask;
|
|||||||
typedef GenericTaskQueue<oop> CMTaskQueue;
|
typedef GenericTaskQueue<oop> CMTaskQueue;
|
||||||
typedef GenericTaskQueueSet<CMTaskQueue> CMTaskQueueSet;
|
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
|
// A generic CM bit map. This is essentially a wrapper around the BitMap
|
||||||
// class, with one bit per (1<<_shifter) HeapWords.
|
// class, with one bit per (1<<_shifter) HeapWords.
|
||||||
|
|
||||||
|
@ -1768,6 +1768,7 @@ G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) :
|
|||||||
_g1_policy(policy_),
|
_g1_policy(policy_),
|
||||||
_dirty_card_queue_set(false),
|
_dirty_card_queue_set(false),
|
||||||
_into_cset_dirty_card_queue_set(false),
|
_into_cset_dirty_card_queue_set(false),
|
||||||
|
_is_alive_closure(this),
|
||||||
_ref_processor(NULL),
|
_ref_processor(NULL),
|
||||||
_process_strong_tasks(new SubTasksDone(G1H_PS_NumElements)),
|
_process_strong_tasks(new SubTasksDone(G1H_PS_NumElements)),
|
||||||
_bot_shared(NULL),
|
_bot_shared(NULL),
|
||||||
@ -2061,7 +2062,8 @@ void G1CollectedHeap::ref_processing_init() {
|
|||||||
mr, // span
|
mr, // span
|
||||||
false, // Reference discovery is not atomic
|
false, // Reference discovery is not atomic
|
||||||
true, // mt_discovery
|
true, // mt_discovery
|
||||||
NULL, // is alive closure: need to fill this in for efficiency
|
&_is_alive_closure, // is alive closure
|
||||||
|
// for efficiency
|
||||||
ParallelGCThreads,
|
ParallelGCThreads,
|
||||||
ParallelRefProcEnabled,
|
ParallelRefProcEnabled,
|
||||||
true); // Setting next fields of discovered
|
true); // Setting next fields of discovered
|
||||||
|
@ -849,6 +849,12 @@ protected:
|
|||||||
void print_gc_alloc_regions();
|
void print_gc_alloc_regions();
|
||||||
#endif // !PRODUCT
|
#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
|
// ("Weak") Reference processing support
|
||||||
ReferenceProcessor* _ref_processor;
|
ReferenceProcessor* _ref_processor;
|
||||||
|
|
||||||
@ -893,7 +899,7 @@ public:
|
|||||||
// specified by the policy object.
|
// specified by the policy object.
|
||||||
jint initialize();
|
jint initialize();
|
||||||
|
|
||||||
void ref_processing_init();
|
virtual void ref_processing_init();
|
||||||
|
|
||||||
void set_par_threads(int t) {
|
void set_par_threads(int t) {
|
||||||
SharedHeap::set_par_threads(t);
|
SharedHeap::set_par_threads(t);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user