aboutsummaryrefslogtreecommitdiff
path: root/src/share/vm/gc_implementation
diff options
context:
space:
mode:
authorpoonam <none@none>2014-08-19 02:05:49 -0700
committerpoonam <none@none>2014-08-19 02:05:49 -0700
commit56e14c1eba290db71f52a648cbb5acbc15cf73f4 (patch)
treec37fc9931ca925403b1116fb52be96e9eb2dc9b2 /src/share/vm/gc_implementation
parente008d70efab96e2f6f604bdbe120b8ca72ad8090 (diff)
downloadjdk8u_hotspot-56e14c1eba290db71f52a648cbb5acbc15cf73f4.tar.gz
8044406: JVM crash with JDK8 (build 1.8.0-b132) with G1 GC
Summary: Fill the last card that has been allocated into with a dummy object Reviewed-by: tschatzl, mgerdin
Diffstat (limited to 'src/share/vm/gc_implementation')
-rw-r--r--src/share/vm/gc_implementation/g1/g1AllocRegion.hpp2
-rw-r--r--src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp29
-rw-r--r--src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp7
3 files changed, 37 insertions, 1 deletions
diff --git a/src/share/vm/gc_implementation/g1/g1AllocRegion.hpp b/src/share/vm/gc_implementation/g1/g1AllocRegion.hpp
index 050490dbb..50cc9be07 100644
--- a/src/share/vm/gc_implementation/g1/g1AllocRegion.hpp
+++ b/src/share/vm/gc_implementation/g1/g1AllocRegion.hpp
@@ -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);
diff --git a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
index c3aad9f4c..8b88e109a 100644
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
@@ -7053,6 +7053,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 {
diff --git a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
index 162ffbad3..4b7e45c6f 100644
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
@@ -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.