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

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

author
tschatzl
date
Fri, 10 Oct 2014 15:51:58 +0200
changeset 7257
e7d0505c8a30
parent 7195
c02ec279b062
child 7535
7ae4e26cb1e0
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

tonyp@2472 1 /*
jwilhelm@6422 2 * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
tonyp@2472 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
tonyp@2472 4 *
tonyp@2472 5 * This code is free software; you can redistribute it and/or modify it
tonyp@2472 6 * under the terms of the GNU General Public License version 2 only, as
tonyp@2472 7 * published by the Free Software Foundation.
tonyp@2472 8 *
tonyp@2472 9 * This code is distributed in the hope that it will be useful, but WITHOUT
tonyp@2472 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
tonyp@2472 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
tonyp@2472 12 * version 2 for more details (a copy is included in the LICENSE file that
tonyp@2472 13 * accompanied this code).
tonyp@2472 14 *
tonyp@2472 15 * You should have received a copy of the GNU General Public License version
tonyp@2472 16 * 2 along with this work; if not, write to the Free Software Foundation,
tonyp@2472 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
tonyp@2472 18 *
tonyp@2472 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
tonyp@2472 20 * or visit www.oracle.com if you need additional information or have any
tonyp@2472 21 * questions.
tonyp@2472 22 *
tonyp@2472 23 */
tonyp@2472 24
tonyp@2472 25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSET_HPP
tonyp@2472 26 #define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSET_HPP
tonyp@2472 27
tonyp@2472 28 #include "gc_implementation/g1/heapRegion.hpp"
tonyp@2472 29
tonyp@2472 30 // Large buffer for some cases where the output might be larger than normal.
tonyp@2643 31 #define HRS_ERR_MSG_BUFSZ 512
tonyp@2643 32 typedef FormatBuffer<HRS_ERR_MSG_BUFSZ> hrs_err_msg;
tonyp@2472 33
tonyp@2472 34 // Set verification will be forced either if someone defines
tonyp@2472 35 // HEAP_REGION_SET_FORCE_VERIFY to be 1, or in builds in which
tonyp@2472 36 // asserts are compiled in.
tonyp@2472 37 #ifndef HEAP_REGION_SET_FORCE_VERIFY
tonyp@2472 38 #define HEAP_REGION_SET_FORCE_VERIFY defined(ASSERT)
tonyp@2472 39 #endif // HEAP_REGION_SET_FORCE_VERIFY
tonyp@2472 40
brutisso@6385 41 class hrs_ext_msg;
brutisso@6385 42
brutisso@6385 43 class HRSMtSafeChecker : public CHeapObj<mtGC> {
brutisso@6385 44 public:
brutisso@6385 45 virtual void check() = 0;
brutisso@6385 46 };
brutisso@6385 47
brutisso@6385 48 class MasterFreeRegionListMtSafeChecker : public HRSMtSafeChecker { public: void check(); };
brutisso@6385 49 class SecondaryFreeRegionListMtSafeChecker : public HRSMtSafeChecker { public: void check(); };
brutisso@6385 50 class HumongousRegionSetMtSafeChecker : public HRSMtSafeChecker { public: void check(); };
brutisso@6385 51 class OldRegionSetMtSafeChecker : public HRSMtSafeChecker { public: void check(); };
brutisso@6385 52
brutisso@6385 53 class HeapRegionSetCount VALUE_OBJ_CLASS_SPEC {
brutisso@6385 54 friend class VMStructs;
brutisso@6385 55 uint _length;
brutisso@6385 56 size_t _capacity;
brutisso@6385 57
brutisso@6385 58 public:
brutisso@6385 59 HeapRegionSetCount() : _length(0), _capacity(0) { }
brutisso@6385 60
brutisso@6385 61 const uint length() const { return _length; }
brutisso@6385 62 const size_t capacity() const { return _capacity; }
brutisso@6385 63
brutisso@6385 64 void increment(uint length_to_add, size_t capacity_to_add) {
brutisso@6385 65 _length += length_to_add;
brutisso@6385 66 _capacity += capacity_to_add;
brutisso@6385 67 }
brutisso@6385 68
brutisso@6385 69 void decrement(const uint length_to_remove, const size_t capacity_to_remove) {
brutisso@6385 70 _length -= length_to_remove;
brutisso@6385 71 _capacity -= capacity_to_remove;
brutisso@6385 72 }
brutisso@6385 73 };
tonyp@2472 74
tonyp@2472 75 // Base class for all the classes that represent heap region sets. It
tonyp@2472 76 // contains the basic attributes that each set needs to maintain
tonyp@2472 77 // (e.g., length, region num, used bytes sum) plus any shared
tonyp@2472 78 // functionality (e.g., verification).
tonyp@2472 79
tonyp@2472 80 class HeapRegionSetBase VALUE_OBJ_CLASS_SPEC {
tonyp@3457 81 friend class VMStructs;
brutisso@6385 82 private:
brutisso@6385 83 bool _is_humongous;
brutisso@7195 84 bool _is_free;
brutisso@6385 85 HRSMtSafeChecker* _mt_safety_checker;
tonyp@2472 86
tonyp@2472 87 protected:
tonyp@2472 88 // The number of regions added to the set. If the set contains
tonyp@2472 89 // only humongous regions, this reflects only 'starts humongous'
tonyp@2472 90 // regions and does not include 'continues humongous' ones.
brutisso@6385 91 HeapRegionSetCount _count;
tonyp@2472 92
tonyp@2472 93 const char* _name;
tonyp@2472 94
brutisso@6385 95 bool _verify_in_progress;
tonyp@3268 96
tonyp@2472 97 // verify_region() is used to ensure that the contents of a region
brutisso@6385 98 // added to / removed from a set are consistent.
brutisso@6385 99 void verify_region(HeapRegion* hr) PRODUCT_RETURN;
tonyp@2472 100
tonyp@2472 101 // Indicates whether all regions in the set should be humongous or
tonyp@2472 102 // not. Only used during verification.
brutisso@6385 103 bool regions_humongous() { return _is_humongous; }
tonyp@2472 104
brutisso@7195 105 // Indicates whether all regions in the set should be free or
tonyp@2472 106 // not. Only used during verification.
brutisso@7195 107 bool regions_free() { return _is_free; }
tonyp@2472 108
brutisso@6385 109 void check_mt_safety() {
brutisso@6385 110 if (_mt_safety_checker != NULL) {
brutisso@6385 111 _mt_safety_checker->check();
brutisso@6385 112 }
brutisso@6385 113 }
brutisso@6385 114
brutisso@6385 115 virtual void fill_in_ext_msg_extra(hrs_ext_msg* msg) { }
brutisso@6385 116
brutisso@7195 117 HeapRegionSetBase(const char* name, bool humongous, bool free, HRSMtSafeChecker* mt_safety_checker);
brutisso@6385 118
brutisso@6385 119 public:
brutisso@6385 120 const char* name() { return _name; }
brutisso@6385 121
tschatzl@7009 122 uint length() const { return _count.length(); }
brutisso@6385 123
brutisso@6385 124 bool is_empty() { return _count.length() == 0; }
brutisso@6385 125
brutisso@6385 126 size_t total_capacity_bytes() {
brutisso@6385 127 return _count.capacity();
brutisso@6385 128 }
brutisso@6385 129
brutisso@6385 130 // It updates the fields of the set to reflect hr being added to
brutisso@6385 131 // the set and tags the region appropriately.
brutisso@6385 132 inline void add(HeapRegion* hr);
brutisso@6385 133
brutisso@6385 134 // It updates the fields of the set to reflect hr being removed
brutisso@6385 135 // from the set and tags the region appropriately.
brutisso@6385 136 inline void remove(HeapRegion* hr);
tonyp@2472 137
tonyp@2472 138 // fill_in_ext_msg() writes the the values of the set's attributes
tonyp@2643 139 // in the custom err_msg (hrs_ext_msg). fill_in_ext_msg_extra()
tonyp@2472 140 // allows subclasses to append further information.
tonyp@2643 141 void fill_in_ext_msg(hrs_ext_msg* msg, const char* message);
tonyp@2472 142
tonyp@2472 143 virtual void verify();
tonyp@2472 144 void verify_start();
tonyp@2472 145 void verify_next_region(HeapRegion* hr);
tonyp@2472 146 void verify_end();
tonyp@2472 147
tonyp@2472 148 #if HEAP_REGION_SET_FORCE_VERIFY
tonyp@2472 149 void verify_optional() {
tonyp@2472 150 verify();
tonyp@2472 151 }
tonyp@2472 152 #else // HEAP_REGION_SET_FORCE_VERIFY
tonyp@2472 153 void verify_optional() { }
tonyp@2472 154 #endif // HEAP_REGION_SET_FORCE_VERIFY
tonyp@2472 155
tonyp@2472 156 virtual void print_on(outputStream* out, bool print_contents = false);
tonyp@2472 157 };
tonyp@2472 158
tonyp@2472 159 // Customized err_msg for heap region sets. Apart from a
tonyp@2472 160 // assert/guarantee-specific message it also prints out the values of
tonyp@2472 161 // the fields of the associated set. This can be very helpful in
tonyp@2472 162 // diagnosing failures.
tonyp@2643 163 class hrs_ext_msg : public hrs_err_msg {
tonyp@2472 164 public:
tschatzl@7050 165 hrs_ext_msg(HeapRegionSetBase* set, const char* message) : hrs_err_msg("%s", "") {
tonyp@2472 166 set->fill_in_ext_msg(this, message);
tonyp@2472 167 }
tonyp@2472 168 };
tonyp@2472 169
tonyp@2643 170 #define hrs_assert_sets_match(_set1_, _set2_) \
tonyp@2472 171 do { \
tonyp@2472 172 assert(((_set1_)->regions_humongous() == \
tonyp@2472 173 (_set2_)->regions_humongous()) && \
brutisso@7195 174 ((_set1_)->regions_free() == (_set2_)->regions_free()), \
tonyp@2643 175 hrs_err_msg("the contents of set %s and set %s should match", \
tonyp@2472 176 (_set1_)->name(), (_set2_)->name())); \
tonyp@2472 177 } while (0)
tonyp@2472 178
tonyp@2472 179 // This class represents heap region sets whose members are not
tonyp@2472 180 // explicitly tracked. It's helpful to group regions using such sets
tonyp@2472 181 // so that we can reason about all the region groups in the heap using
tonyp@2472 182 // the same interface (namely, the HeapRegionSetBase API).
tonyp@2472 183
tonyp@2472 184 class HeapRegionSet : public HeapRegionSetBase {
brutisso@6385 185 public:
brutisso@6385 186 HeapRegionSet(const char* name, bool humongous, HRSMtSafeChecker* mt_safety_checker):
brutisso@7195 187 HeapRegionSetBase(name, humongous, false /* free */, mt_safety_checker) { }
tonyp@2472 188
brutisso@6385 189 void bulk_remove(const HeapRegionSetCount& removed) {
brutisso@6385 190 _count.decrement(removed.length(), removed.capacity());
tonyp@2472 191 }
tonyp@2472 192 };
tonyp@2472 193
jwilhelm@6422 194 // A set that links all the regions added to it in a doubly-linked
tschatzl@7050 195 // sorted list. We should try to avoid doing operations that iterate over
tonyp@2472 196 // such lists in performance critical paths. Typically we should
tschatzl@7050 197 // add / remove one region at a time or concatenate two lists.
tonyp@2472 198
brutisso@6385 199 class FreeRegionListIterator;
tonyp@2472 200
brutisso@6385 201 class FreeRegionList : public HeapRegionSetBase {
brutisso@6385 202 friend class FreeRegionListIterator;
tonyp@2472 203
tonyp@2472 204 private:
tonyp@2472 205 HeapRegion* _head;
tonyp@2472 206 HeapRegion* _tail;
tonyp@2472 207
jwilhelm@6422 208 // _last is used to keep track of where we added an element the last
tschatzl@7050 209 // time. It helps to improve performance when adding several ordered items in a row.
jwilhelm@6422 210 HeapRegion* _last;
jwilhelm@6422 211
brutisso@6385 212 static uint _unrealistically_long_length;
brutisso@6385 213
tschatzl@7050 214 inline HeapRegion* remove_from_head_impl();
tschatzl@7050 215 inline HeapRegion* remove_from_tail_impl();
tonyp@2472 216
tonyp@2472 217 protected:
tonyp@2643 218 virtual void fill_in_ext_msg_extra(hrs_ext_msg* msg);
tonyp@2472 219
tonyp@2472 220 // See the comment for HeapRegionSetBase::clear()
tonyp@2472 221 virtual void clear();
tonyp@2472 222
brutisso@6385 223 public:
brutisso@6385 224 FreeRegionList(const char* name, HRSMtSafeChecker* mt_safety_checker = NULL):
brutisso@6385 225 HeapRegionSetBase(name, false /* humongous */, true /* empty */, mt_safety_checker) {
tonyp@2472 226 clear();
tonyp@2472 227 }
tonyp@2472 228
brutisso@6385 229 void verify_list();
brutisso@6385 230
tschatzl@7050 231 #ifdef ASSERT
tschatzl@7050 232 bool contains(HeapRegion* hr) const {
tschatzl@7050 233 return hr->containing_set() == this;
tschatzl@7050 234 }
tschatzl@7050 235 #endif
brutisso@6385 236
brutisso@6385 237 static void set_unrealistically_long_length(uint len);
brutisso@6385 238
jwilhelm@6422 239 // Add hr to the list. The region should not be a member of another set.
jwilhelm@6422 240 // Assumes that the list is ordered and will preserve that order. The order
tschatzl@7091 241 // is determined by hrm_index.
jwilhelm@6422 242 inline void add_ordered(HeapRegion* hr);
jwilhelm@6422 243
jwilhelm@6422 244 // Removes from head or tail based on the given argument.
tschatzl@7050 245 HeapRegion* remove_region(bool from_head);
jwilhelm@6422 246
jwilhelm@6422 247 // Merge two ordered lists. The result is also ordered. The order is
tschatzl@7091 248 // determined by hrm_index.
jwilhelm@6422 249 void add_ordered(FreeRegionList* from_list);
jwilhelm@6422 250
tonyp@2472 251 // It empties the list by removing all regions from it.
tonyp@2472 252 void remove_all();
tonyp@2472 253
tschatzl@7050 254 // Remove all (contiguous) regions from first to first + num_regions -1 from
tschatzl@7050 255 // this list.
tschatzl@7050 256 // Num_regions must be > 1.
tschatzl@7050 257 void remove_starting_at(HeapRegion* first, uint num_regions);
tonyp@2472 258
tonyp@2472 259 virtual void verify();
tonyp@2472 260
tonyp@2472 261 virtual void print_on(outputStream* out, bool print_contents = false);
tonyp@2472 262 };
tonyp@2472 263
tonyp@2643 264 // Iterator class that provides a convenient way to iterate over the
tschatzl@7050 265 // regions of a FreeRegionList.
tonyp@2472 266
brutisso@6385 267 class FreeRegionListIterator : public StackObj {
tonyp@2472 268 private:
brutisso@6385 269 FreeRegionList* _list;
jwilhelm@6422 270 HeapRegion* _curr;
tonyp@2472 271
tonyp@2472 272 public:
tonyp@2472 273 bool more_available() {
tonyp@2472 274 return _curr != NULL;
tonyp@2472 275 }
tonyp@2472 276
tonyp@2472 277 HeapRegion* get_next() {
tonyp@2472 278 assert(more_available(),
tonyp@2472 279 "get_next() should be called when more regions are available");
tonyp@2472 280
tonyp@2472 281 // If we are going to introduce a count in the iterator we should
tonyp@2472 282 // do the "cycle" check.
tonyp@2472 283
tonyp@2472 284 HeapRegion* hr = _curr;
brutisso@6385 285 _list->verify_region(hr);
tonyp@2472 286 _curr = hr->next();
tonyp@2472 287 return hr;
tonyp@2472 288 }
tonyp@2472 289
jwilhelm@6422 290 FreeRegionListIterator(FreeRegionList* list) : _curr(NULL), _list(list) {
tschatzl@7050 291 _curr = list->_head;
tonyp@2472 292 }
tonyp@2472 293 };
tonyp@2472 294
tonyp@2472 295 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSET_HPP

mercurial