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

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

author
tschatzl
date
Fri, 10 Oct 2014 15:51:58 +0200
changeset 7257
e7d0505c8a30
parent 7091
a8ea2f110d87
child 7535
7ae4e26cb1e0
child 7835
e5406a79ae90
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_HEAPREGIONMANAGER_HPP
    26 #define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_HPP
    28 #include "gc_implementation/g1/g1BiasedArray.hpp"
    29 #include "gc_implementation/g1/g1RegionToSpaceMapper.hpp"
    30 #include "gc_implementation/g1/heapRegionSet.hpp"
    32 class HeapRegion;
    33 class HeapRegionClosure;
    34 class FreeRegionList;
    36 class G1HeapRegionTable : public G1BiasedMappedArray<HeapRegion*> {
    37  protected:
    38   virtual HeapRegion* default_value() const { return NULL; }
    39 };
    41 // This class keeps track of the actual heap memory, auxiliary data
    42 // and its metadata (i.e., HeapRegion instances) and the list of free regions.
    43 //
    44 // This allows maximum flexibility for deciding what to commit or uncommit given
    45 // a request from outside.
    46 //
    47 // HeapRegions are kept in the _regions array in address order. A region's
    48 // index in the array corresponds to its index in the heap (i.e., 0 is the
    49 // region at the bottom of the heap, 1 is the one after it, etc.). Two
    50 // regions that are consecutive in the array should also be adjacent in the
    51 // address space (i.e., region(i).end() == region(i+1).bottom().
    52 //
    53 // We create a HeapRegion when we commit the region's address space
    54 // for the first time. When we uncommit the address space of a
    55 // region we retain the HeapRegion to be able to re-use it in the
    56 // future (in case we recommit it).
    57 //
    58 // We keep track of three lengths:
    59 //
    60 // * _num_committed (returned by length()) is the number of currently
    61 //   committed regions. These may not be contiguous.
    62 // * _allocated_heapregions_length (not exposed outside this class) is the
    63 //   number of regions+1 for which we have HeapRegions.
    64 // * max_length() returns the maximum number of regions the heap can have.
    65 //
    67 class HeapRegionManager: public CHeapObj<mtGC> {
    68   friend class VMStructs;
    70   G1HeapRegionTable _regions;
    72   G1RegionToSpaceMapper* _heap_mapper;
    73   G1RegionToSpaceMapper* _prev_bitmap_mapper;
    74   G1RegionToSpaceMapper* _next_bitmap_mapper;
    75   G1RegionToSpaceMapper* _bot_mapper;
    76   G1RegionToSpaceMapper* _cardtable_mapper;
    77   G1RegionToSpaceMapper* _card_counts_mapper;
    79   FreeRegionList _free_list;
    81   // Each bit in this bitmap indicates that the corresponding region is available
    82   // for allocation.
    83   BitMap _available_map;
    85    // The number of regions committed in the heap.
    86   uint _num_committed;
    88   // Internal only. The highest heap region +1 we allocated a HeapRegion instance for.
    89   uint _allocated_heapregions_length;
    91    HeapWord* heap_bottom() const { return _regions.bottom_address_mapped(); }
    92    HeapWord* heap_end() const {return _regions.end_address_mapped(); }
    94   void make_regions_available(uint index, uint num_regions = 1);
    96   // Pass down commit calls to the VirtualSpace.
    97   void commit_regions(uint index, size_t num_regions = 1);
    98   void uncommit_regions(uint index, size_t num_regions = 1);
   100   // Notify other data structures about change in the heap layout.
   101   void update_committed_space(HeapWord* old_end, HeapWord* new_end);
   102   // Calculate the starting region for each worker during parallel iteration so
   103   // that they do not all start from the same region.
   104   uint start_region_for_worker(uint worker_i, uint num_workers, uint num_regions) const;
   106   // Find a contiguous set of empty or uncommitted regions of length num and return
   107   // the index of the first region or G1_NO_HRM_INDEX if the search was unsuccessful.
   108   // If only_empty is true, only empty regions are considered.
   109   // Searches from bottom to top of the heap, doing a first-fit.
   110   uint find_contiguous(size_t num, bool only_empty);
   111   // Finds the next sequence of unavailable regions starting from start_idx. Returns the
   112   // length of the sequence found. If this result is zero, no such sequence could be found,
   113   // otherwise res_idx indicates the start index of these regions.
   114   uint find_unavailable_from_idx(uint start_idx, uint* res_idx) const;
   115   // Finds the next sequence of empty regions starting from start_idx, going backwards in
   116   // the heap. Returns the length of the sequence found. If this value is zero, no
   117   // sequence could be found, otherwise res_idx contains the start index of this range.
   118   uint find_empty_from_idx_reverse(uint start_idx, uint* res_idx) const;
   119   // Allocate a new HeapRegion for the given index.
   120   HeapRegion* new_heap_region(uint hrm_index);
   121 #ifdef ASSERT
   122 public:
   123   bool is_free(HeapRegion* hr) const;
   124 #endif
   125   // Returns whether the given region is available for allocation.
   126   bool is_available(uint region) const;
   128  public:
   129   // Empty constructor, we'll initialize it with the initialize() method.
   130   HeapRegionManager() : _regions(), _heap_mapper(NULL), _num_committed(0),
   131                     _next_bitmap_mapper(NULL), _prev_bitmap_mapper(NULL), _bot_mapper(NULL),
   132                     _allocated_heapregions_length(0), _available_map(),
   133                     _free_list("Free list", new MasterFreeRegionListMtSafeChecker())
   134   { }
   136   void initialize(G1RegionToSpaceMapper* heap_storage,
   137                   G1RegionToSpaceMapper* prev_bitmap,
   138                   G1RegionToSpaceMapper* next_bitmap,
   139                   G1RegionToSpaceMapper* bot,
   140                   G1RegionToSpaceMapper* cardtable,
   141                   G1RegionToSpaceMapper* card_counts);
   143   // Return the "dummy" region used for G1AllocRegion. This is currently a hardwired
   144   // new HeapRegion that owns HeapRegion at index 0. Since at the moment we commit
   145   // the heap from the lowest address, this region (and its associated data
   146   // structures) are available and we do not need to check further.
   147   HeapRegion* get_dummy_region() { return new_heap_region(0); }
   149   // Return the HeapRegion at the given index. Assume that the index
   150   // is valid.
   151   inline HeapRegion* at(uint index) const;
   153   // If addr is within the committed space return its corresponding
   154   // HeapRegion, otherwise return NULL.
   155   inline HeapRegion* addr_to_region(HeapWord* addr) const;
   157   // Insert the given region into the free region list.
   158   inline void insert_into_free_list(HeapRegion* hr);
   160   // Insert the given region list into the global free region list.
   161   void insert_list_into_free_list(FreeRegionList* list) {
   162     _free_list.add_ordered(list);
   163   }
   165   HeapRegion* allocate_free_region(bool is_old) {
   166     HeapRegion* hr = _free_list.remove_region(is_old);
   168     if (hr != NULL) {
   169       assert(hr->next() == NULL, "Single region should not have next");
   170       assert(is_available(hr->hrm_index()), "Must be committed");
   171     }
   172     return hr;
   173   }
   175   inline void allocate_free_regions_starting_at(uint first, uint num_regions);
   177   // Remove all regions from the free list.
   178   void remove_all_free_regions() {
   179     _free_list.remove_all();
   180   }
   182   // Return the number of committed free regions in the heap.
   183   uint num_free_regions() const {
   184     return _free_list.length();
   185   }
   187   size_t total_capacity_bytes() const {
   188     return num_free_regions() * HeapRegion::GrainBytes;
   189   }
   191   // Return the number of available (uncommitted) regions.
   192   uint available() const { return max_length() - length(); }
   194   // Return the number of regions that have been committed in the heap.
   195   uint length() const { return _num_committed; }
   197   // Return the maximum number of regions in the heap.
   198   uint max_length() const { return (uint)_regions.length(); }
   200   MemRegion reserved() const { return MemRegion(heap_bottom(), heap_end()); }
   202   // Expand the sequence to reflect that the heap has grown. Either create new
   203   // HeapRegions, or re-use existing ones. Returns the number of regions the
   204   // sequence was expanded by. If a HeapRegion allocation fails, the resulting
   205   // number of regions might be smaller than what's desired.
   206   uint expand_by(uint num_regions);
   208   // Makes sure that the regions from start to start+num_regions-1 are available
   209   // for allocation. Returns the number of regions that were committed to achieve
   210   // this.
   211   uint expand_at(uint start, uint num_regions);
   213   // Find a contiguous set of empty regions of length num. Returns the start index of
   214   // that set, or G1_NO_HRM_INDEX.
   215   uint find_contiguous_only_empty(size_t num) { return find_contiguous(num, true); }
   216   // Find a contiguous set of empty or unavailable regions of length num. Returns the
   217   // start index of that set, or G1_NO_HRM_INDEX.
   218   uint find_contiguous_empty_or_unavailable(size_t num) { return find_contiguous(num, false); }
   220   HeapRegion* next_region_in_heap(const HeapRegion* r) const;
   222   // Apply blk->doHeapRegion() on all committed regions in address order,
   223   // terminating the iteration early if doHeapRegion() returns true.
   224   void iterate(HeapRegionClosure* blk) const;
   226   void par_iterate(HeapRegionClosure* blk, uint worker_id, uint no_of_par_workers, jint claim_value) const;
   228   // Uncommit up to num_regions_to_remove regions that are completely free.
   229   // Return the actual number of uncommitted regions.
   230   uint shrink_by(uint num_regions_to_remove);
   232   void verify();
   234   // Do some sanity checking.
   235   void verify_optional() PRODUCT_RETURN;
   236 };
   238 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_HPP

mercurial