src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp

Tue, 05 Mar 2013 15:36:56 -0800

author
tamao
date
Tue, 05 Mar 2013 15:36:56 -0800
changeset 4733
9def4075da6d
parent 4173
8a5ea0a9ccc4
child 5811
d55c004e1d4d
permissions
-rw-r--r--

8008079: G1: Add nextObject routine to CMBitMapRO and replace nextWord
Summary: Update the task local finger to the start of the next object when marking aborts, in order to avoid the redundant scanning of all 0's when the marking task restarts, if otherwise updating to the next word. In addition, reuse the routine nextObject() in routine iterate().
Reviewed-by: johnc, ysr
Contributed-by: tamao <tao.mao@oracle.com>

tonyp@2968 1 /*
tamao@4733 2 * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
tonyp@2968 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
tonyp@2968 4 *
tonyp@2968 5 * This code is free software; you can redistribute it and/or modify it
tonyp@2968 6 * under the terms of the GNU General Public License version 2 only, as
tonyp@2968 7 * published by the Free Software Foundation.
tonyp@2968 8 *
tonyp@2968 9 * This code is distributed in the hope that it will be useful, but WITHOUT
tonyp@2968 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
tonyp@2968 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
tonyp@2968 12 * version 2 for more details (a copy is included in the LICENSE file that
tonyp@2968 13 * accompanied this code).
tonyp@2968 14 *
tonyp@2968 15 * You should have received a copy of the GNU General Public License version
tonyp@2968 16 * 2 along with this work; if not, write to the Free Software Foundation,
tonyp@2968 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
tonyp@2968 18 *
tonyp@2968 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
tonyp@2968 20 * or visit www.oracle.com if you need additional information or have any
tonyp@2968 21 * questions.
tonyp@2968 22 *
tonyp@2968 23 */
tonyp@2968 24
tonyp@2968 25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_CONCURRENTMARK_INLINE_HPP
tonyp@2968 26 #define SHARE_VM_GC_IMPLEMENTATION_G1_CONCURRENTMARK_INLINE_HPP
tonyp@2968 27
tonyp@2968 28 #include "gc_implementation/g1/concurrentMark.hpp"
tonyp@2968 29 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
tonyp@2968 30
johnc@4123 31 // Utility routine to set an exclusive range of cards on the given
johnc@4123 32 // card liveness bitmap
johnc@4123 33 inline void ConcurrentMark::set_card_bitmap_range(BitMap* card_bm,
johnc@4123 34 BitMap::idx_t start_idx,
johnc@4123 35 BitMap::idx_t end_idx,
johnc@4123 36 bool is_par) {
johnc@4123 37
johnc@4123 38 // Set the exclusive bit range [start_idx, end_idx).
johnc@4123 39 assert((end_idx - start_idx) > 0, "at least one card");
johnc@4123 40 assert(end_idx <= card_bm->size(), "sanity");
johnc@4123 41
johnc@4123 42 // Silently clip the end index
johnc@4123 43 end_idx = MIN2(end_idx, card_bm->size());
johnc@4123 44
johnc@4123 45 // For small ranges use a simple loop; otherwise use set_range or
johnc@4123 46 // use par_at_put_range (if parallel). The range is made up of the
johnc@4123 47 // cards that are spanned by an object/mem region so 8 cards will
johnc@4123 48 // allow up to object sizes up to 4K to be handled using the loop.
johnc@4123 49 if ((end_idx - start_idx) <= 8) {
johnc@4123 50 for (BitMap::idx_t i = start_idx; i < end_idx; i += 1) {
johnc@4123 51 if (is_par) {
johnc@4123 52 card_bm->par_set_bit(i);
johnc@4123 53 } else {
johnc@4123 54 card_bm->set_bit(i);
johnc@4123 55 }
johnc@4123 56 }
johnc@4123 57 } else {
johnc@4123 58 // Note BitMap::par_at_put_range() and BitMap::set_range() are exclusive.
johnc@4123 59 if (is_par) {
johnc@4123 60 card_bm->par_at_put_range(start_idx, end_idx, true);
johnc@4123 61 } else {
johnc@4123 62 card_bm->set_range(start_idx, end_idx);
johnc@4123 63 }
johnc@4123 64 }
johnc@4123 65 }
johnc@4123 66
johnc@3463 67 // Returns the index in the liveness accounting card bitmap
johnc@3463 68 // for the given address
johnc@3463 69 inline BitMap::idx_t ConcurrentMark::card_bitmap_index_for(HeapWord* addr) {
johnc@3463 70 // Below, the term "card num" means the result of shifting an address
johnc@3463 71 // by the card shift -- address 0 corresponds to card number 0. One
johnc@3463 72 // must subtract the card num of the bottom of the heap to obtain a
johnc@3463 73 // card table index.
johnc@3463 74 intptr_t card_num = intptr_t(uintptr_t(addr) >> CardTableModRefBS::card_shift);
johnc@3463 75 return card_num - heap_bottom_card_num();
johnc@3463 76 }
johnc@3463 77
johnc@3463 78 // Counts the given memory region in the given task/worker
johnc@3463 79 // counting data structures.
johnc@3463 80 inline void ConcurrentMark::count_region(MemRegion mr, HeapRegion* hr,
johnc@3463 81 size_t* marked_bytes_array,
johnc@3463 82 BitMap* task_card_bm) {
johnc@3463 83 G1CollectedHeap* g1h = _g1h;
johnc@4123 84 CardTableModRefBS* ct_bs = (CardTableModRefBS*) (g1h->barrier_set());
johnc@4123 85
johnc@3463 86 HeapWord* start = mr.start();
johnc@4123 87 HeapWord* end = mr.end();
johnc@3463 88 size_t region_size_bytes = mr.byte_size();
tonyp@3713 89 uint index = hr->hrs_index();
johnc@3463 90
johnc@3463 91 assert(!hr->continuesHumongous(), "should not be HC region");
johnc@3463 92 assert(hr == g1h->heap_region_containing(start), "sanity");
johnc@3463 93 assert(hr == g1h->heap_region_containing(mr.last()), "sanity");
johnc@3463 94 assert(marked_bytes_array != NULL, "pre-condition");
johnc@3463 95 assert(task_card_bm != NULL, "pre-condition");
johnc@3463 96
johnc@3463 97 // Add to the task local marked bytes for this region.
johnc@3463 98 marked_bytes_array[index] += region_size_bytes;
johnc@3463 99
johnc@3463 100 BitMap::idx_t start_idx = card_bitmap_index_for(start);
johnc@4123 101 BitMap::idx_t end_idx = card_bitmap_index_for(end);
johnc@3463 102
johnc@4123 103 // Note: if we're looking at the last region in heap - end
johnc@4123 104 // could be actually just beyond the end of the heap; end_idx
johnc@4123 105 // will then correspond to a (non-existent) card that is also
johnc@4123 106 // just beyond the heap.
johnc@4123 107 if (g1h->is_in_g1_reserved(end) && !ct_bs->is_card_aligned(end)) {
johnc@4123 108 // end of region is not card aligned - incremement to cover
johnc@4123 109 // all the cards spanned by the region.
johnc@4123 110 end_idx += 1;
johnc@3463 111 }
johnc@4123 112 // The card bitmap is task/worker specific => no need to use
johnc@4123 113 // the 'par' BitMap routines.
johnc@4123 114 // Set bits in the exclusive bit range [start_idx, end_idx).
johnc@4123 115 set_card_bitmap_range(task_card_bm, start_idx, end_idx, false /* is_par */);
johnc@3463 116 }
johnc@3463 117
tonyp@3464 118 // Counts the given memory region in the task/worker counting
tonyp@3464 119 // data structures for the given worker id.
tonyp@3464 120 inline void ConcurrentMark::count_region(MemRegion mr,
tonyp@3464 121 HeapRegion* hr,
tonyp@3464 122 uint worker_id) {
tonyp@3464 123 size_t* marked_bytes_array = count_marked_bytes_array_for(worker_id);
tonyp@3464 124 BitMap* task_card_bm = count_card_bitmap_for(worker_id);
tonyp@3464 125 count_region(mr, hr, marked_bytes_array, task_card_bm);
tonyp@3464 126 }
tonyp@3464 127
johnc@3463 128 // Counts the given memory region, which may be a single object, in the
johnc@3463 129 // task/worker counting data structures for the given worker id.
johnc@3463 130 inline void ConcurrentMark::count_region(MemRegion mr, uint worker_id) {
johnc@3463 131 HeapWord* addr = mr.start();
johnc@3463 132 HeapRegion* hr = _g1h->heap_region_containing_raw(addr);
tonyp@3464 133 count_region(mr, hr, worker_id);
johnc@3463 134 }
johnc@3463 135
johnc@3463 136 // Counts the given object in the given task/worker counting data structures.
johnc@3463 137 inline void ConcurrentMark::count_object(oop obj,
johnc@3463 138 HeapRegion* hr,
johnc@3463 139 size_t* marked_bytes_array,
johnc@3463 140 BitMap* task_card_bm) {
johnc@3463 141 MemRegion mr((HeapWord*)obj, obj->size());
johnc@3463 142 count_region(mr, hr, marked_bytes_array, task_card_bm);
johnc@3463 143 }
johnc@3463 144
johnc@3463 145 // Counts the given object in the task/worker counting data
johnc@3463 146 // structures for the given worker id.
tonyp@3464 147 inline void ConcurrentMark::count_object(oop obj,
tonyp@3464 148 HeapRegion* hr,
tonyp@3464 149 uint worker_id) {
johnc@3463 150 size_t* marked_bytes_array = count_marked_bytes_array_for(worker_id);
johnc@3463 151 BitMap* task_card_bm = count_card_bitmap_for(worker_id);
johnc@3463 152 HeapWord* addr = (HeapWord*) obj;
johnc@3463 153 count_object(obj, hr, marked_bytes_array, task_card_bm);
johnc@3463 154 }
johnc@3463 155
johnc@3463 156 // Attempts to mark the given object and, if successful, counts
johnc@3463 157 // the object in the given task/worker counting structures.
johnc@3463 158 inline bool ConcurrentMark::par_mark_and_count(oop obj,
johnc@3463 159 HeapRegion* hr,
johnc@3463 160 size_t* marked_bytes_array,
johnc@3463 161 BitMap* task_card_bm) {
johnc@3463 162 HeapWord* addr = (HeapWord*)obj;
johnc@3463 163 if (_nextMarkBitMap->parMark(addr)) {
johnc@3463 164 // Update the task specific count data for the object.
johnc@3463 165 count_object(obj, hr, marked_bytes_array, task_card_bm);
johnc@3463 166 return true;
johnc@3463 167 }
johnc@3463 168 return false;
johnc@3463 169 }
johnc@3463 170
johnc@3463 171 // Attempts to mark the given object and, if successful, counts
johnc@3463 172 // the object in the task/worker counting structures for the
johnc@3463 173 // given worker id.
johnc@3463 174 inline bool ConcurrentMark::par_mark_and_count(oop obj,
tonyp@3464 175 size_t word_size,
tonyp@3464 176 HeapRegion* hr,
tonyp@3464 177 uint worker_id) {
tonyp@3464 178 HeapWord* addr = (HeapWord*)obj;
tonyp@3464 179 if (_nextMarkBitMap->parMark(addr)) {
tonyp@3464 180 MemRegion mr(addr, word_size);
tonyp@3464 181 count_region(mr, hr, worker_id);
tonyp@3464 182 return true;
tonyp@3464 183 }
tonyp@3464 184 return false;
tonyp@3464 185 }
tonyp@3464 186
tonyp@3464 187 // Attempts to mark the given object and, if successful, counts
tonyp@3464 188 // the object in the task/worker counting structures for the
tonyp@3464 189 // given worker id.
tonyp@3464 190 inline bool ConcurrentMark::par_mark_and_count(oop obj,
johnc@3463 191 HeapRegion* hr,
johnc@3463 192 uint worker_id) {
johnc@3463 193 HeapWord* addr = (HeapWord*)obj;
johnc@3463 194 if (_nextMarkBitMap->parMark(addr)) {
johnc@3463 195 // Update the task specific count data for the object.
johnc@3463 196 count_object(obj, hr, worker_id);
johnc@3463 197 return true;
johnc@3463 198 }
johnc@3463 199 return false;
johnc@3463 200 }
johnc@3463 201
johnc@3463 202 // As above - but we don't know the heap region containing the
johnc@3463 203 // object and so have to supply it.
johnc@3463 204 inline bool ConcurrentMark::par_mark_and_count(oop obj, uint worker_id) {
johnc@3463 205 HeapWord* addr = (HeapWord*)obj;
johnc@3463 206 HeapRegion* hr = _g1h->heap_region_containing_raw(addr);
johnc@3463 207 return par_mark_and_count(obj, hr, worker_id);
johnc@3463 208 }
johnc@3463 209
johnc@3463 210 // Similar to the above routine but we already know the size, in words, of
johnc@3463 211 // the object that we wish to mark/count
johnc@3463 212 inline bool ConcurrentMark::par_mark_and_count(oop obj,
johnc@3463 213 size_t word_size,
johnc@3463 214 uint worker_id) {
johnc@3463 215 HeapWord* addr = (HeapWord*)obj;
johnc@3463 216 if (_nextMarkBitMap->parMark(addr)) {
johnc@3463 217 // Update the task specific count data for the object.
johnc@3463 218 MemRegion mr(addr, word_size);
johnc@3463 219 count_region(mr, worker_id);
johnc@3463 220 return true;
johnc@3463 221 }
johnc@3463 222 return false;
johnc@3463 223 }
johnc@3463 224
johnc@3463 225 // Unconditionally mark the given object, and unconditinally count
johnc@3463 226 // the object in the counting structures for worker id 0.
johnc@3463 227 // Should *not* be called from parallel code.
johnc@3463 228 inline bool ConcurrentMark::mark_and_count(oop obj, HeapRegion* hr) {
johnc@3463 229 HeapWord* addr = (HeapWord*)obj;
johnc@3463 230 _nextMarkBitMap->mark(addr);
johnc@3463 231 // Update the task specific count data for the object.
johnc@3463 232 count_object(obj, hr, 0 /* worker_id */);
johnc@3463 233 return true;
johnc@3463 234 }
johnc@3463 235
johnc@3463 236 // As above - but we don't have the heap region containing the
johnc@3463 237 // object, so we have to supply it.
johnc@3463 238 inline bool ConcurrentMark::mark_and_count(oop obj) {
johnc@3463 239 HeapWord* addr = (HeapWord*)obj;
johnc@3463 240 HeapRegion* hr = _g1h->heap_region_containing_raw(addr);
johnc@3463 241 return mark_and_count(obj, hr);
johnc@3463 242 }
johnc@3463 243
johnc@3454 244 inline bool CMBitMapRO::iterate(BitMapClosure* cl, MemRegion mr) {
johnc@3454 245 HeapWord* start_addr = MAX2(startWord(), mr.start());
johnc@3454 246 HeapWord* end_addr = MIN2(endWord(), mr.end());
johnc@3454 247
johnc@3454 248 if (end_addr > start_addr) {
johnc@3454 249 // Right-open interval [start-offset, end-offset).
johnc@3454 250 BitMap::idx_t start_offset = heapWordToOffset(start_addr);
johnc@3454 251 BitMap::idx_t end_offset = heapWordToOffset(end_addr);
johnc@3454 252
johnc@3454 253 start_offset = _bm.get_next_one_offset(start_offset, end_offset);
johnc@3454 254 while (start_offset < end_offset) {
johnc@3454 255 if (!cl->do_bit(start_offset)) {
johnc@3454 256 return false;
johnc@3454 257 }
tamao@4733 258 HeapWord* next_addr = MIN2(nextObject(offsetToHeapWord(start_offset)), end_addr);
johnc@3454 259 BitMap::idx_t next_offset = heapWordToOffset(next_addr);
johnc@3454 260 start_offset = _bm.get_next_one_offset(next_offset, end_offset);
johnc@3454 261 }
johnc@3454 262 }
johnc@3454 263 return true;
johnc@3454 264 }
johnc@3454 265
johnc@3454 266 inline bool CMBitMapRO::iterate(BitMapClosure* cl) {
johnc@3454 267 MemRegion mr(startWord(), sizeInWords());
johnc@3454 268 return iterate(cl, mr);
johnc@3454 269 }
johnc@3454 270
tonyp@2968 271 inline void CMTask::push(oop obj) {
tonyp@2968 272 HeapWord* objAddr = (HeapWord*) obj;
tonyp@2968 273 assert(_g1h->is_in_g1_reserved(objAddr), "invariant");
tonyp@2968 274 assert(!_g1h->is_on_master_free_list(
tonyp@2968 275 _g1h->heap_region_containing((HeapWord*) objAddr)), "invariant");
tonyp@2968 276 assert(!_g1h->is_obj_ill(obj), "invariant");
tonyp@2968 277 assert(_nextMarkBitMap->isMarked(objAddr), "invariant");
tonyp@2968 278
tonyp@2968 279 if (_cm->verbose_high()) {
johnc@4173 280 gclog_or_tty->print_cr("[%u] pushing "PTR_FORMAT, _worker_id, (void*) obj);
tonyp@2968 281 }
tonyp@2968 282
tonyp@2968 283 if (!_task_queue->push(obj)) {
tonyp@2968 284 // The local task queue looks full. We need to push some entries
tonyp@2968 285 // to the global stack.
tonyp@2968 286
tonyp@2968 287 if (_cm->verbose_medium()) {
johnc@4173 288 gclog_or_tty->print_cr("[%u] task queue overflow, "
tonyp@2968 289 "moving entries to the global stack",
johnc@4173 290 _worker_id);
tonyp@2968 291 }
tonyp@2968 292 move_entries_to_global_stack();
tonyp@2968 293
tonyp@2968 294 // this should succeed since, even if we overflow the global
tonyp@2968 295 // stack, we should have definitely removed some entries from the
tonyp@2968 296 // local queue. So, there must be space on it.
tonyp@2968 297 bool success = _task_queue->push(obj);
tonyp@2968 298 assert(success, "invariant");
tonyp@2968 299 }
tonyp@2968 300
tonyp@2968 301 statsOnly( int tmp_size = _task_queue->size();
tonyp@2973 302 if (tmp_size > _local_max_size) {
tonyp@2968 303 _local_max_size = tmp_size;
tonyp@2973 304 }
tonyp@2968 305 ++_local_pushes );
tonyp@2968 306 }
tonyp@2968 307
tonyp@2968 308 // This determines whether the method below will check both the local
tonyp@2968 309 // and global fingers when determining whether to push on the stack a
tonyp@2968 310 // gray object (value 1) or whether it will only check the global one
tonyp@2968 311 // (value 0). The tradeoffs are that the former will be a bit more
tonyp@2968 312 // accurate and possibly push less on the stack, but it might also be
tonyp@2968 313 // a little bit slower.
tonyp@2968 314
tonyp@2968 315 #define _CHECK_BOTH_FINGERS_ 1
tonyp@2968 316
tonyp@2968 317 inline void CMTask::deal_with_reference(oop obj) {
tonyp@2968 318 if (_cm->verbose_high()) {
johnc@4173 319 gclog_or_tty->print_cr("[%u] we're dealing with reference = "PTR_FORMAT,
johnc@4173 320 _worker_id, (void*) obj);
tonyp@2968 321 }
tonyp@2968 322
tonyp@2968 323 ++_refs_reached;
tonyp@2968 324
tonyp@2968 325 HeapWord* objAddr = (HeapWord*) obj;
tonyp@2968 326 assert(obj->is_oop_or_null(true /* ignore mark word */), "Error");
johnc@3463 327 if (_g1h->is_in_g1_reserved(objAddr)) {
tonyp@2968 328 assert(obj != NULL, "null check is implicit");
tonyp@2968 329 if (!_nextMarkBitMap->isMarked(objAddr)) {
tonyp@2968 330 // Only get the containing region if the object is not marked on the
tonyp@2968 331 // bitmap (otherwise, it's a waste of time since we won't do
tonyp@2968 332 // anything with it).
tonyp@2968 333 HeapRegion* hr = _g1h->heap_region_containing_raw(obj);
tonyp@2968 334 if (!hr->obj_allocated_since_next_marking(obj)) {
tonyp@2968 335 if (_cm->verbose_high()) {
johnc@4173 336 gclog_or_tty->print_cr("[%u] "PTR_FORMAT" is not considered marked",
johnc@4173 337 _worker_id, (void*) obj);
tonyp@2968 338 }
tonyp@2968 339
tonyp@2968 340 // we need to mark it first
johnc@3463 341 if (_cm->par_mark_and_count(obj, hr, _marked_bytes_array, _card_bm)) {
tonyp@2968 342 // No OrderAccess:store_load() is needed. It is implicit in the
johnc@3463 343 // CAS done in CMBitMap::parMark() call in the routine above.
tonyp@2968 344 HeapWord* global_finger = _cm->finger();
tonyp@2968 345
tonyp@2968 346 #if _CHECK_BOTH_FINGERS_
tonyp@2968 347 // we will check both the local and global fingers
tonyp@2968 348
tonyp@2968 349 if (_finger != NULL && objAddr < _finger) {
tonyp@2968 350 if (_cm->verbose_high()) {
johnc@4173 351 gclog_or_tty->print_cr("[%u] below the local finger ("PTR_FORMAT"), "
johnc@4173 352 "pushing it", _worker_id, _finger);
tonyp@2968 353 }
tonyp@2968 354 push(obj);
tonyp@2968 355 } else if (_curr_region != NULL && objAddr < _region_limit) {
tonyp@2968 356 // do nothing
tonyp@2968 357 } else if (objAddr < global_finger) {
tonyp@2968 358 // Notice that the global finger might be moving forward
tonyp@2968 359 // concurrently. This is not a problem. In the worst case, we
tonyp@2968 360 // mark the object while it is above the global finger and, by
tonyp@2968 361 // the time we read the global finger, it has moved forward
tonyp@2968 362 // passed this object. In this case, the object will probably
tonyp@2968 363 // be visited when a task is scanning the region and will also
tonyp@2968 364 // be pushed on the stack. So, some duplicate work, but no
tonyp@2968 365 // correctness problems.
tonyp@2968 366
tonyp@2968 367 if (_cm->verbose_high()) {
johnc@4173 368 gclog_or_tty->print_cr("[%u] below the global finger "
tonyp@2968 369 "("PTR_FORMAT"), pushing it",
johnc@4173 370 _worker_id, global_finger);
tonyp@2968 371 }
tonyp@2968 372 push(obj);
tonyp@2968 373 } else {
tonyp@2968 374 // do nothing
tonyp@2968 375 }
tonyp@2968 376 #else // _CHECK_BOTH_FINGERS_
tonyp@2968 377 // we will only check the global finger
tonyp@2968 378
tonyp@2968 379 if (objAddr < global_finger) {
tonyp@2968 380 // see long comment above
tonyp@2968 381
tonyp@2968 382 if (_cm->verbose_high()) {
johnc@4173 383 gclog_or_tty->print_cr("[%u] below the global finger "
tonyp@2968 384 "("PTR_FORMAT"), pushing it",
johnc@4173 385 _worker_id, global_finger);
tonyp@2968 386 }
tonyp@2968 387 push(obj);
tonyp@2968 388 }
tonyp@2968 389 #endif // _CHECK_BOTH_FINGERS_
tonyp@2968 390 }
tonyp@2968 391 }
tonyp@2968 392 }
tonyp@2968 393 }
tonyp@2968 394 }
tonyp@2968 395
tonyp@3416 396 inline void ConcurrentMark::markPrev(oop p) {
tonyp@3416 397 assert(!_prevMarkBitMap->isMarked((HeapWord*) p), "sanity");
tonyp@3416 398 // Note we are overriding the read-only view of the prev map here, via
tonyp@3416 399 // the cast.
tonyp@3416 400 ((CMBitMap*)_prevMarkBitMap)->mark((HeapWord*) p);
tonyp@3416 401 }
tonyp@3416 402
tonyp@3464 403 inline void ConcurrentMark::grayRoot(oop obj, size_t word_size,
tonyp@3464 404 uint worker_id, HeapRegion* hr) {
tonyp@3464 405 assert(obj != NULL, "pre-condition");
tonyp@3416 406 HeapWord* addr = (HeapWord*) obj;
tonyp@3464 407 if (hr == NULL) {
tonyp@3464 408 hr = _g1h->heap_region_containing_raw(addr);
tonyp@3464 409 } else {
tonyp@3464 410 assert(hr->is_in(addr), "pre-condition");
tonyp@3464 411 }
tonyp@3464 412 assert(hr != NULL, "sanity");
tonyp@3464 413 // Given that we're looking for a region that contains an object
tonyp@3464 414 // header it's impossible to get back a HC region.
tonyp@3464 415 assert(!hr->continuesHumongous(), "sanity");
tonyp@3416 416
tonyp@3416 417 // We cannot assert that word_size == obj->size() given that obj
tonyp@3416 418 // might not be in a consistent state (another thread might be in
tonyp@3416 419 // the process of copying it). So the best thing we can do is to
tonyp@3416 420 // assert that word_size is under an upper bound which is its
tonyp@3416 421 // containing region's capacity.
tonyp@3416 422 assert(word_size * HeapWordSize <= hr->capacity(),
tonyp@3416 423 err_msg("size: "SIZE_FORMAT" capacity: "SIZE_FORMAT" "HR_FORMAT,
tonyp@3416 424 word_size * HeapWordSize, hr->capacity(),
tonyp@3416 425 HR_FORMAT_PARAMS(hr)));
tonyp@3416 426
tonyp@3464 427 if (addr < hr->next_top_at_mark_start()) {
tonyp@3464 428 if (!_nextMarkBitMap->isMarked(addr)) {
tonyp@3464 429 par_mark_and_count(obj, word_size, hr, worker_id);
tonyp@3464 430 }
tonyp@3416 431 }
tonyp@3416 432 }
tonyp@3416 433
tonyp@2968 434 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_CONCURRENTMARK_INLINE_HPP

mercurial