1 /*
   2  * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  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_IMPLEMENTATION_G1_CONCURRENTMARK_INLINE_HPP
  26 #define SHARE_VM_GC_IMPLEMENTATION_G1_CONCURRENTMARK_INLINE_HPP
  27 
  28 #include "gc_implementation/g1/concurrentMark.hpp"
  29 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
  30 
  31 // Counts the given memory region in the given task/worker
  32 // counting data structures.
  33 inline void ConcurrentMark::count_region(MemRegion mr, HeapRegion* hr,
  34                                          size_t* marked_bytes_array,
  35                                          BitMap* task_card_bm) {
  36   G1CollectedHeap* g1h = _g1h;
  37   HeapWord* start = mr.start();
  38   HeapWord* last = mr.last();
  39   size_t region_size = mr.byte_size();
  40   size_t index = hr->hrs_index();
  41 
  42   assert(!hr->continuesHumongous(), "should not be HC region");
  43   assert(hr == g1h->heap_region_containing(start), "sanity");
  44   assert(hr == g1h->heap_region_containing(mr.last()), "sanity");
  45   assert(marked_bytes_array != NULL, "pre-condition");
  46   assert(task_card_bm != NULL, "pre-condition");
  47 
  48   // Add to the task local marked bytes for this region.
  49   marked_bytes_array[index] += region_size;
  50 
  51   // Below, the term "card num" means the result of shifting an address
  52   // by the card shift -- address 0 corresponds to card number 0.  One
  53   // must subtract the card num of the bottom of the heap to obtain a
  54   // card table index.
  55 
  56   intptr_t start_card_num = intptr_t(uintptr_t(start) >> CardTableModRefBS::card_shift);
  57   intptr_t last_card_num  = intptr_t(uintptr_t(last) >> CardTableModRefBS::card_shift);
  58 
  59   BitMap::idx_t start_idx = start_card_num - heap_bottom_card_num();
  60   BitMap::idx_t last_idx = last_card_num - heap_bottom_card_num();
  61   
  62   // The card bitmap is task/worker specific => no need to use 'par' routines.
  63   // Set bits in the inclusive bit range [start_idx, last_idx].
  64   for (BitMap::idx_t i = start_idx; i <= last_idx; i += 1) {
  65     task_card_bm->set_bit(i);
  66   }
  67 }
  68 
  69 // Counts the given memory region in the ask/worker counting
  70 // data structures for the given worker id.
  71 inline void ConcurrentMark::count_region(MemRegion mr, int worker_i) {
  72   size_t* marked_bytes_array = count_marked_bytes_array_for(worker_i);
  73   BitMap* task_card_bm = count_card_bitmap_for(worker_i);
  74   HeapWord* addr = mr.start();
  75   HeapRegion* hr = _g1h->heap_region_containing(addr);
  76   count_region(mr, hr, marked_bytes_array, task_card_bm);
  77 }
  78 
  79 // Counts the given object in the given task/worker counting data structures.
  80 inline void ConcurrentMark::count_object(oop obj,
  81                                          HeapRegion* hr,
  82                                          size_t* marked_bytes_array,
  83                                          BitMap* task_card_bm) {
  84   MemRegion mr((HeapWord*)obj, obj->size());
  85   count_region(mr, hr, marked_bytes_array, task_card_bm);
  86 }
  87 
  88 // Counts the given object in the task/worker counting data
  89 // structures for the given worker id.
  90 inline void ConcurrentMark::count_object(oop obj, HeapRegion* hr, int worker_i) {
  91   size_t* marked_bytes_array = count_marked_bytes_array_for(worker_i);
  92   BitMap* task_card_bm = count_card_bitmap_for(worker_i);
  93   HeapWord* addr = (HeapWord*) obj;
  94   count_object(obj, hr, marked_bytes_array, task_card_bm);
  95 }
  96 
  97 // Attempts to mark the given object and, if successful, counts
  98 // the object in the given task/worker counting structures.
  99 inline bool ConcurrentMark::par_mark_and_count(oop obj,
 100                                                HeapRegion* hr,
 101                                                size_t* marked_bytes_array,
 102                                                BitMap* task_card_bm) {
 103   HeapWord* addr = (HeapWord*)obj;
 104   if (_nextMarkBitMap->parMark(addr)) {
 105     // Update the task specific count data for the object.
 106     count_object(obj, hr, marked_bytes_array, task_card_bm);
 107     return true;
 108   }
 109   return false;
 110 }
 111 
 112 // Attempts to mark the given object and, if successful, counts
 113 // the object in the task/worker counting structures for the
 114 // given worker id.
 115 inline bool ConcurrentMark::par_mark_and_count(oop obj,
 116                                                HeapRegion* hr,
 117                                                int worker_i) {
 118   HeapWord* addr = (HeapWord*)obj;
 119   if (_nextMarkBitMap->parMark(addr)) {
 120     // Update the task specific count data for the object.
 121     count_object(obj, hr, worker_i);
 122     return true;
 123   }
 124   return false;
 125 }
 126 
 127 // As above - but we don't know the heap region containing the
 128 // object and so have to supply it.
 129 inline bool ConcurrentMark::par_mark_and_count(oop obj, int worker_i) {
 130   HeapWord* addr = (HeapWord*)obj;
 131   HeapRegion* hr = _g1h->heap_region_containing(addr);
 132   return par_mark_and_count(obj, hr, worker_i);
 133 }
 134 
 135 // Unconditionally mark the given object, and unconditinally count
 136 // the object in the counting structures for worker id 0.
 137 // Should *not* be called from parallel code.
 138 inline bool ConcurrentMark::mark_and_count(oop obj, HeapRegion* hr) {
 139   HeapWord* addr = (HeapWord*)obj;
 140   _nextMarkBitMap->mark(addr);
 141   // Update the task specific count data for the object.
 142   count_object(obj, hr, 0 /* worker_i */);
 143   return true;
 144 }
 145 
 146 // As above - but we don't have the heap region containing the
 147 // object, so we have to supply it.
 148 inline bool ConcurrentMark::mark_and_count(oop obj) {
 149   HeapWord* addr = (HeapWord*)obj;
 150   HeapRegion* hr = _g1h->heap_region_containing(addr);
 151   return mark_and_count(obj, hr);
 152 }
 153 
 154 inline void CMTask::push(oop obj) {
 155   HeapWord* objAddr = (HeapWord*) obj;
 156   assert(_g1h->is_in_g1_reserved(objAddr), "invariant");
 157   assert(!_g1h->is_on_master_free_list(
 158               _g1h->heap_region_containing((HeapWord*) objAddr)), "invariant");
 159   assert(!_g1h->is_obj_ill(obj), "invariant");
 160   assert(_nextMarkBitMap->isMarked(objAddr), "invariant");
 161 
 162   if (_cm->verbose_high()) {
 163     gclog_or_tty->print_cr("[%d] pushing "PTR_FORMAT, _task_id, (void*) obj);
 164   }
 165 
 166   if (!_task_queue->push(obj)) {
 167     // The local task queue looks full. We need to push some entries
 168     // to the global stack.
 169 
 170     if (_cm->verbose_medium()) {
 171       gclog_or_tty->print_cr("[%d] task queue overflow, "
 172                              "moving entries to the global stack",
 173                              _task_id);
 174     }
 175     move_entries_to_global_stack();
 176 
 177     // this should succeed since, even if we overflow the global
 178     // stack, we should have definitely removed some entries from the
 179     // local queue. So, there must be space on it.
 180     bool success = _task_queue->push(obj);
 181     assert(success, "invariant");
 182   }
 183 
 184   statsOnly( int tmp_size = _task_queue->size();
 185              if (tmp_size > _local_max_size) {
 186                _local_max_size = tmp_size;
 187              }
 188              ++_local_pushes );
 189 }
 190 
 191 // This determines whether the method below will check both the local
 192 // and global fingers when determining whether to push on the stack a
 193 // gray object (value 1) or whether it will only check the global one
 194 // (value 0). The tradeoffs are that the former will be a bit more
 195 // accurate and possibly push less on the stack, but it might also be
 196 // a little bit slower.
 197 
 198 #define _CHECK_BOTH_FINGERS_      1
 199 
 200 inline void CMTask::deal_with_reference(oop obj) {
 201   if (_cm->verbose_high()) {
 202     gclog_or_tty->print_cr("[%d] we're dealing with reference = "PTR_FORMAT,
 203                            _task_id, (void*) obj);
 204   }
 205 
 206   ++_refs_reached;
 207 
 208   HeapWord* objAddr = (HeapWord*) obj;
 209   assert(obj->is_oop_or_null(true /* ignore mark word */), "Error");
 210   if (_g1h->is_in_g1_reserved(objAddr)) {
 211     assert(obj != NULL, "null check is implicit");
 212     if (!_nextMarkBitMap->isMarked(objAddr)) {
 213       // Only get the containing region if the object is not marked on the
 214       // bitmap (otherwise, it's a waste of time since we won't do
 215       // anything with it).
 216       HeapRegion* hr = _g1h->heap_region_containing_raw(obj);
 217       if (!hr->obj_allocated_since_next_marking(obj)) {
 218         if (_cm->verbose_high()) {
 219           gclog_or_tty->print_cr("[%d] "PTR_FORMAT" is not considered marked",
 220                                  _task_id, (void*) obj);
 221         }
 222 
 223         // we need to mark it first
 224         if (_cm->par_mark_and_count(obj, hr, _marked_bytes_array, _card_bm)) {
 225           // No OrderAccess:store_load() is needed. It is implicit in the
 226           // CAS done in CMBitMap::parMark() call in the routine above.
 227           HeapWord* global_finger = _cm->finger();
 228 
 229 #if _CHECK_BOTH_FINGERS_
 230           // we will check both the local and global fingers
 231 
 232           if (_finger != NULL && objAddr < _finger) {
 233             if (_cm->verbose_high()) {
 234               gclog_or_tty->print_cr("[%d] below the local finger ("PTR_FORMAT"), "
 235                                      "pushing it", _task_id, _finger);
 236             }
 237             push(obj);
 238           } else if (_curr_region != NULL && objAddr < _region_limit) {
 239             // do nothing
 240           } else if (objAddr < global_finger) {
 241             // Notice that the global finger might be moving forward
 242             // concurrently. This is not a problem. In the worst case, we
 243             // mark the object while it is above the global finger and, by
 244             // the time we read the global finger, it has moved forward
 245             // passed this object. In this case, the object will probably
 246             // be visited when a task is scanning the region and will also
 247             // be pushed on the stack. So, some duplicate work, but no
 248             // correctness problems.
 249 
 250             if (_cm->verbose_high()) {
 251               gclog_or_tty->print_cr("[%d] below the global finger "
 252                                      "("PTR_FORMAT"), pushing it",
 253                                      _task_id, global_finger);
 254             }
 255             push(obj);
 256           } else {
 257             // do nothing
 258           }
 259 #else // _CHECK_BOTH_FINGERS_
 260           // we will only check the global finger
 261 
 262           if (objAddr < global_finger) {
 263             // see long comment above
 264 
 265             if (_cm->verbose_high()) {
 266               gclog_or_tty->print_cr("[%d] below the global finger "
 267                                      "("PTR_FORMAT"), pushing it",
 268                                      _task_id, global_finger);
 269             }
 270             push(obj);
 271           }
 272 #endif // _CHECK_BOTH_FINGERS_
 273         }
 274       }
 275     }
 276   }
 277 }
 278 
 279 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_CONCURRENTMARK_INLINE_HPP