< prev index next >

src/share/vm/gc/g1/g1ConcurrentMark.inline.hpp

Print this page
rev 10493 : [mq]: 8077144-concurrent-mark-thread-init-fix


  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_GC_G1_G1CONCURRENTMARK_INLINE_HPP
  26 #define SHARE_VM_GC_G1_G1CONCURRENTMARK_INLINE_HPP
  27 
  28 #include "gc/g1/g1CollectedHeap.inline.hpp"
  29 #include "gc/g1/g1ConcurrentMark.hpp"
  30 #include "gc/shared/taskqueue.inline.hpp"
  31 
  32 // Utility routine to set an exclusive range of cards on the given
  33 // card liveness bitmap
  34 inline void G1ConcurrentMark::set_card_bitmap_range(BitMap* card_bm,
  35                                                     BitMap::idx_t start_idx,
  36                                                     BitMap::idx_t end_idx,
  37                                                     bool is_par) {
  38 
  39   // Set the exclusive bit range [start_idx, end_idx).
  40   assert((end_idx - start_idx) > 0, "at least one card");
  41   assert(end_idx <= card_bm->size(), "sanity");
  42 
  43   // Silently clip the end index
  44   end_idx = MIN2(end_idx, card_bm->size());
  45 
  46   // For small ranges use a simple loop; otherwise use set_range or
  47   // use par_at_put_range (if parallel). The range is made up of the
  48   // cards that are spanned by an object/mem region so 8 cards will
  49   // allow up to object sizes up to 4K to be handled using the loop.
  50   if ((end_idx - start_idx) <= 8) {
  51     for (BitMap::idx_t i = start_idx; i < end_idx; i += 1) {
  52       if (is_par) {
  53         card_bm->par_set_bit(i);
  54       } else {
  55         card_bm->set_bit(i);
  56       }
  57     }
  58   } else {
  59     // Note BitMap::par_at_put_range() and BitMap::set_range() are exclusive.
  60     if (is_par) {
  61       card_bm->par_at_put_range(start_idx, end_idx, true);
  62     } else {
  63       card_bm->set_range(start_idx, end_idx);
  64     }
  65   }
  66 }
  67 
  68 // Returns the index in the liveness accounting card bitmap
  69 // for the given address
  70 inline BitMap::idx_t G1ConcurrentMark::card_bitmap_index_for(HeapWord* addr) {
  71   // Below, the term "card num" means the result of shifting an address
  72   // by the card shift -- address 0 corresponds to card number 0.  One
  73   // must subtract the card num of the bottom of the heap to obtain a
  74   // card table index.
  75   intptr_t card_num = intptr_t(uintptr_t(addr) >> CardTableModRefBS::card_shift);
  76   return card_num - heap_bottom_card_num();
  77 }
  78 
  79 // Counts the given memory region in the given task/worker
  80 // counting data structures.
  81 inline void G1ConcurrentMark::count_region(MemRegion mr, HeapRegion* hr,
  82                                            size_t* marked_bytes_array,
  83                                            BitMap* task_card_bm) {
  84   G1CollectedHeap* g1h = _g1h;
  85   CardTableModRefBS* ct_bs = g1h->g1_barrier_set();
  86 
  87   HeapWord* start = mr.start();
  88   HeapWord* end = mr.end();
  89   size_t region_size_bytes = mr.byte_size();
  90   uint index = hr->hrm_index();
  91 
  92   assert(hr == g1h->heap_region_containing(start), "sanity");
  93   assert(marked_bytes_array != NULL, "pre-condition");
  94   assert(task_card_bm != NULL, "pre-condition");
  95 
  96   // Add to the task local marked bytes for this region.
  97   marked_bytes_array[index] += region_size_bytes;
  98 
  99   BitMap::idx_t start_idx = card_bitmap_index_for(start);
 100   BitMap::idx_t end_idx = card_bitmap_index_for(end);
 101 
 102   // Note: if we're looking at the last region in heap - end
 103   // could be actually just beyond the end of the heap; end_idx
 104   // will then correspond to a (non-existent) card that is also
 105   // just beyond the heap.
 106   if (g1h->is_in_g1_reserved(end) && !ct_bs->is_card_aligned(end)) {
 107     // end of region is not card aligned - increment to cover
 108     // all the cards spanned by the region.
 109     end_idx += 1;
 110   }
 111   // The card bitmap is task/worker specific => no need to use
 112   // the 'par' BitMap routines.
 113   // Set bits in the exclusive bit range [start_idx, end_idx).
 114   set_card_bitmap_range(task_card_bm, start_idx, end_idx, false /* is_par */);
 115 }
 116 
 117 // Counts the given object in the given task/worker counting data structures.
 118 inline void G1ConcurrentMark::count_object(oop obj,
 119                                            HeapRegion* hr,
 120                                            size_t* marked_bytes_array,
 121                                            BitMap* task_card_bm,
 122                                            size_t word_size) {
 123   assert(!hr->is_continues_humongous(), "Cannot enter count_object with continues humongous");
 124   if (!hr->is_starts_humongous()) {
 125     MemRegion mr((HeapWord*)obj, word_size);
 126     count_region(mr, hr, marked_bytes_array, task_card_bm);
 127   } else {
 128     do {
 129       MemRegion mr(hr->bottom(), hr->top());
 130       count_region(mr, hr, marked_bytes_array, task_card_bm);
 131       hr = _g1h->next_region_in_humongous(hr);
 132     } while (hr != NULL);
 133   }
 134 }
 135 
 136 // Attempts to mark the given object and, if successful, counts
 137 // the object in the given task/worker counting structures.
 138 inline bool G1ConcurrentMark::par_mark_and_count(oop obj,
 139                                                  HeapRegion* hr,
 140                                                  size_t* marked_bytes_array,
 141                                                  BitMap* task_card_bm) {
 142   if (_nextMarkBitMap->parMark((HeapWord*)obj)) {
 143     // Update the task specific count data for the object.
 144     count_object(obj, hr, marked_bytes_array, task_card_bm, obj->size());
 145     return true;
 146   }
 147   return false;
 148 }
 149 
 150 // Attempts to mark the given object and, if successful, counts
 151 // the object in the task/worker counting structures for the
 152 // given worker id.
 153 inline bool G1ConcurrentMark::par_mark_and_count(oop obj,
 154                                                  size_t word_size,
 155                                                  HeapRegion* hr,
 156                                                  uint worker_id) {
 157   if (_nextMarkBitMap->parMark((HeapWord*)obj)) {
 158     size_t* marked_bytes_array = count_marked_bytes_array_for(worker_id);
 159     BitMap* task_card_bm = count_card_bitmap_for(worker_id);
 160     count_object(obj, hr, marked_bytes_array, task_card_bm, word_size);
 161     return true;
 162   }
 163   return false;
 164 }
 165 
 166 inline bool G1CMBitMapRO::iterate(BitMapClosure* cl, MemRegion mr) {
 167   HeapWord* start_addr = MAX2(startWord(), mr.start());
 168   HeapWord* end_addr = MIN2(endWord(), mr.end());
 169 
 170   if (end_addr > start_addr) {
 171     // Right-open interval [start-offset, end-offset).
 172     BitMap::idx_t start_offset = heapWordToOffset(start_addr);
 173     BitMap::idx_t end_offset = heapWordToOffset(end_addr);
 174 
 175     start_offset = _bm.get_next_one_offset(start_offset, end_offset);
 176     while (start_offset < end_offset) {
 177       if (!cl->do_bit(start_offset)) {
 178         return false;
 179       }
 180       HeapWord* next_addr = MIN2(nextObject(offsetToHeapWord(start_offset)), end_addr);
 181       BitMap::idx_t next_offset = heapWordToOffset(next_addr);
 182       start_offset = _bm.get_next_one_offset(next_offset, end_offset);
 183     }


 277     } // Else check global finger.
 278   }
 279   // Check global finger.
 280   return objAddr < global_finger;
 281 }
 282 
 283 template<bool scan>
 284 inline void G1CMTask::process_grey_object(oop obj) {
 285   assert(scan || obj->is_typeArray(), "Skipping scan of grey non-typeArray");
 286   assert(_nextMarkBitMap->isMarked((HeapWord*) obj), "invariant");
 287 
 288   size_t obj_size = obj->size();
 289   _words_scanned += obj_size;
 290 
 291   if (scan) {
 292     obj->oop_iterate(_cm_oop_closure);
 293   }
 294   check_limits();
 295 }
 296 
 297 
 298 
 299 inline void G1CMTask::make_reference_grey(oop obj, HeapRegion* hr) {
 300   if (_cm->par_mark_and_count(obj, hr, _marked_bytes_array, _card_bm)) {
 301     // No OrderAccess:store_load() is needed. It is implicit in the
 302     // CAS done in G1CMBitMap::parMark() call in the routine above.
 303     HeapWord* global_finger = _cm->finger();
 304 
 305     // We only need to push a newly grey object on the mark
 306     // stack if it is in a section of memory the mark bitmap
 307     // scan has already examined.  Mark bitmap scanning
 308     // maintains progress "fingers" for determining that.
 309     //
 310     // Notice that the global finger might be moving forward
 311     // concurrently. This is not a problem. In the worst case, we
 312     // mark the object while it is above the global finger and, by
 313     // the time we read the global finger, it has moved forward
 314     // past this object. In this case, the object will probably
 315     // be visited when a task is scanning the region and will also
 316     // be pushed on the stack. So, some duplicate work, but no
 317     // correctness problems.
 318     if (is_below_finger(obj, global_finger)) {
 319       if (obj->is_typeArray()) {
 320         // Immediately process arrays of primitive types, rather


 331       } else {
 332         push(obj);
 333       }
 334     }
 335   }
 336 }
 337 
 338 inline void G1CMTask::deal_with_reference(oop obj) {
 339   increment_refs_reached();
 340 
 341   HeapWord* objAddr = (HeapWord*) obj;
 342   assert(obj->is_oop_or_null(true /* ignore mark word */), "Expected an oop or NULL at " PTR_FORMAT, p2i(obj));
 343   if (_g1h->is_in_g1_reserved(objAddr)) {
 344     assert(obj != NULL, "null check is implicit");
 345     if (!_nextMarkBitMap->isMarked(objAddr)) {
 346       // Only get the containing region if the object is not marked on the
 347       // bitmap (otherwise, it's a waste of time since we won't do
 348       // anything with it).
 349       HeapRegion* hr = _g1h->heap_region_containing(obj);
 350       if (!hr->obj_allocated_since_next_marking(obj)) {
 351         make_reference_grey(obj, hr);
 352       }
 353     }
 354   }
 355 }
 356 
 357 inline void G1ConcurrentMark::markPrev(oop p) {
 358   assert(!_prevMarkBitMap->isMarked((HeapWord*) p), "sanity");
 359   // Note we are overriding the read-only view of the prev map here, via
 360   // the cast.
 361   ((G1CMBitMap*)_prevMarkBitMap)->mark((HeapWord*) p);
 362 }
 363 
 364 bool G1ConcurrentMark::isPrevMarked(oop p) const {
 365   assert(p != NULL && p->is_oop(), "expected an oop");
 366   HeapWord* addr = (HeapWord*)p;
 367   assert(addr >= _prevMarkBitMap->startWord() ||
 368          addr < _prevMarkBitMap->endWord(), "in a region");
 369 
 370   return _prevMarkBitMap->isMarked(addr);
 371 }
 372 
 373 inline void G1ConcurrentMark::grayRoot(oop obj, size_t word_size,
 374                                        uint worker_id, HeapRegion* hr) {
 375   assert(obj != NULL, "pre-condition");
 376   HeapWord* addr = (HeapWord*) obj;
 377   if (hr == NULL) {
 378     hr = _g1h->heap_region_containing(addr);
 379   } else {
 380     assert(hr->is_in(addr), "pre-condition");
 381   }
 382   assert(hr != NULL, "sanity");
 383   // Given that we're looking for a region that contains an object
 384   // header it's impossible to get back a HC region.
 385   assert(!hr->is_continues_humongous(), "sanity");
 386 
 387   if (addr < hr->next_top_at_mark_start()) {
 388     if (!_nextMarkBitMap->isMarked(addr)) {
 389       par_mark_and_count(obj, word_size, hr, worker_id);
 390     }
 391   }
 392 }
 393 
 394 #endif // SHARE_VM_GC_G1_G1CONCURRENTMARK_INLINE_HPP


  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_GC_G1_G1CONCURRENTMARK_INLINE_HPP
  26 #define SHARE_VM_GC_G1_G1CONCURRENTMARK_INLINE_HPP
  27 
  28 #include "gc/g1/g1CollectedHeap.inline.hpp"
  29 #include "gc/g1/g1ConcurrentMark.hpp"
  30 #include "gc/shared/taskqueue.inline.hpp"
  31 
  32 inline BitMap::idx_t G1ConcurrentMark::card_live_bitmap_index_for(HeapWord* addr) {






































  33   // Below, the term "card num" means the result of shifting an address
  34   // by the card shift -- address 0 corresponds to card number 0.  One
  35   // must subtract the card num of the bottom of the heap to obtain a
  36   // card table index.
  37   intptr_t card_num = intptr_t(uintptr_t(addr) >> CardTableModRefBS::card_shift);
  38   return card_num - heap_bottom_card_num();
  39 }
  40 
  41 inline bool G1ConcurrentMark::par_mark(oop obj) {
  42   return _nextMarkBitMap->parMark((HeapWord*)obj);



















































































  43 }
  44 
  45 inline bool G1CMBitMapRO::iterate(BitMapClosure* cl, MemRegion mr) {
  46   HeapWord* start_addr = MAX2(startWord(), mr.start());
  47   HeapWord* end_addr = MIN2(endWord(), mr.end());
  48 
  49   if (end_addr > start_addr) {
  50     // Right-open interval [start-offset, end-offset).
  51     BitMap::idx_t start_offset = heapWordToOffset(start_addr);
  52     BitMap::idx_t end_offset = heapWordToOffset(end_addr);
  53 
  54     start_offset = _bm.get_next_one_offset(start_offset, end_offset);
  55     while (start_offset < end_offset) {
  56       if (!cl->do_bit(start_offset)) {
  57         return false;
  58       }
  59       HeapWord* next_addr = MIN2(nextObject(offsetToHeapWord(start_offset)), end_addr);
  60       BitMap::idx_t next_offset = heapWordToOffset(next_addr);
  61       start_offset = _bm.get_next_one_offset(next_offset, end_offset);
  62     }


 156     } // Else check global finger.
 157   }
 158   // Check global finger.
 159   return objAddr < global_finger;
 160 }
 161 
 162 template<bool scan>
 163 inline void G1CMTask::process_grey_object(oop obj) {
 164   assert(scan || obj->is_typeArray(), "Skipping scan of grey non-typeArray");
 165   assert(_nextMarkBitMap->isMarked((HeapWord*) obj), "invariant");
 166 
 167   size_t obj_size = obj->size();
 168   _words_scanned += obj_size;
 169 
 170   if (scan) {
 171     obj->oop_iterate(_cm_oop_closure);
 172   }
 173   check_limits();
 174 }
 175 
 176 inline void G1CMTask::make_reference_grey(oop obj) {
 177   if (_cm->par_mark(obj)) {


 178     // No OrderAccess:store_load() is needed. It is implicit in the
 179     // CAS done in G1CMBitMap::parMark() call in the routine above.
 180     HeapWord* global_finger = _cm->finger();
 181 
 182     // We only need to push a newly grey object on the mark
 183     // stack if it is in a section of memory the mark bitmap
 184     // scan has already examined.  Mark bitmap scanning
 185     // maintains progress "fingers" for determining that.
 186     //
 187     // Notice that the global finger might be moving forward
 188     // concurrently. This is not a problem. In the worst case, we
 189     // mark the object while it is above the global finger and, by
 190     // the time we read the global finger, it has moved forward
 191     // past this object. In this case, the object will probably
 192     // be visited when a task is scanning the region and will also
 193     // be pushed on the stack. So, some duplicate work, but no
 194     // correctness problems.
 195     if (is_below_finger(obj, global_finger)) {
 196       if (obj->is_typeArray()) {
 197         // Immediately process arrays of primitive types, rather


 208       } else {
 209         push(obj);
 210       }
 211     }
 212   }
 213 }
 214 
 215 inline void G1CMTask::deal_with_reference(oop obj) {
 216   increment_refs_reached();
 217 
 218   HeapWord* objAddr = (HeapWord*) obj;
 219   assert(obj->is_oop_or_null(true /* ignore mark word */), "Expected an oop or NULL at " PTR_FORMAT, p2i(obj));
 220   if (_g1h->is_in_g1_reserved(objAddr)) {
 221     assert(obj != NULL, "null check is implicit");
 222     if (!_nextMarkBitMap->isMarked(objAddr)) {
 223       // Only get the containing region if the object is not marked on the
 224       // bitmap (otherwise, it's a waste of time since we won't do
 225       // anything with it).
 226       HeapRegion* hr = _g1h->heap_region_containing(obj);
 227       if (!hr->obj_allocated_since_next_marking(obj)) {
 228         make_reference_grey(obj);
 229       }
 230     }
 231   }
 232 }
 233 
 234 inline void G1ConcurrentMark::markPrev(oop p) {
 235   assert(!_prevMarkBitMap->isMarked((HeapWord*) p), "sanity");
 236   // Note we are overriding the read-only view of the prev map here, via
 237   // the cast.
 238   ((G1CMBitMap*)_prevMarkBitMap)->mark((HeapWord*) p);
 239 }
 240 
 241 bool G1ConcurrentMark::isPrevMarked(oop p) const {
 242   assert(p != NULL && p->is_oop(), "expected an oop");
 243   HeapWord* addr = (HeapWord*)p;
 244   assert(addr >= _prevMarkBitMap->startWord() ||
 245          addr < _prevMarkBitMap->endWord(), "in a region");
 246 
 247   return _prevMarkBitMap->isMarked(addr);
 248 }
 249 
 250 inline void G1ConcurrentMark::grayRoot(oop obj, HeapRegion* hr) {

 251   assert(obj != NULL, "pre-condition");
 252   HeapWord* addr = (HeapWord*) obj;
 253   if (hr == NULL) {
 254     hr = _g1h->heap_region_containing(addr);
 255   } else {
 256     assert(hr->is_in(addr), "pre-condition");
 257   }
 258   assert(hr != NULL, "sanity");
 259   // Given that we're looking for a region that contains an object
 260   // header it's impossible to get back a HC region.
 261   assert(!hr->is_continues_humongous(), "sanity");
 262 
 263   if (addr < hr->next_top_at_mark_start()) {
 264     if (!_nextMarkBitMap->isMarked(addr)) {
 265       par_mark(obj);
 266     }
 267   }
 268 }
 269 
 270 #endif // SHARE_VM_GC_G1_G1CONCURRENTMARK_INLINE_HPP
< prev index next >