< prev index next >
src/share/vm/gc/g1/concurrentMark.cpp
Print this page
*** 804,819 ****
virtual bool doHeapRegion(HeapRegion* r) {
// This closure can be called concurrently to the mutator, so we must make sure
// that the result of the getNextMarkedWordAddress() call is compared to the
// value passed to it as limit to detect any found bits.
! // We can use the region's orig_end() for the limit and the comparison value
! // as it always contains the "real" end of the region that never changes and
! // has no side effects.
! // Due to the latter, there can also be no problem with the compiler generating
! // reloads of the orig_end() call.
! HeapWord* end = r->orig_end();
return _bitmap->getNextMarkedWordAddress(r->bottom(), end) != end;
}
};
bool ConcurrentMark::nextMarkBitmapIsClear() {
--- 804,815 ----
virtual bool doHeapRegion(HeapRegion* r) {
// This closure can be called concurrently to the mutator, so we must make sure
// that the result of the getNextMarkedWordAddress() call is compared to the
// value passed to it as limit to detect any found bits.
! // end never changes in G1.
! HeapWord* end = r->end();
return _bitmap->getNextMarkedWordAddress(r->bottom(), end) != end;
}
};
bool ConcurrentMark::nextMarkBitmapIsClear() {
*** 823,835 ****
}
class NoteStartOfMarkHRClosure: public HeapRegionClosure {
public:
bool doHeapRegion(HeapRegion* r) {
- if (!r->is_continues_humongous()) {
r->note_start_of_marking();
- }
return false;
}
};
void ConcurrentMark::checkpointRootsInitialPre() {
--- 819,829 ----
*** 1284,1309 ****
BitMap* _region_bm;
BitMap* _card_bm;
// Takes a region that's not empty (i.e., it has at least one
// live object in it and sets its corresponding bit on the region
! // bitmap to 1. If the region is "starts humongous" it will also set
! // to 1 the bits on the region bitmap that correspond to its
! // associated "continues humongous" regions.
void set_bit_for_region(HeapRegion* hr) {
- assert(!hr->is_continues_humongous(), "should have filtered those out");
-
BitMap::idx_t index = (BitMap::idx_t) hr->hrm_index();
- if (!hr->is_starts_humongous()) {
- // Normal (non-humongous) case: just set the bit.
_region_bm->par_at_put(index, true);
- } else {
- // Starts humongous case: calculate how many regions are part of
- // this humongous region and then set the bit range.
- BitMap::idx_t end_index = (BitMap::idx_t) hr->last_hc_index();
- _region_bm->par_at_put_range(index, end_index, true);
- }
}
public:
CMCountDataClosureBase(G1CollectedHeap* g1h,
BitMap* region_bm, BitMap* card_bm):
--- 1278,1291 ----
BitMap* _region_bm;
BitMap* _card_bm;
// Takes a region that's not empty (i.e., it has at least one
// live object in it and sets its corresponding bit on the region
! // bitmap to 1.
void set_bit_for_region(HeapRegion* hr) {
BitMap::idx_t index = (BitMap::idx_t) hr->hrm_index();
_region_bm->par_at_put(index, true);
}
public:
CMCountDataClosureBase(G1CollectedHeap* g1h,
BitMap* region_bm, BitMap* card_bm):
*** 1323,1344 ****
BitMap* region_bm, BitMap* card_bm) :
CMCountDataClosureBase(g1h, region_bm, card_bm),
_bm(bm), _region_marked_bytes(0) { }
bool doHeapRegion(HeapRegion* hr) {
-
- if (hr->is_continues_humongous()) {
- // We will ignore these here and process them when their
- // associated "starts humongous" region is processed (see
- // set_bit_for_heap_region()). Note that we cannot rely on their
- // associated "starts humongous" region to have their bit set to
- // 1 since, due to the region chunking in the parallel region
- // iteration, a "continues humongous" region might be visited
- // before its associated "starts humongous".
- return false;
- }
-
HeapWord* ntams = hr->next_top_at_mark_start();
HeapWord* start = hr->bottom();
assert(start <= hr->end() && start <= ntams && ntams <= hr->end(),
"Preconditions not met - "
--- 1305,1314 ----
*** 1372,1381 ****
--- 1342,1356 ----
_cm->set_card_bitmap_range(_card_bm, start_idx, end_idx, true /* is_par */);
// Add the size of this object to the number of marked bytes.
marked_bytes += (size_t)obj_sz * HeapWordSize;
+ // This will happen if we are handling a humongous object that spans
+ // several heap regions.
+ if (obj_end > hr->end()) {
+ break;
+ }
// Find the next marked object after this one.
start = _bm->getNextMarkedWordAddress(obj_end, ntams);
}
// Mark the allocated-since-marking portion...
*** 1444,1464 ****
_failures(0) { }
int failures() const { return _failures; }
bool doHeapRegion(HeapRegion* hr) {
- if (hr->is_continues_humongous()) {
- // We will ignore these here and process them when their
- // associated "starts humongous" region is processed (see
- // set_bit_for_heap_region()). Note that we cannot rely on their
- // associated "starts humongous" region to have their bit set to
- // 1 since, due to the region chunking in the parallel region
- // iteration, a "continues humongous" region might be visited
- // before its associated "starts humongous".
- return false;
- }
-
int failures = 0;
// Call the CalcLiveObjectsClosure to walk the marking bitmap for
// this region and set the corresponding bits in the expected region
// and card bitmaps.
--- 1419,1428 ----
*** 1467,1481 ****
// Verify the marked bytes for this region.
size_t exp_marked_bytes = _calc_cl.region_marked_bytes();
size_t act_marked_bytes = hr->next_marked_bytes();
// We're not OK if expected marked bytes > actual marked bytes. It means
// we have missed accounting some objects during the actual marking.
- if (exp_marked_bytes > act_marked_bytes) {
failures += 1;
}
// Verify the bit, for this region, in the actual and expected
// (which was just calculated) region bit maps.
// We're not OK if the bit in the calculated expected region
// bitmap is set and the bit in the actual region bitmap is not.
--- 1431,1460 ----
// Verify the marked bytes for this region.
size_t exp_marked_bytes = _calc_cl.region_marked_bytes();
size_t act_marked_bytes = hr->next_marked_bytes();
+ if (exp_marked_bytes > act_marked_bytes) {
+ if (hr->is_starts_humongous()) {
+ // For start_humongous regions, the size of the whole object will be
+ // in exp_marked_bytes.
+ HeapRegion* region = hr;
+ int num_regions;
+ for (num_regions = 0; region != NULL; num_regions++) {
+ region = _g1h->next_region_in_humongous(region);
+ }
+ if ((num_regions-1) * HeapRegion::GrainBytes >= exp_marked_bytes) {
+ failures += 1;
+ } else if (num_regions * HeapRegion::GrainBytes < exp_marked_bytes) {
+ failures += 1;
+ }
+ } else {
// We're not OK if expected marked bytes > actual marked bytes. It means
// we have missed accounting some objects during the actual marking.
failures += 1;
}
+ }
// Verify the bit, for this region, in the actual and expected
// (which was just calculated) region bit maps.
// We're not OK if the bit in the calculated expected region
// bitmap is set and the bit in the actual region bitmap is not.
*** 1571,1592 ****
BitMap* region_bm,
BitMap* card_bm) :
CMCountDataClosureBase(g1h, region_bm, card_bm) { }
bool doHeapRegion(HeapRegion* hr) {
-
- if (hr->is_continues_humongous()) {
- // We will ignore these here and process them when their
- // associated "starts humongous" region is processed (see
- // set_bit_for_heap_region()). Note that we cannot rely on their
- // associated "starts humongous" region to have their bit set to
- // 1 since, due to the region chunking in the parallel region
- // iteration, a "continues humongous" region might be visited
- // before its associated "starts humongous".
- return false;
- }
-
HeapWord* ntams = hr->next_top_at_mark_start();
HeapWord* top = hr->top();
assert(hr->bottom() <= ntams && ntams <= hr->end(), "Preconditions.");
--- 1550,1559 ----
*** 1679,1689 ****
size_t freed_bytes() { return _freed_bytes; }
const HeapRegionSetCount& old_regions_removed() { return _old_regions_removed; }
const HeapRegionSetCount& humongous_regions_removed() { return _humongous_regions_removed; }
bool doHeapRegion(HeapRegion *hr) {
! if (hr->is_continues_humongous() || hr->is_archive()) {
return false;
}
// We use a claim value of zero here because all regions
// were claimed with value 1 in the FinalCount task.
_g1->reset_gc_time_stamps(hr);
--- 1646,1656 ----
size_t freed_bytes() { return _freed_bytes; }
const HeapRegionSetCount& old_regions_removed() { return _old_regions_removed; }
const HeapRegionSetCount& humongous_regions_removed() { return _humongous_regions_removed; }
bool doHeapRegion(HeapRegion *hr) {
! if (hr->is_archive()) {
return false;
}
// We use a claim value of zero here because all regions
// were claimed with value 1 in the FinalCount task.
_g1->reset_gc_time_stamps(hr);
*** 1691,1701 ****
if (hr->used() > 0 && hr->max_live_bytes() == 0 && !hr->is_young()) {
_freed_bytes += hr->used();
hr->set_containing_set(NULL);
if (hr->is_humongous()) {
- assert(hr->is_starts_humongous(), "we should only see starts humongous");
_humongous_regions_removed.increment(1u, hr->capacity());
_g1->free_humongous_region(hr, _local_cleanup_list, true);
} else {
_old_regions_removed.increment(1u, hr->capacity());
_g1->free_region(hr, _local_cleanup_list, true);
--- 1658,1667 ----
*** 2340,2350 ****
// This is very similar to CMTask::deal_with_reference, but with
// more relaxed requirements for the argument, so this must be more
// circumspect about treating the argument as an object.
void do_entry(void* entry) const {
_task->increment_refs_reached();
! HeapRegion* hr = _g1h->heap_region_containing_raw(entry);
if (entry < hr->next_top_at_mark_start()) {
// Until we get here, we don't know whether entry refers to a valid
// object; it could instead have been a stale reference.
oop obj = static_cast<oop>(entry);
assert(obj->is_oop(true /* ignore mark word */),
--- 2306,2316 ----
// This is very similar to CMTask::deal_with_reference, but with
// more relaxed requirements for the argument, so this must be more
// circumspect about treating the argument as an object.
void do_entry(void* entry) const {
_task->increment_refs_reached();
! HeapRegion* hr = _g1h->heap_region_containing(entry);
if (entry < hr->next_top_at_mark_start()) {
// Until we get here, we don't know whether entry refers to a valid
// object; it could instead have been a stale reference.
oop obj = static_cast<oop>(entry);
assert(obj->is_oop(true /* ignore mark word */),
*** 2490,2525 ****
// _heap_end will not change underneath our feet; it only changes at
// yield points.
while (finger < _heap_end) {
assert(_g1h->is_in_g1_reserved(finger), "invariant");
! // Note on how this code handles humongous regions. In the
! // normal case the finger will reach the start of a "starts
! // humongous" (SH) region. Its end will either be the end of the
! // last "continues humongous" (CH) region in the sequence, or the
! // standard end of the SH region (if the SH is the only region in
! // the sequence). That way claim_region() will skip over the CH
! // regions. However, there is a subtle race between a CM thread
! // executing this method and a mutator thread doing a humongous
! // object allocation. The two are not mutually exclusive as the CM
! // thread does not need to hold the Heap_lock when it gets
! // here. So there is a chance that claim_region() will come across
! // a free region that's in the progress of becoming a SH or a CH
! // region. In the former case, it will either
! // a) Miss the update to the region's end, in which case it will
! // visit every subsequent CH region, will find their bitmaps
! // empty, and do nothing, or
! // b) Will observe the update of the region's end (in which case
! // it will skip the subsequent CH regions).
! // If it comes across a region that suddenly becomes CH, the
! // scenario will be similar to b). So, the race between
! // claim_region() and a humongous object allocation might force us
! // to do a bit of unnecessary work (due to some unnecessary bitmap
! // iterations) but it should not introduce and correctness issues.
! HeapRegion* curr_region = _g1h->heap_region_containing_raw(finger);
! // Above heap_region_containing_raw may return NULL as we always scan claim
// until the end of the heap. In this case, just jump to the next region.
HeapWord* end = curr_region != NULL ? curr_region->end() : finger + HeapRegion::GrainWords;
// Is the gap between reading the finger and doing the CAS too long?
HeapWord* res = (HeapWord*) Atomic::cmpxchg_ptr(end, &_finger, finger);
--- 2456,2468 ----
// _heap_end will not change underneath our feet; it only changes at
// yield points.
while (finger < _heap_end) {
assert(_g1h->is_in_g1_reserved(finger), "invariant");
! HeapRegion* curr_region = _g1h->heap_region_containing(finger);
! // Above heap_region_containing may return NULL as we always scan claim
// until the end of the heap. In this case, just jump to the next region.
HeapWord* end = curr_region != NULL ? curr_region->end() : finger + HeapRegion::GrainWords;
// Is the gap between reading the finger and doing the CAS too long?
HeapWord* res = (HeapWord*) Atomic::cmpxchg_ptr(end, &_finger, finger);
*** 2591,2610 ****
}
// Verify the global finger
HeapWord* global_finger = finger();
if (global_finger != NULL && global_finger < _heap_end) {
- // The global finger always points to a heap region boundary. We
- // use heap_region_containing_raw() to get the containing region
- // given that the global finger could be pointing to a free region
- // which subsequently becomes continues humongous. If that
- // happens, heap_region_containing() will return the bottom of the
- // corresponding starts humongous region and the check below will
- // not hold any more.
// Since we always iterate over all regions, we might get a NULL HeapRegion
// here.
! HeapRegion* global_hr = _g1h->heap_region_containing_raw(global_finger);
guarantee(global_hr == NULL || global_finger == global_hr->bottom(),
"global finger: " PTR_FORMAT " region: " HR_FORMAT,
p2i(global_finger), HR_FORMAT_PARAMS(global_hr));
}
--- 2534,2546 ----
}
// Verify the global finger
HeapWord* global_finger = finger();
if (global_finger != NULL && global_finger < _heap_end) {
// Since we always iterate over all regions, we might get a NULL HeapRegion
// here.
! HeapRegion* global_hr = _g1h->heap_region_containing(global_finger);
guarantee(global_hr == NULL || global_finger == global_hr->bottom(),
"global finger: " PTR_FORMAT " region: " HR_FORMAT,
p2i(global_finger), HR_FORMAT_PARAMS(global_hr));
}
*** 2613,2623 ****
for (uint i = 0; i < parallel_marking_threads(); ++i) {
CMTask* task = _tasks[i];
HeapWord* task_finger = task->finger();
if (task_finger != NULL && task_finger < _heap_end) {
// See above note on the global finger verification.
! HeapRegion* task_hr = _g1h->heap_region_containing_raw(task_finger);
guarantee(task_hr == NULL || task_finger == task_hr->bottom() ||
!task_hr->in_collection_set(),
"task finger: " PTR_FORMAT " region: " HR_FORMAT,
p2i(task_finger), HR_FORMAT_PARAMS(task_hr));
}
--- 2549,2559 ----
for (uint i = 0; i < parallel_marking_threads(); ++i) {
CMTask* task = _tasks[i];
HeapWord* task_finger = task->finger();
if (task_finger != NULL && task_finger < _heap_end) {
// See above note on the global finger verification.
! HeapRegion* task_hr = _g1h->heap_region_containing(task_finger);
guarantee(task_hr == NULL || task_finger == task_hr->bottom() ||
!task_hr->in_collection_set(),
"task finger: " PTR_FORMAT " region: " HR_FORMAT,
p2i(task_finger), HR_FORMAT_PARAMS(task_hr));
}
*** 2641,2661 ****
_g1h(g1h), _cm(g1h->concurrent_mark()),
_ct_bs(barrier_set_cast<CardTableModRefBS>(g1h->barrier_set())),
_cm_card_bm(cm_card_bm), _max_worker_id(max_worker_id) { }
bool doHeapRegion(HeapRegion* hr) {
- if (hr->is_continues_humongous()) {
- // We will ignore these here and process them when their
- // associated "starts humongous" region is processed.
- // Note that we cannot rely on their associated
- // "starts humongous" region to have their bit set to 1
- // since, due to the region chunking in the parallel region
- // iteration, a "continues humongous" region might be visited
- // before its associated "starts humongous".
- return false;
- }
-
HeapWord* start = hr->bottom();
HeapWord* limit = hr->next_top_at_mark_start();
HeapWord* end = hr->end();
assert(start <= limit && limit <= hr->top() && hr->top() <= hr->end(),
--- 2577,2586 ----
*** 2959,2970 ****
{ }
void CMTask::setup_for_region(HeapRegion* hr) {
assert(hr != NULL,
"claim_region() should have filtered out NULL regions");
- assert(!hr->is_continues_humongous(),
- "claim_region() should have filtered out continues humongous regions");
_curr_region = hr;
_finger = hr->bottom();
update_region_limit();
}
--- 2884,2893 ----
< prev index next >