src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp

Print this page
rev 6626 : imported patch 8035400-move-g1parscanthreadstate-into-own-files
rev 6627 : imported patch 8035400-2-bengt-fixes
rev 6628 : imported patch 8035401-fix-visibility-of-g1parscanthreadstate
rev 6629 : imported patch 8035401-3-fix-constructor
rev 6630 : imported patch 8035401-2-another-inline-try

*** 67,76 **** --- 67,81 ---- _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,154 **** 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_local(ref)) { ! deal_with_reference(ref); } ! } 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); --- 142,159 ---- 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)) { ! dispatch_reference(ref); } ! while (_refs->pop_local(ref)) { ! dispatch_reference(ref); } ! } 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,251 **** --- 252,309 ---- 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 */); + } + }