< prev index next >
src/share/vm/gc/g1/g1CardLiveData.cpp
Print this page
rev 10869 : [mq]: 8153170-kim-review
@@ -26,20 +26,22 @@
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1ConcurrentMark.inline.hpp"
#include "gc/g1/g1CardLiveData.inline.hpp"
#include "gc/g1/suspendibleThreadSet.hpp"
#include "gc/shared/workgroup.hpp"
+#include "logging/log.hpp"
#include "memory/universe.hpp"
#include "runtime/atomic.inline.hpp"
#include "runtime/globals.hpp"
#include "runtime/os.hpp"
#include "utilities/bitMap.inline.hpp"
#include "utilities/debug.hpp"
G1CardLiveData::G1CardLiveData() :
_max_capacity(0),
_cards_per_region(0),
+ _gc_timestamp_at_create(0),
_live_regions(NULL),
_live_regions_size_in_bits(0),
_live_cards(NULL),
_live_cards_size_in_bits(0) {
}
@@ -125,10 +127,17 @@
// We cache the last mark set. This avoids setting the same bit multiple times.
// This is particularly interesting for dense bitmaps, as this avoids doing
// lots of work most of the time.
BitMap::idx_t _last_marked_bit_idx;
+ void clear_card_bitmap_range(HeapWord* start, HeapWord* end) {
+ BitMap::idx_t start_idx = card_live_bitmap_index_for(start);
+ BitMap::idx_t end_idx = card_live_bitmap_index_for((HeapWord*)align_ptr_up(end, CardTableModRefBS::card_size));
+
+ _card_bm.clear_range(start_idx, end_idx);
+ }
+
// Mark the card liveness bitmap for the object spanning from start to end.
void mark_card_bitmap_range(HeapWord* start, HeapWord* end) {
BitMap::idx_t start_idx = card_live_bitmap_index_for(start);
BitMap::idx_t end_idx = card_live_bitmap_index_for((HeapWord*)align_ptr_up(end, CardTableModRefBS::card_size));
@@ -167,10 +176,14 @@
// bitmap to 1.
void set_bit_for_region(HeapRegion* hr) {
_region_bm.par_set_bit(hr->hrm_index());
}
+ void reset_live_data(HeapRegion* hr) {
+ clear_card_bitmap_range(hr->next_top_at_mark_start(), hr->end());
+ }
+
// Mark the range of bits covered by allocations done since the last marking
// in the given heap region, i.e. from NTAMS to top of the given region.
// Returns if there has been some allocation in this region since the last marking.
bool mark_allocated_since_marking(HeapRegion* hr) {
reset_mark_cache();
@@ -297,10 +310,12 @@
g1h->heap_region_par_iterate(&cl, worker_id, &_hr_claimer);
}
};
void G1CardLiveData::create(WorkGang* workers, G1CMBitMap* mark_bitmap) {
+ _gc_timestamp_at_create = G1CollectedHeap::heap()->get_gc_time_stamp();
+
uint n_workers = workers->active_workers();
G1CreateCardLiveDataTask cl(mark_bitmap,
this,
n_workers);
@@ -314,18 +329,28 @@
// card liveness bitmap. Also sets the bit for each region
// containing live data, in the region liveness bitmap.
class G1FinalizeCardLiveDataClosure: public HeapRegionClosure {
private:
G1CardLiveDataHelper _helper;
+
+ uint _gc_timestamp_at_create;
+
+ bool has_been_reclaimed(HeapRegion* hr) const {
+ return hr->get_gc_time_stamp() > _gc_timestamp_at_create;
+ }
public:
G1FinalizeCardLiveDataClosure(G1CollectedHeap* g1h,
G1CMBitMap* bitmap,
G1CardLiveData* live_data) :
HeapRegionClosure(),
- _helper(live_data, g1h->reserved_region().start()) { }
+ _helper(live_data, g1h->reserved_region().start()),
+ _gc_timestamp_at_create(live_data->gc_timestamp_at_create()) { }
bool doHeapRegion(HeapRegion* hr) {
+ if (has_been_reclaimed(hr)) {
+ _helper.reset_live_data(hr);
+ }
bool allocated_since_marking = _helper.mark_allocated_since_marking(hr);
if (allocated_since_marking || hr->next_marked_bytes() > 0) {
_helper.set_bit_for_region(hr);
}
return false;
@@ -451,12 +476,14 @@
size_t exp_marked_bytes = create_live_data_count(hr);
size_t act_marked_bytes = hr->next_marked_bytes();
// Verify the marked bytes for this region.
if (exp_marked_bytes != act_marked_bytes) {
+ log_error(gc)("Expected marked bytes " SIZE_FORMAT " != actual marked bytes " SIZE_FORMAT " in region %u", exp_marked_bytes, act_marked_bytes, hr->hrm_index());
failures += 1;
} else if (exp_marked_bytes > HeapRegion::GrainBytes) {
+ log_error(gc)("Expected marked bytes " SIZE_FORMAT " larger than possible " SIZE_FORMAT " in region %u", exp_marked_bytes, HeapRegion::GrainBytes, hr->hrm_index());
failures += 1;
}
// Verify the bit, for this region, in the actual and expected
// (which was just calculated) region bit maps.
@@ -464,11 +491,12 @@
// bitmap is set and the bit in the actual region bitmap is not.
uint index = hr->hrm_index();
bool expected = _exp_live_data->is_region_live(index);
bool actual = _act_live_data->is_region_live(index);
- if (expected && !actual) {
+ if (expected != actual) {
+ log_error(gc)("Expected liveness %d not equal actual %d in region %u", expected, actual, hr->hrm_index());
failures += 1;
}
// Verify that the card bit maps for the cards spanned by the current
// region match. We have an error if we have a set bit in the expected
@@ -479,11 +507,12 @@
for (BitMap::idx_t i = start_idx; i < end_idx; i+=1) {
expected = _exp_live_data->is_card_live_at(i);
actual = _act_live_data->is_card_live_at(i);
- if (expected && !actual) {
+ if (expected != actual) {
+ log_error(gc)("Expected card liveness %d not equal actual card liveness %d at card " SIZE_FORMAT " in region %u", expected, actual, i, hr->hrm_index());
failures += 1;
}
}
_failures += failures;
< prev index next >