< prev index next >
src/share/vm/gc/shared/cardTableRS.cpp
Print this page
rev 12906 : [mq]: gc_interface
*** 72,116 ****
void KlassRemSet::clear_mod_union() {
ClearKlassModUnionClosure closure;
ClassLoaderDataGraph::classes_do(&closure);
}
- CardTableRS::CardTableRS(MemRegion whole_heap) :
- _bs(NULL),
- _cur_youngergen_card_val(youngergenP1_card)
- {
- _ct_bs = new CardTableModRefBSForCTRS(whole_heap);
- _ct_bs->initialize();
- set_bs(_ct_bs);
- // max_gens is really GenCollectedHeap::heap()->gen_policy()->number_of_generations()
- // (which is always 2, young & old), but GenCollectedHeap has not been initialized yet.
- uint max_gens = 2;
- _last_cur_val_in_gen = NEW_C_HEAP_ARRAY3(jbyte, max_gens + 1,
- mtGC, CURRENT_PC, AllocFailStrategy::RETURN_NULL);
- if (_last_cur_val_in_gen == NULL) {
- vm_exit_during_initialization("Could not create last_cur_val_in_gen array.");
- }
- for (uint i = 0; i < max_gens + 1; i++) {
- _last_cur_val_in_gen[i] = clean_card_val();
- }
- _ct_bs->set_CTRS(this);
- }
-
- CardTableRS::~CardTableRS() {
- if (_ct_bs) {
- delete _ct_bs;
- _ct_bs = NULL;
- }
- if (_last_cur_val_in_gen) {
- FREE_C_HEAP_ARRAY(jbyte, _last_cur_val_in_gen);
- }
- }
-
- void CardTableRS::resize_covered_region(MemRegion new_region) {
- _ct_bs->resize_covered_region(new_region);
- }
-
jbyte CardTableRS::find_unused_youngergenP_card_value() {
for (jbyte v = youngergenP1_card;
v < cur_youngergen_and_prev_nonclean_card;
v++) {
bool seen = false;
--- 72,81 ----
*** 244,254 ****
}
// fast forward through potential continuous whole-word range of clean cards beginning at a word-boundary
if (is_word_aligned(cur_entry)) {
jbyte* cur_row = cur_entry - BytesPerWord;
! while (cur_row >= limit && *((intptr_t*)cur_row) == CardTableRS::clean_card_row()) {
cur_row -= BytesPerWord;
}
cur_entry = cur_row + BytesPerWord;
cur_hw = _ct->addr_for(cur_entry);
}
--- 209,219 ----
}
// fast forward through potential continuous whole-word range of clean cards beginning at a word-boundary
if (is_word_aligned(cur_entry)) {
jbyte* cur_row = cur_entry - BytesPerWord;
! while (cur_row >= limit && *((intptr_t*)cur_row) == CardTableRS::clean_card_row_val()) {
cur_row -= BytesPerWord;
}
cur_entry = cur_row + BytesPerWord;
cur_hw = _ct->addr_for(cur_entry);
}
*** 280,290 ****
// precleaned ==> cur_youngergen_and_prev_nonclean_card
// prev-younger-gen ==> cur_youngergen_and_prev_nonclean_card
// cur-younger-gen ==> cur_younger_gen
// cur_youngergen_and_prev_nonclean_card ==> no change.
void CardTableRS::write_ref_field_gc_par(void* field, oop new_val) {
! volatile jbyte* entry = _ct_bs->byte_for(field);
do {
jbyte entry_val = *entry;
// We put this first because it's probably the most common case.
if (entry_val == clean_card_val()) {
// No threat of contention with cleaning threads.
--- 245,255 ----
// precleaned ==> cur_youngergen_and_prev_nonclean_card
// prev-younger-gen ==> cur_youngergen_and_prev_nonclean_card
// cur-younger-gen ==> cur_younger_gen
// cur_youngergen_and_prev_nonclean_card ==> no change.
void CardTableRS::write_ref_field_gc_par(void* field, oop new_val) {
! volatile jbyte* entry = byte_for(field);
do {
jbyte entry_val = *entry;
// We put this first because it's probably the most common case.
if (entry_val == clean_card_val()) {
// No threat of contention with cleaning threads.
*** 338,348 ****
log_warning(gc)("CMS+ParNew: Flickering used_region_at_save_marks()!!");
}
ShouldNotReachHere();
}
#endif
! _ct_bs->non_clean_card_iterate_possibly_parallel(sp, urasm, cl, this, n_threads);
}
void CardTableRS::clear_into_younger(Generation* old_gen) {
assert(GenCollectedHeap::heap()->is_old_gen(old_gen),
"Should only be called for the old generation");
--- 303,313 ----
log_warning(gc)("CMS+ParNew: Flickering used_region_at_save_marks()!!");
}
ShouldNotReachHere();
}
#endif
! non_clean_card_iterate_possibly_parallel(sp, urasm, cl, this, n_threads);
}
void CardTableRS::clear_into_younger(Generation* old_gen) {
assert(GenCollectedHeap::heap()->is_old_gen(old_gen),
"Should only be called for the old generation");
*** 639,645 ****
void CardTableRS::verify() {
// At present, we only know how to verify the card table RS for
// generational heaps.
VerifyCTGenClosure blk(this);
GenCollectedHeap::heap()->generation_iterate(&blk, false);
! _ct_bs->verify();
}
--- 604,719 ----
void CardTableRS::verify() {
// At present, we only know how to verify the card table RS for
// generational heaps.
VerifyCTGenClosure blk(this);
GenCollectedHeap::heap()->generation_iterate(&blk, false);
! CardTable::verify();
! }
!
! CardTableRS::CardTableRS(MemRegion whole_heap) :
! CardTable(whole_heap, /* scanned concurrently */ UseConcMarkSweepGC),
! _cur_youngergen_card_val(youngergenP1_card),
! // LNC functionality
! _lowest_non_clean(NULL),
! _lowest_non_clean_chunk_size(NULL),
! _lowest_non_clean_base_chunk_index(NULL),
! _last_LNC_resizing_collection(NULL)
! {
! // max_gens is really GenCollectedHeap::heap()->gen_policy()->number_of_generations()
! // (which is always 2, young & old), but GenCollectedHeap has not been initialized yet.
! uint max_gens = 2;
! _last_cur_val_in_gen = NEW_C_HEAP_ARRAY3(jbyte, max_gens + 1,
! mtGC, CURRENT_PC, AllocFailStrategy::RETURN_NULL);
! if (_last_cur_val_in_gen == NULL) {
! vm_exit_during_initialization("Could not create last_cur_val_in_gen array.");
! }
! for (uint i = 0; i < max_gens + 1; i++) {
! _last_cur_val_in_gen[i] = clean_card_val();
! }
! }
!
! CardTableRS::~CardTableRS() {
! if (_last_cur_val_in_gen) {
! FREE_C_HEAP_ARRAY(jbyte, _last_cur_val_in_gen);
! }
! if (_lowest_non_clean) {
! FREE_C_HEAP_ARRAY(CardArr, _lowest_non_clean);
! _lowest_non_clean = NULL;
! }
! if (_lowest_non_clean_chunk_size) {
! FREE_C_HEAP_ARRAY(size_t, _lowest_non_clean_chunk_size);
! _lowest_non_clean_chunk_size = NULL;
! }
! if (_lowest_non_clean_base_chunk_index) {
! FREE_C_HEAP_ARRAY(uintptr_t, _lowest_non_clean_base_chunk_index);
! _lowest_non_clean_base_chunk_index = NULL;
! }
! if (_last_LNC_resizing_collection) {
! FREE_C_HEAP_ARRAY(int, _last_LNC_resizing_collection);
! _last_LNC_resizing_collection = NULL;
! }
! }
!
! void CardTableRS::initialize() {
! CardTable::initialize();
! _lowest_non_clean =
! NEW_C_HEAP_ARRAY(CardArr, _max_covered_regions, mtGC);
! _lowest_non_clean_chunk_size =
! NEW_C_HEAP_ARRAY(size_t, _max_covered_regions, mtGC);
! _lowest_non_clean_base_chunk_index =
! NEW_C_HEAP_ARRAY(uintptr_t, _max_covered_regions, mtGC);
! _last_LNC_resizing_collection =
! NEW_C_HEAP_ARRAY(int, _max_covered_regions, mtGC);
! if (_lowest_non_clean == NULL
! || _lowest_non_clean_chunk_size == NULL
! || _lowest_non_clean_base_chunk_index == NULL
! || _last_LNC_resizing_collection == NULL)
! vm_exit_during_initialization("couldn't allocate an LNC array.");
! for (int i = 0; i < _max_covered_regions; i++) {
! _lowest_non_clean[i] = NULL;
! _lowest_non_clean_chunk_size[i] = 0;
! _last_LNC_resizing_collection[i] = -1;
! }
! }
!
! bool CardTableRS::card_will_be_scanned(jbyte cv) {
! return card_is_dirty_wrt_gen_iter(cv) || is_prev_nonclean_card_val(cv);
! }
!
! bool CardTableRS::card_may_have_been_dirty(jbyte cv) {
! return
! cv != clean_card &&
! (card_is_dirty_wrt_gen_iter(cv) ||
! CardTableRS::youngergen_may_have_been_dirty(cv));
! }
!
! void CardTableRS::non_clean_card_iterate_possibly_parallel(
! Space* sp,
! MemRegion mr,
! OopsInGenClosure* cl,
! CardTableRS* ct,
! uint n_threads)
! {
! if (!mr.is_empty()) {
! if (n_threads > 0) {
! #if INCLUDE_ALL_GCS
! non_clean_card_iterate_parallel_work(sp, mr, cl, ct, n_threads);
! #else // INCLUDE_ALL_GCS
! fatal("Parallel gc not supported here.");
! #endif // INCLUDE_ALL_GCS
! } else {
! // clear_cl finds contiguous dirty ranges of cards to process and clear.
!
! // This is the single-threaded version used by DefNew.
! const bool parallel = false;
!
! DirtyCardToOopClosure* dcto_cl = sp->new_dcto_cl(cl, precision(), cl->gen_boundary(), parallel);
! ClearNoncleanCardWrapper clear_cl(dcto_cl, ct, parallel);
!
! clear_cl.do_MemRegion(mr);
! }
! }
! }
!
! bool CardTableRS::is_in_young(void* addr) const {
! return GenCollectedHeap::heap()->is_in_young((oop)addr);
}
< prev index next >