hotspot/src/share/vm/memory/cardTableRS.cpp
Print this page
rev 611 : Merge
*** 1,10 ****
#ifdef USE_PRAGMA_IDENT_SRC
#pragma ident "@(#)cardTableRS.cpp 1.45 07/05/25 12:54:50 JVM"
#endif
/*
! * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
--- 1,10 ----
#ifdef USE_PRAGMA_IDENT_SRC
#pragma ident "@(#)cardTableRS.cpp 1.45 07/05/25 12:54:50 JVM"
#endif
/*
! * Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 28,62 ****
# include "incls/_precompiled.incl"
# include "incls/_cardTableRS.cpp.incl"
CardTableRS::CardTableRS(MemRegion whole_heap,
int max_covered_regions) :
! GenRemSet(&_ct_bs),
! _ct_bs(whole_heap, max_covered_regions),
! _cur_youngergen_card_val(youngergenP1_card)
{
_last_cur_val_in_gen = new jbyte[GenCollectedHeap::max_gens + 1];
if (_last_cur_val_in_gen == NULL) {
vm_exit_during_initialization("Could not last_cur_val_in_gen array.");
}
for (int i = 0; i < GenCollectedHeap::max_gens + 1; i++) {
_last_cur_val_in_gen[i] = clean_card_val();
}
! _ct_bs.set_CTRS(this);
}
void CardTableRS::resize_covered_region(MemRegion new_region) {
! _ct_bs.resize_covered_region(new_region);
}
jbyte CardTableRS::find_unused_youngergenP_card_value() {
- GenCollectedHeap* gch = GenCollectedHeap::heap();
for (jbyte v = youngergenP1_card;
v < cur_youngergen_and_prev_nonclean_card;
v++) {
bool seen = false;
! for (int g = 0; g < gch->n_gens()+1; g++) {
if (_last_cur_val_in_gen[g] == v) {
seen = true;
break;
}
}
--- 28,76 ----
# include "incls/_precompiled.incl"
# include "incls/_cardTableRS.cpp.incl"
CardTableRS::CardTableRS(MemRegion whole_heap,
int max_covered_regions) :
! GenRemSet(),
! _cur_youngergen_card_val(youngergenP1_card),
! _regions_to_iterate(max_covered_regions - 1)
{
+ #ifndef SERIALGC
+ if (UseG1GC) {
+ if (G1RSBarrierUseQueue) {
+ _ct_bs = new G1SATBCardTableLoggingModRefBS(whole_heap,
+ max_covered_regions);
+ } else {
+ _ct_bs = new G1SATBCardTableModRefBS(whole_heap, max_covered_regions);
+ }
+ } else {
+ _ct_bs = new CardTableModRefBSForCTRS(whole_heap, max_covered_regions);
+ }
+ #else
+ _ct_bs = new CardTableModRefBSForCTRS(whole_heap, max_covered_regions);
+ #endif
+ set_bs(_ct_bs);
_last_cur_val_in_gen = new jbyte[GenCollectedHeap::max_gens + 1];
if (_last_cur_val_in_gen == NULL) {
vm_exit_during_initialization("Could not last_cur_val_in_gen array.");
}
for (int i = 0; i < GenCollectedHeap::max_gens + 1; i++) {
_last_cur_val_in_gen[i] = clean_card_val();
}
! _ct_bs->set_CTRS(this);
}
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;
! for (int g = 0; g < _regions_to_iterate; g++) {
if (_last_cur_val_in_gen[g] == v) {
seen = true;
break;
}
}
*** 192,202 ****
// dirty ==> cur_youngergen_and_prev_nonclean_card
// 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(oop* field, oop new_val) {
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()) {
--- 206,216 ----
// dirty ==> cur_youngergen_and_prev_nonclean_card
// 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) {
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()) {
*** 222,236 ****
} while (true);
}
void CardTableRS::younger_refs_in_space_iterate(Space* sp,
OopsInGenClosure* cl) {
! DirtyCardToOopClosure* dcto_cl = sp->new_dcto_cl(cl, _ct_bs.precision(),
cl->gen_boundary());
ClearNoncleanCardWrapper clear_cl(dcto_cl, this);
! _ct_bs.non_clean_card_iterate(sp, sp->used_region_at_save_marks(),
dcto_cl, &clear_cl, false);
}
void CardTableRS::clear_into_younger(Generation* gen, bool clear_perm) {
GenCollectedHeap* gch = GenCollectedHeap::heap();
--- 236,250 ----
} while (true);
}
void CardTableRS::younger_refs_in_space_iterate(Space* sp,
OopsInGenClosure* cl) {
! DirtyCardToOopClosure* dcto_cl = sp->new_dcto_cl(cl, _ct_bs->precision(),
cl->gen_boundary());
ClearNoncleanCardWrapper clear_cl(dcto_cl, this);
! _ct_bs->non_clean_card_iterate(sp, sp->used_region_at_save_marks(),
dcto_cl, &clear_cl, false);
}
void CardTableRS::clear_into_younger(Generation* gen, bool clear_perm) {
GenCollectedHeap* gch = GenCollectedHeap::heap();
*** 291,322 ****
}
}
class VerifyCleanCardClosure: public OopClosure {
! HeapWord* boundary;
! HeapWord* begin; HeapWord* end;
! public:
! void do_oop(oop* p) {
HeapWord* jp = (HeapWord*)p;
! if (jp >= begin && jp < end) {
! guarantee(*p == NULL || (HeapWord*)p < boundary
! || (HeapWord*)(*p) >= boundary,
"pointer on clean card crosses boundary");
}
}
! VerifyCleanCardClosure(HeapWord* b, HeapWord* _begin, HeapWord* _end) :
! boundary(b), begin(_begin), end(_end) {}
};
class VerifyCTSpaceClosure: public SpaceClosure {
CardTableRS* _ct;
HeapWord* _boundary;
public:
VerifyCTSpaceClosure(CardTableRS* ct, HeapWord* boundary) :
_ct(ct), _boundary(boundary) {}
! void do_space(Space* s) { _ct->verify_space(s, _boundary); }
};
class VerifyCTGenClosure: public GenCollectedHeap::GenClosure {
CardTableRS* _ct;
public:
--- 305,344 ----
}
}
class VerifyCleanCardClosure: public OopClosure {
! private:
! HeapWord* _boundary;
! HeapWord* _begin;
! HeapWord* _end;
! protected:
! template <class T> void do_oop_work(T* p) {
HeapWord* jp = (HeapWord*)p;
! if (jp >= _begin && jp < _end) {
! oop obj = oopDesc::load_decode_heap_oop(p);
! guarantee(obj == NULL ||
! (HeapWord*)p < _boundary ||
! (HeapWord*)obj >= _boundary,
"pointer on clean card crosses boundary");
}
}
! public:
! VerifyCleanCardClosure(HeapWord* b, HeapWord* begin, HeapWord* end) :
! _boundary(b), _begin(begin), _end(end) {}
! virtual void do_oop(oop* p) { VerifyCleanCardClosure::do_oop_work(p); }
! virtual void do_oop(narrowOop* p) { VerifyCleanCardClosure::do_oop_work(p); }
};
class VerifyCTSpaceClosure: public SpaceClosure {
+ private:
CardTableRS* _ct;
HeapWord* _boundary;
public:
VerifyCTSpaceClosure(CardTableRS* ct, HeapWord* boundary) :
_ct(ct), _boundary(boundary) {}
! virtual void do_space(Space* s) { _ct->verify_space(s, _boundary); }
};
class VerifyCTGenClosure: public GenCollectedHeap::GenClosure {
CardTableRS* _ct;
public:
*** 542,552 ****
Generation* pg = SharedHeap::heap()->perm_gen();
HeapWord* pg_boundary = pg->reserved().start();
if (ch->kind() == CollectedHeap::GenCollectedHeap) {
GenCollectedHeap::heap()->generation_iterate(&blk, false);
! _ct_bs.verify();
// If the old gen collections also collect perm, then we are only
// interested in perm-to-young pointers, not perm-to-old pointers.
GenCollectedHeap* gch = GenCollectedHeap::heap();
CollectorPolicy* cp = gch->collector_policy();
--- 564,574 ----
Generation* pg = SharedHeap::heap()->perm_gen();
HeapWord* pg_boundary = pg->reserved().start();
if (ch->kind() == CollectedHeap::GenCollectedHeap) {
GenCollectedHeap::heap()->generation_iterate(&blk, false);
! _ct_bs->verify();
// If the old gen collections also collect perm, then we are only
// interested in perm-to-young pointers, not perm-to-old pointers.
GenCollectedHeap* gch = GenCollectedHeap::heap();
CollectorPolicy* cp = gch->collector_policy();
*** 557,570 ****
VerifyCTSpaceClosure perm_space_blk(this, pg_boundary);
SharedHeap::heap()->perm_gen()->space_iterate(&perm_space_blk, true);
}
! void CardTableRS::verify_empty(MemRegion mr) {
if (!mr.is_empty()) {
jbyte* cur_entry = byte_for(mr.start());
jbyte* limit = byte_after(mr.last());
for (;cur_entry < limit; cur_entry++) {
guarantee(*cur_entry == CardTableModRefBS::clean_card,
"Unexpected dirty card found");
}
}
--- 579,598 ----
VerifyCTSpaceClosure perm_space_blk(this, pg_boundary);
SharedHeap::heap()->perm_gen()->space_iterate(&perm_space_blk, true);
}
! void CardTableRS::verify_aligned_region_empty(MemRegion mr) {
if (!mr.is_empty()) {
jbyte* cur_entry = byte_for(mr.start());
jbyte* limit = byte_after(mr.last());
+ // The region mr may not start on a card boundary so
+ // the first card may reflect a write to the space
+ // just prior to mr.
+ if (!is_aligned(mr.start())) {
+ cur_entry++;
+ }
for (;cur_entry < limit; cur_entry++) {
guarantee(*cur_entry == CardTableModRefBS::clean_card,
"Unexpected dirty card found");
}
}