src/share/vm/gc_implementation/g1/collectionSetChooser.hpp

Fri, 10 Oct 2014 15:51:58 +0200

author
tschatzl
date
Fri, 10 Oct 2014 15:51:58 +0200
changeset 7257
e7d0505c8a30
parent 6198
55fb97c4c58d
child 6876
710a3c8b516e
child 9327
f96fcd9e1e1b
permissions
-rw-r--r--

8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso

     1 /*
     2  * Copyright (c) 2001, 2013, 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  */
    25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_COLLECTIONSETCHOOSER_HPP
    26 #define SHARE_VM_GC_IMPLEMENTATION_G1_COLLECTIONSETCHOOSER_HPP
    28 #include "gc_implementation/g1/heapRegion.hpp"
    29 #include "utilities/growableArray.hpp"
    31 class CollectionSetChooser: public CHeapObj<mtGC> {
    33   GrowableArray<HeapRegion*> _regions;
    35   // Unfortunately, GrowableArray uses ints for length and indexes. To
    36   // avoid excessive casting in the rest of the class the following
    37   // wrapper methods are provided that use uints.
    39   uint regions_length()          { return (uint) _regions.length(); }
    40   HeapRegion* regions_at(uint i) { return _regions.at((int) i);     }
    41   void regions_at_put(uint i, HeapRegion* hr) {
    42     _regions.at_put((int) i, hr);
    43   }
    44   void regions_at_put_grow(uint i, HeapRegion* hr) {
    45     _regions.at_put_grow((int) i, hr);
    46   }
    47   void regions_trunc_to(uint i)  { _regions.trunc_to((uint) i); }
    49   // The index of the next candidate old region to be considered for
    50   // addition to the CSet.
    51   uint _curr_index;
    53   // The number of candidate old regions added to the CSet chooser.
    54   // Note: this is not updated when removing a region using
    55   // remove_and_move_to_next() below.
    56   uint _length;
    58   // Keeps track of the start of the next array chunk to be claimed by
    59   // parallel GC workers.
    60   uint _first_par_unreserved_idx;
    62   // If a region has more live bytes than this threshold, it will not
    63   // be added to the CSet chooser and will not be a candidate for
    64   // collection.
    65   size_t _region_live_threshold_bytes;
    67   // The sum of reclaimable bytes over all the regions in the CSet chooser.
    68   size_t _remaining_reclaimable_bytes;
    70 public:
    72   // Return the current candidate region to be considered for
    73   // collection without removing it from the CSet chooser.
    74   HeapRegion* peek() {
    75     HeapRegion* res = NULL;
    76     if (_curr_index < _length) {
    77       res = regions_at(_curr_index);
    78       assert(res != NULL,
    79              err_msg("Unexpected NULL hr in _regions at index %u",
    80                      _curr_index));
    81     }
    82     return res;
    83   }
    85   // Remove the given region from the CSet chooser and move to the
    86   // next one. The given region should be the current candidate region
    87   // in the CSet chooser.
    88   void remove_and_move_to_next(HeapRegion* hr) {
    89     assert(hr != NULL, "pre-condition");
    90     assert(_curr_index < _length, "pre-condition");
    91     assert(regions_at(_curr_index) == hr, "pre-condition");
    92     regions_at_put(_curr_index, NULL);
    93     assert(hr->reclaimable_bytes() <= _remaining_reclaimable_bytes,
    94            err_msg("remaining reclaimable bytes inconsistent "
    95                    "from region: "SIZE_FORMAT" remaining: "SIZE_FORMAT,
    96                    hr->reclaimable_bytes(), _remaining_reclaimable_bytes));
    97     _remaining_reclaimable_bytes -= hr->reclaimable_bytes();
    98     _curr_index += 1;
    99   }
   101   CollectionSetChooser();
   103   void sort_regions();
   105   // Determine whether to add the given region to the CSet chooser or
   106   // not. Currently, we skip humongous regions (we never add them to
   107   // the CSet, we only reclaim them during cleanup) and regions whose
   108   // live bytes are over the threshold.
   109   bool should_add(HeapRegion* hr) {
   110     assert(hr->is_marked(), "pre-condition");
   111     assert(!hr->is_young(), "should never consider young regions");
   112     return !hr->isHumongous() &&
   113             hr->live_bytes() < _region_live_threshold_bytes;
   114   }
   116   // Returns the number candidate old regions added
   117   uint length() { return _length; }
   119   // Serial version.
   120   void add_region(HeapRegion *hr);
   122   // Must be called before calls to claim_array_chunk().
   123   // n_regions is the number of regions, chunk_size the chunk size.
   124   void prepare_for_par_region_addition(uint n_regions, uint chunk_size);
   125   // Returns the first index in a contiguous chunk of chunk_size indexes
   126   // that the calling thread has reserved.  These must be set by the
   127   // calling thread using set_region() (to NULL if necessary).
   128   uint claim_array_chunk(uint chunk_size);
   129   // Set the marked array entry at index to hr.  Careful to claim the index
   130   // first if in parallel.
   131   void set_region(uint index, HeapRegion* hr);
   132   // Atomically increment the number of added regions by region_num
   133   // and the amount of reclaimable bytes by reclaimable_bytes.
   134   void update_totals(uint region_num, size_t reclaimable_bytes);
   136   void clear();
   138   // Return the number of candidate regions that remain to be collected.
   139   uint remaining_regions() { return _length - _curr_index; }
   141   // Determine whether the CSet chooser has more candidate regions or not.
   142   bool is_empty() { return remaining_regions() == 0; }
   144   // Return the reclaimable bytes that remain to be collected on
   145   // all the candidate regions in the CSet chooser.
   146   size_t remaining_reclaimable_bytes() { return _remaining_reclaimable_bytes; }
   148   // Returns true if the used portion of "_regions" is properly
   149   // sorted, otherwise asserts false.
   150   void verify() PRODUCT_RETURN;
   151 };
   153 class CSetChooserParUpdater : public StackObj {
   154 private:
   155   CollectionSetChooser* _chooser;
   156   bool _parallel;
   157   uint _chunk_size;
   158   uint _cur_chunk_idx;
   159   uint _cur_chunk_end;
   160   uint _regions_added;
   161   size_t _reclaimable_bytes_added;
   163 public:
   164   CSetChooserParUpdater(CollectionSetChooser* chooser,
   165                         bool parallel, uint chunk_size) :
   166     _chooser(chooser), _parallel(parallel), _chunk_size(chunk_size),
   167     _cur_chunk_idx(0), _cur_chunk_end(0),
   168     _regions_added(0), _reclaimable_bytes_added(0) { }
   170   ~CSetChooserParUpdater() {
   171     if (_parallel && _regions_added > 0) {
   172       _chooser->update_totals(_regions_added, _reclaimable_bytes_added);
   173     }
   174   }
   176   void add_region(HeapRegion* hr) {
   177     if (_parallel) {
   178       if (_cur_chunk_idx == _cur_chunk_end) {
   179         _cur_chunk_idx = _chooser->claim_array_chunk(_chunk_size);
   180         _cur_chunk_end = _cur_chunk_idx + _chunk_size;
   181       }
   182       assert(_cur_chunk_idx < _cur_chunk_end, "invariant");
   183       _chooser->set_region(_cur_chunk_idx, hr);
   184       _cur_chunk_idx += 1;
   185     } else {
   186       _chooser->add_region(hr);
   187     }
   188     _regions_added += 1;
   189     _reclaimable_bytes_added += hr->reclaimable_bytes();
   190   }
   192   bool should_add(HeapRegion* hr) { return _chooser->should_add(hr); }
   193 };
   195 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_COLLECTIONSETCHOOSER_HPP

mercurial