< prev index next >

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

Print this page
rev 7322 : 8076265: Simplify deal_with_reference
Summary: Eliminate _CHECK_BOTH_FINGERS_ and simplify.
Reviewed-by: brutisso, tschatzl


 242       gclog_or_tty->print_cr("[%u] task queue overflow, "
 243                              "moving entries to the global stack",
 244                              _worker_id);
 245     }
 246     move_entries_to_global_stack();
 247 
 248     // this should succeed since, even if we overflow the global
 249     // stack, we should have definitely removed some entries from the
 250     // local queue. So, there must be space on it.
 251     bool success = _task_queue->push(obj);
 252     assert(success, "invariant");
 253   }
 254 
 255   statsOnly( int tmp_size = _task_queue->size();
 256              if (tmp_size > _local_max_size) {
 257                _local_max_size = tmp_size;
 258              }
 259              ++_local_pushes );
 260 }
 261 
 262 // This determines whether the method below will check both the local
 263 // and global fingers when determining whether to push on the stack a
 264 // gray object (value 1) or whether it will only check the global one
 265 // (value 0). The tradeoffs are that the former will be a bit more
 266 // accurate and possibly push less on the stack, but it might also be
 267 // a little bit slower.
 268 
 269 #define _CHECK_BOTH_FINGERS_      1





















 270 
 271 inline void CMTask::deal_with_reference(oop obj) {
 272   if (_cm->verbose_high()) {
 273     gclog_or_tty->print_cr("[%u] we're dealing with reference = "PTR_FORMAT,
 274                            _worker_id, p2i((void*) obj));
 275   }
 276 
 277   ++_refs_reached;
 278 
 279   HeapWord* objAddr = (HeapWord*) obj;
 280   assert(obj->is_oop_or_null(true /* ignore mark word */), "Error");
 281   if (_g1h->is_in_g1_reserved(objAddr)) {
 282     assert(obj != NULL, "null check is implicit");
 283     if (!_nextMarkBitMap->isMarked(objAddr)) {
 284       // Only get the containing region if the object is not marked on the
 285       // bitmap (otherwise, it's a waste of time since we won't do
 286       // anything with it).
 287       HeapRegion* hr = _g1h->heap_region_containing_raw(obj);
 288       if (!hr->obj_allocated_since_next_marking(obj)) {
 289         if (_cm->verbose_high()) {
 290           gclog_or_tty->print_cr("[%u] "PTR_FORMAT" is not considered marked",
 291                                  _worker_id, p2i((void*) obj));
 292         }
 293 
 294         // we need to mark it first
 295         if (_cm->par_mark_and_count(obj, hr, _marked_bytes_array, _card_bm)) {
 296           // No OrderAccess:store_load() is needed. It is implicit in the
 297           // CAS done in CMBitMap::parMark() call in the routine above.
 298           HeapWord* global_finger = _cm->finger();
 299 
 300 #if _CHECK_BOTH_FINGERS_
 301           // we will check both the local and global fingers
 302 
 303           if (_finger != NULL && objAddr < _finger) {
 304             if (_cm->verbose_high()) {
 305               gclog_or_tty->print_cr("[%u] below the local finger ("PTR_FORMAT"), "
 306                                      "pushing it", _worker_id, p2i(_finger));
 307             }
 308             push(obj);
 309           } else if (_curr_region != NULL && objAddr < _region_limit) {
 310             // do nothing
 311           } else if (objAddr < global_finger) {
 312             // Notice that the global finger might be moving forward
 313             // concurrently. This is not a problem. In the worst case, we
 314             // mark the object while it is above the global finger and, by
 315             // the time we read the global finger, it has moved forward
 316             // passed this object. In this case, the object will probably
 317             // be visited when a task is scanning the region and will also
 318             // be pushed on the stack. So, some duplicate work, but no
 319             // correctness problems.
 320 
 321             if (_cm->verbose_high()) {
 322               gclog_or_tty->print_cr("[%u] below the global finger "
 323                                      "("PTR_FORMAT"), pushing it",
 324                                      _worker_id, p2i(global_finger));
 325             }
 326             push(obj);
 327           } else {
 328             // do nothing
 329           }
 330 #else // _CHECK_BOTH_FINGERS_
 331           // we will only check the global finger
 332 
 333           if (objAddr < global_finger) {
 334             // see long comment above
 335 
 336             if (_cm->verbose_high()) {
 337               gclog_or_tty->print_cr("[%u] below the global finger "
 338                                      "("PTR_FORMAT"), pushing it",
 339                                      _worker_id, p2i(global_finger));


 340             }
 341             push(obj);
 342           }
 343 #endif // _CHECK_BOTH_FINGERS_
 344         }
 345       }
 346     }
 347   }
 348 }
 349 
 350 inline void ConcurrentMark::markPrev(oop p) {
 351   assert(!_prevMarkBitMap->isMarked((HeapWord*) p), "sanity");
 352   // Note we are overriding the read-only view of the prev map here, via
 353   // the cast.
 354   ((CMBitMap*)_prevMarkBitMap)->mark((HeapWord*) p);
 355 }
 356 
 357 inline void ConcurrentMark::grayRoot(oop obj, size_t word_size,
 358                                      uint worker_id, HeapRegion* hr) {
 359   assert(obj != NULL, "pre-condition");
 360   HeapWord* addr = (HeapWord*) obj;
 361   if (hr == NULL) {
 362     hr = _g1h->heap_region_containing_raw(addr);
 363   } else {




 242       gclog_or_tty->print_cr("[%u] task queue overflow, "
 243                              "moving entries to the global stack",
 244                              _worker_id);
 245     }
 246     move_entries_to_global_stack();
 247 
 248     // this should succeed since, even if we overflow the global
 249     // stack, we should have definitely removed some entries from the
 250     // local queue. So, there must be space on it.
 251     bool success = _task_queue->push(obj);
 252     assert(success, "invariant");
 253   }
 254 
 255   statsOnly( int tmp_size = _task_queue->size();
 256              if (tmp_size > _local_max_size) {
 257                _local_max_size = tmp_size;
 258              }
 259              ++_local_pushes );
 260 }
 261 
 262 inline bool CMTask::is_below_finger(HeapWord* objAddr,
 263                                     HeapWord* global_finger) const {
 264   // If objAddr is above the global finger, then the mark bitmap scan
 265   // will find it later, and no push is needed.  Similarly, if we have
 266   // a current region and objAddr is between the local finger and the
 267   // end of the current region, then no push is needed.  The tradeoff
 268   // of checking both vs only checking the global finger is that the
 269   // local check will be more accurate and so result in fewer pushes,
 270   // but may also be a little slower.
 271   if (_finger != NULL) {
 272     // We have a current region.
 273 
 274     // Finger and region values are all NULL or all non-NULL.  We
 275     // use _finger to check since we immediately use its value.
 276     assert(_curr_region != NULL, "invariant");
 277     assert(_region_limit != NULL, "invariant");
 278     assert(_region_limit <= global_finger, "invariant");
 279 
 280     // True if objAddr is less than the local finger, or is between
 281     // the region limit and the global finger.
 282     if (objAddr < _finger) {
 283       return true;
 284     } else if (objAddr < _region_limit) {
 285       return false;
 286     } // Else check global finger.
 287   }
 288   // Check global finger.
 289   return objAddr < global_finger;
 290 }
 291 
 292 inline void CMTask::deal_with_reference(oop obj) {
 293   if (_cm->verbose_high()) {
 294     gclog_or_tty->print_cr("[%u] we're dealing with reference = "PTR_FORMAT,
 295                            _worker_id, p2i((void*) obj));
 296   }
 297 
 298   ++_refs_reached;
 299 
 300   HeapWord* objAddr = (HeapWord*) obj;
 301   assert(obj->is_oop_or_null(true /* ignore mark word */), "Error");
 302   if (_g1h->is_in_g1_reserved(objAddr)) {
 303     assert(obj != NULL, "null check is implicit");
 304     if (!_nextMarkBitMap->isMarked(objAddr)) {
 305       // Only get the containing region if the object is not marked on the
 306       // bitmap (otherwise, it's a waste of time since we won't do
 307       // anything with it).
 308       HeapRegion* hr = _g1h->heap_region_containing_raw(obj);
 309       if (!hr->obj_allocated_since_next_marking(obj)) {
 310         if (_cm->verbose_high()) {
 311           gclog_or_tty->print_cr("[%u] "PTR_FORMAT" is not considered marked",
 312                                  _worker_id, p2i((void*) obj));
 313         }
 314 
 315         // we need to mark it first
 316         if (_cm->par_mark_and_count(obj, hr, _marked_bytes_array, _card_bm)) {
 317           // No OrderAccess:store_load() is needed. It is implicit in the
 318           // CAS done in CMBitMap::parMark() call in the routine above.
 319           HeapWord* global_finger = _cm->finger();
 320 
 321           // We only need to push a newly grey object on the mark
 322           // stack if it is in a section of memory the mark bitmap
 323           // scan has already examined.  Mark bitmap scanning
 324           // maintains progress "fingers" for determining that.
 325           //







 326           // Notice that the global finger might be moving forward
 327           // concurrently. This is not a problem. In the worst case, we
 328           // mark the object while it is above the global finger and, by
 329           // the time we read the global finger, it has moved forward
 330           // past this object. In this case, the object will probably
 331           // be visited when a task is scanning the region and will also
 332           // be pushed on the stack. So, some duplicate work, but no
 333           // correctness problems.
 334           if (is_below_finger(objAddr, global_finger)) {















 335             if (_cm->verbose_high()) {
 336               gclog_or_tty->print_cr("[%u] below a finger (local: " PTR_FORMAT
 337                                      ", global: " PTR_FORMAT ") pushing "
 338                                      PTR_FORMAT " on mark stack",
 339                                      _worker_id, p2i(_finger),
 340                                      p2i(global_finger), p2i(objAddr));
 341             }
 342             push(obj);
 343           }

 344         }
 345       }
 346     }
 347   }
 348 }
 349 
 350 inline void ConcurrentMark::markPrev(oop p) {
 351   assert(!_prevMarkBitMap->isMarked((HeapWord*) p), "sanity");
 352   // Note we are overriding the read-only view of the prev map here, via
 353   // the cast.
 354   ((CMBitMap*)_prevMarkBitMap)->mark((HeapWord*) p);
 355 }
 356 
 357 inline void ConcurrentMark::grayRoot(oop obj, size_t word_size,
 358                                      uint worker_id, HeapRegion* hr) {
 359   assert(obj != NULL, "pre-condition");
 360   HeapWord* addr = (HeapWord*) obj;
 361   if (hr == NULL) {
 362     hr = _g1h->heap_region_containing_raw(addr);
 363   } else {


< prev index next >