src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
Print this page
rev 6279 : imported patch fast-cset-uses-biasedarray
rev 6282 : 8028710: G1 does not retire allocation buffers after reference processing work
Summary: G1 does not retire allocation buffers after reference processing work when -XX:+ParallelRefProcEnabled is enabled.
Reviewed-by:
rev 6283 : 8019342: G1: High "Other" time most likely due to card redirtying
Summary: Parallelize card redirtying to decrease the time it takes.
Reviewed-by: tbd, tbd
rev 6284 : [mq]: fixes-cleanup
rev 6285 : 8040002: Clean up code and code duplication in re-diryting cards for verification
Summary: Card re-dirtying code for verification and actual redirtying uses two different, almost completely identical card closures. Also the verification code still assumes a perm gen.
Reviewed-by: tbd, tbd
*** 114,170 ****
void set_concurrent(bool b) { _concurrent = b; }
};
class ClearLoggedCardTableEntryClosure: public CardTableEntryClosure {
! int _calls;
! G1CollectedHeap* _g1h;
CardTableModRefBS* _ctbs;
int _histo[256];
! public:
ClearLoggedCardTableEntryClosure() :
! _calls(0), _g1h(G1CollectedHeap::heap()), _ctbs(_g1h->g1_barrier_set())
{
for (int i = 0; i < 256; i++) _histo[i] = 0;
}
bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
- if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) {
- _calls++;
unsigned char* ujb = (unsigned char*)card_ptr;
int ind = (int)(*ujb);
_histo[ind]++;
! *card_ptr = -1;
! }
return true;
}
! int calls() { return _calls; }
void print_histo() {
gclog_or_tty->print_cr("Card table value histogram:");
for (int i = 0; i < 256; i++) {
if (_histo[i] != 0) {
gclog_or_tty->print_cr(" %d: %d", i, _histo[i]);
}
}
}
};
! class RedirtyLoggedCardTableEntryClosure: public CardTableEntryClosure {
! int _calls;
! G1CollectedHeap* _g1h;
! CardTableModRefBS* _ctbs;
! public:
! RedirtyLoggedCardTableEntryClosure() :
! _calls(0), _g1h(G1CollectedHeap::heap()), _ctbs(_g1h->g1_barrier_set()) {}
bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
! if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) {
! _calls++;
! *card_ptr = 0;
! }
return true;
}
! int calls() { return _calls; }
};
YoungList::YoungList(G1CollectedHeap* g1h) :
_g1h(g1h), _head(NULL), _length(0), _last_sampled_rs_lengths(0),
_survivor_head(NULL), _survivor_tail(NULL), _survivor_length(0) {
--- 114,171 ----
void set_concurrent(bool b) { _concurrent = b; }
};
class ClearLoggedCardTableEntryClosure: public CardTableEntryClosure {
! size_t _num_processed;
CardTableModRefBS* _ctbs;
int _histo[256];
!
! public:
ClearLoggedCardTableEntryClosure() :
! _num_processed(0), _ctbs(G1CollectedHeap::heap()->g1_barrier_set())
{
for (int i = 0; i < 256; i++) _histo[i] = 0;
}
+
bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
unsigned char* ujb = (unsigned char*)card_ptr;
int ind = (int)(*ujb);
_histo[ind]++;
!
! *card_ptr = (jbyte)CardTableModRefBS::clean_card_val();
! _num_processed++;
!
return true;
}
!
! size_t num_processed() { return _num_processed; }
!
void print_histo() {
gclog_or_tty->print_cr("Card table value histogram:");
for (int i = 0; i < 256; i++) {
if (_histo[i] != 0) {
gclog_or_tty->print_cr(" %d: %d", i, _histo[i]);
}
}
}
};
! class RedirtyLoggedCardTableEntryClosure : public CardTableEntryClosure {
! private:
! size_t _num_processed;
!
! public:
! RedirtyLoggedCardTableEntryClosure() : CardTableEntryClosure(), _num_processed(0) { }
bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
! *card_ptr = CardTableModRefBS::dirty_card_val();
! _num_processed++;
return true;
}
!
! size_t num_processed() const { return _num_processed; }
};
YoungList::YoungList(G1CollectedHeap* g1h) :
_g1h(g1h), _head(NULL), _length(0), _last_sampled_rs_lengths(0),
_survivor_head(NULL), _survivor_tail(NULL), _survivor_length(0) {
*** 489,501 ****
RedirtyLoggedCardTableEntryClosure redirty;
dcqs.apply_closure_to_all_completed_buffers(&redirty);
dcqs.iterate_closure_all_threads(&redirty, false);
gclog_or_tty->print_cr("Log entries = %d, dirty cards = %d.",
! clear.calls(), orig_count);
! guarantee(redirty.calls() == clear.calls(),
! "Or else mechanism is broken.");
CountNonCleanMemRegionClosure count3(this);
ct_bs->mod_card_iterate(&count3);
if (count3.n() != orig_count) {
gclog_or_tty->print_cr("Should have restored them all: orig = %d, final = %d.",
--- 490,503 ----
RedirtyLoggedCardTableEntryClosure redirty;
dcqs.apply_closure_to_all_completed_buffers(&redirty);
dcqs.iterate_closure_all_threads(&redirty, false);
gclog_or_tty->print_cr("Log entries = %d, dirty cards = %d.",
! clear.num_processed(), orig_count);
! guarantee(redirty.num_processed() == clear.num_processed(),
! err_msg("Redirtied "SIZE_FORMAT" cards, bug cleared "SIZE_FORMAT,
! redirty.num_processed(), clear.num_processed()));
CountNonCleanMemRegionClosure count3(this);
ct_bs->mod_card_iterate(&count3);
if (count3.n() != orig_count) {
gclog_or_tty->print_cr("Should have restored them all: orig = %d, final = %d.",
*** 5252,5287 ****
if (G1StringDedup::is_enabled()) {
G1StringDedup::unlink(is_alive);
}
}
- class RedirtyLoggedCardTableEntryFastClosure : public CardTableEntryClosure {
- private:
- size_t _num_processed;
-
- public:
- RedirtyLoggedCardTableEntryFastClosure() : CardTableEntryClosure(), _num_processed(0) { }
-
- bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
- *card_ptr = CardTableModRefBS::dirty_card_val();
- _num_processed++;
- return true;
- }
-
- size_t num_processed() const { return _num_processed; }
- };
-
class G1RedirtyLoggedCardsTask : public AbstractGangTask {
private:
DirtyCardQueueSet* _queue;
public:
G1RedirtyLoggedCardsTask(DirtyCardQueueSet* queue) : AbstractGangTask("Redirty Cards"), _queue(queue) { }
virtual void work(uint worker_id) {
double start_time = os::elapsedTime();
! RedirtyLoggedCardTableEntryFastClosure cl;
if (G1CollectedHeap::heap()->use_parallel_gc_threads()) {
_queue->par_apply_closure_to_all_completed_buffers(&cl);
} else {
_queue->apply_closure_to_all_completed_buffers(&cl);
}
--- 5254,5273 ----
if (G1StringDedup::is_enabled()) {
G1StringDedup::unlink(is_alive);
}
}
class G1RedirtyLoggedCardsTask : public AbstractGangTask {
private:
DirtyCardQueueSet* _queue;
public:
G1RedirtyLoggedCardsTask(DirtyCardQueueSet* queue) : AbstractGangTask("Redirty Cards"), _queue(queue) { }
virtual void work(uint worker_id) {
double start_time = os::elapsedTime();
! RedirtyLoggedCardTableEntryClosure cl;
if (G1CollectedHeap::heap()->use_parallel_gc_threads()) {
_queue->par_apply_closure_to_all_completed_buffers(&cl);
} else {
_queue->apply_closure_to_all_completed_buffers(&cl);
}