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

Sat, 06 Oct 2012 01:17:44 -0700

author
johnc
date
Sat, 06 Oct 2012 01:17:44 -0700
changeset 4173
8a5ea0a9ccc4
parent 4123
988bf00cc564
child 4733
9def4075da6d
permissions
-rw-r--r--

7127708: G1: change task num types from int to uint in concurrent mark
Summary: Change the type of various task num fields, parameters etc to unsigned and rename them to be more consistent with the other collectors. Code changes were also reviewed by Vitaly Davidovich.
Reviewed-by: johnc
Contributed-by: Kaushik Srenevasan <kaushik@twitter.com>

tonyp@2968 1 /*
tonyp@3416 2 * Copyright (c) 2001, 2012, 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 HeapWord* obj_addr = offsetToHeapWord(start_offset);
johnc@3454 256 oop obj = (oop) obj_addr;
johnc@3454 257 if (!cl->do_bit(start_offset)) {
johnc@3454 258 return false;
johnc@3454 259 }
johnc@3454 260 HeapWord* next_addr = MIN2(obj_addr + obj->size(), end_addr);
johnc@3454 261 BitMap::idx_t next_offset = heapWordToOffset(next_addr);
johnc@3454 262 start_offset = _bm.get_next_one_offset(next_offset, end_offset);
johnc@3454 263 }
johnc@3454 264 }
johnc@3454 265 return true;
johnc@3454 266 }
johnc@3454 267
johnc@3454 268 inline bool CMBitMapRO::iterate(BitMapClosure* cl) {
johnc@3454 269 MemRegion mr(startWord(), sizeInWords());
johnc@3454 270 return iterate(cl, mr);
johnc@3454 271 }
johnc@3454 272
tonyp@2968 273 inline void CMTask::push(oop obj) {
tonyp@2968 274 HeapWord* objAddr = (HeapWord*) obj;
tonyp@2968 275 assert(_g1h->is_in_g1_reserved(objAddr), "invariant");
tonyp@2968 276 assert(!_g1h->is_on_master_free_list(
tonyp@2968 277 _g1h->heap_region_containing((HeapWord*) objAddr)), "invariant");
tonyp@2968 278 assert(!_g1h->is_obj_ill(obj), "invariant");
tonyp@2968 279 assert(_nextMarkBitMap->isMarked(objAddr), "invariant");
tonyp@2968 280
tonyp@2968 281 if (_cm->verbose_high()) {
johnc@4173 282 gclog_or_tty->print_cr("[%u] pushing "PTR_FORMAT, _worker_id, (void*) obj);
tonyp@2968 283 }
tonyp@2968 284
tonyp@2968 285 if (!_task_queue->push(obj)) {
tonyp@2968 286 // The local task queue looks full. We need to push some entries
tonyp@2968 287 // to the global stack.
tonyp@2968 288
tonyp@2968 289 if (_cm->verbose_medium()) {
johnc@4173 290 gclog_or_tty->print_cr("[%u] task queue overflow, "
tonyp@2968 291 "moving entries to the global stack",
johnc@4173 292 _worker_id);
tonyp@2968 293 }
tonyp@2968 294 move_entries_to_global_stack();
tonyp@2968 295
tonyp@2968 296 // this should succeed since, even if we overflow the global
tonyp@2968 297 // stack, we should have definitely removed some entries from the
tonyp@2968 298 // local queue. So, there must be space on it.
tonyp@2968 299 bool success = _task_queue->push(obj);
tonyp@2968 300 assert(success, "invariant");
tonyp@2968 301 }
tonyp@2968 302
tonyp@2968 303 statsOnly( int tmp_size = _task_queue->size();
tonyp@2973 304 if (tmp_size > _local_max_size) {
tonyp@2968 305 _local_max_size = tmp_size;
tonyp@2973 306 }
tonyp@2968 307 ++_local_pushes );
tonyp@2968 308 }
tonyp@2968 309
tonyp@2968 310 // This determines whether the method below will check both the local
tonyp@2968 311 // and global fingers when determining whether to push on the stack a
tonyp@2968 312 // gray object (value 1) or whether it will only check the global one
tonyp@2968 313 // (value 0). The tradeoffs are that the former will be a bit more
tonyp@2968 314 // accurate and possibly push less on the stack, but it might also be
tonyp@2968 315 // a little bit slower.
tonyp@2968 316
tonyp@2968 317 #define _CHECK_BOTH_FINGERS_ 1
tonyp@2968 318
tonyp@2968 319 inline void CMTask::deal_with_reference(oop obj) {
tonyp@2968 320 if (_cm->verbose_high()) {
johnc@4173 321 gclog_or_tty->print_cr("[%u] we're dealing with reference = "PTR_FORMAT,
johnc@4173 322 _worker_id, (void*) obj);
tonyp@2968 323 }
tonyp@2968 324
tonyp@2968 325 ++_refs_reached;
tonyp@2968 326
tonyp@2968 327 HeapWord* objAddr = (HeapWord*) obj;
tonyp@2968 328 assert(obj->is_oop_or_null(true /* ignore mark word */), "Error");
johnc@3463 329 if (_g1h->is_in_g1_reserved(objAddr)) {
tonyp@2968 330 assert(obj != NULL, "null check is implicit");
tonyp@2968 331 if (!_nextMarkBitMap->isMarked(objAddr)) {
tonyp@2968 332 // Only get the containing region if the object is not marked on the
tonyp@2968 333 // bitmap (otherwise, it's a waste of time since we won't do
tonyp@2968 334 // anything with it).
tonyp@2968 335 HeapRegion* hr = _g1h->heap_region_containing_raw(obj);
tonyp@2968 336 if (!hr->obj_allocated_since_next_marking(obj)) {
tonyp@2968 337 if (_cm->verbose_high()) {
johnc@4173 338 gclog_or_tty->print_cr("[%u] "PTR_FORMAT" is not considered marked",
johnc@4173 339 _worker_id, (void*) obj);
tonyp@2968 340 }
tonyp@2968 341
tonyp@2968 342 // we need to mark it first
johnc@3463 343 if (_cm->par_mark_and_count(obj, hr, _marked_bytes_array, _card_bm)) {
tonyp@2968 344 // No OrderAccess:store_load() is needed. It is implicit in the
johnc@3463 345 // CAS done in CMBitMap::parMark() call in the routine above.
tonyp@2968 346 HeapWord* global_finger = _cm->finger();
tonyp@2968 347
tonyp@2968 348 #if _CHECK_BOTH_FINGERS_
tonyp@2968 349 // we will check both the local and global fingers
tonyp@2968 350
tonyp@2968 351 if (_finger != NULL && objAddr < _finger) {
tonyp@2968 352 if (_cm->verbose_high()) {
johnc@4173 353 gclog_or_tty->print_cr("[%u] below the local finger ("PTR_FORMAT"), "
johnc@4173 354 "pushing it", _worker_id, _finger);
tonyp@2968 355 }
tonyp@2968 356 push(obj);
tonyp@2968 357 } else if (_curr_region != NULL && objAddr < _region_limit) {
tonyp@2968 358 // do nothing
tonyp@2968 359 } else if (objAddr < global_finger) {
tonyp@2968 360 // Notice that the global finger might be moving forward
tonyp@2968 361 // concurrently. This is not a problem. In the worst case, we
tonyp@2968 362 // mark the object while it is above the global finger and, by
tonyp@2968 363 // the time we read the global finger, it has moved forward
tonyp@2968 364 // passed this object. In this case, the object will probably
tonyp@2968 365 // be visited when a task is scanning the region and will also
tonyp@2968 366 // be pushed on the stack. So, some duplicate work, but no
tonyp@2968 367 // correctness problems.
tonyp@2968 368
tonyp@2968 369 if (_cm->verbose_high()) {
johnc@4173 370 gclog_or_tty->print_cr("[%u] below the global finger "
tonyp@2968 371 "("PTR_FORMAT"), pushing it",
johnc@4173 372 _worker_id, global_finger);
tonyp@2968 373 }
tonyp@2968 374 push(obj);
tonyp@2968 375 } else {
tonyp@2968 376 // do nothing
tonyp@2968 377 }
tonyp@2968 378 #else // _CHECK_BOTH_FINGERS_
tonyp@2968 379 // we will only check the global finger
tonyp@2968 380
tonyp@2968 381 if (objAddr < global_finger) {
tonyp@2968 382 // see long comment above
tonyp@2968 383
tonyp@2968 384 if (_cm->verbose_high()) {
johnc@4173 385 gclog_or_tty->print_cr("[%u] below the global finger "
tonyp@2968 386 "("PTR_FORMAT"), pushing it",
johnc@4173 387 _worker_id, global_finger);
tonyp@2968 388 }
tonyp@2968 389 push(obj);
tonyp@2968 390 }
tonyp@2968 391 #endif // _CHECK_BOTH_FINGERS_
tonyp@2968 392 }
tonyp@2968 393 }
tonyp@2968 394 }
tonyp@2968 395 }
tonyp@2968 396 }
tonyp@2968 397
tonyp@3416 398 inline void ConcurrentMark::markPrev(oop p) {
tonyp@3416 399 assert(!_prevMarkBitMap->isMarked((HeapWord*) p), "sanity");
tonyp@3416 400 // Note we are overriding the read-only view of the prev map here, via
tonyp@3416 401 // the cast.
tonyp@3416 402 ((CMBitMap*)_prevMarkBitMap)->mark((HeapWord*) p);
tonyp@3416 403 }
tonyp@3416 404
tonyp@3464 405 inline void ConcurrentMark::grayRoot(oop obj, size_t word_size,
tonyp@3464 406 uint worker_id, HeapRegion* hr) {
tonyp@3464 407 assert(obj != NULL, "pre-condition");
tonyp@3416 408 HeapWord* addr = (HeapWord*) obj;
tonyp@3464 409 if (hr == NULL) {
tonyp@3464 410 hr = _g1h->heap_region_containing_raw(addr);
tonyp@3464 411 } else {
tonyp@3464 412 assert(hr->is_in(addr), "pre-condition");
tonyp@3464 413 }
tonyp@3464 414 assert(hr != NULL, "sanity");
tonyp@3464 415 // Given that we're looking for a region that contains an object
tonyp@3464 416 // header it's impossible to get back a HC region.
tonyp@3464 417 assert(!hr->continuesHumongous(), "sanity");
tonyp@3416 418
tonyp@3416 419 // We cannot assert that word_size == obj->size() given that obj
tonyp@3416 420 // might not be in a consistent state (another thread might be in
tonyp@3416 421 // the process of copying it). So the best thing we can do is to
tonyp@3416 422 // assert that word_size is under an upper bound which is its
tonyp@3416 423 // containing region's capacity.
tonyp@3416 424 assert(word_size * HeapWordSize <= hr->capacity(),
tonyp@3416 425 err_msg("size: "SIZE_FORMAT" capacity: "SIZE_FORMAT" "HR_FORMAT,
tonyp@3416 426 word_size * HeapWordSize, hr->capacity(),
tonyp@3416 427 HR_FORMAT_PARAMS(hr)));
tonyp@3416 428
tonyp@3464 429 if (addr < hr->next_top_at_mark_start()) {
tonyp@3464 430 if (!_nextMarkBitMap->isMarked(addr)) {
tonyp@3464 431 par_mark_and_count(obj, word_size, hr, worker_id);
tonyp@3464 432 }
tonyp@3416 433 }
tonyp@3416 434 }
tonyp@3416 435
tonyp@2968 436 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_CONCURRENTMARK_INLINE_HPP

mercurial