提交 37367381 编写于 作者: J johnc

6971296: G1: simplify G1RemSet class hierarchy

Summary: Remove G1RemSet base class and StupidG1RemSet class; rename HRInto_G1RemSet to just G1RemSet.
Reviewed-by: ysr, tonyp
上级 7d9eea06
......@@ -791,7 +791,7 @@ class RebuildRSOutOfRegionClosure: public HeapRegionClosure {
int _worker_i;
public:
RebuildRSOutOfRegionClosure(G1CollectedHeap* g1, int worker_i = 0) :
_cl(g1->g1_rem_set()->as_HRInto_G1RemSet(), worker_i),
_cl(g1->g1_rem_set(), worker_i),
_worker_i(worker_i),
_g1h(g1)
{ }
......@@ -890,7 +890,7 @@ void G1CollectedHeap::do_collection(bool explicit_gc,
abandon_cur_alloc_region();
abandon_gc_alloc_regions();
assert(_cur_alloc_region == NULL, "Invariant.");
g1_rem_set()->as_HRInto_G1RemSet()->cleanupHRRS();
g1_rem_set()->cleanupHRRS();
tear_down_region_lists();
set_used_regions_to_need_zero_fill();
......@@ -1506,15 +1506,11 @@ jint G1CollectedHeap::initialize() {
}
// Also create a G1 rem set.
if (G1UseHRIntoRS) {
if (mr_bs()->is_a(BarrierSet::CardTableModRef)) {
_g1_rem_set = new HRInto_G1RemSet(this, (CardTableModRefBS*)mr_bs());
} else {
vm_exit_during_initialization("G1 requires a cardtable mod ref bs.");
return JNI_ENOMEM;
}
if (mr_bs()->is_a(BarrierSet::CardTableModRef)) {
_g1_rem_set = new G1RemSet(this, (CardTableModRefBS*)mr_bs());
} else {
_g1_rem_set = new StupidG1RemSet(this);
vm_exit_during_initialization("G1 requires a cardtable mod ref bs.");
return JNI_ENOMEM;
}
// Carve out the G1 part of the heap.
......@@ -2706,8 +2702,7 @@ size_t G1CollectedHeap::max_pending_card_num() {
}
size_t G1CollectedHeap::cards_scanned() {
HRInto_G1RemSet* g1_rset = (HRInto_G1RemSet*) g1_rem_set();
return g1_rset->cardsScanned();
return g1_rem_set()->cardsScanned();
}
void
......
......@@ -25,8 +25,6 @@
class HeapRegion;
class G1CollectedHeap;
class G1RemSet;
class HRInto_G1RemSet;
class G1RemSet;
class ConcurrentMark;
class DirtyCardToOopClosure;
class CMBitMap;
......
......@@ -97,13 +97,6 @@ public:
}
};
void
StupidG1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc,
int worker_i) {
IntoCSRegionClosure rc(_g1, oc);
_g1->heap_region_iterate(&rc);
}
class VerifyRSCleanCardOopClosure: public OopClosure {
G1CollectedHeap* _g1;
public:
......@@ -119,8 +112,9 @@ public:
}
};
HRInto_G1RemSet::HRInto_G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs)
: G1RemSet(g1), _ct_bs(ct_bs), _g1p(_g1->g1_policy()),
G1RemSet::G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs)
: _g1(g1), _conc_refine_cards(0),
_ct_bs(ct_bs), _g1p(_g1->g1_policy()),
_cg1r(g1->concurrent_g1_refine()),
_traversal_in_progress(false),
_cset_rs_update_cl(NULL),
......@@ -134,7 +128,7 @@ HRInto_G1RemSet::HRInto_G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs)
}
}
HRInto_G1RemSet::~HRInto_G1RemSet() {
G1RemSet::~G1RemSet() {
delete _seq_task;
for (uint i = 0; i < n_workers(); i++) {
assert(_cset_rs_update_cl[i] == NULL, "it should be");
......@@ -277,7 +271,7 @@ public:
// p threads
// Then thread t will start at region t * floor (n/p)
HeapRegion* HRInto_G1RemSet::calculateStartRegion(int worker_i) {
HeapRegion* G1RemSet::calculateStartRegion(int worker_i) {
HeapRegion* result = _g1p->collection_set();
if (ParallelGCThreads > 0) {
size_t cs_size = _g1p->collection_set_size();
......@@ -290,7 +284,7 @@ HeapRegion* HRInto_G1RemSet::calculateStartRegion(int worker_i) {
return result;
}
void HRInto_G1RemSet::scanRS(OopsInHeapRegionClosure* oc, int worker_i) {
void G1RemSet::scanRS(OopsInHeapRegionClosure* oc, int worker_i) {
double rs_time_start = os::elapsedTime();
HeapRegion *startRegion = calculateStartRegion(worker_i);
......@@ -340,7 +334,7 @@ public:
}
};
void HRInto_G1RemSet::updateRS(DirtyCardQueue* into_cset_dcq, int worker_i) {
void G1RemSet::updateRS(DirtyCardQueue* into_cset_dcq, int worker_i) {
double start = os::elapsedTime();
// Apply the given closure to all remaining log entries.
RefineRecordRefsIntoCSCardTableEntryClosure into_cset_update_rs_cl(_g1, into_cset_dcq);
......@@ -439,12 +433,11 @@ public:
}
};
void HRInto_G1RemSet::cleanupHRRS() {
void G1RemSet::cleanupHRRS() {
HeapRegionRemSet::cleanup();
}
void
HRInto_G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc,
void G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc,
int worker_i) {
#if CARD_REPEAT_HISTO
ct_freq_update_histo_and_reset();
......@@ -508,8 +501,7 @@ HRInto_G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc,
_cset_rs_update_cl[worker_i] = NULL;
}
void HRInto_G1RemSet::
prepare_for_oops_into_collection_set_do() {
void G1RemSet::prepare_for_oops_into_collection_set_do() {
#if G1_REM_SET_LOGGING
PrintRSClosure cl;
_g1->collection_set_iterate(&cl);
......@@ -581,7 +573,7 @@ public:
// RSet updating,
// * the post-write barrier shouldn't be logging updates to young
// regions (but there is a situation where this can happen - see
// the comment in HRInto_G1RemSet::concurrentRefineOneCard below -
// the comment in G1RemSet::concurrentRefineOneCard below -
// that should not be applicable here), and
// * during actual RSet updating, the filtering of cards in young
// regions in HeapRegion::oops_on_card_seq_iterate_careful is
......@@ -601,7 +593,7 @@ public:
}
};
void HRInto_G1RemSet::cleanup_after_oops_into_collection_set_do() {
void G1RemSet::cleanup_after_oops_into_collection_set_do() {
guarantee( _cards_scanned != NULL, "invariant" );
_total_cards_scanned = 0;
for (uint i = 0; i < n_workers(); ++i)
......@@ -692,12 +684,12 @@ public:
}
};
void HRInto_G1RemSet::scrub(BitMap* region_bm, BitMap* card_bm) {
void G1RemSet::scrub(BitMap* region_bm, BitMap* card_bm) {
ScrubRSClosure scrub_cl(region_bm, card_bm);
_g1->heap_region_iterate(&scrub_cl);
}
void HRInto_G1RemSet::scrub_par(BitMap* region_bm, BitMap* card_bm,
void G1RemSet::scrub_par(BitMap* region_bm, BitMap* card_bm,
int worker_num, int claim_val) {
ScrubRSClosure scrub_cl(region_bm, card_bm);
_g1->heap_region_par_iterate_chunked(&scrub_cl, worker_num, claim_val);
......@@ -741,7 +733,7 @@ public:
virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
};
bool HRInto_G1RemSet::concurrentRefineOneCard_impl(jbyte* card_ptr, int worker_i,
bool G1RemSet::concurrentRefineOneCard_impl(jbyte* card_ptr, int worker_i,
bool check_for_refs_into_cset) {
// Construct the region representing the card.
HeapWord* start = _ct_bs->addr_for(card_ptr);
......@@ -820,7 +812,7 @@ bool HRInto_G1RemSet::concurrentRefineOneCard_impl(jbyte* card_ptr, int worker_i
return trigger_cl.value();
}
bool HRInto_G1RemSet::concurrentRefineOneCard(jbyte* card_ptr, int worker_i,
bool G1RemSet::concurrentRefineOneCard(jbyte* card_ptr, int worker_i,
bool check_for_refs_into_cset) {
// If the card is no longer dirty, nothing to do.
if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
......@@ -995,7 +987,7 @@ public:
}
};
void HRInto_G1RemSet::print_summary_info() {
void G1RemSet::print_summary_info() {
G1CollectedHeap* g1 = G1CollectedHeap::heap();
#if CARD_REPEAT_HISTO
......@@ -1029,30 +1021,26 @@ void HRInto_G1RemSet::print_summary_info() {
g1->concurrent_g1_refine()->threads_do(&p);
gclog_or_tty->print_cr("");
if (G1UseHRIntoRS) {
HRRSStatsIter blk;
g1->heap_region_iterate(&blk);
gclog_or_tty->print_cr(" Total heap region rem set sizes = " SIZE_FORMAT "K."
" Max = " SIZE_FORMAT "K.",
blk.total_mem_sz()/K, blk.max_mem_sz()/K);
gclog_or_tty->print_cr(" Static structures = " SIZE_FORMAT "K,"
" free_lists = " SIZE_FORMAT "K.",
HeapRegionRemSet::static_mem_size()/K,
HeapRegionRemSet::fl_mem_size()/K);
gclog_or_tty->print_cr(" %d occupied cards represented.",
blk.occupied());
gclog_or_tty->print_cr(" Max sz region = [" PTR_FORMAT ", " PTR_FORMAT " )"
", cap = " SIZE_FORMAT "K, occ = " SIZE_FORMAT "K.",
blk.max_mem_sz_region()->bottom(), blk.max_mem_sz_region()->end(),
(blk.max_mem_sz_region()->rem_set()->mem_size() + K - 1)/K,
(blk.max_mem_sz_region()->rem_set()->occupied() + K - 1)/K);
gclog_or_tty->print_cr(" Did %d coarsenings.",
HeapRegionRemSet::n_coarsenings());
}
HRRSStatsIter blk;
g1->heap_region_iterate(&blk);
gclog_or_tty->print_cr(" Total heap region rem set sizes = " SIZE_FORMAT "K."
" Max = " SIZE_FORMAT "K.",
blk.total_mem_sz()/K, blk.max_mem_sz()/K);
gclog_or_tty->print_cr(" Static structures = " SIZE_FORMAT "K,"
" free_lists = " SIZE_FORMAT "K.",
HeapRegionRemSet::static_mem_size()/K,
HeapRegionRemSet::fl_mem_size()/K);
gclog_or_tty->print_cr(" %d occupied cards represented.",
blk.occupied());
gclog_or_tty->print_cr(" Max sz region = [" PTR_FORMAT ", " PTR_FORMAT " )"
", cap = " SIZE_FORMAT "K, occ = " SIZE_FORMAT "K.",
blk.max_mem_sz_region()->bottom(), blk.max_mem_sz_region()->end(),
(blk.max_mem_sz_region()->rem_set()->mem_size() + K - 1)/K,
(blk.max_mem_sz_region()->rem_set()->occupied() + K - 1)/K);
gclog_or_tty->print_cr(" Did %d coarsenings.", HeapRegionRemSet::n_coarsenings());
}
void HRInto_G1RemSet::prepare_for_verify() {
void G1RemSet::prepare_for_verify() {
if (G1HRRSFlushLogBuffersOnVerify &&
(VerifyBeforeGC || VerifyAfterGC)
&& !_g1->full_collection()) {
......
......@@ -27,107 +27,18 @@
class G1CollectedHeap;
class CardTableModRefBarrierSet;
class HRInto_G1RemSet;
class ConcurrentG1Refine;
// A G1RemSet in which each heap region has a rem set that records the
// external heap references into it. Uses a mod ref bs to track updates,
// so that they can be used to update the individual region remsets.
class G1RemSet: public CHeapObj {
protected:
G1CollectedHeap* _g1;
unsigned _conc_refine_cards;
size_t n_workers();
public:
G1RemSet(G1CollectedHeap* g1) :
_g1(g1), _conc_refine_cards(0)
{}
// Invoke "blk->do_oop" on all pointers into the CS in object in regions
// outside the CS (having invoked "blk->set_region" to set the "from"
// region correctly beforehand.) The "worker_i" param is for the
// parallel case where the number of the worker thread calling this
// function can be helpful in partitioning the work to be done. It
// should be the same as the "i" passed to the calling thread's
// work(i) function. In the sequential case this param will be ingored.
virtual void oops_into_collection_set_do(OopsInHeapRegionClosure* blk,
int worker_i) = 0;
// Prepare for and cleanup after an oops_into_collection_set_do
// call. Must call each of these once before and after (in sequential
// code) any threads call oops into collection set do. (This offers an
// opportunity to sequential setup and teardown of structures needed by a
// parallel iteration over the CS's RS.)
virtual void prepare_for_oops_into_collection_set_do() = 0;
virtual void cleanup_after_oops_into_collection_set_do() = 0;
// If "this" is of the given subtype, return "this", else "NULL".
virtual HRInto_G1RemSet* as_HRInto_G1RemSet() { return NULL; }
// Record, if necessary, the fact that *p (where "p" is in region "from",
// and is, a fortiori, required to be non-NULL) has changed to its new value.
virtual void write_ref(HeapRegion* from, oop* p) = 0;
virtual void write_ref(HeapRegion* from, narrowOop* p) = 0;
virtual void par_write_ref(HeapRegion* from, oop* p, int tid) = 0;
virtual void par_write_ref(HeapRegion* from, narrowOop* p, int tid) = 0;
// 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
// 0 bit contains no part of any live object. Eliminates any remembered
// set entries that correspond to dead heap ranges.
virtual void scrub(BitMap* region_bm, BitMap* card_bm) = 0;
// Like the above, but assumes is called in parallel: "worker_num" is the
// parallel thread id of the current thread, and "claim_val" is the
// value that should be used to claim heap regions.
virtual void scrub_par(BitMap* region_bm, BitMap* card_bm,
int worker_num, int claim_val) = 0;
// Refine the card corresponding to "card_ptr". If "sts" is non-NULL,
// join and leave around parts that must be atomic wrt GC. (NULL means
// being done at a safepoint.)
// With some implementations of this routine, when check_for_refs_into_cset
// is true, a true result may be returned if the given card contains oops
// that have references into the current collection set.
virtual bool concurrentRefineOneCard(jbyte* card_ptr, int worker_i,
bool check_for_refs_into_cset) {
return false;
}
// Print any relevant summary info.
virtual void print_summary_info() {}
// Prepare remebered set for verification.
virtual void prepare_for_verify() {};
};
// The simplest possible G1RemSet: iterates over all objects in non-CS
// regions, searching for pointers into the CS.
class StupidG1RemSet: public G1RemSet {
public:
StupidG1RemSet(G1CollectedHeap* g1) : G1RemSet(g1) {}
void oops_into_collection_set_do(OopsInHeapRegionClosure* blk,
int worker_i);
void prepare_for_oops_into_collection_set_do() {}
void cleanup_after_oops_into_collection_set_do() {}
// Nothing is necessary in the version below.
void write_ref(HeapRegion* from, oop* p) {}
void write_ref(HeapRegion* from, narrowOop* p) {}
void par_write_ref(HeapRegion* from, oop* p, int tid) {}
void par_write_ref(HeapRegion* from, narrowOop* p, int tid) {}
void scrub(BitMap* region_bm, BitMap* card_bm) {}
void scrub_par(BitMap* region_bm, BitMap* card_bm,
int worker_num, int claim_val) {}
};
// A G1RemSet in which each heap region has a rem set that records the
// external heap references into it. Uses a mod ref bs to track updates,
// so that they can be used to update the individual region remsets.
class HRInto_G1RemSet: public G1RemSet {
protected:
enum SomePrivateConstants {
UpdateRStoMergeSync = 0,
......@@ -175,27 +86,31 @@ public:
// scanned.
void cleanupHRRS();
HRInto_G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs);
~HRInto_G1RemSet();
G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs);
~G1RemSet();
// Invoke "blk->do_oop" on all pointers into the CS in objects in regions
// outside the CS (having invoked "blk->set_region" to set the "from"
// region correctly beforehand.) The "worker_i" param is for the
// parallel case where the number of the worker thread calling this
// function can be helpful in partitioning the work to be done. It
// should be the same as the "i" passed to the calling thread's
// work(i) function. In the sequential case this param will be ingored.
void oops_into_collection_set_do(OopsInHeapRegionClosure* blk,
int worker_i);
// Prepare for and cleanup after an oops_into_collection_set_do
// call. Must call each of these once before and after (in sequential
// code) any threads call oops_into_collection_set_do. (This offers an
// opportunity to sequential setup and teardown of structures needed by a
// parallel iteration over the CS's RS.)
void prepare_for_oops_into_collection_set_do();
void cleanup_after_oops_into_collection_set_do();
void scanRS(OopsInHeapRegionClosure* oc, int worker_i);
template <class T> void scanNewRefsRS_work(OopsInHeapRegionClosure* oc, int worker_i);
void scanNewRefsRS(OopsInHeapRegionClosure* oc, int worker_i) {
if (UseCompressedOops) {
scanNewRefsRS_work<narrowOop>(oc, worker_i);
} else {
scanNewRefsRS_work<oop>(oc, worker_i);
}
}
void updateRS(DirtyCardQueue* into_cset_dcq, int worker_i);
HeapRegion* calculateStartRegion(int i);
HRInto_G1RemSet* as_HRInto_G1RemSet() { return this; }
HeapRegion* calculateStartRegion(int i);
CardTableModRefBS* ct_bs() { return _ct_bs; }
size_t cardsScanned() { return _total_cards_scanned; }
......@@ -219,17 +134,31 @@ public:
bool self_forwarded(oop obj);
// 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
// 0 bit contains no part of any live object. Eliminates any remembered
// set entries that correspond to dead heap ranges.
void scrub(BitMap* region_bm, BitMap* card_bm);
// Like the above, but assumes is called in parallel: "worker_num" is the
// parallel thread id of the current thread, and "claim_val" is the
// value that should be used to claim heap regions.
void scrub_par(BitMap* region_bm, BitMap* card_bm,
int worker_num, int claim_val);
// If check_for_refs_into_cset is true then a true result is returned
// if the card contains oops that have references into the current
// collection set.
// Refine the card corresponding to "card_ptr". If "sts" is non-NULL,
// join and leave around parts that must be atomic wrt GC. (NULL means
// being done at a safepoint.)
// If check_for_refs_into_cset is true, a true result is returned
// if the given card contains oops that have references into the
// current collection set.
virtual bool concurrentRefineOneCard(jbyte* card_ptr, int worker_i,
bool check_for_refs_into_cset);
// Print any relevant summary info.
virtual void print_summary_info();
// Prepare remembered set for verification.
virtual void prepare_for_verify();
};
......@@ -250,13 +179,13 @@ public:
class UpdateRSOopClosure: public OopClosure {
HeapRegion* _from;
HRInto_G1RemSet* _rs;
G1RemSet* _rs;
int _worker_i;
template <class T> void do_oop_work(T* p);
public:
UpdateRSOopClosure(HRInto_G1RemSet* rs, int worker_i = 0) :
UpdateRSOopClosure(G1RemSet* rs, int worker_i = 0) :
_from(NULL), _rs(rs), _worker_i(worker_i) {
guarantee(_rs != NULL, "Requires an HRIntoG1RemSet");
}
......
......@@ -30,16 +30,18 @@ inline size_t G1RemSet::n_workers() {
}
}
template <class T> inline void HRInto_G1RemSet::write_ref_nv(HeapRegion* from, T* p) {
template <class T>
inline void G1RemSet::write_ref_nv(HeapRegion* from, T* p) {
par_write_ref_nv(from, p, 0);
}
inline bool HRInto_G1RemSet::self_forwarded(oop obj) {
inline bool G1RemSet::self_forwarded(oop obj) {
bool result = (obj->is_forwarded() && (obj->forwardee()== obj));
return result;
}
template <class T> inline void HRInto_G1RemSet::par_write_ref_nv(HeapRegion* from, T* p, int tid) {
template <class T>
inline void G1RemSet::par_write_ref_nv(HeapRegion* from, T* p, int tid) {
oop obj = oopDesc::load_decode_heap_oop(p);
#ifdef ASSERT
// can't do because of races
......@@ -77,7 +79,7 @@ template <class T> inline void HRInto_G1RemSet::par_write_ref_nv(HeapRegion* fro
// Deferred updates to the CSet are either discarded (in the normal case),
// or processed (if an evacuation failure occurs) at the end
// of the collection.
// See HRInto_G1RemSet::cleanup_after_oops_into_collection_set_do().
// See G1RemSet::cleanup_after_oops_into_collection_set_do().
} else {
#if G1_REM_SET_LOGGING
gclog_or_tty->print_cr("Adding " PTR_FORMAT " (" PTR_FORMAT ") to RS"
......@@ -91,12 +93,14 @@ template <class T> inline void HRInto_G1RemSet::par_write_ref_nv(HeapRegion* fro
}
}
template <class T> inline void UpdateRSOopClosure::do_oop_work(T* p) {
template <class T>
inline void UpdateRSOopClosure::do_oop_work(T* p) {
assert(_from != NULL, "from region must be non-NULL");
_rs->par_write_ref(_from, p, _worker_i);
}
template <class T> inline void UpdateRSetImmediate::do_oop_work(T* p) {
template <class T>
inline void UpdateRSetImmediate::do_oop_work(T* p) {
assert(_from->is_in_reserved(p), "paranoia");
T heap_oop = oopDesc::load_heap_oop(p);
if (!oopDesc::is_null(heap_oop) && !_from->is_survivor()) {
......
......@@ -40,9 +40,6 @@
develop(intx, G1PolicyVerbose, 0, \
"The verbosity level on G1 policy decisions") \
\
develop(bool, G1UseHRIntoRS, true, \
"Determines whether the 'advanced' HR Into rem set is used.") \
\
develop(intx, G1MarkingVerboseLevel, 0, \
"Level (0-4) of verboseness of the marking code") \
\
......
......@@ -310,10 +310,16 @@ heapRegionSeq.hpp heapRegion.hpp
heapRegionSeq.inline.hpp heapRegionSeq.hpp
instanceKlass.cpp g1RemSet.inline.hpp
instanceRefKlass.cpp g1RemSet.inline.hpp
klass.hpp g1OopClosures.hpp
memoryService.cpp g1MemoryPool.hpp
objArrayKlass.cpp g1RemSet.inline.hpp
ptrQueue.cpp allocation.hpp
ptrQueue.cpp allocation.inline.hpp
ptrQueue.cpp mutex.hpp
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册