Thu, 09 Oct 2014 15:42:23 +0200
8055479: TLAB stability
Reviewed-by: brutisso, stefank, ahgross
1.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Fri Sep 26 17:48:10 2014 -0400 1.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Oct 09 15:42:23 2014 +0200 1.3 @@ -737,7 +737,7 @@ 1.4 // Support for parallelizing survivor space rescan 1.5 if ((CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) || CMSParallelInitialMarkEnabled) { 1.6 const size_t max_plab_samples = 1.7 - ((DefNewGeneration*)_young_gen)->max_survivor_size()/MinTLABSize; 1.8 + ((DefNewGeneration*)_young_gen)->max_survivor_size() / plab_sample_minimum_size(); 1.9 1.10 _survivor_plab_array = NEW_C_HEAP_ARRAY(ChunkArray, ParallelGCThreads, mtGC); 1.11 _survivor_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, 2*max_plab_samples, mtGC); 1.12 @@ -795,6 +795,12 @@ 1.13 _inter_sweep_timer.start(); // start of time 1.14 } 1.15 1.16 +size_t CMSCollector::plab_sample_minimum_size() { 1.17 + // The default value of MinTLABSize is 2k, but there is 1.18 + // no way to get the default value if the flag has been overridden. 1.19 + return MAX2(ThreadLocalAllocBuffer::min_size() * HeapWordSize, 2 * K); 1.20 +} 1.21 + 1.22 const char* ConcurrentMarkSweepGeneration::name() const { 1.23 return "concurrent mark-sweep generation"; 1.24 }
2.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Fri Sep 26 17:48:10 2014 -0400 2.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Thu Oct 09 15:42:23 2014 +0200 2.3 @@ -763,6 +763,10 @@ 2.4 size_t* _cursor; 2.5 ChunkArray* _survivor_plab_array; 2.6 2.7 + // A bounded minimum size of PLABs, should not return too small values since 2.8 + // this will affect the size of the data structures used for parallel young gen rescan 2.9 + size_t plab_sample_minimum_size(); 2.10 + 2.11 // Support for marking stack overflow handling 2.12 bool take_from_overflow_list(size_t num, CMSMarkStack* to_stack); 2.13 bool par_take_from_overflow_list(size_t num,
3.1 --- a/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp Fri Sep 26 17:48:10 2014 -0400 3.2 +++ b/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp Thu Oct 09 15:42:23 2014 +0200 3.3 @@ -62,7 +62,8 @@ 3.4 ParGCAllocBuffer(size_t word_sz); 3.5 3.6 static const size_t min_size() { 3.7 - return ThreadLocalAllocBuffer::min_size(); 3.8 + // Make sure that we return something that is larger than AlignmentReserve 3.9 + return align_object_size(MAX2(MinTLABSize / HeapWordSize, (uintx)oopDesc::header_size())) + AlignmentReserve; 3.10 } 3.11 3.12 static const size_t max_size() {
4.1 --- a/src/share/vm/memory/threadLocalAllocBuffer.cpp Fri Sep 26 17:48:10 2014 -0400 4.2 +++ b/src/share/vm/memory/threadLocalAllocBuffer.cpp Thu Oct 09 15:42:23 2014 +0200 4.3 @@ -235,22 +235,19 @@ 4.4 } 4.5 4.6 size_t ThreadLocalAllocBuffer::initial_desired_size() { 4.7 - size_t init_sz; 4.8 + size_t init_sz = 0; 4.9 4.10 if (TLABSize > 0) { 4.11 - init_sz = MIN2(TLABSize / HeapWordSize, max_size()); 4.12 - } else if (global_stats() == NULL) { 4.13 - // Startup issue - main thread initialized before heap initialized. 4.14 - init_sz = min_size(); 4.15 - } else { 4.16 + init_sz = TLABSize / HeapWordSize; 4.17 + } else if (global_stats() != NULL) { 4.18 // Initial size is a function of the average number of allocating threads. 4.19 unsigned nof_threads = global_stats()->allocating_threads_avg(); 4.20 4.21 init_sz = (Universe::heap()->tlab_capacity(myThread()) / HeapWordSize) / 4.22 (nof_threads * target_refills()); 4.23 init_sz = align_object_size(init_sz); 4.24 - init_sz = MIN2(MAX2(init_sz, min_size()), max_size()); 4.25 } 4.26 + init_sz = MIN2(MAX2(init_sz, min_size()), max_size()); 4.27 return init_sz; 4.28 } 4.29
5.1 --- a/src/share/vm/memory/threadLocalAllocBuffer.hpp Fri Sep 26 17:48:10 2014 -0400 5.2 +++ b/src/share/vm/memory/threadLocalAllocBuffer.hpp Thu Oct 09 15:42:23 2014 +0200 5.3 @@ -105,7 +105,7 @@ 5.4 // do nothing. tlabs must be inited by initialize() calls 5.5 } 5.6 5.7 - static const size_t min_size() { return align_object_size(MinTLABSize / HeapWordSize); } 5.8 + static const size_t min_size() { return align_object_size(MinTLABSize / HeapWordSize) + alignment_reserve(); } 5.9 static const size_t max_size() { assert(_max_size != 0, "max_size not set up"); return _max_size; } 5.10 static void set_max_size(size_t max_size) { _max_size = max_size; } 5.11