From 681cbb5ed7fe010829471aaa8715410ec0f2c8b0 Mon Sep 17 00:00:00 2001 From: johnc Date: Mon, 6 Aug 2012 12:20:14 -0700 Subject: [PATCH] 6818524: G1: use ergonomic resizing of PLABs Summary: Employ PLABStats instances to record information about survivor and old PLABs, and use the recorded stats to adjust the sizes of survivor and old PLABS. Reviewed-by: johnc, ysr Contributed-by: Brandon Mitchell --- .../gc_implementation/g1/g1CollectedHeap.cpp | 20 ++++++++-- .../gc_implementation/g1/g1CollectedHeap.hpp | 39 +++++++++++++++---- .../parNew/parNewGeneration.cpp | 5 ++- .../parNew/parNewGeneration.hpp | 4 +- .../{parNew => shared}/parGCAllocBuffer.cpp | 8 ++-- .../{parNew => shared}/parGCAllocBuffer.hpp | 6 +-- src/share/vm/memory/tenuredGeneration.cpp | 4 +- src/share/vm/precompiled/precompiled.hpp | 4 +- 8 files changed, 63 insertions(+), 27 deletions(-) rename src/share/vm/gc_implementation/{parNew => shared}/parGCAllocBuffer.cpp (98%) rename src/share/vm/gc_implementation/{parNew => shared}/parGCAllocBuffer.hpp (97%) diff --git a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index 81e422262..7b54c481f 100644 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -1891,6 +1891,8 @@ G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) : _young_list(new YoungList(this)), _gc_time_stamp(0), _retained_old_gc_alloc_region(NULL), + _survivor_plab_stats(YoungPLABSize, PLABWeight), + _old_plab_stats(OldPLABSize, PLABWeight), _expand_heap_after_alloc_failure(true), _surviving_young_words(NULL), _old_marking_cycles_started(0), @@ -4099,17 +4101,22 @@ size_t G1CollectedHeap::desired_plab_sz(GCAllocPurpose purpose) size_t gclab_word_size; switch (purpose) { case GCAllocForSurvived: - gclab_word_size = YoungPLABSize; + gclab_word_size = _survivor_plab_stats.desired_plab_sz(); break; case GCAllocForTenured: - gclab_word_size = OldPLABSize; + gclab_word_size = _old_plab_stats.desired_plab_sz(); break; default: assert(false, "unknown GCAllocPurpose"); - gclab_word_size = OldPLABSize; + gclab_word_size = _old_plab_stats.desired_plab_sz(); break; } - return gclab_word_size; + + // Prevent humongous PLAB sizes for two reasons: + // * PLABs are allocated using a similar paths as oops, but should + // never be in a humongous region + // * Allowing humongous PLABs needlessly churns the region free lists + return MIN2(_humongous_object_threshold_in_words, gclab_word_size); } void G1CollectedHeap::init_mutator_alloc_region() { @@ -4165,6 +4172,11 @@ void G1CollectedHeap::release_gc_alloc_regions() { // want either way so no reason to check explicitly for either // condition. _retained_old_gc_alloc_region = _old_gc_alloc_region.release(); + + if (ResizePLAB) { + _survivor_plab_stats.adjust_desired_plab_sz(); + _old_plab_stats.adjust_desired_plab_sz(); + } } void G1CollectedHeap::abandon_gc_alloc_regions() { diff --git a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp index 32972e86c..2c9a3d031 100644 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp @@ -33,7 +33,7 @@ #include "gc_implementation/g1/heapRegionSeq.hpp" #include "gc_implementation/g1/heapRegionSets.hpp" #include "gc_implementation/shared/hSpaceCounters.hpp" -#include "gc_implementation/parNew/parGCAllocBuffer.hpp" +#include "gc_implementation/shared/parGCAllocBuffer.hpp" #include "memory/barrierSet.hpp" #include "memory/memRegion.hpp" #include "memory/sharedHeap.hpp" @@ -278,10 +278,33 @@ private: // survivor objects. SurvivorGCAllocRegion _survivor_gc_alloc_region; + // PLAB sizing policy for survivors. + PLABStats _survivor_plab_stats; + // Alloc region used to satisfy allocation requests by the GC for // old objects. OldGCAllocRegion _old_gc_alloc_region; + // PLAB sizing policy for tenured objects. + PLABStats _old_plab_stats; + + PLABStats* stats_for_purpose(GCAllocPurpose purpose) { + PLABStats* stats = NULL; + + switch (purpose) { + case GCAllocForSurvived: + stats = &_survivor_plab_stats; + break; + case GCAllocForTenured: + stats = &_old_plab_stats; + break; + default: + assert(false, "unrecognized GCAllocPurpose"); + } + + return stats; + } + // The last old region we allocated to during the last GC. // Typically, it is not full so we should re-use it during the next GC. HeapRegion* _retained_old_gc_alloc_region; @@ -314,7 +337,7 @@ private: G1MonitoringSupport* _g1mm; // Determines PLAB size for a particular allocation purpose. - static size_t desired_plab_sz(GCAllocPurpose purpose); + size_t desired_plab_sz(GCAllocPurpose purpose); // Outside of GC pauses, the number of bytes used in all regions other // than the current allocation region. @@ -1811,19 +1834,19 @@ public: } HeapWord* 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); - assert(gclab_word_size == alloc_buf->word_sz(), - "dynamic resizing is not supported"); add_to_alloc_buffer_waste(alloc_buf->words_remaining()); - alloc_buf->retire(false, false); + alloc_buf->flush_stats_and_retire(_g1h->stats_for_purpose(purpose), + 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); @@ -1908,7 +1931,9 @@ public: for (int ap = 0; ap < GCAllocPurposeCount; ++ap) { size_t waste = _alloc_buffers[ap]->words_remaining(); add_to_alloc_buffer_waste(waste); - _alloc_buffers[ap]->retire(true, false); + _alloc_buffers[ap]->flush_stats_and_retire(_g1h->stats_for_purpose((GCAllocPurpose)ap), + true /* end_of_gc */, + false /* retain */); } } diff --git a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp index 12472f6ad..061e52aad 100644 --- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp @@ -24,11 +24,11 @@ #include "precompiled.hpp" #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp" -#include "gc_implementation/parNew/parGCAllocBuffer.hpp" #include "gc_implementation/parNew/parNewGeneration.hpp" #include "gc_implementation/parNew/parOopClosures.inline.hpp" #include "gc_implementation/shared/adaptiveSizePolicy.hpp" #include "gc_implementation/shared/ageTable.hpp" +#include "gc_implementation/shared/parGCAllocBuffer.hpp" #include "gc_implementation/shared/spaceDecorator.hpp" #include "memory/defNewGeneration.inline.hpp" #include "memory/genCollectedHeap.hpp" @@ -453,7 +453,8 @@ void ParScanThreadStateSet::flush() // retire the last buffer. par_scan_state.to_space_alloc_buffer()-> flush_stats_and_retire(_gen.plab_stats(), - false /* !retain */); + true /* end_of_gc */, + false /* retain */); // Every thread has its own age table. We need to merge // them all into one. diff --git a/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp b/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp index 5b124a953..b8a2d1ea0 100644 --- a/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARNEWGENERATION_HPP #define SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARNEWGENERATION_HPP -#include "gc_implementation/parNew/parGCAllocBuffer.hpp" +#include "gc_implementation/shared/parGCAllocBuffer.hpp" #include "memory/defNewGeneration.hpp" #include "utilities/taskqueue.hpp" diff --git a/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp b/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp similarity index 98% rename from src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp rename to src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp index 466d2f632..b768df970 100644 --- a/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp +++ b/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "gc_implementation/parNew/parGCAllocBuffer.hpp" +#include "gc_implementation/shared/parGCAllocBuffer.hpp" #include "memory/sharedHeap.hpp" #include "oops/arrayOop.hpp" #include "oops/oop.inline.hpp" @@ -110,9 +110,7 @@ void PLABStats::adjust_desired_plab_sz() { plab_sz = align_object_size(plab_sz); // Latch the result if (PrintPLAB) gclog_or_tty->print(" desired_plab_sz = %d) ", plab_sz); - if (ResizePLAB) { - _desired_plab_sz = plab_sz; - } + _desired_plab_sz = plab_sz; // Now clear the accumulators for next round: // note this needs to be fixed in the case where we // are retaining across scavenges. FIX ME !!! XXX diff --git a/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.hpp b/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp similarity index 97% rename from src/share/vm/gc_implementation/parNew/parGCAllocBuffer.hpp rename to src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp index ea2fbf617..fcb4c786f 100644 --- a/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.hpp +++ b/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -121,14 +121,14 @@ public: // Flush the stats supporting ergonomic sizing of PLAB's void flush_stats(PLABStats* stats); - void flush_stats_and_retire(PLABStats* stats, bool retain) { + void flush_stats_and_retire(PLABStats* stats, bool end_of_gc, bool retain) { // We flush the stats first in order to get a reading of // unused space in the last buffer. if (ResizePLAB) { flush_stats(stats); } // Retire the last allocation buffer. - retire(true, retain); + retire(end_of_gc, retain); } // Force future allocations to fail and queries for contains() diff --git a/src/share/vm/memory/tenuredGeneration.cpp b/src/share/vm/memory/tenuredGeneration.cpp index 50b2615ba..1d38095f8 100644 --- a/src/share/vm/memory/tenuredGeneration.cpp +++ b/src/share/vm/memory/tenuredGeneration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,8 @@ */ #include "precompiled.hpp" -#include "gc_implementation/parNew/parGCAllocBuffer.hpp" #include "gc_implementation/shared/collectorCounters.hpp" +#include "gc_implementation/shared/parGCAllocBuffer.hpp" #include "memory/allocation.inline.hpp" #include "memory/blockOffsetTable.inline.hpp" #include "memory/generation.inline.hpp" diff --git a/src/share/vm/precompiled/precompiled.hpp b/src/share/vm/precompiled/precompiled.hpp index 0414e070a..789ab5139 100644 --- a/src/share/vm/precompiled/precompiled.hpp +++ b/src/share/vm/precompiled/precompiled.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -306,7 +306,6 @@ # include "gc_implementation/g1/g1_specialized_oop_closures.hpp" # include "gc_implementation/g1/ptrQueue.hpp" # include "gc_implementation/g1/satbQueue.hpp" -# include "gc_implementation/parNew/parGCAllocBuffer.hpp" # include "gc_implementation/parNew/parOopClosures.hpp" # include "gc_implementation/parallelScavenge/objectStartArray.hpp" # include "gc_implementation/parallelScavenge/parMarkBitMap.hpp" @@ -322,6 +321,7 @@ # include "gc_implementation/parallelScavenge/psYoungGen.hpp" # include "gc_implementation/shared/gcAdaptivePolicyCounters.hpp" # include "gc_implementation/shared/gcPolicyCounters.hpp" +# include "gc_implementation/shared/parGCAllocBuffer.hpp" #endif // SERIALGC #endif // !DONT_USE_PRECOMPILED_HEADER -- GitLab