--- a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp Mon Aug 18 19:30:24 2014 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp Tue Aug 19 14:09:10 2014 +0200
@@ -33,31 +33,26 @@
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
+void G1CardCountsMappingChangedListener::on_commit(uint start_idx, size_t num_regions) {
+ MemRegion mr(G1CollectedHeap::heap()->bottom_addr_for_region(start_idx), num_regions * HeapRegion::GrainWords);
+ _counts->clear_range(mr);
+}
+
void G1CardCounts::clear_range(size_t from_card_num, size_t to_card_num) {
if (has_count_table()) {
- assert(from_card_num >= 0 && from_card_num < _committed_max_card_num,
- err_msg("from card num out of range: "SIZE_FORMAT, from_card_num));
assert(from_card_num < to_card_num,
err_msg("Wrong order? from: " SIZE_FORMAT ", to: "SIZE_FORMAT,
from_card_num, to_card_num));
- assert(to_card_num <= _committed_max_card_num,
- err_msg("to card num out of range: "
- "to: "SIZE_FORMAT ", "
- "max: "SIZE_FORMAT,
- to_card_num, _committed_max_card_num));
-
- to_card_num = MIN2(_committed_max_card_num, to_card_num);
-
Copy::fill_to_bytes(&_card_counts[from_card_num], (to_card_num - from_card_num));
}
}
G1CardCounts::G1CardCounts(G1CollectedHeap *g1h):
- _g1h(g1h), _card_counts(NULL),
- _reserved_max_card_num(0), _committed_max_card_num(0),
- _committed_size(0) {}
+ _listener(), _g1h(g1h), _card_counts(NULL), _reserved_max_card_num(0) {
+ _listener.set_cardcounts(this);
+}
-void G1CardCounts::initialize() {
+void G1CardCounts::initialize(G1RegionToSpaceMapper* mapper) {
assert(_g1h->max_capacity() > 0, "initialization order");
assert(_g1h->capacity() == 0, "initialization order");
@@ -70,70 +65,9 @@
_ct_bs = _g1h->g1_barrier_set();
_ct_bot = _ct_bs->byte_for_const(_g1h->reserved_region().start());
- // Allocate/Reserve the counts table
- size_t reserved_bytes = _g1h->max_capacity();
- _reserved_max_card_num = reserved_bytes >> CardTableModRefBS::card_shift;
-
- size_t reserved_size = _reserved_max_card_num * sizeof(jbyte);
- ReservedSpace rs(ReservedSpace::allocation_align_size_up(reserved_size));
- if (!rs.is_reserved()) {
- warning("Could not reserve enough space for the card counts table");
- guarantee(!has_reserved_count_table(), "should be NULL");
- return;
- }
-
- MemTracker::record_virtual_memory_type((address)rs.base(), mtGC);
-
- _card_counts_storage.initialize(rs, 0);
- _card_counts = (jubyte*) _card_counts_storage.low();
- }
-}
-
-void G1CardCounts::resize(size_t heap_capacity) {
- // Expand the card counts table to handle a heap with the given capacity.
-
- if (!has_reserved_count_table()) {
- // Don't expand if we failed to reserve the card counts table.
- return;
- }
-
- assert(_committed_size ==
- ReservedSpace::allocation_align_size_up(_committed_size),
- err_msg("Unaligned? committed_size: " SIZE_FORMAT, _committed_size));
-
- // Verify that the committed space for the card counts matches our
- // committed max card num. Note for some allocation alignments, the
- // amount of space actually committed for the counts table will be able
- // to span more cards than the number spanned by the maximum heap.
- size_t prev_committed_size = _committed_size;
- size_t prev_committed_card_num = committed_to_card_num(prev_committed_size);
-
- assert(prev_committed_card_num == _committed_max_card_num,
- err_msg("Card mismatch: "
- "prev: " SIZE_FORMAT ", "
- "committed: "SIZE_FORMAT", "
- "reserved: "SIZE_FORMAT,
- prev_committed_card_num, _committed_max_card_num, _reserved_max_card_num));
-
- size_t new_size = (heap_capacity >> CardTableModRefBS::card_shift) * sizeof(jbyte);
- size_t new_committed_size = ReservedSpace::allocation_align_size_up(new_size);
- size_t new_committed_card_num = committed_to_card_num(new_committed_size);
-
- if (_committed_max_card_num < new_committed_card_num) {
- // we need to expand the backing store for the card counts
- size_t expand_size = new_committed_size - prev_committed_size;
-
- if (!_card_counts_storage.expand_by(expand_size)) {
- warning("Card counts table backing store commit failure");
- return;
- }
- assert(_card_counts_storage.committed_size() == new_committed_size,
- "expansion commit failure");
-
- _committed_size = new_committed_size;
- _committed_max_card_num = new_committed_card_num;
-
- clear_range(prev_committed_card_num, _committed_max_card_num);
+ _card_counts = (jubyte*) mapper->reserved().start();
+ _reserved_max_card_num = mapper->reserved().byte_size();
+ mapper->set_mapping_changed_listener(&_listener);
}
}
@@ -149,12 +83,13 @@
uint count = 0;
if (has_count_table()) {
size_t card_num = ptr_2_card_num(card_ptr);
- if (card_num < _committed_max_card_num) {
- count = (uint) _card_counts[card_num];
- if (count < G1ConcRSHotCardLimit) {
- _card_counts[card_num] =
- (jubyte)(MIN2((uintx)(_card_counts[card_num] + 1), G1ConcRSHotCardLimit));
- }
+ assert(card_num < _reserved_max_card_num,
+ err_msg("Card "SIZE_FORMAT" outside of card counts table (max size "SIZE_FORMAT")",
+ card_num, _reserved_max_card_num));
+ count = (uint) _card_counts[card_num];
+ if (count < G1ConcRSHotCardLimit) {
+ _card_counts[card_num] =
+ (jubyte)(MIN2((uintx)(_card_counts[card_num] + 1), G1ConcRSHotCardLimit));
}
}
return count;
@@ -165,31 +100,23 @@
}
void G1CardCounts::clear_region(HeapRegion* hr) {
- assert(!hr->isHumongous(), "Should have been cleared");
- if (has_count_table()) {
- HeapWord* bottom = hr->bottom();
+ MemRegion mr(hr->bottom(), hr->end());
+ clear_range(mr);
+}
- // We use the last address in hr as hr could be the
- // last region in the heap. In which case trying to find
- // the card for hr->end() will be an OOB access to the
- // card table.
- HeapWord* last = hr->end() - 1;
- assert(_g1h->g1_committed().contains(last),
- err_msg("last not in committed: "
- "last: " PTR_FORMAT ", "
- "committed: [" PTR_FORMAT ", " PTR_FORMAT ")",
- last,
- _g1h->g1_committed().start(),
- _g1h->g1_committed().end()));
-
- const jbyte* from_card_ptr = _ct_bs->byte_for_const(bottom);
- const jbyte* last_card_ptr = _ct_bs->byte_for_const(last);
+void G1CardCounts::clear_range(MemRegion mr) {
+ if (has_count_table()) {
+ const jbyte* from_card_ptr = _ct_bs->byte_for_const(mr.start());
+ // We use the last address in the range as the range could represent the
+ // last region in the heap. In which case trying to find the card will be an
+ // OOB access to the card table.
+ const jbyte* last_card_ptr = _ct_bs->byte_for_const(mr.last());
#ifdef ASSERT
HeapWord* start_addr = _ct_bs->addr_for(from_card_ptr);
- assert(start_addr == hr->bottom(), "alignment");
+ assert(start_addr == mr.start(), "MemRegion start must be aligned to a card.");
HeapWord* last_addr = _ct_bs->addr_for(last_card_ptr);
- assert((last_addr + CardTableModRefBS::card_size_in_words) == hr->end(), "alignment");
+ assert((last_addr + CardTableModRefBS::card_size_in_words) == mr.end(), "MemRegion end must be aligned to a card.");
#endif // ASSERT
// Clear the counts for the (exclusive) card range.
@@ -199,14 +126,22 @@
}
}
+class G1CardCountsClearClosure : public HeapRegionClosure {
+ private:
+ G1CardCounts* _card_counts;
+ public:
+ G1CardCountsClearClosure(G1CardCounts* card_counts) :
+ HeapRegionClosure(), _card_counts(card_counts) { }
+
+
+ virtual bool doHeapRegion(HeapRegion* r) {
+ _card_counts->clear_region(r);
+ return false;
+ }
+};
+
void G1CardCounts::clear_all() {
assert(SafepointSynchronize::is_at_safepoint(), "don't call this otherwise");
- clear_range((size_t)0, _committed_max_card_num);
+ G1CardCountsClearClosure cl(this);
+ _g1h->heap_region_iterate(&cl);
}
-
-G1CardCounts::~G1CardCounts() {
- if (has_reserved_count_table()) {
- _card_counts_storage.release();
- }
-}
-