Mercurial > hg > truffle
diff src/share/vm/gc_implementation/g1/g1RemSet.hpp @ 1960:878b57474103
6978187: G1: assert(ParallelGCThreads> 1 || n_yielded() == _hrrs->occupied()) strikes again
Summary: An evacuation failure while copying the roots caused an object, A, to be forwarded to itself. During the subsequent RSet updating a reference to A was processed causing the reference to be added to the RSet of A's heap region. As a result of adding to the remembered set we ran into the issue described in 6930581 - the sparse table expanded and the RSet scanning code walked the cards in one instance of RHashTable (_cur) while the occupied() counts the cards in the expanded table (_next).
Reviewed-by: tonyp, iveresov
author | johnc |
---|---|
date | Tue, 16 Nov 2010 14:07:33 -0800 |
parents | c32059ef4dc0 |
children | f95d63e2154a |
line wrap: on
line diff
--- a/src/share/vm/gc_implementation/g1/g1RemSet.hpp Mon Nov 15 16:25:14 2010 -0800 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.hpp Tue Nov 16 14:07:33 2010 -0800 @@ -59,11 +59,6 @@ size_t* _cards_scanned; size_t _total_cards_scanned; - // _traversal_in_progress is "true" iff a traversal is in progress. - - bool _traversal_in_progress; - void set_traversal(bool b) { _traversal_in_progress = b; } - // Used for caching the closure that is responsible for scanning // references into the collection set. OopsInHeapRegionClosure** _cset_rs_update_cl; @@ -76,10 +71,6 @@ bool concurrentRefineOneCard_impl(jbyte* card_ptr, int worker_i, bool check_for_refs_into_cset); -protected: - template <class T> void write_ref_nv(HeapRegion* from, T* p); - template <class T> void par_write_ref_nv(HeapRegion* from, T* p, int tid); - public: // This is called to reset dual hash tables after the gc pause // is finished and the initial hash table is no longer being @@ -117,22 +108,8 @@ // Record, if necessary, the fact that *p (where "p" is in region "from", // which is required to be non-NULL) has changed to a new non-NULL value. - // [Below the virtual version calls a non-virtual protected - // workhorse that is templatified for narrow vs wide oop.] - inline void write_ref(HeapRegion* from, oop* p) { - write_ref_nv(from, p); - } - inline void write_ref(HeapRegion* from, narrowOop* p) { - write_ref_nv(from, p); - } - inline void par_write_ref(HeapRegion* from, oop* p, int tid) { - par_write_ref_nv(from, p, tid); - } - inline void par_write_ref(HeapRegion* from, narrowOop* p, int tid) { - par_write_ref_nv(from, p, tid); - } - - bool self_forwarded(oop obj); + template <class T> void write_ref(HeapRegion* from, T* p); + template <class T> void par_write_ref(HeapRegion* from, T* p, int tid); // Requires "region_bm" and "card_bm" to be bitmaps with 1 bit per region // or card, respectively, such that a region or card with a corresponding @@ -186,9 +163,8 @@ public: UpdateRSOopClosure(G1RemSet* rs, int worker_i = 0) : - _from(NULL), _rs(rs), _worker_i(worker_i) { - guarantee(_rs != NULL, "Requires an HRIntoG1RemSet"); - } + _from(NULL), _rs(rs), _worker_i(worker_i) + {} void set_from(HeapRegion* from) { assert(from != NULL, "from region must be non-NULL"); @@ -215,3 +191,43 @@ virtual void do_oop(narrowOop* p) { do_oop_work(p); } virtual void do_oop( oop* p) { do_oop_work(p); } }; + +class UpdateRSOrPushRefOopClosure: public OopClosure { + G1CollectedHeap* _g1; + G1RemSet* _g1_rem_set; + HeapRegion* _from; + OopsInHeapRegionClosure* _push_ref_cl; + bool _record_refs_into_cset; + int _worker_i; + + template <class T> void do_oop_work(T* p); + +public: + UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h, + G1RemSet* rs, + OopsInHeapRegionClosure* push_ref_cl, + bool record_refs_into_cset, + int worker_i = 0) : + _g1(g1h), + _g1_rem_set(rs), + _from(NULL), + _record_refs_into_cset(record_refs_into_cset), + _push_ref_cl(push_ref_cl), + _worker_i(worker_i) { } + + void set_from(HeapRegion* from) { + assert(from != NULL, "from region must be non-NULL"); + _from = from; + } + + bool self_forwarded(oop obj) { + bool result = (obj->is_forwarded() && (obj->forwardee()== obj)); + return result; + } + + virtual void do_oop(narrowOop* p) { do_oop_work(p); } + virtual void do_oop(oop* p) { do_oop_work(p); } + + bool apply_to_weak_ref_discovered_field() { return true; } +}; +