src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp
Print this page
rev 6334 : 8035400: Move G1ParScanThreadState into its own files
Summary: Extract the G1ParScanThreadState class from G1CollectedHeap.?pp into its own files.
Reviewed-by: brutisso, mgerdin
rev 6335 : 8035401: Fix visibility of G1ParScanThreadState members
Summary: After JDK-8035400 there were several opportunities to fix the visibility of several members of the G1ParScanThreadState class.
Reviewed-by: brutisso, mgerdin
@@ -67,10 +67,15 @@
_alloc_buffers[GCAllocForTenured] = &_tenured_alloc_buffer;
_start = os::elapsedTime();
}
+G1ParScanThreadState::~G1ParScanThreadState() {
+ retire_alloc_buffers();
+ FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base, mtGC);
+}
+
void
G1ParScanThreadState::print_termination_stats_hdr(outputStream* const st)
{
st->print_raw_cr("GC Termination Stats");
st->print_raw_cr(" elapsed --strong roots-- -------termination-------"
@@ -137,18 +142,18 @@
assert(_evac_failure_cl != NULL, "not set");
StarTask ref;
do {
// Drain the overflow stack first, so other threads can steal.
- while (refs()->pop_overflow(ref)) {
- deal_with_reference(ref);
+ while (_refs->pop_overflow(ref)) {
+ dispatch_reference(ref);
}
- while (refs()->pop_local(ref)) {
- deal_with_reference(ref);
+ while (_refs->pop_local(ref)) {
+ dispatch_reference(ref);
}
- } while (!refs()->is_empty());
+ } while (!_refs->is_empty());
}
oop G1ParScanThreadState::copy_to_survivor_space(oop const old) {
size_t word_sz = old->size();
HeapRegion* from_region = _g1h->heap_region_containing_raw(old);
@@ -247,5 +252,58 @@
undo_allocation(alloc_purpose, obj_ptr, word_sz);
obj = forward_ptr;
}
return obj;
}
+
+HeapWord* G1ParScanThreadState::allocate_slow(GCAllocPurpose purpose, size_t word_sz) {
+ HeapWord* obj = NULL;
+ size_t gclab_word_size = _g1h->desired_plab_sz(purpose);
+ if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) {
+ G1ParGCAllocBuffer* alloc_buf = alloc_buffer(purpose);
+ add_to_alloc_buffer_waste(alloc_buf->words_remaining());
+ alloc_buf->retire(false /* end_of_gc */, false /* retain */);
+
+ HeapWord* buf = _g1h->par_allocate_during_gc(purpose, gclab_word_size);
+ if (buf == NULL) {
+ return NULL; // Let caller handle allocation failure.
+ }
+ // Otherwise.
+ alloc_buf->set_word_size(gclab_word_size);
+ alloc_buf->set_buf(buf);
+
+ obj = alloc_buf->allocate(word_sz);
+ assert(obj != NULL, "buffer was definitely big enough...");
+ } else {
+ obj = _g1h->par_allocate_during_gc(purpose, word_sz);
+ }
+ return obj;
+}
+
+void G1ParScanThreadState::undo_allocation(GCAllocPurpose purpose, HeapWord* obj, size_t word_sz) {
+ if (alloc_buffer(purpose)->contains(obj)) {
+ assert(alloc_buffer(purpose)->contains(obj + word_sz - 1),
+ "should contain whole object");
+ alloc_buffer(purpose)->undo_allocation(obj, word_sz);
+ } else {
+ CollectedHeap::fill_with_object(obj, word_sz);
+ add_to_undo_waste(word_sz);
+ }
+}
+
+HeapWord* G1ParScanThreadState::allocate(GCAllocPurpose purpose, size_t word_sz) {
+ HeapWord* obj = alloc_buffer(purpose)->allocate(word_sz);
+ if (obj != NULL) {
+ return obj;
+ }
+ return allocate_slow(purpose, word_sz);
+}
+
+void G1ParScanThreadState::retire_alloc_buffers() {
+ for (int ap = 0; ap < GCAllocPurposeCount; ++ap) {
+ size_t waste = _alloc_buffers[ap]->words_remaining();
+ add_to_alloc_buffer_waste(waste);
+ _alloc_buffers[ap]->flush_stats_and_retire(_g1h->stats_for_purpose((GCAllocPurpose)ap),
+ true /* end_of_gc */,
+ false /* retain */);
+ }
+}