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

changeset 3463
d30fa85f9994
parent 3454
2e966d967c5c
child 3464
eff609af17d7
     1.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp	Tue Jan 24 17:08:58 2012 -0500
     1.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp	Thu Jan 12 00:06:47 2012 -0800
     1.3 @@ -28,6 +28,159 @@
     1.4  #include "gc_implementation/g1/concurrentMark.hpp"
     1.5  #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
     1.6  
     1.7 +// Returns the index in the liveness accounting card bitmap
     1.8 +// for the given address
     1.9 +inline BitMap::idx_t ConcurrentMark::card_bitmap_index_for(HeapWord* addr) {
    1.10 +  // Below, the term "card num" means the result of shifting an address
    1.11 +  // by the card shift -- address 0 corresponds to card number 0.  One
    1.12 +  // must subtract the card num of the bottom of the heap to obtain a
    1.13 +  // card table index.
    1.14 +
    1.15 +  intptr_t card_num = intptr_t(uintptr_t(addr) >> CardTableModRefBS::card_shift);
    1.16 +  return card_num - heap_bottom_card_num();
    1.17 +}
    1.18 +
    1.19 +// Counts the given memory region in the given task/worker
    1.20 +// counting data structures.
    1.21 +inline void ConcurrentMark::count_region(MemRegion mr, HeapRegion* hr,
    1.22 +                                         size_t* marked_bytes_array,
    1.23 +                                         BitMap* task_card_bm) {
    1.24 +  G1CollectedHeap* g1h = _g1h;
    1.25 +  HeapWord* start = mr.start();
    1.26 +  HeapWord* last = mr.last();
    1.27 +  size_t region_size_bytes = mr.byte_size();
    1.28 +  size_t index = hr->hrs_index();
    1.29 +
    1.30 +  assert(!hr->continuesHumongous(), "should not be HC region");
    1.31 +  assert(hr == g1h->heap_region_containing(start), "sanity");
    1.32 +  assert(hr == g1h->heap_region_containing(mr.last()), "sanity");
    1.33 +  assert(marked_bytes_array != NULL, "pre-condition");
    1.34 +  assert(task_card_bm != NULL, "pre-condition");
    1.35 +
    1.36 +  // Add to the task local marked bytes for this region.
    1.37 +  marked_bytes_array[index] += region_size_bytes;
    1.38 +
    1.39 +  BitMap::idx_t start_idx = card_bitmap_index_for(start);
    1.40 +  BitMap::idx_t last_idx = card_bitmap_index_for(last);
    1.41 +
    1.42 +  // The card bitmap is task/worker specific => no need to use 'par' routines.
    1.43 +  // Set bits in the inclusive bit range [start_idx, last_idx].
    1.44 +  //
    1.45 +  // For small ranges use a simple loop; otherwise use set_range
    1.46 +  // The range are the cards that are spanned by the object/region
    1.47 +  // so 8 cards will allow objects/regions up to 4K to be handled
    1.48 +  // using the loop.
    1.49 +  if ((last_idx - start_idx) <= 8) {
    1.50 +    for (BitMap::idx_t i = start_idx; i <= last_idx; i += 1) {
    1.51 +     task_card_bm->set_bit(i);
    1.52 +    }
    1.53 +  } else {
    1.54 +    assert(last_idx < task_card_bm->size(), "sanity");
    1.55 +    // Note: BitMap::set_range() is exclusive.
    1.56 +    task_card_bm->set_range(start_idx, last_idx+1);
    1.57 +  }
    1.58 +}
    1.59 +
    1.60 +// Counts the given memory region, which may be a single object, in the
    1.61 +// task/worker counting data structures for the given worker id.
    1.62 +inline void ConcurrentMark::count_region(MemRegion mr, uint worker_id) {
    1.63 +  size_t* marked_bytes_array = count_marked_bytes_array_for(worker_id);
    1.64 +  BitMap* task_card_bm = count_card_bitmap_for(worker_id);
    1.65 +  HeapWord* addr = mr.start();
    1.66 +  HeapRegion* hr = _g1h->heap_region_containing_raw(addr);
    1.67 +  count_region(mr, hr, marked_bytes_array, task_card_bm);
    1.68 +}
    1.69 +
    1.70 +// Counts the given object in the given task/worker counting data structures.
    1.71 +inline void ConcurrentMark::count_object(oop obj,
    1.72 +                                         HeapRegion* hr,
    1.73 +                                         size_t* marked_bytes_array,
    1.74 +                                         BitMap* task_card_bm) {
    1.75 +  MemRegion mr((HeapWord*)obj, obj->size());
    1.76 +  count_region(mr, hr, marked_bytes_array, task_card_bm);
    1.77 +}
    1.78 +
    1.79 +// Counts the given object in the task/worker counting data
    1.80 +// structures for the given worker id.
    1.81 +inline void ConcurrentMark::count_object(oop obj, HeapRegion* hr, uint worker_id) {
    1.82 +  size_t* marked_bytes_array = count_marked_bytes_array_for(worker_id);
    1.83 +  BitMap* task_card_bm = count_card_bitmap_for(worker_id);
    1.84 +  HeapWord* addr = (HeapWord*) obj;
    1.85 +  count_object(obj, hr, marked_bytes_array, task_card_bm);
    1.86 +}
    1.87 +
    1.88 +// Attempts to mark the given object and, if successful, counts
    1.89 +// the object in the given task/worker counting structures.
    1.90 +inline bool ConcurrentMark::par_mark_and_count(oop obj,
    1.91 +                                               HeapRegion* hr,
    1.92 +                                               size_t* marked_bytes_array,
    1.93 +                                               BitMap* task_card_bm) {
    1.94 +  HeapWord* addr = (HeapWord*)obj;
    1.95 +  if (_nextMarkBitMap->parMark(addr)) {
    1.96 +    // Update the task specific count data for the object.
    1.97 +    count_object(obj, hr, marked_bytes_array, task_card_bm);
    1.98 +    return true;
    1.99 +  }
   1.100 +  return false;
   1.101 +}
   1.102 +
   1.103 +// Attempts to mark the given object and, if successful, counts
   1.104 +// the object in the task/worker counting structures for the
   1.105 +// given worker id.
   1.106 +inline bool ConcurrentMark::par_mark_and_count(oop obj,
   1.107 +                                               HeapRegion* hr,
   1.108 +                                               uint worker_id) {
   1.109 +  HeapWord* addr = (HeapWord*)obj;
   1.110 +  if (_nextMarkBitMap->parMark(addr)) {
   1.111 +    // Update the task specific count data for the object.
   1.112 +    count_object(obj, hr, worker_id);
   1.113 +    return true;
   1.114 +  }
   1.115 +  return false;
   1.116 +}
   1.117 +
   1.118 +// As above - but we don't know the heap region containing the
   1.119 +// object and so have to supply it.
   1.120 +inline bool ConcurrentMark::par_mark_and_count(oop obj, uint worker_id) {
   1.121 +  HeapWord* addr = (HeapWord*)obj;
   1.122 +  HeapRegion* hr = _g1h->heap_region_containing_raw(addr);
   1.123 +  return par_mark_and_count(obj, hr, worker_id);
   1.124 +}
   1.125 +
   1.126 +// Similar to the above routine but we already know the size, in words, of
   1.127 +// the object that we wish to mark/count
   1.128 +inline bool ConcurrentMark::par_mark_and_count(oop obj,
   1.129 +                                               size_t word_size,
   1.130 +                                               uint worker_id) {
   1.131 +  HeapWord* addr = (HeapWord*)obj;
   1.132 +  if (_nextMarkBitMap->parMark(addr)) {
   1.133 +    // Update the task specific count data for the object.
   1.134 +    MemRegion mr(addr, word_size);
   1.135 +    count_region(mr, worker_id);
   1.136 +    return true;
   1.137 +  }
   1.138 +  return false;
   1.139 +}
   1.140 +
   1.141 +// Unconditionally mark the given object, and unconditinally count
   1.142 +// the object in the counting structures for worker id 0.
   1.143 +// Should *not* be called from parallel code.
   1.144 +inline bool ConcurrentMark::mark_and_count(oop obj, HeapRegion* hr) {
   1.145 +  HeapWord* addr = (HeapWord*)obj;
   1.146 +  _nextMarkBitMap->mark(addr);
   1.147 +  // Update the task specific count data for the object.
   1.148 +  count_object(obj, hr, 0 /* worker_id */);
   1.149 +  return true;
   1.150 +}
   1.151 +
   1.152 +// As above - but we don't have the heap region containing the
   1.153 +// object, so we have to supply it.
   1.154 +inline bool ConcurrentMark::mark_and_count(oop obj) {
   1.155 +  HeapWord* addr = (HeapWord*)obj;
   1.156 +  HeapRegion* hr = _g1h->heap_region_containing_raw(addr);
   1.157 +  return mark_and_count(obj, hr);
   1.158 +}
   1.159 +
   1.160  inline bool CMBitMapRO::iterate(BitMapClosure* cl, MemRegion mr) {
   1.161    HeapWord* start_addr = MAX2(startWord(), mr.start());
   1.162    HeapWord* end_addr = MIN2(endWord(), mr.end());
   1.163 @@ -113,7 +266,7 @@
   1.164  
   1.165    HeapWord* objAddr = (HeapWord*) obj;
   1.166    assert(obj->is_oop_or_null(true /* ignore mark word */), "Error");
   1.167 - if (_g1h->is_in_g1_reserved(objAddr)) {
   1.168 +  if (_g1h->is_in_g1_reserved(objAddr)) {
   1.169      assert(obj != NULL, "null check is implicit");
   1.170      if (!_nextMarkBitMap->isMarked(objAddr)) {
   1.171        // Only get the containing region if the object is not marked on the
   1.172 @@ -127,9 +280,9 @@
   1.173          }
   1.174  
   1.175          // we need to mark it first
   1.176 -        if (_nextMarkBitMap->parMark(objAddr)) {
   1.177 +        if (_cm->par_mark_and_count(obj, hr, _marked_bytes_array, _card_bm)) {
   1.178            // No OrderAccess:store_load() is needed. It is implicit in the
   1.179 -          // CAS done in parMark(objAddr) above
   1.180 +          // CAS done in CMBitMap::parMark() call in the routine above.
   1.181            HeapWord* global_finger = _cm->finger();
   1.182  
   1.183  #if _CHECK_BOTH_FINGERS_
   1.184 @@ -189,12 +342,7 @@
   1.185    ((CMBitMap*)_prevMarkBitMap)->mark((HeapWord*) p);
   1.186  }
   1.187  
   1.188 -inline void ConcurrentMark::markNext(oop p) {
   1.189 -  assert(!_nextMarkBitMap->isMarked((HeapWord*) p), "sanity");
   1.190 -  _nextMarkBitMap->mark((HeapWord*) p);
   1.191 -}
   1.192 -
   1.193 -inline void ConcurrentMark::grayRoot(oop obj, size_t word_size) {
   1.194 +inline void ConcurrentMark::grayRoot(oop obj, size_t word_size, uint worker_id) {
   1.195    HeapWord* addr = (HeapWord*) obj;
   1.196  
   1.197    // Currently we don't do anything with word_size but we will use it
   1.198 @@ -220,7 +368,7 @@
   1.199  #endif // ASSERT
   1.200  
   1.201    if (!_nextMarkBitMap->isMarked(addr)) {
   1.202 -    _nextMarkBitMap->parMark(addr);
   1.203 +    par_mark_and_count(obj, word_size, worker_id);
   1.204    }
   1.205  }
   1.206  

mercurial