hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp
changeset 30317 febd2373771c
parent 30098 a4b1c7d6317a
parent 30316 6c651fa22980
child 30318 8f085493151f
equal deleted inserted replaced
30098:a4b1c7d6317a 30317:febd2373771c
     1 /*
       
     2  * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  *
       
    23  */
       
    24 
       
    25 #include "precompiled.hpp"
       
    26 #include "gc_implementation/shared/parGCAllocBuffer.hpp"
       
    27 #include "memory/threadLocalAllocBuffer.hpp"
       
    28 #include "oops/arrayOop.hpp"
       
    29 #include "oops/oop.inline.hpp"
       
    30 
       
    31 size_t ParGCAllocBuffer::min_size() {
       
    32   // Make sure that we return something that is larger than AlignmentReserve
       
    33   return align_object_size(MAX2(MinTLABSize / HeapWordSize, (uintx)oopDesc::header_size())) + AlignmentReserve;
       
    34 }
       
    35 
       
    36 size_t ParGCAllocBuffer::max_size() {
       
    37   return ThreadLocalAllocBuffer::max_size();
       
    38 }
       
    39 
       
    40 ParGCAllocBuffer::ParGCAllocBuffer(size_t desired_plab_sz_) :
       
    41   _word_sz(desired_plab_sz_), _bottom(NULL), _top(NULL),
       
    42   _end(NULL), _hard_end(NULL), _allocated(0), _wasted(0)
       
    43 {
       
    44   // ArrayOopDesc::header_size depends on command line initialization.
       
    45   AlignmentReserve = oopDesc::header_size() > MinObjAlignment ? align_object_size(arrayOopDesc::header_size(T_INT)) : 0;
       
    46   assert(min_size() > AlignmentReserve,
       
    47          err_msg("Minimum PLAB size " SIZE_FORMAT" must be larger than alignment reserve " SIZE_FORMAT" "
       
    48                  "to be able to contain objects", min_size(), AlignmentReserve));
       
    49 }
       
    50 
       
    51 // If the minimum object size is greater than MinObjAlignment, we can
       
    52 // end up with a shard at the end of the buffer that's smaller than
       
    53 // the smallest object.  We can't allow that because the buffer must
       
    54 // look like it's full of objects when we retire it, so we make
       
    55 // sure we have enough space for a filler int array object.
       
    56 size_t ParGCAllocBuffer::AlignmentReserve;
       
    57 
       
    58 void ParGCAllocBuffer::flush_and_retire_stats(PLABStats* stats) {
       
    59   // Retire the last allocation buffer.
       
    60   size_t unused = retire_internal();
       
    61 
       
    62   // Now flush the statistics.
       
    63   stats->add_allocated(_allocated);
       
    64   stats->add_wasted(_wasted);
       
    65   stats->add_unused(unused);
       
    66 
       
    67   // Since we have flushed the stats we need to clear  the _allocated and _wasted
       
    68   // fields in case somebody retains an instance of this over GCs. Not doing so
       
    69   // will artifically inflate the values in the statistics.
       
    70   _allocated = 0;
       
    71   _wasted = 0;
       
    72 }
       
    73 
       
    74 void ParGCAllocBuffer::retire() {
       
    75   _wasted += retire_internal();
       
    76 }
       
    77 
       
    78 size_t ParGCAllocBuffer::retire_internal() {
       
    79   size_t result = 0;
       
    80   if (_top < _hard_end) {
       
    81     CollectedHeap::fill_with_object(_top, _hard_end);
       
    82     result += invalidate();
       
    83   }
       
    84   return result;
       
    85 }
       
    86 
       
    87 // Compute desired plab size and latch result for later
       
    88 // use. This should be called once at the end of parallel
       
    89 // scavenge; it clears the sensor accumulators.
       
    90 void PLABStats::adjust_desired_plab_sz(uint no_of_gc_workers) {
       
    91   assert(ResizePLAB, "Not set");
       
    92 
       
    93   assert(is_object_aligned(max_size()) && min_size() <= max_size(),
       
    94          "PLAB clipping computation may be incorrect");
       
    95 
       
    96   if (_allocated == 0) {
       
    97     assert(_unused == 0,
       
    98            err_msg("Inconsistency in PLAB stats: "
       
    99                    "_allocated: "SIZE_FORMAT", "
       
   100                    "_wasted: "SIZE_FORMAT", "
       
   101                    "_unused: "SIZE_FORMAT,
       
   102                    _allocated, _wasted, _unused));
       
   103 
       
   104     _allocated = 1;
       
   105   }
       
   106   double wasted_frac    = (double)_unused / (double)_allocated;
       
   107   size_t target_refills = (size_t)((wasted_frac * TargetSurvivorRatio) / TargetPLABWastePct);
       
   108   if (target_refills == 0) {
       
   109     target_refills = 1;
       
   110   }
       
   111   size_t used = _allocated - _wasted - _unused;
       
   112   size_t recent_plab_sz = used / (target_refills * no_of_gc_workers);
       
   113   // Take historical weighted average
       
   114   _filter.sample(recent_plab_sz);
       
   115   // Clip from above and below, and align to object boundary
       
   116   size_t new_plab_sz = MAX2(min_size(), (size_t)_filter.average());
       
   117   new_plab_sz = MIN2(max_size(), new_plab_sz);
       
   118   new_plab_sz = align_object_size(new_plab_sz);
       
   119   // Latch the result
       
   120   if (PrintPLAB) {
       
   121     gclog_or_tty->print(" (plab_sz = " SIZE_FORMAT" desired_plab_sz = " SIZE_FORMAT") ", recent_plab_sz, new_plab_sz);
       
   122   }
       
   123   _desired_plab_sz = new_plab_sz;
       
   124 
       
   125   reset();
       
   126 }
       
   127 
       
   128 #ifndef PRODUCT
       
   129 void ParGCAllocBuffer::print() {
       
   130   gclog_or_tty->print_cr("parGCAllocBuffer: _bottom: " PTR_FORMAT "  _top: " PTR_FORMAT
       
   131     "  _end: " PTR_FORMAT "  _hard_end: " PTR_FORMAT ")",
       
   132     p2i(_bottom), p2i(_top), p2i(_end), p2i(_hard_end));
       
   133 }
       
   134 #endif // !PRODUCT