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

Wed, 15 Feb 2012 13:06:53 -0500

author
tonyp
date
Wed, 15 Feb 2012 13:06:53 -0500
changeset 3539
a9647476d1a4
parent 3463
d30fa85f9994
child 3691
2a0172480595
permissions
-rw-r--r--

7132029: G1: mixed GC phase lasts for longer than it should
Summary: Revamp of the mechanism that chooses old regions for inclusion in the CSet. It simplifies the code and introduces min and max bounds on the number of old regions added to the CSet at each mixed GC to avoid pathological cases. It also ensures that when we do a mixed GC we'll always find old regions to add to the CSet (i.e., it eliminates the case where a mixed GC will collect no old regions which can happen today).
Reviewed-by: johnc, brutisso

ysr@777 1 /*
johnc@3412 2 * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
ysr@777 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ysr@777 4 *
ysr@777 5 * This code is free software; you can redistribute it and/or modify it
ysr@777 6 * under the terms of the GNU General Public License version 2 only, as
ysr@777 7 * published by the Free Software Foundation.
ysr@777 8 *
ysr@777 9 * This code is distributed in the hope that it will be useful, but WITHOUT
ysr@777 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ysr@777 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ysr@777 12 * version 2 for more details (a copy is included in the LICENSE file that
ysr@777 13 * accompanied this code).
ysr@777 14 *
ysr@777 15 * You should have received a copy of the GNU General Public License version
ysr@777 16 * 2 along with this work; if not, write to the Free Software Foundation,
ysr@777 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ysr@777 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
ysr@777 22 *
ysr@777 23 */
ysr@777 24
stefank@2314 25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGION_HPP
stefank@2314 26 #define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGION_HPP
stefank@2314 27
stefank@2314 28 #include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp"
stefank@2314 29 #include "gc_implementation/g1/g1_specialized_oop_closures.hpp"
stefank@2314 30 #include "gc_implementation/g1/survRateGroup.hpp"
stefank@2314 31 #include "gc_implementation/shared/ageTable.hpp"
stefank@2314 32 #include "gc_implementation/shared/spaceDecorator.hpp"
stefank@2314 33 #include "memory/space.inline.hpp"
stefank@2314 34 #include "memory/watermark.hpp"
stefank@2314 35
ysr@777 36 #ifndef SERIALGC
ysr@777 37
ysr@777 38 // A HeapRegion is the smallest piece of a G1CollectedHeap that
ysr@777 39 // can be collected independently.
ysr@777 40
ysr@777 41 // NOTE: Although a HeapRegion is a Space, its
ysr@777 42 // Space::initDirtyCardClosure method must not be called.
ysr@777 43 // The problem is that the existence of this method breaks
ysr@777 44 // the independence of barrier sets from remembered sets.
ysr@777 45 // The solution is to remove this method from the definition
ysr@777 46 // of a Space.
ysr@777 47
ysr@777 48 class CompactibleSpace;
ysr@777 49 class ContiguousSpace;
ysr@777 50 class HeapRegionRemSet;
ysr@777 51 class HeapRegionRemSetIterator;
ysr@777 52 class HeapRegion;
tonyp@2472 53 class HeapRegionSetBase;
tonyp@2472 54
tonyp@2963 55 #define HR_FORMAT SIZE_FORMAT":(%s)["PTR_FORMAT","PTR_FORMAT","PTR_FORMAT"]"
tonyp@2963 56 #define HR_FORMAT_PARAMS(_hr_) \
tonyp@2963 57 (_hr_)->hrs_index(), \
tonyp@2963 58 (_hr_)->is_survivor() ? "S" : (_hr_)->is_young() ? "E" : "-", \
tonyp@2963 59 (_hr_)->bottom(), (_hr_)->top(), (_hr_)->end()
ysr@777 60
ysr@777 61 // A dirty card to oop closure for heap regions. It
ysr@777 62 // knows how to get the G1 heap and how to use the bitmap
ysr@777 63 // in the concurrent marker used by G1 to filter remembered
ysr@777 64 // sets.
ysr@777 65
ysr@777 66 class HeapRegionDCTOC : public ContiguousSpaceDCTOC {
ysr@777 67 public:
ysr@777 68 // Specification of possible DirtyCardToOopClosure filtering.
ysr@777 69 enum FilterKind {
ysr@777 70 NoFilterKind,
ysr@777 71 IntoCSFilterKind,
ysr@777 72 OutOfRegionFilterKind
ysr@777 73 };
ysr@777 74
ysr@777 75 protected:
ysr@777 76 HeapRegion* _hr;
ysr@777 77 FilterKind _fk;
ysr@777 78 G1CollectedHeap* _g1;
ysr@777 79
ysr@777 80 void walk_mem_region_with_cl(MemRegion mr,
ysr@777 81 HeapWord* bottom, HeapWord* top,
ysr@777 82 OopClosure* cl);
ysr@777 83
ysr@777 84 // We don't specialize this for FilteringClosure; filtering is handled by
ysr@777 85 // the "FilterKind" mechanism. But we provide this to avoid a compiler
ysr@777 86 // warning.
ysr@777 87 void walk_mem_region_with_cl(MemRegion mr,
ysr@777 88 HeapWord* bottom, HeapWord* top,
ysr@777 89 FilteringClosure* cl) {
ysr@777 90 HeapRegionDCTOC::walk_mem_region_with_cl(mr, bottom, top,
ysr@777 91 (OopClosure*)cl);
ysr@777 92 }
ysr@777 93
ysr@777 94 // Get the actual top of the area on which the closure will
ysr@777 95 // operate, given where the top is assumed to be (the end of the
ysr@777 96 // memory region passed to do_MemRegion) and where the object
ysr@777 97 // at the top is assumed to start. For example, an object may
ysr@777 98 // start at the top but actually extend past the assumed top,
ysr@777 99 // in which case the top becomes the end of the object.
ysr@777 100 HeapWord* get_actual_top(HeapWord* top, HeapWord* top_obj) {
ysr@777 101 return ContiguousSpaceDCTOC::get_actual_top(top, top_obj);
ysr@777 102 }
ysr@777 103
ysr@777 104 // Walk the given memory region from bottom to (actual) top
ysr@777 105 // looking for objects and applying the oop closure (_cl) to
ysr@777 106 // them. The base implementation of this treats the area as
ysr@777 107 // blocks, where a block may or may not be an object. Sub-
ysr@777 108 // classes should override this to provide more accurate
ysr@777 109 // or possibly more efficient walking.
ysr@777 110 void walk_mem_region(MemRegion mr, HeapWord* bottom, HeapWord* top) {
ysr@777 111 Filtering_DCTOC::walk_mem_region(mr, bottom, top);
ysr@777 112 }
ysr@777 113
ysr@777 114 public:
ysr@777 115 HeapRegionDCTOC(G1CollectedHeap* g1,
ysr@777 116 HeapRegion* hr, OopClosure* cl,
ysr@777 117 CardTableModRefBS::PrecisionStyle precision,
ysr@777 118 FilterKind fk);
ysr@777 119 };
ysr@777 120
ysr@777 121 // The complicating factor is that BlockOffsetTable diverged
ysr@777 122 // significantly, and we need functionality that is only in the G1 version.
ysr@777 123 // So I copied that code, which led to an alternate G1 version of
ysr@777 124 // OffsetTableContigSpace. If the two versions of BlockOffsetTable could
ysr@777 125 // be reconciled, then G1OffsetTableContigSpace could go away.
ysr@777 126
ysr@777 127 // The idea behind time stamps is the following. Doing a save_marks on
ysr@777 128 // all regions at every GC pause is time consuming (if I remember
ysr@777 129 // well, 10ms or so). So, we would like to do that only for regions
ysr@777 130 // that are GC alloc regions. To achieve this, we use time
ysr@777 131 // stamps. For every evacuation pause, G1CollectedHeap generates a
ysr@777 132 // unique time stamp (essentially a counter that gets
ysr@777 133 // incremented). Every time we want to call save_marks on a region,
ysr@777 134 // we set the saved_mark_word to top and also copy the current GC
ysr@777 135 // time stamp to the time stamp field of the space. Reading the
ysr@777 136 // saved_mark_word involves checking the time stamp of the
ysr@777 137 // region. If it is the same as the current GC time stamp, then we
ysr@777 138 // can safely read the saved_mark_word field, as it is valid. If the
ysr@777 139 // time stamp of the region is not the same as the current GC time
ysr@777 140 // stamp, then we instead read top, as the saved_mark_word field is
ysr@777 141 // invalid. Time stamps (on the regions and also on the
ysr@777 142 // G1CollectedHeap) are reset at every cleanup (we iterate over
ysr@777 143 // the regions anyway) and at the end of a Full GC. The current scheme
ysr@777 144 // that uses sequential unsigned ints will fail only if we have 4b
ysr@777 145 // evacuation pauses between two cleanups, which is _highly_ unlikely.
ysr@777 146
ysr@777 147 class G1OffsetTableContigSpace: public ContiguousSpace {
ysr@777 148 friend class VMStructs;
ysr@777 149 protected:
ysr@777 150 G1BlockOffsetArrayContigSpace _offsets;
ysr@777 151 Mutex _par_alloc_lock;
ysr@777 152 volatile unsigned _gc_time_stamp;
tonyp@2715 153 // When we need to retire an allocation region, while other threads
tonyp@2715 154 // are also concurrently trying to allocate into it, we typically
tonyp@2715 155 // allocate a dummy object at the end of the region to ensure that
tonyp@2715 156 // no more allocations can take place in it. However, sometimes we
tonyp@2715 157 // want to know where the end of the last "real" object we allocated
tonyp@2715 158 // into the region was and this is what this keeps track.
tonyp@2715 159 HeapWord* _pre_dummy_top;
ysr@777 160
ysr@777 161 public:
ysr@777 162 // Constructor. If "is_zeroed" is true, the MemRegion "mr" may be
ysr@777 163 // assumed to contain zeros.
ysr@777 164 G1OffsetTableContigSpace(G1BlockOffsetSharedArray* sharedOffsetArray,
ysr@777 165 MemRegion mr, bool is_zeroed = false);
ysr@777 166
ysr@777 167 void set_bottom(HeapWord* value);
ysr@777 168 void set_end(HeapWord* value);
ysr@777 169
ysr@777 170 virtual HeapWord* saved_mark_word() const;
ysr@777 171 virtual void set_saved_mark();
ysr@777 172 void reset_gc_time_stamp() { _gc_time_stamp = 0; }
ysr@777 173
tonyp@2715 174 // See the comment above in the declaration of _pre_dummy_top for an
tonyp@2715 175 // explanation of what it is.
tonyp@2715 176 void set_pre_dummy_top(HeapWord* pre_dummy_top) {
tonyp@2715 177 assert(is_in(pre_dummy_top) && pre_dummy_top <= top(), "pre-condition");
tonyp@2715 178 _pre_dummy_top = pre_dummy_top;
tonyp@2715 179 }
tonyp@2715 180 HeapWord* pre_dummy_top() {
tonyp@2715 181 return (_pre_dummy_top == NULL) ? top() : _pre_dummy_top;
tonyp@2715 182 }
tonyp@2715 183 void reset_pre_dummy_top() { _pre_dummy_top = NULL; }
tonyp@2715 184
tonyp@791 185 virtual void initialize(MemRegion mr, bool clear_space, bool mangle_space);
tonyp@791 186 virtual void clear(bool mangle_space);
ysr@777 187
ysr@777 188 HeapWord* block_start(const void* p);
ysr@777 189 HeapWord* block_start_const(const void* p) const;
ysr@777 190
ysr@777 191 // Add offset table update.
ysr@777 192 virtual HeapWord* allocate(size_t word_size);
ysr@777 193 HeapWord* par_allocate(size_t word_size);
ysr@777 194
ysr@777 195 // MarkSweep support phase3
ysr@777 196 virtual HeapWord* initialize_threshold();
ysr@777 197 virtual HeapWord* cross_threshold(HeapWord* start, HeapWord* end);
ysr@777 198
ysr@777 199 virtual void print() const;
tonyp@2453 200
tonyp@2453 201 void reset_bot() {
tonyp@2453 202 _offsets.zero_bottom_entry();
tonyp@2453 203 _offsets.initialize_threshold();
tonyp@2453 204 }
tonyp@2453 205
tonyp@2453 206 void update_bot_for_object(HeapWord* start, size_t word_size) {
tonyp@2453 207 _offsets.alloc_block(start, word_size);
tonyp@2453 208 }
tonyp@2453 209
tonyp@2453 210 void print_bot_on(outputStream* out) {
tonyp@2453 211 _offsets.print_on(out);
tonyp@2453 212 }
ysr@777 213 };
ysr@777 214
ysr@777 215 class HeapRegion: public G1OffsetTableContigSpace {
ysr@777 216 friend class VMStructs;
ysr@777 217 private:
ysr@777 218
tonyp@790 219 enum HumongousType {
tonyp@790 220 NotHumongous = 0,
tonyp@790 221 StartsHumongous,
tonyp@790 222 ContinuesHumongous
tonyp@790 223 };
tonyp@790 224
ysr@777 225 // Requires that the region "mr" be dense with objects, and begin and end
ysr@777 226 // with an object.
ysr@777 227 void oops_in_mr_iterate(MemRegion mr, OopClosure* cl);
ysr@777 228
ysr@777 229 // The remembered set for this region.
ysr@777 230 // (Might want to make this "inline" later, to avoid some alloc failure
ysr@777 231 // issues.)
ysr@777 232 HeapRegionRemSet* _rem_set;
ysr@777 233
ysr@777 234 G1BlockOffsetArrayContigSpace* offsets() { return &_offsets; }
ysr@777 235
ysr@777 236 protected:
tonyp@2963 237 // The index of this region in the heap region sequence.
tonyp@2963 238 size_t _hrs_index;
ysr@777 239
tonyp@790 240 HumongousType _humongous_type;
ysr@777 241 // For a humongous region, region in which it starts.
ysr@777 242 HeapRegion* _humongous_start_region;
ysr@777 243 // For the start region of a humongous sequence, it's original end().
ysr@777 244 HeapWord* _orig_end;
ysr@777 245
ysr@777 246 // True iff the region is in current collection_set.
ysr@777 247 bool _in_collection_set;
ysr@777 248
ysr@777 249 // True iff an attempt to evacuate an object in the region failed.
ysr@777 250 bool _evacuation_failed;
ysr@777 251
ysr@777 252 // A heap region may be a member one of a number of special subsets, each
ysr@777 253 // represented as linked lists through the field below. Currently, these
ysr@777 254 // sets include:
ysr@777 255 // The collection set.
ysr@777 256 // The set of allocation regions used in a collection pause.
ysr@777 257 // Spaces that may contain gray objects.
ysr@777 258 HeapRegion* _next_in_special_set;
ysr@777 259
ysr@777 260 // next region in the young "generation" region set
ysr@777 261 HeapRegion* _next_young_region;
ysr@777 262
apetrusenko@1231 263 // Next region whose cards need cleaning
apetrusenko@1231 264 HeapRegion* _next_dirty_cards_region;
apetrusenko@1231 265
tonyp@2472 266 // Fields used by the HeapRegionSetBase class and subclasses.
tonyp@2472 267 HeapRegion* _next;
tonyp@2472 268 #ifdef ASSERT
tonyp@2472 269 HeapRegionSetBase* _containing_set;
tonyp@2472 270 #endif // ASSERT
tonyp@2472 271 bool _pending_removal;
tonyp@2472 272
ysr@777 273 // For parallel heapRegion traversal.
ysr@777 274 jint _claimed;
ysr@777 275
ysr@777 276 // We use concurrent marking to determine the amount of live data
ysr@777 277 // in each heap region.
ysr@777 278 size_t _prev_marked_bytes; // Bytes known to be live via last completed marking.
ysr@777 279 size_t _next_marked_bytes; // Bytes known to be live via in-progress marking.
ysr@777 280
ysr@777 281 // See "sort_index" method. -1 means is not in the array.
ysr@777 282 int _sort_index;
ysr@777 283
ysr@777 284 // <PREDICTION>
ysr@777 285 double _gc_efficiency;
ysr@777 286 // </PREDICTION>
ysr@777 287
ysr@777 288 enum YoungType {
ysr@777 289 NotYoung, // a region is not young
ysr@777 290 Young, // a region is young
tonyp@2963 291 Survivor // a region is young and it contains survivors
ysr@777 292 };
ysr@777 293
johnc@2021 294 volatile YoungType _young_type;
ysr@777 295 int _young_index_in_cset;
ysr@777 296 SurvRateGroup* _surv_rate_group;
ysr@777 297 int _age_index;
ysr@777 298
ysr@777 299 // The start of the unmarked area. The unmarked area extends from this
ysr@777 300 // word until the top and/or end of the region, and is the part
ysr@777 301 // of the region for which no marking was done, i.e. objects may
ysr@777 302 // have been allocated in this part since the last mark phase.
ysr@777 303 // "prev" is the top at the start of the last completed marking.
ysr@777 304 // "next" is the top at the start of the in-progress marking (if any.)
ysr@777 305 HeapWord* _prev_top_at_mark_start;
ysr@777 306 HeapWord* _next_top_at_mark_start;
ysr@777 307 // If a collection pause is in progress, this is the top at the start
ysr@777 308 // of that pause.
ysr@777 309
ysr@777 310 // We've counted the marked bytes of objects below here.
ysr@777 311 HeapWord* _top_at_conc_mark_count;
ysr@777 312
ysr@777 313 void init_top_at_mark_start() {
ysr@777 314 assert(_prev_marked_bytes == 0 &&
ysr@777 315 _next_marked_bytes == 0,
ysr@777 316 "Must be called after zero_marked_bytes.");
ysr@777 317 HeapWord* bot = bottom();
ysr@777 318 _prev_top_at_mark_start = bot;
ysr@777 319 _next_top_at_mark_start = bot;
ysr@777 320 _top_at_conc_mark_count = bot;
ysr@777 321 }
ysr@777 322
ysr@777 323 void set_young_type(YoungType new_type) {
ysr@777 324 //assert(_young_type != new_type, "setting the same type" );
ysr@777 325 // TODO: add more assertions here
ysr@777 326 _young_type = new_type;
ysr@777 327 }
ysr@777 328
johnc@1829 329 // Cached attributes used in the collection set policy information
johnc@1829 330
johnc@1829 331 // The RSet length that was added to the total value
johnc@1829 332 // for the collection set.
johnc@1829 333 size_t _recorded_rs_length;
johnc@1829 334
johnc@1829 335 // The predicted elapsed time that was added to total value
johnc@1829 336 // for the collection set.
johnc@1829 337 double _predicted_elapsed_time_ms;
johnc@1829 338
johnc@1829 339 // The predicted number of bytes to copy that was added to
johnc@1829 340 // the total value for the collection set.
johnc@1829 341 size_t _predicted_bytes_to_copy;
johnc@1829 342
ysr@777 343 public:
ysr@777 344 // If "is_zeroed" is "true", the region "mr" can be assumed to contain zeros.
tonyp@2963 345 HeapRegion(size_t hrs_index,
tonyp@2963 346 G1BlockOffsetSharedArray* sharedOffsetArray,
ysr@777 347 MemRegion mr, bool is_zeroed);
ysr@777 348
johnc@3182 349 static int LogOfHRGrainBytes;
johnc@3182 350 static int LogOfHRGrainWords;
johnc@3182 351
johnc@3182 352 static size_t GrainBytes;
johnc@3182 353 static size_t GrainWords;
johnc@3182 354 static size_t CardsPerRegion;
tonyp@1377 355
tonyp@3176 356 static size_t align_up_to_region_byte_size(size_t sz) {
tonyp@3176 357 return (sz + (size_t) GrainBytes - 1) &
tonyp@3176 358 ~((1 << (size_t) LogOfHRGrainBytes) - 1);
tonyp@3176 359 }
tonyp@3176 360
tonyp@1377 361 // It sets up the heap region size (GrainBytes / GrainWords), as
tonyp@1377 362 // well as other related fields that are based on the heap region
tonyp@1377 363 // size (LogOfHRGrainBytes / LogOfHRGrainWords /
tonyp@1377 364 // CardsPerRegion). All those fields are considered constant
tonyp@1377 365 // throughout the JVM's execution, therefore they should only be set
tonyp@1377 366 // up once during initialization time.
tonyp@1377 367 static void setup_heap_region_size(uintx min_heap_size);
ysr@777 368
tonyp@790 369 enum ClaimValues {
johnc@3296 370 InitialClaimValue = 0,
johnc@3296 371 FinalCountClaimValue = 1,
johnc@3296 372 NoteEndClaimValue = 2,
johnc@3296 373 ScrubRemSetClaimValue = 3,
johnc@3296 374 ParVerifyClaimValue = 4,
johnc@3296 375 RebuildRSClaimValue = 5,
johnc@3412 376 CompleteMarkCSetClaimValue = 6,
johnc@3463 377 ParEvacFailureClaimValue = 7,
johnc@3463 378 AggregateCountClaimValue = 8,
johnc@3463 379 VerifyCountClaimValue = 9
tonyp@790 380 };
tonyp@790 381
tonyp@2454 382 inline HeapWord* par_allocate_no_bot_updates(size_t word_size) {
tonyp@2454 383 assert(is_young(), "we can only skip BOT updates on young regions");
tonyp@2454 384 return ContiguousSpace::par_allocate(word_size);
tonyp@2454 385 }
tonyp@2454 386 inline HeapWord* allocate_no_bot_updates(size_t word_size) {
tonyp@2454 387 assert(is_young(), "we can only skip BOT updates on young regions");
tonyp@2454 388 return ContiguousSpace::allocate(word_size);
tonyp@2454 389 }
tonyp@2454 390
ysr@777 391 // If this region is a member of a HeapRegionSeq, the index in that
ysr@777 392 // sequence, otherwise -1.
tonyp@2963 393 size_t hrs_index() const { return _hrs_index; }
ysr@777 394
ysr@777 395 // The number of bytes marked live in the region in the last marking phase.
ysr@777 396 size_t marked_bytes() { return _prev_marked_bytes; }
tonyp@2717 397 size_t live_bytes() {
tonyp@2717 398 return (top() - prev_top_at_mark_start()) * HeapWordSize + marked_bytes();
tonyp@2717 399 }
tonyp@2717 400
ysr@777 401 // The number of bytes counted in the next marking.
ysr@777 402 size_t next_marked_bytes() { return _next_marked_bytes; }
ysr@777 403 // The number of bytes live wrt the next marking.
ysr@777 404 size_t next_live_bytes() {
tonyp@2717 405 return
tonyp@2717 406 (top() - next_top_at_mark_start()) * HeapWordSize + next_marked_bytes();
ysr@777 407 }
ysr@777 408
ysr@777 409 // A lower bound on the amount of garbage bytes in the region.
ysr@777 410 size_t garbage_bytes() {
ysr@777 411 size_t used_at_mark_start_bytes =
ysr@777 412 (prev_top_at_mark_start() - bottom()) * HeapWordSize;
ysr@777 413 assert(used_at_mark_start_bytes >= marked_bytes(),
ysr@777 414 "Can't mark more than we have.");
ysr@777 415 return used_at_mark_start_bytes - marked_bytes();
ysr@777 416 }
ysr@777 417
tonyp@3539 418 // Return the amount of bytes we'll reclaim if we collect this
tonyp@3539 419 // region. This includes not only the known garbage bytes in the
tonyp@3539 420 // region but also any unallocated space in it, i.e., [top, end),
tonyp@3539 421 // since it will also be reclaimed if we collect the region.
tonyp@3539 422 size_t reclaimable_bytes() {
tonyp@3539 423 size_t known_live_bytes = live_bytes();
tonyp@3539 424 assert(known_live_bytes <= capacity(), "sanity");
tonyp@3539 425 return capacity() - known_live_bytes;
tonyp@3539 426 }
tonyp@3539 427
ysr@777 428 // An upper bound on the number of live bytes in the region.
ysr@777 429 size_t max_live_bytes() { return used() - garbage_bytes(); }
ysr@777 430
ysr@777 431 void add_to_marked_bytes(size_t incr_bytes) {
ysr@777 432 _next_marked_bytes = _next_marked_bytes + incr_bytes;
johnc@3292 433 assert(_next_marked_bytes <= used(), "invariant" );
ysr@777 434 }
ysr@777 435
ysr@777 436 void zero_marked_bytes() {
ysr@777 437 _prev_marked_bytes = _next_marked_bytes = 0;
ysr@777 438 }
ysr@777 439
tonyp@790 440 bool isHumongous() const { return _humongous_type != NotHumongous; }
tonyp@790 441 bool startsHumongous() const { return _humongous_type == StartsHumongous; }
tonyp@790 442 bool continuesHumongous() const { return _humongous_type == ContinuesHumongous; }
ysr@777 443 // For a humongous region, region in which it starts.
ysr@777 444 HeapRegion* humongous_start_region() const {
ysr@777 445 return _humongous_start_region;
ysr@777 446 }
ysr@777 447
brutisso@3216 448 // Same as Space::is_in_reserved, but will use the original size of the region.
brutisso@3216 449 // The original size is different only for start humongous regions. They get
brutisso@3216 450 // their _end set up to be the end of the last continues region of the
brutisso@3216 451 // corresponding humongous object.
brutisso@3216 452 bool is_in_reserved_raw(const void* p) const {
brutisso@3216 453 return _bottom <= p && p < _orig_end;
brutisso@3216 454 }
brutisso@3216 455
tonyp@2453 456 // Makes the current region be a "starts humongous" region, i.e.,
tonyp@2453 457 // the first region in a series of one or more contiguous regions
tonyp@2453 458 // that will contain a single "humongous" object. The two parameters
tonyp@2453 459 // are as follows:
tonyp@2453 460 //
tonyp@2453 461 // new_top : The new value of the top field of this region which
tonyp@2453 462 // points to the end of the humongous object that's being
tonyp@2453 463 // allocated. If there is more than one region in the series, top
tonyp@2453 464 // will lie beyond this region's original end field and on the last
tonyp@2453 465 // region in the series.
tonyp@2453 466 //
tonyp@2453 467 // new_end : The new value of the end field of this region which
tonyp@2453 468 // points to the end of the last region in the series. If there is
tonyp@2453 469 // one region in the series (namely: this one) end will be the same
tonyp@2453 470 // as the original end of this region.
tonyp@2453 471 //
tonyp@2453 472 // Updating top and end as described above makes this region look as
tonyp@2453 473 // if it spans the entire space taken up by all the regions in the
tonyp@2453 474 // series and an single allocation moved its top to new_top. This
tonyp@2453 475 // ensures that the space (capacity / allocated) taken up by all
tonyp@2453 476 // humongous regions can be calculated by just looking at the
tonyp@2453 477 // "starts humongous" regions and by ignoring the "continues
tonyp@2453 478 // humongous" regions.
tonyp@2453 479 void set_startsHumongous(HeapWord* new_top, HeapWord* new_end);
ysr@777 480
tonyp@2453 481 // Makes the current region be a "continues humongous'
tonyp@2453 482 // region. first_hr is the "start humongous" region of the series
tonyp@2453 483 // which this region will be part of.
tonyp@2453 484 void set_continuesHumongous(HeapRegion* first_hr);
ysr@777 485
tonyp@2472 486 // Unsets the humongous-related fields on the region.
tonyp@2472 487 void set_notHumongous();
tonyp@2472 488
ysr@777 489 // If the region has a remembered set, return a pointer to it.
ysr@777 490 HeapRegionRemSet* rem_set() const {
ysr@777 491 return _rem_set;
ysr@777 492 }
ysr@777 493
ysr@777 494 // True iff the region is in current collection_set.
ysr@777 495 bool in_collection_set() const {
ysr@777 496 return _in_collection_set;
ysr@777 497 }
ysr@777 498 void set_in_collection_set(bool b) {
ysr@777 499 _in_collection_set = b;
ysr@777 500 }
ysr@777 501 HeapRegion* next_in_collection_set() {
ysr@777 502 assert(in_collection_set(), "should only invoke on member of CS.");
ysr@777 503 assert(_next_in_special_set == NULL ||
ysr@777 504 _next_in_special_set->in_collection_set(),
ysr@777 505 "Malformed CS.");
ysr@777 506 return _next_in_special_set;
ysr@777 507 }
ysr@777 508 void set_next_in_collection_set(HeapRegion* r) {
ysr@777 509 assert(in_collection_set(), "should only invoke on member of CS.");
ysr@777 510 assert(r == NULL || r->in_collection_set(), "Malformed CS.");
ysr@777 511 _next_in_special_set = r;
ysr@777 512 }
ysr@777 513
tonyp@2472 514 // Methods used by the HeapRegionSetBase class and subclasses.
tonyp@2472 515
tonyp@2472 516 // Getter and setter for the next field used to link regions into
tonyp@2472 517 // linked lists.
tonyp@2472 518 HeapRegion* next() { return _next; }
tonyp@2472 519
tonyp@2472 520 void set_next(HeapRegion* next) { _next = next; }
tonyp@2472 521
tonyp@2472 522 // Every region added to a set is tagged with a reference to that
tonyp@2472 523 // set. This is used for doing consistency checking to make sure that
tonyp@2472 524 // the contents of a set are as they should be and it's only
tonyp@2472 525 // available in non-product builds.
tonyp@2472 526 #ifdef ASSERT
tonyp@2472 527 void set_containing_set(HeapRegionSetBase* containing_set) {
tonyp@2472 528 assert((containing_set == NULL && _containing_set != NULL) ||
tonyp@2472 529 (containing_set != NULL && _containing_set == NULL),
tonyp@2472 530 err_msg("containing_set: "PTR_FORMAT" "
tonyp@2472 531 "_containing_set: "PTR_FORMAT,
tonyp@2472 532 containing_set, _containing_set));
tonyp@2472 533
tonyp@2472 534 _containing_set = containing_set;
tonyp@2643 535 }
tonyp@2472 536
tonyp@2472 537 HeapRegionSetBase* containing_set() { return _containing_set; }
tonyp@2472 538 #else // ASSERT
tonyp@2472 539 void set_containing_set(HeapRegionSetBase* containing_set) { }
tonyp@2472 540
tonyp@2643 541 // containing_set() is only used in asserts so there's no reason
tonyp@2472 542 // to provide a dummy version of it.
tonyp@2472 543 #endif // ASSERT
tonyp@2472 544
tonyp@2472 545 // If we want to remove regions from a list in bulk we can simply tag
tonyp@2472 546 // them with the pending_removal tag and call the
tonyp@2472 547 // remove_all_pending() method on the list.
tonyp@2472 548
tonyp@2472 549 bool pending_removal() { return _pending_removal; }
tonyp@2472 550
tonyp@2472 551 void set_pending_removal(bool pending_removal) {
tonyp@2643 552 if (pending_removal) {
tonyp@2643 553 assert(!_pending_removal && containing_set() != NULL,
tonyp@2643 554 "can only set pending removal to true if it's false and "
tonyp@2643 555 "the region belongs to a region set");
tonyp@2643 556 } else {
tonyp@2643 557 assert( _pending_removal && containing_set() == NULL,
tonyp@2643 558 "can only set pending removal to false if it's true and "
tonyp@2643 559 "the region does not belong to a region set");
tonyp@2643 560 }
tonyp@2472 561
tonyp@2472 562 _pending_removal = pending_removal;
ysr@777 563 }
ysr@777 564
ysr@777 565 HeapRegion* get_next_young_region() { return _next_young_region; }
ysr@777 566 void set_next_young_region(HeapRegion* hr) {
ysr@777 567 _next_young_region = hr;
ysr@777 568 }
ysr@777 569
apetrusenko@1231 570 HeapRegion* get_next_dirty_cards_region() const { return _next_dirty_cards_region; }
apetrusenko@1231 571 HeapRegion** next_dirty_cards_region_addr() { return &_next_dirty_cards_region; }
apetrusenko@1231 572 void set_next_dirty_cards_region(HeapRegion* hr) { _next_dirty_cards_region = hr; }
apetrusenko@1231 573 bool is_on_dirty_cards_region_list() const { return get_next_dirty_cards_region() != NULL; }
apetrusenko@1231 574
tonyp@2963 575 HeapWord* orig_end() { return _orig_end; }
tonyp@2963 576
ysr@777 577 // Allows logical separation between objects allocated before and after.
ysr@777 578 void save_marks();
ysr@777 579
ysr@777 580 // Reset HR stuff to default values.
ysr@777 581 void hr_clear(bool par, bool clear_space);
tonyp@2849 582 void par_clear();
ysr@777 583
tonyp@791 584 void initialize(MemRegion mr, bool clear_space, bool mangle_space);
ysr@777 585
ysr@777 586 // Get the start of the unmarked area in this region.
ysr@777 587 HeapWord* prev_top_at_mark_start() const { return _prev_top_at_mark_start; }
ysr@777 588 HeapWord* next_top_at_mark_start() const { return _next_top_at_mark_start; }
ysr@777 589
ysr@777 590 // Apply "cl->do_oop" to (the addresses of) all reference fields in objects
ysr@777 591 // allocated in the current region before the last call to "save_mark".
ysr@777 592 void oop_before_save_marks_iterate(OopClosure* cl);
ysr@777 593
ysr@777 594 // Note the start or end of marking. This tells the heap region
ysr@777 595 // that the collector is about to start or has finished (concurrently)
ysr@777 596 // marking the heap.
ysr@777 597
tonyp@3416 598 // Notify the region that concurrent marking is starting. Initialize
tonyp@3416 599 // all fields related to the next marking info.
tonyp@3416 600 inline void note_start_of_marking();
ysr@777 601
tonyp@3416 602 // Notify the region that concurrent marking has finished. Copy the
tonyp@3416 603 // (now finalized) next marking info fields into the prev marking
tonyp@3416 604 // info fields.
tonyp@3416 605 inline void note_end_of_marking();
ysr@777 606
tonyp@3416 607 // Notify the region that it will be used as to-space during a GC
tonyp@3416 608 // and we are about to start copying objects into it.
tonyp@3416 609 inline void note_start_of_copying(bool during_initial_mark);
ysr@777 610
tonyp@3416 611 // Notify the region that it ceases being to-space during a GC and
tonyp@3416 612 // we will not copy objects into it any more.
tonyp@3416 613 inline void note_end_of_copying(bool during_initial_mark);
tonyp@3416 614
tonyp@3416 615 // Notify the region that we are about to start processing
tonyp@3416 616 // self-forwarded objects during evac failure handling.
tonyp@3416 617 void note_self_forwarding_removal_start(bool during_initial_mark,
tonyp@3416 618 bool during_conc_mark);
tonyp@3416 619
tonyp@3416 620 // Notify the region that we have finished processing self-forwarded
tonyp@3416 621 // objects during evac failure handling.
tonyp@3416 622 void note_self_forwarding_removal_end(bool during_initial_mark,
tonyp@3416 623 bool during_conc_mark,
tonyp@3416 624 size_t marked_bytes);
ysr@777 625
ysr@777 626 // Returns "false" iff no object in the region was allocated when the
ysr@777 627 // last mark phase ended.
ysr@777 628 bool is_marked() { return _prev_top_at_mark_start != bottom(); }
ysr@777 629
ysr@777 630 // If "is_marked()" is true, then this is the index of the region in
ysr@777 631 // an array constructed at the end of marking of the regions in a
ysr@777 632 // "desirability" order.
ysr@777 633 int sort_index() {
ysr@777 634 return _sort_index;
ysr@777 635 }
ysr@777 636 void set_sort_index(int i) {
ysr@777 637 _sort_index = i;
ysr@777 638 }
ysr@777 639
ysr@777 640 void init_top_at_conc_mark_count() {
ysr@777 641 _top_at_conc_mark_count = bottom();
ysr@777 642 }
ysr@777 643
ysr@777 644 void set_top_at_conc_mark_count(HeapWord *cur) {
ysr@777 645 assert(bottom() <= cur && cur <= end(), "Sanity.");
ysr@777 646 _top_at_conc_mark_count = cur;
ysr@777 647 }
ysr@777 648
ysr@777 649 HeapWord* top_at_conc_mark_count() {
ysr@777 650 return _top_at_conc_mark_count;
ysr@777 651 }
ysr@777 652
ysr@777 653 void reset_during_compaction() {
ysr@777 654 guarantee( isHumongous() && startsHumongous(),
ysr@777 655 "should only be called for humongous regions");
ysr@777 656
ysr@777 657 zero_marked_bytes();
ysr@777 658 init_top_at_mark_start();
ysr@777 659 }
ysr@777 660
ysr@777 661 void calc_gc_efficiency(void);
ysr@777 662 double gc_efficiency() { return _gc_efficiency;}
ysr@777 663
ysr@777 664 bool is_young() const { return _young_type != NotYoung; }
ysr@777 665 bool is_survivor() const { return _young_type == Survivor; }
ysr@777 666
ysr@777 667 int young_index_in_cset() const { return _young_index_in_cset; }
ysr@777 668 void set_young_index_in_cset(int index) {
ysr@777 669 assert( (index == -1) || is_young(), "pre-condition" );
ysr@777 670 _young_index_in_cset = index;
ysr@777 671 }
ysr@777 672
ysr@777 673 int age_in_surv_rate_group() {
ysr@777 674 assert( _surv_rate_group != NULL, "pre-condition" );
ysr@777 675 assert( _age_index > -1, "pre-condition" );
ysr@777 676 return _surv_rate_group->age_in_group(_age_index);
ysr@777 677 }
ysr@777 678
ysr@777 679 void record_surv_words_in_group(size_t words_survived) {
ysr@777 680 assert( _surv_rate_group != NULL, "pre-condition" );
ysr@777 681 assert( _age_index > -1, "pre-condition" );
ysr@777 682 int age_in_group = age_in_surv_rate_group();
ysr@777 683 _surv_rate_group->record_surviving_words(age_in_group, words_survived);
ysr@777 684 }
ysr@777 685
ysr@777 686 int age_in_surv_rate_group_cond() {
ysr@777 687 if (_surv_rate_group != NULL)
ysr@777 688 return age_in_surv_rate_group();
ysr@777 689 else
ysr@777 690 return -1;
ysr@777 691 }
ysr@777 692
ysr@777 693 SurvRateGroup* surv_rate_group() {
ysr@777 694 return _surv_rate_group;
ysr@777 695 }
ysr@777 696
ysr@777 697 void install_surv_rate_group(SurvRateGroup* surv_rate_group) {
ysr@777 698 assert( surv_rate_group != NULL, "pre-condition" );
ysr@777 699 assert( _surv_rate_group == NULL, "pre-condition" );
ysr@777 700 assert( is_young(), "pre-condition" );
ysr@777 701
ysr@777 702 _surv_rate_group = surv_rate_group;
ysr@777 703 _age_index = surv_rate_group->next_age_index();
ysr@777 704 }
ysr@777 705
ysr@777 706 void uninstall_surv_rate_group() {
ysr@777 707 if (_surv_rate_group != NULL) {
ysr@777 708 assert( _age_index > -1, "pre-condition" );
ysr@777 709 assert( is_young(), "pre-condition" );
ysr@777 710
ysr@777 711 _surv_rate_group = NULL;
ysr@777 712 _age_index = -1;
ysr@777 713 } else {
ysr@777 714 assert( _age_index == -1, "pre-condition" );
ysr@777 715 }
ysr@777 716 }
ysr@777 717
ysr@777 718 void set_young() { set_young_type(Young); }
ysr@777 719
ysr@777 720 void set_survivor() { set_young_type(Survivor); }
ysr@777 721
ysr@777 722 void set_not_young() { set_young_type(NotYoung); }
ysr@777 723
ysr@777 724 // Determine if an object has been allocated since the last
ysr@777 725 // mark performed by the collector. This returns true iff the object
ysr@777 726 // is within the unmarked area of the region.
ysr@777 727 bool obj_allocated_since_prev_marking(oop obj) const {
ysr@777 728 return (HeapWord *) obj >= prev_top_at_mark_start();
ysr@777 729 }
ysr@777 730 bool obj_allocated_since_next_marking(oop obj) const {
ysr@777 731 return (HeapWord *) obj >= next_top_at_mark_start();
ysr@777 732 }
ysr@777 733
ysr@777 734 // For parallel heapRegion traversal.
ysr@777 735 bool claimHeapRegion(int claimValue);
ysr@777 736 jint claim_value() { return _claimed; }
ysr@777 737 // Use this carefully: only when you're sure no one is claiming...
ysr@777 738 void set_claim_value(int claimValue) { _claimed = claimValue; }
ysr@777 739
ysr@777 740 // Returns the "evacuation_failed" property of the region.
ysr@777 741 bool evacuation_failed() { return _evacuation_failed; }
ysr@777 742
ysr@777 743 // Sets the "evacuation_failed" property of the region.
ysr@777 744 void set_evacuation_failed(bool b) {
ysr@777 745 _evacuation_failed = b;
ysr@777 746
ysr@777 747 if (b) {
ysr@777 748 init_top_at_conc_mark_count();
ysr@777 749 _next_marked_bytes = 0;
ysr@777 750 }
ysr@777 751 }
ysr@777 752
ysr@777 753 // Requires that "mr" be entirely within the region.
ysr@777 754 // Apply "cl->do_object" to all objects that intersect with "mr".
ysr@777 755 // If the iteration encounters an unparseable portion of the region,
ysr@777 756 // or if "cl->abort()" is true after a closure application,
ysr@777 757 // terminate the iteration and return the address of the start of the
ysr@777 758 // subregion that isn't done. (The two can be distinguished by querying
ysr@777 759 // "cl->abort()".) Return of "NULL" indicates that the iteration
ysr@777 760 // completed.
ysr@777 761 HeapWord*
ysr@777 762 object_iterate_mem_careful(MemRegion mr, ObjectClosure* cl);
ysr@777 763
tonyp@2849 764 // filter_young: if true and the region is a young region then we
tonyp@2849 765 // skip the iteration.
tonyp@2849 766 // card_ptr: if not NULL, and we decide that the card is not young
tonyp@2849 767 // and we iterate over it, we'll clean the card before we start the
tonyp@2849 768 // iteration.
ysr@777 769 HeapWord*
ysr@777 770 oops_on_card_seq_iterate_careful(MemRegion mr,
johnc@2021 771 FilterOutOfRegionClosure* cl,
tonyp@2849 772 bool filter_young,
tonyp@2849 773 jbyte* card_ptr);
ysr@777 774
ysr@777 775 // A version of block start that is guaranteed to find *some* block
ysr@777 776 // boundary at or before "p", but does not object iteration, and may
ysr@777 777 // therefore be used safely when the heap is unparseable.
ysr@777 778 HeapWord* block_start_careful(const void* p) const {
ysr@777 779 return _offsets.block_start_careful(p);
ysr@777 780 }
ysr@777 781
ysr@777 782 // Requires that "addr" is within the region. Returns the start of the
ysr@777 783 // first ("careful") block that starts at or after "addr", or else the
ysr@777 784 // "end" of the region if there is no such block.
ysr@777 785 HeapWord* next_block_start_careful(HeapWord* addr);
ysr@777 786
johnc@1829 787 size_t recorded_rs_length() const { return _recorded_rs_length; }
johnc@1829 788 double predicted_elapsed_time_ms() const { return _predicted_elapsed_time_ms; }
johnc@1829 789 size_t predicted_bytes_to_copy() const { return _predicted_bytes_to_copy; }
johnc@1829 790
johnc@1829 791 void set_recorded_rs_length(size_t rs_length) {
johnc@1829 792 _recorded_rs_length = rs_length;
johnc@1829 793 }
johnc@1829 794
johnc@1829 795 void set_predicted_elapsed_time_ms(double ms) {
johnc@1829 796 _predicted_elapsed_time_ms = ms;
johnc@1829 797 }
johnc@1829 798
johnc@1829 799 void set_predicted_bytes_to_copy(size_t bytes) {
johnc@1829 800 _predicted_bytes_to_copy = bytes;
johnc@1829 801 }
johnc@1829 802
ysr@777 803 #define HeapRegion_OOP_SINCE_SAVE_MARKS_DECL(OopClosureType, nv_suffix) \
ysr@777 804 virtual void oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl);
ysr@777 805 SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(HeapRegion_OOP_SINCE_SAVE_MARKS_DECL)
ysr@777 806
ysr@777 807 CompactibleSpace* next_compaction_space() const;
ysr@777 808
ysr@777 809 virtual void reset_after_compaction();
ysr@777 810
ysr@777 811 void print() const;
ysr@777 812 void print_on(outputStream* st) const;
ysr@777 813
johnc@2969 814 // vo == UsePrevMarking -> use "prev" marking information,
johnc@2969 815 // vo == UseNextMarking -> use "next" marking information
johnc@2969 816 // vo == UseMarkWord -> use the mark word in the object header
johnc@2969 817 //
tonyp@1246 818 // NOTE: Only the "prev" marking information is guaranteed to be
tonyp@1246 819 // consistent most of the time, so most calls to this should use
johnc@2969 820 // vo == UsePrevMarking.
johnc@2969 821 // Currently, there is only one case where this is called with
johnc@2969 822 // vo == UseNextMarking, which is to verify the "next" marking
johnc@2969 823 // information at the end of remark.
johnc@2969 824 // Currently there is only one place where this is called with
johnc@2969 825 // vo == UseMarkWord, which is to verify the marking during a
johnc@2969 826 // full GC.
johnc@2969 827 void verify(bool allow_dirty, VerifyOption vo, bool *failures) const;
tonyp@1246 828
tonyp@1246 829 // Override; it uses the "prev" marking information
ysr@777 830 virtual void verify(bool allow_dirty) const;
ysr@777 831 };
ysr@777 832
ysr@777 833 // HeapRegionClosure is used for iterating over regions.
ysr@777 834 // Terminates the iteration when the "doHeapRegion" method returns "true".
ysr@777 835 class HeapRegionClosure : public StackObj {
ysr@777 836 friend class HeapRegionSeq;
ysr@777 837 friend class G1CollectedHeap;
ysr@777 838
ysr@777 839 bool _complete;
ysr@777 840 void incomplete() { _complete = false; }
ysr@777 841
ysr@777 842 public:
ysr@777 843 HeapRegionClosure(): _complete(true) {}
ysr@777 844
ysr@777 845 // Typically called on each region until it returns true.
ysr@777 846 virtual bool doHeapRegion(HeapRegion* r) = 0;
ysr@777 847
ysr@777 848 // True after iteration if the closure was applied to all heap regions
ysr@777 849 // and returned "false" in all cases.
ysr@777 850 bool complete() { return _complete; }
ysr@777 851 };
ysr@777 852
ysr@777 853 #endif // SERIALGC
stefank@2314 854
stefank@2314 855 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGION_HPP

mercurial