From 5dbfc6ae237dab2c06621a84894918b5a34a6984 Mon Sep 17 00:00:00 2001 From: mgerdin Date: Thu, 9 Oct 2014 15:42:23 +0200 Subject: [PATCH] 8055479: TLAB stability Reviewed-by: brutisso, stefank, ahgross --- .../concurrentMarkSweepGeneration.cpp | 8 +++++++- .../concurrentMarkSweepGeneration.hpp | 4 ++++ .../vm/gc_implementation/shared/parGCAllocBuffer.hpp | 3 ++- src/share/vm/memory/threadLocalAllocBuffer.cpp | 11 ++++------- src/share/vm/memory/threadLocalAllocBuffer.hpp | 2 +- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp index dea030fa8..1a0097d09 100644 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -737,7 +737,7 @@ CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen, // Support for parallelizing survivor space rescan if ((CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) || CMSParallelInitialMarkEnabled) { const size_t max_plab_samples = - ((DefNewGeneration*)_young_gen)->max_survivor_size()/MinTLABSize; + ((DefNewGeneration*)_young_gen)->max_survivor_size() / plab_sample_minimum_size(); _survivor_plab_array = NEW_C_HEAP_ARRAY(ChunkArray, ParallelGCThreads, mtGC); _survivor_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, 2*max_plab_samples, mtGC); @@ -795,6 +795,12 @@ CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen, _inter_sweep_timer.start(); // start of time } +size_t CMSCollector::plab_sample_minimum_size() { + // The default value of MinTLABSize is 2k, but there is + // no way to get the default value if the flag has been overridden. + return MAX2(ThreadLocalAllocBuffer::min_size() * HeapWordSize, 2 * K); +} + const char* ConcurrentMarkSweepGeneration::name() const { return "concurrent mark-sweep generation"; } diff --git a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp index 2c87671df..7cd4153ff 100644 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp @@ -763,6 +763,10 @@ class CMSCollector: public CHeapObj { size_t* _cursor; ChunkArray* _survivor_plab_array; + // A bounded minimum size of PLABs, should not return too small values since + // this will affect the size of the data structures used for parallel young gen rescan + size_t plab_sample_minimum_size(); + // Support for marking stack overflow handling bool take_from_overflow_list(size_t num, CMSMarkStack* to_stack); bool par_take_from_overflow_list(size_t num, diff --git a/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp b/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp index aac3e9815..c02822f09 100644 --- a/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp +++ b/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp @@ -62,7 +62,8 @@ public: ParGCAllocBuffer(size_t word_sz); static const size_t min_size() { - return ThreadLocalAllocBuffer::min_size(); + // Make sure that we return something that is larger than AlignmentReserve + return align_object_size(MAX2(MinTLABSize / HeapWordSize, (uintx)oopDesc::header_size())) + AlignmentReserve; } static const size_t max_size() { diff --git a/src/share/vm/memory/threadLocalAllocBuffer.cpp b/src/share/vm/memory/threadLocalAllocBuffer.cpp index b59cfd80d..06033439c 100644 --- a/src/share/vm/memory/threadLocalAllocBuffer.cpp +++ b/src/share/vm/memory/threadLocalAllocBuffer.cpp @@ -235,22 +235,19 @@ void ThreadLocalAllocBuffer::startup_initialization() { } size_t ThreadLocalAllocBuffer::initial_desired_size() { - size_t init_sz; + size_t init_sz = 0; if (TLABSize > 0) { - init_sz = MIN2(TLABSize / HeapWordSize, max_size()); - } else if (global_stats() == NULL) { - // Startup issue - main thread initialized before heap initialized. - init_sz = min_size(); - } else { + init_sz = TLABSize / HeapWordSize; + } else if (global_stats() != NULL) { // Initial size is a function of the average number of allocating threads. unsigned nof_threads = global_stats()->allocating_threads_avg(); init_sz = (Universe::heap()->tlab_capacity(myThread()) / HeapWordSize) / (nof_threads * target_refills()); init_sz = align_object_size(init_sz); - init_sz = MIN2(MAX2(init_sz, min_size()), max_size()); } + init_sz = MIN2(MAX2(init_sz, min_size()), max_size()); return init_sz; } diff --git a/src/share/vm/memory/threadLocalAllocBuffer.hpp b/src/share/vm/memory/threadLocalAllocBuffer.hpp index e0dc61a73..07308ff7e 100644 --- a/src/share/vm/memory/threadLocalAllocBuffer.hpp +++ b/src/share/vm/memory/threadLocalAllocBuffer.hpp @@ -105,7 +105,7 @@ public: // do nothing. tlabs must be inited by initialize() calls } - static const size_t min_size() { return align_object_size(MinTLABSize / HeapWordSize); } + static const size_t min_size() { return align_object_size(MinTLABSize / HeapWordSize) + alignment_reserve(); } static const size_t max_size() { assert(_max_size != 0, "max_size not set up"); return _max_size; } static void set_max_size(size_t max_size) { _max_size = max_size; } -- GitLab