diff -r b27ec66071c7 -r 72a43d3841e7 hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp Thu Sep 04 16:53:27 2014 -0700 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp Fri Sep 05 09:49:19 2014 +0200 @@ -38,11 +38,8 @@ _g1_rem(g1h->g1_rem_set()), _hash_seed(17), _queue_num(queue_num), _term_attempts(0), - _surviving_alloc_buffer(g1h->desired_plab_sz(GCAllocForSurvived)), - _tenured_alloc_buffer(g1h->desired_plab_sz(GCAllocForTenured)), _age_table(false), _scanner(g1h, rp), - _strong_roots_time(0), _term_time(0), - _alloc_buffer_waste(0), _undo_waste(0) { + _strong_roots_time(0), _term_time(0) { _scanner.set_par_scan_thread_state(this); // we allocate G1YoungSurvRateNumRegions plus one entries, since // we "sacrifice" entry 0 to keep track of surviving bytes for @@ -60,14 +57,14 @@ _surviving_young_words = _surviving_young_words_base + PADDING_ELEM_NUM; memset(_surviving_young_words, 0, (size_t) real_length * sizeof(size_t)); - _alloc_buffers[GCAllocForSurvived] = &_surviving_alloc_buffer; - _alloc_buffers[GCAllocForTenured] = &_tenured_alloc_buffer; + _g1_par_allocator = G1ParGCAllocator::create_allocator(_g1h); _start = os::elapsedTime(); } G1ParScanThreadState::~G1ParScanThreadState() { - retire_alloc_buffers(); + _g1_par_allocator->retire_alloc_buffers(); + delete _g1_par_allocator; FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base, mtGC); } @@ -90,14 +87,16 @@ const double elapsed_ms = elapsed_time() * 1000.0; const double s_roots_ms = strong_roots_time() * 1000.0; const double term_ms = term_time() * 1000.0; + const size_t alloc_buffer_waste = _g1_par_allocator->alloc_buffer_waste(); + const size_t undo_waste = _g1_par_allocator->undo_waste(); st->print_cr("%3d %9.2f %9.2f %6.2f " "%9.2f %6.2f " SIZE_FORMAT_W(8) " " SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7), i, elapsed_ms, s_roots_ms, s_roots_ms * 100 / elapsed_ms, term_ms, term_ms * 100 / elapsed_ms, term_attempts(), - (alloc_buffer_waste() + undo_waste()) * HeapWordSize / K, - alloc_buffer_waste() * HeapWordSize / K, - undo_waste() * HeapWordSize / K); + (alloc_buffer_waste + undo_waste) * HeapWordSize / K, + alloc_buffer_waste * HeapWordSize / K, + undo_waste * HeapWordSize / K); } #ifdef ASSERT @@ -164,12 +163,13 @@ : m->age(); GCAllocPurpose alloc_purpose = g1p->evacuation_destination(from_region, age, word_sz); - HeapWord* obj_ptr = allocate(alloc_purpose, word_sz); + AllocationContext_t context = from_region->allocation_context(); + HeapWord* obj_ptr = _g1_par_allocator->allocate(alloc_purpose, word_sz, context); #ifndef PRODUCT // Should this evacuation fail? if (_g1h->evacuation_should_fail()) { if (obj_ptr != NULL) { - undo_allocation(alloc_purpose, obj_ptr, word_sz); + _g1_par_allocator->undo_allocation(alloc_purpose, obj_ptr, word_sz, context); obj_ptr = NULL; } } @@ -246,66 +246,8 @@ obj->oop_iterate_backwards(&_scanner); } } else { - undo_allocation(alloc_purpose, obj_ptr, word_sz); + _g1_par_allocator->undo_allocation(alloc_purpose, obj_ptr, word_sz, context); 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 = NULL; - if (purpose == GCAllocForSurvived) { - obj = alloc_buffer(GCAllocForSurvived)->allocate_aligned(word_sz, SurvivorAlignmentInBytes); - } else { - obj = alloc_buffer(GCAllocForTenured)->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 */); - } -}