8044406: JVM crash with JDK8 (build 1.8.0-b132) with G1 GC
Fill the last card that has been allocated into with a dummy object Reviewed-by: tschatzl, mgerdin
This commit is contained in:
parent
17e9dba8e9
commit
2617d54723
@ -173,7 +173,7 @@ public:
|
||||
|
||||
// Should be called when we want to release the active region which
|
||||
// is returned after it's been retired.
|
||||
HeapRegion* release();
|
||||
virtual HeapRegion* release();
|
||||
|
||||
#if G1_ALLOC_REGION_TRACING
|
||||
void trace(const char* str, size_t word_size = 0, HeapWord* result = NULL);
|
||||
|
@ -6833,6 +6833,35 @@ void OldGCAllocRegion::retire_region(HeapRegion* alloc_region,
|
||||
_g1h->retire_gc_alloc_region(alloc_region, allocated_bytes,
|
||||
GCAllocForTenured);
|
||||
}
|
||||
|
||||
HeapRegion* OldGCAllocRegion::release() {
|
||||
HeapRegion* cur = get();
|
||||
if (cur != NULL) {
|
||||
// Determine how far we are from the next card boundary. If it is smaller than
|
||||
// the minimum object size we can allocate into, expand into the next card.
|
||||
HeapWord* top = cur->top();
|
||||
HeapWord* aligned_top = (HeapWord*)align_ptr_up(top, G1BlockOffsetSharedArray::N_bytes);
|
||||
|
||||
size_t to_allocate_words = pointer_delta(aligned_top, top, HeapWordSize);
|
||||
|
||||
if (to_allocate_words != 0) {
|
||||
// We are not at a card boundary. Fill up, possibly into the next, taking the
|
||||
// end of the region and the minimum object size into account.
|
||||
to_allocate_words = MIN2(pointer_delta(cur->end(), cur->top(), HeapWordSize),
|
||||
MAX2(to_allocate_words, G1CollectedHeap::min_fill_size()));
|
||||
|
||||
// Skip allocation if there is not enough space to allocate even the smallest
|
||||
// possible object. In this case this region will not be retained, so the
|
||||
// original problem cannot occur.
|
||||
if (to_allocate_words >= G1CollectedHeap::min_fill_size()) {
|
||||
HeapWord* dummy = attempt_allocation(to_allocate_words, true /* bot_updates */);
|
||||
CollectedHeap::fill_with_object(dummy, to_allocate_words);
|
||||
}
|
||||
}
|
||||
}
|
||||
return G1AllocRegion::release();
|
||||
}
|
||||
|
||||
// Heap region set verification
|
||||
|
||||
class VerifyRegionListsClosure : public HeapRegionClosure {
|
||||
|
@ -183,6 +183,13 @@ protected:
|
||||
public:
|
||||
OldGCAllocRegion()
|
||||
: G1AllocRegion("Old GC Alloc Region", true /* bot_updates */) { }
|
||||
|
||||
// This specialization of release() makes sure that the last card that has been
|
||||
// allocated into has been completely filled by a dummy object.
|
||||
// This avoids races when remembered set scanning wants to update the BOT of the
|
||||
// last card in the retained old gc alloc region, and allocation threads
|
||||
// allocating into that card at the same time.
|
||||
virtual HeapRegion* release();
|
||||
};
|
||||
|
||||
// The G1 STW is alive closure.
|
||||
|
Loading…
Reference in New Issue
Block a user