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

Tue, 21 Aug 2012 14:10:39 -0700

author
johnc
date
Tue, 21 Aug 2012 14:10:39 -0700
changeset 3998
7383557659bd
parent 3957
a2f7274eb6ef
child 6385
58fc1b1523dc
permissions
-rw-r--r--

7185699: G1: Prediction model discrepancies
Summary: Correct the result value of G1CollectedHeap::pending_card_num(). Change the code that calculates the GC efficiency of a non-young heap region to use historical data from mixed GCs and the actual number of live bytes when predicting how long it would take to collect the region. Changes were also reviewed by Thomas Schatzl.
Reviewed-by: azeemj, brutisso

tonyp@2472 1 /*
tonyp@3457 2 * Copyright (c) 2011, 2012, 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
tonyp@2472 41 //////////////////// HeapRegionSetBase ////////////////////
tonyp@2472 42
tonyp@2472 43 // Base class for all the classes that represent heap region sets. It
tonyp@2472 44 // contains the basic attributes that each set needs to maintain
tonyp@2472 45 // (e.g., length, region num, used bytes sum) plus any shared
tonyp@2472 46 // functionality (e.g., verification).
tonyp@2472 47
tonyp@2643 48 class hrs_ext_msg;
tonyp@2472 49
tonyp@3268 50 typedef enum {
tonyp@3268 51 HRSPhaseNone,
tonyp@3268 52 HRSPhaseEvacuation,
tonyp@3268 53 HRSPhaseCleanup,
tonyp@3268 54 HRSPhaseFullGC
tonyp@3268 55 } HRSPhase;
tonyp@3268 56
tonyp@3268 57 class HRSPhaseSetter;
tonyp@3268 58
tonyp@2472 59 class HeapRegionSetBase VALUE_OBJ_CLASS_SPEC {
tonyp@2643 60 friend class hrs_ext_msg;
tonyp@3268 61 friend class HRSPhaseSetter;
tonyp@3457 62 friend class VMStructs;
tonyp@2472 63
tonyp@2472 64 protected:
tonyp@3713 65 static uint _unrealistically_long_length;
tonyp@2472 66
tonyp@2472 67 // The number of regions added to the set. If the set contains
tonyp@2472 68 // only humongous regions, this reflects only 'starts humongous'
tonyp@2472 69 // regions and does not include 'continues humongous' ones.
tonyp@3713 70 uint _length;
tonyp@2472 71
tonyp@2472 72 // The total number of regions represented by the set. If the set
tonyp@2472 73 // does not contain humongous regions, this should be the same as
tonyp@2472 74 // _length. If the set contains only humongous regions, this will
tonyp@2472 75 // include the 'continues humongous' regions.
tonyp@3713 76 uint _region_num;
tonyp@2472 77
tonyp@2472 78 // We don't keep track of the total capacity explicitly, we instead
tonyp@2472 79 // recalculate it based on _region_num and the heap region size.
tonyp@2472 80
tonyp@2472 81 // The sum of used bytes in the all the regions in the set.
tonyp@2472 82 size_t _total_used_bytes;
tonyp@2472 83
tonyp@2472 84 const char* _name;
tonyp@2472 85
tonyp@2472 86 bool _verify_in_progress;
tonyp@3713 87 uint _calc_length;
tonyp@3713 88 uint _calc_region_num;
tonyp@2472 89 size_t _calc_total_capacity_bytes;
tonyp@2472 90 size_t _calc_total_used_bytes;
tonyp@2472 91
tonyp@3268 92 // This is here so that it can be used in the subclasses to assert
tonyp@3268 93 // something different depending on which phase the GC is in. This
tonyp@3268 94 // can be particularly helpful in the check_mt_safety() methods.
tonyp@3268 95 static HRSPhase _phase;
tonyp@3268 96
tonyp@3268 97 // Only used by HRSPhaseSetter.
tonyp@3268 98 static void clear_phase();
tonyp@3268 99 static void set_phase(HRSPhase phase);
tonyp@3268 100
tonyp@2472 101 // verify_region() is used to ensure that the contents of a region
tonyp@2472 102 // added to / removed from a set are consistent. Different sets
tonyp@2472 103 // make different assumptions about the regions added to them. So
tonyp@2472 104 // each set can override verify_region_extra(), which is called
tonyp@2472 105 // from verify_region(), and do any extra verification it needs to
tonyp@2472 106 // perform in that.
tonyp@2472 107 virtual const char* verify_region_extra(HeapRegion* hr) { return NULL; }
tonyp@2472 108 bool verify_region(HeapRegion* hr,
tonyp@2472 109 HeapRegionSetBase* expected_containing_set);
tonyp@2472 110
tonyp@2472 111 // Indicates whether all regions in the set should be humongous or
tonyp@2472 112 // not. Only used during verification.
tonyp@2472 113 virtual bool regions_humongous() = 0;
tonyp@2472 114
tonyp@2472 115 // Indicates whether all regions in the set should be empty or
tonyp@2472 116 // not. Only used during verification.
tonyp@2472 117 virtual bool regions_empty() = 0;
tonyp@2472 118
tonyp@2472 119 // Subclasses can optionally override this to do MT safety protocol
tonyp@2472 120 // checks. It is called in an assert from all methods that perform
tonyp@2472 121 // updates on the set (and subclasses should also call it too).
tonyp@2472 122 virtual bool check_mt_safety() { return true; }
tonyp@2472 123
tonyp@2472 124 // fill_in_ext_msg() writes the the values of the set's attributes
tonyp@2643 125 // in the custom err_msg (hrs_ext_msg). fill_in_ext_msg_extra()
tonyp@2472 126 // allows subclasses to append further information.
tonyp@2643 127 virtual void fill_in_ext_msg_extra(hrs_ext_msg* msg) { }
tonyp@2643 128 void fill_in_ext_msg(hrs_ext_msg* msg, const char* message);
tonyp@2472 129
tonyp@2472 130 // It updates the fields of the set to reflect hr being added to
tonyp@2472 131 // the set.
tonyp@2472 132 inline void update_for_addition(HeapRegion* hr);
tonyp@2472 133
tonyp@2472 134 // It updates the fields of the set to reflect hr being added to
tonyp@2472 135 // the set and tags the region appropriately.
tonyp@2472 136 inline void add_internal(HeapRegion* hr);
tonyp@2472 137
tonyp@2472 138 // It updates the fields of the set to reflect hr being removed
tonyp@2472 139 // from the set.
tonyp@2472 140 inline void update_for_removal(HeapRegion* hr);
tonyp@2472 141
tonyp@2472 142 // It updates the fields of the set to reflect hr being removed
tonyp@2472 143 // from the set and tags the region appropriately.
tonyp@2472 144 inline void remove_internal(HeapRegion* hr);
tonyp@2472 145
tonyp@2472 146 // It clears all the fields of the sets. Note: it will not iterate
tonyp@2472 147 // over the set and remove regions from it. It assumes that the
tonyp@2472 148 // caller has already done so. It will literally just clear the fields.
tonyp@2472 149 virtual void clear();
tonyp@2472 150
tonyp@2472 151 HeapRegionSetBase(const char* name);
tonyp@2472 152
tonyp@2472 153 public:
tonyp@3713 154 static void set_unrealistically_long_length(uint len);
tonyp@2472 155
tonyp@2472 156 const char* name() { return _name; }
tonyp@2472 157
tonyp@3713 158 uint length() { return _length; }
tonyp@2472 159
tonyp@2472 160 bool is_empty() { return _length == 0; }
tonyp@2472 161
tonyp@3713 162 uint region_num() { return _region_num; }
tonyp@2472 163
tonyp@2472 164 size_t total_capacity_bytes() {
tonyp@3713 165 return (size_t) region_num() << HeapRegion::LogOfHRGrainBytes;
tonyp@2472 166 }
tonyp@2472 167
tonyp@2472 168 size_t total_used_bytes() { return _total_used_bytes; }
tonyp@2472 169
tonyp@2472 170 virtual void verify();
tonyp@2472 171 void verify_start();
tonyp@2472 172 void verify_next_region(HeapRegion* hr);
tonyp@2472 173 void verify_end();
tonyp@2472 174
tonyp@2472 175 #if HEAP_REGION_SET_FORCE_VERIFY
tonyp@2472 176 void verify_optional() {
tonyp@2472 177 verify();
tonyp@2472 178 }
tonyp@2472 179 #else // HEAP_REGION_SET_FORCE_VERIFY
tonyp@2472 180 void verify_optional() { }
tonyp@2472 181 #endif // HEAP_REGION_SET_FORCE_VERIFY
tonyp@2472 182
tonyp@2472 183 virtual void print_on(outputStream* out, bool print_contents = false);
tonyp@2472 184 };
tonyp@2472 185
tonyp@2472 186 // Customized err_msg for heap region sets. Apart from a
tonyp@2472 187 // assert/guarantee-specific message it also prints out the values of
tonyp@2472 188 // the fields of the associated set. This can be very helpful in
tonyp@2472 189 // diagnosing failures.
tonyp@2472 190
tonyp@2643 191 class hrs_ext_msg : public hrs_err_msg {
tonyp@2472 192 public:
tonyp@2643 193 hrs_ext_msg(HeapRegionSetBase* set, const char* message) : hrs_err_msg("") {
tonyp@2472 194 set->fill_in_ext_msg(this, message);
tonyp@2472 195 }
tonyp@2472 196 };
tonyp@2472 197
tonyp@3268 198 class HRSPhaseSetter {
tonyp@3268 199 public:
tonyp@3268 200 HRSPhaseSetter(HRSPhase phase) {
tonyp@3268 201 HeapRegionSetBase::set_phase(phase);
tonyp@3268 202 }
tonyp@3268 203 ~HRSPhaseSetter() {
tonyp@3268 204 HeapRegionSetBase::clear_phase();
tonyp@3268 205 }
tonyp@3268 206 };
tonyp@3268 207
tonyp@2472 208 // These two macros are provided for convenience, to keep the uses of
tonyp@2472 209 // these two asserts a bit more concise.
tonyp@2472 210
tonyp@2643 211 #define hrs_assert_mt_safety_ok(_set_) \
tonyp@2472 212 do { \
tonyp@2643 213 assert((_set_)->check_mt_safety(), hrs_ext_msg((_set_), "MT safety")); \
tonyp@2472 214 } while (0)
tonyp@2472 215
tonyp@2643 216 #define hrs_assert_region_ok(_set_, _hr_, _expected_) \
tonyp@2472 217 do { \
tonyp@2472 218 assert((_set_)->verify_region((_hr_), (_expected_)), \
tonyp@2643 219 hrs_ext_msg((_set_), "region verification")); \
tonyp@2472 220 } while (0)
tonyp@2472 221
tonyp@2472 222 //////////////////// HeapRegionSet ////////////////////
tonyp@2472 223
tonyp@2643 224 #define hrs_assert_sets_match(_set1_, _set2_) \
tonyp@2472 225 do { \
tonyp@2472 226 assert(((_set1_)->regions_humongous() == \
tonyp@2472 227 (_set2_)->regions_humongous()) && \
tonyp@2472 228 ((_set1_)->regions_empty() == (_set2_)->regions_empty()), \
tonyp@2643 229 hrs_err_msg("the contents of set %s and set %s should match", \
tonyp@2472 230 (_set1_)->name(), (_set2_)->name())); \
tonyp@2472 231 } while (0)
tonyp@2472 232
tonyp@2472 233 // This class represents heap region sets whose members are not
tonyp@2472 234 // explicitly tracked. It's helpful to group regions using such sets
tonyp@2472 235 // so that we can reason about all the region groups in the heap using
tonyp@2472 236 // the same interface (namely, the HeapRegionSetBase API).
tonyp@2472 237
tonyp@2472 238 class HeapRegionSet : public HeapRegionSetBase {
tonyp@2472 239 protected:
tonyp@2472 240 virtual const char* verify_region_extra(HeapRegion* hr) {
tonyp@2472 241 if (hr->next() != NULL) {
tonyp@2472 242 return "next() should always be NULL as we do not link the regions";
tonyp@2472 243 }
tonyp@2472 244
tonyp@2472 245 return HeapRegionSetBase::verify_region_extra(hr);
tonyp@2472 246 }
tonyp@2472 247
tonyp@2472 248 HeapRegionSet(const char* name) : HeapRegionSetBase(name) {
tonyp@2472 249 clear();
tonyp@2472 250 }
tonyp@2472 251
tonyp@2472 252 public:
tonyp@2472 253 // It adds hr to the set. The region should not be a member of
tonyp@2472 254 // another set.
tonyp@2472 255 inline void add(HeapRegion* hr);
tonyp@2472 256
tonyp@2472 257 // It removes hr from the set. The region should be a member of
tonyp@2472 258 // this set.
tonyp@2472 259 inline void remove(HeapRegion* hr);
tonyp@2472 260
tonyp@2472 261 // It removes a region from the set. Instead of updating the fields
tonyp@2472 262 // of the set to reflect this removal, it accumulates the updates
tonyp@2472 263 // in proxy_set. The idea is that proxy_set is thread-local to
tonyp@2472 264 // avoid multiple threads updating the fields of the set
tonyp@2472 265 // concurrently and having to synchronize. The method
tonyp@2472 266 // update_from_proxy() will update the fields of the set from the
tonyp@2472 267 // proxy_set.
tonyp@2472 268 inline void remove_with_proxy(HeapRegion* hr, HeapRegionSet* proxy_set);
tonyp@2472 269
tonyp@2472 270 // After multiple calls to remove_with_proxy() the updates to the
tonyp@2472 271 // fields of the set are accumulated in proxy_set. This call
tonyp@2472 272 // updates the fields of the set from proxy_set.
tonyp@2472 273 void update_from_proxy(HeapRegionSet* proxy_set);
tonyp@2472 274 };
tonyp@2472 275
tonyp@2472 276 //////////////////// HeapRegionLinkedList ////////////////////
tonyp@2472 277
tonyp@2472 278 // A set that links all the regions added to it in a singly-linked
tonyp@2472 279 // list. We should try to avoid doing operations that iterate over
tonyp@2472 280 // such lists in performance critical paths. Typically we should
tonyp@2472 281 // add / remove one region at a time or concatenate two lists. All
tonyp@2472 282 // those operations are done in constant time.
tonyp@2472 283
tonyp@2472 284 class HeapRegionLinkedListIterator;
tonyp@2472 285
tonyp@2472 286 class HeapRegionLinkedList : public HeapRegionSetBase {
tonyp@2472 287 friend class HeapRegionLinkedListIterator;
tonyp@2472 288
tonyp@2472 289 private:
tonyp@2472 290 HeapRegion* _head;
tonyp@2472 291 HeapRegion* _tail;
tonyp@2472 292
tonyp@2472 293 // These are provided for use by the friend classes.
tonyp@2472 294 HeapRegion* head() { return _head; }
tonyp@2472 295 HeapRegion* tail() { return _tail; }
tonyp@2472 296
tonyp@2472 297 protected:
tonyp@2643 298 virtual void fill_in_ext_msg_extra(hrs_ext_msg* msg);
tonyp@2472 299
tonyp@2472 300 // See the comment for HeapRegionSetBase::clear()
tonyp@2472 301 virtual void clear();
tonyp@2472 302
tonyp@2472 303 HeapRegionLinkedList(const char* name) : HeapRegionSetBase(name) {
tonyp@2472 304 clear();
tonyp@2472 305 }
tonyp@2472 306
tonyp@2472 307 public:
tonyp@2714 308 // It adds hr to the list as the new head. The region should not be
tonyp@2714 309 // a member of another set.
tonyp@2714 310 inline void add_as_head(HeapRegion* hr);
tonyp@2714 311
tonyp@2472 312 // It adds hr to the list as the new tail. The region should not be
tonyp@2472 313 // a member of another set.
tonyp@2472 314 inline void add_as_tail(HeapRegion* hr);
tonyp@2472 315
tonyp@2472 316 // It removes and returns the head of the list. It assumes that the
tonyp@2472 317 // list is not empty so it will return a non-NULL value.
tonyp@2472 318 inline HeapRegion* remove_head();
tonyp@2472 319
tonyp@2472 320 // Convenience method.
tonyp@2472 321 inline HeapRegion* remove_head_or_null();
tonyp@2472 322
tonyp@2472 323 // It moves the regions from from_list to this list and empties
tonyp@2472 324 // from_list. The new regions will appear in the same order as they
tonyp@2714 325 // were in from_list and be linked in the beginning of this list.
tonyp@2714 326 void add_as_head(HeapRegionLinkedList* from_list);
tonyp@2714 327
tonyp@2714 328 // It moves the regions from from_list to this list and empties
tonyp@2714 329 // from_list. The new regions will appear in the same order as they
tonyp@2472 330 // were in from_list and be linked in the end of this list.
tonyp@2472 331 void add_as_tail(HeapRegionLinkedList* from_list);
tonyp@2472 332
tonyp@2472 333 // It empties the list by removing all regions from it.
tonyp@2472 334 void remove_all();
tonyp@2472 335
tonyp@2472 336 // It removes all regions in the list that are pending for removal
tonyp@2472 337 // (i.e., they have been tagged with "pending_removal"). The list
tonyp@2472 338 // must not be empty, target_count should reflect the exact number
tonyp@2472 339 // of regions that are pending for removal in the list, and
tonyp@2472 340 // target_count should be > 1 (currently, we never need to remove a
tonyp@2472 341 // single region using this).
tonyp@3713 342 void remove_all_pending(uint target_count);
tonyp@2472 343
tonyp@2472 344 virtual void verify();
tonyp@2472 345
tonyp@2472 346 virtual void print_on(outputStream* out, bool print_contents = false);
tonyp@2472 347 };
tonyp@2472 348
tonyp@2643 349 //////////////////// HeapRegionLinkedListIterator ////////////////////
tonyp@2472 350
tonyp@2643 351 // Iterator class that provides a convenient way to iterate over the
tonyp@2643 352 // regions of a HeapRegionLinkedList instance.
tonyp@2472 353
tonyp@2472 354 class HeapRegionLinkedListIterator : public StackObj {
tonyp@2472 355 private:
tonyp@2472 356 HeapRegionLinkedList* _list;
tonyp@2472 357 HeapRegion* _curr;
tonyp@2472 358
tonyp@2472 359 public:
tonyp@2472 360 bool more_available() {
tonyp@2472 361 return _curr != NULL;
tonyp@2472 362 }
tonyp@2472 363
tonyp@2472 364 HeapRegion* get_next() {
tonyp@2472 365 assert(more_available(),
tonyp@2472 366 "get_next() should be called when more regions are available");
tonyp@2472 367
tonyp@2472 368 // If we are going to introduce a count in the iterator we should
tonyp@2472 369 // do the "cycle" check.
tonyp@2472 370
tonyp@2472 371 HeapRegion* hr = _curr;
tonyp@2472 372 assert(_list->verify_region(hr, _list), "region verification");
tonyp@2472 373 _curr = hr->next();
tonyp@2472 374 return hr;
tonyp@2472 375 }
tonyp@2472 376
tonyp@2472 377 HeapRegionLinkedListIterator(HeapRegionLinkedList* list)
tonyp@2472 378 : _curr(NULL), _list(list) {
tonyp@2472 379 _curr = list->head();
tonyp@2472 380 }
tonyp@2472 381 };
tonyp@2472 382
tonyp@2472 383 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSET_HPP

mercurial