Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp
38920 views
/*1* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "gc_implementation/g1/g1Allocator.hpp"26#include "gc_implementation/g1/g1CollectedHeap.hpp"27#include "gc_implementation/g1/g1CollectorPolicy.hpp"28#include "gc_implementation/g1/heapRegion.inline.hpp"29#include "gc_implementation/g1/heapRegionSet.inline.hpp"3031void G1DefaultAllocator::init_mutator_alloc_region() {32assert(_mutator_alloc_region.get() == NULL, "pre-condition");33_mutator_alloc_region.init();34}3536void G1DefaultAllocator::release_mutator_alloc_region() {37_mutator_alloc_region.release();38assert(_mutator_alloc_region.get() == NULL, "post-condition");39}4041void G1Allocator::reuse_retained_old_region(EvacuationInfo& evacuation_info,42OldGCAllocRegion* old,43HeapRegion** retained_old) {44HeapRegion* retained_region = *retained_old;45*retained_old = NULL;4647// We will discard the current GC alloc region if:48// a) it's in the collection set (it can happen!),49// b) it's already full (no point in using it),50// c) it's empty (this means that it was emptied during51// a cleanup and it should be on the free list now), or52// d) it's humongous (this means that it was emptied53// during a cleanup and was added to the free list, but54// has been subsequently used to allocate a humongous55// object that may be less than the region size).56if (retained_region != NULL &&57!retained_region->in_collection_set() &&58!(retained_region->top() == retained_region->end()) &&59!retained_region->is_empty() &&60!retained_region->isHumongous()) {61retained_region->record_timestamp();62// The retained region was added to the old region set when it was63// retired. We have to remove it now, since we don't allow regions64// we allocate to in the region sets. We'll re-add it later, when65// it's retired again.66_g1h->_old_set.remove(retained_region);67bool during_im = _g1h->g1_policy()->during_initial_mark_pause();68retained_region->note_start_of_copying(during_im);69old->set(retained_region);70_g1h->_hr_printer.reuse(retained_region);71evacuation_info.set_alloc_regions_used_before(retained_region->used());72}73}7475void G1DefaultAllocator::init_gc_alloc_regions(EvacuationInfo& evacuation_info) {76assert_at_safepoint(true /* should_be_vm_thread */);7778_survivor_gc_alloc_region.init();79_old_gc_alloc_region.init();80reuse_retained_old_region(evacuation_info,81&_old_gc_alloc_region,82&_retained_old_gc_alloc_region);83}8485void G1DefaultAllocator::release_gc_alloc_regions(uint no_of_gc_workers, EvacuationInfo& evacuation_info) {86AllocationContext_t context = AllocationContext::current();87evacuation_info.set_allocation_regions(survivor_gc_alloc_region(context)->count() +88old_gc_alloc_region(context)->count());89survivor_gc_alloc_region(context)->release();90// If we have an old GC alloc region to release, we'll save it in91// _retained_old_gc_alloc_region. If we don't92// _retained_old_gc_alloc_region will become NULL. This is what we93// want either way so no reason to check explicitly for either94// condition.95_retained_old_gc_alloc_region = old_gc_alloc_region(context)->release();96if (_retained_old_gc_alloc_region != NULL) {97_retained_old_gc_alloc_region->record_retained_region();98}99100if (ResizePLAB) {101_g1h->_survivor_plab_stats.adjust_desired_plab_sz(no_of_gc_workers);102_g1h->_old_plab_stats.adjust_desired_plab_sz(no_of_gc_workers);103}104}105106void G1DefaultAllocator::abandon_gc_alloc_regions() {107assert(survivor_gc_alloc_region(AllocationContext::current())->get() == NULL, "pre-condition");108assert(old_gc_alloc_region(AllocationContext::current())->get() == NULL, "pre-condition");109_retained_old_gc_alloc_region = NULL;110}111112G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) :113ParGCAllocBuffer(gclab_word_size), _retired(true) { }114115HeapWord* G1ParGCAllocator::allocate_direct_or_new_plab(InCSetState dest,116size_t word_sz,117AllocationContext_t context) {118size_t gclab_word_size = _g1h->desired_plab_sz(dest);119if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) {120G1ParGCAllocBuffer* alloc_buf = alloc_buffer(dest, context);121add_to_alloc_buffer_waste(alloc_buf->words_remaining());122alloc_buf->retire(false /* end_of_gc */, false /* retain */);123124HeapWord* buf = _g1h->par_allocate_during_gc(dest, gclab_word_size, context);125if (buf == NULL) {126return NULL; // Let caller handle allocation failure.127}128// Otherwise.129alloc_buf->set_word_size(gclab_word_size);130alloc_buf->set_buf(buf);131132HeapWord* const obj = alloc_buf->allocate(word_sz);133assert(obj != NULL, "buffer was definitely big enough...");134return obj;135} else {136return _g1h->par_allocate_during_gc(dest, word_sz, context);137}138}139140G1DefaultParGCAllocator::G1DefaultParGCAllocator(G1CollectedHeap* g1h) :141G1ParGCAllocator(g1h),142_surviving_alloc_buffer(g1h->desired_plab_sz(InCSetState::Young)),143_tenured_alloc_buffer(g1h->desired_plab_sz(InCSetState::Old)) {144for (uint state = 0; state < InCSetState::Num; state++) {145_alloc_buffers[state] = NULL;146}147_alloc_buffers[InCSetState::Young] = &_surviving_alloc_buffer;148_alloc_buffers[InCSetState::Old] = &_tenured_alloc_buffer;149}150151void G1DefaultParGCAllocator::retire_alloc_buffers() {152for (uint state = 0; state < InCSetState::Num; state++) {153G1ParGCAllocBuffer* const buf = _alloc_buffers[state];154if (buf != NULL) {155add_to_alloc_buffer_waste(buf->words_remaining());156buf->flush_stats_and_retire(_g1h->alloc_buffer_stats(state),157true /* end_of_gc */,158false /* retain */);159}160}161}162163164