< prev index next >

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

Print this page
rev 7327 : 8075215: SATB buffer processing found reclaimed humongous object
Summary: Don't assume SATB buffer entries are valid objects
Reviewed-by: brutisso, ecaspole

@@ -257,29 +257,29 @@
                _local_max_size = tmp_size;
              }
              ++_local_pushes );
 }
 
-inline bool CMTask::is_below_finger(HeapWord* objAddr,
-                                    HeapWord* global_finger) const {
-  // If objAddr is above the global finger, then the mark bitmap scan
+inline bool CMTask::is_below_finger(oop obj, HeapWord* global_finger) const {
+  // If obj is above the global finger, then the mark bitmap scan
   // will find it later, and no push is needed.  Similarly, if we have
-  // a current region and objAddr is between the local finger and the
+  // a current region and obj is between the local finger and the
   // end of the current region, then no push is needed.  The tradeoff
   // of checking both vs only checking the global finger is that the
   // local check will be more accurate and so result in fewer pushes,
   // but may also be a little slower.
+  HeapWord* objAddr = (HeapWord*)obj;
   if (_finger != NULL) {
     // We have a current region.
 
     // Finger and region values are all NULL or all non-NULL.  We
     // use _finger to check since we immediately use its value.
     assert(_curr_region != NULL, "invariant");
     assert(_region_limit != NULL, "invariant");
     assert(_region_limit <= global_finger, "invariant");
 
-    // True if objAddr is less than the local finger, or is between
+    // True if obj is less than the local finger, or is between
     // the region limit and the global finger.
     if (objAddr < _finger) {
       return true;
     } else if (objAddr < _region_limit) {
       return false;

@@ -287,35 +287,18 @@
   }
   // Check global finger.
   return objAddr < global_finger;
 }
 
-inline void CMTask::deal_with_reference(oop obj) {
-  if (_cm->verbose_high()) {
-    gclog_or_tty->print_cr("[%u] we're dealing with reference = "PTR_FORMAT,
-                           _worker_id, p2i((void*) obj));
-  }
-
-  ++_refs_reached;
+inline void CMTask::make_reference_grey(oop obj, HeapRegion* hr) {
+  if (_cm->par_mark_and_count(obj, hr, _marked_bytes_array, _card_bm)) {
 
-  HeapWord* objAddr = (HeapWord*) obj;
-  assert(obj->is_oop_or_null(true /* ignore mark word */), "Error");
-  if (_g1h->is_in_g1_reserved(objAddr)) {
-    assert(obj != NULL, "null check is implicit");
-    if (!_nextMarkBitMap->isMarked(objAddr)) {
-      // Only get the containing region if the object is not marked on the
-      // bitmap (otherwise, it's a waste of time since we won't do
-      // anything with it).
-      HeapRegion* hr = _g1h->heap_region_containing_raw(obj);
-      if (!hr->obj_allocated_since_next_marking(obj)) {
         if (_cm->verbose_high()) {
-          gclog_or_tty->print_cr("[%u] "PTR_FORMAT" is not considered marked",
-                                 _worker_id, p2i((void*) obj));
+      gclog_or_tty->print_cr("[%u] marked object " PTR_FORMAT,
+                             _worker_id, p2i(obj));
         }
 
-        // we need to mark it first
-        if (_cm->par_mark_and_count(obj, hr, _marked_bytes_array, _card_bm)) {
           // No OrderAccess:store_load() is needed. It is implicit in the
           // CAS done in CMBitMap::parMark() call in the routine above.
           HeapWord* global_finger = _cm->finger();
 
           // We only need to push a newly grey object on the mark

@@ -329,11 +312,11 @@
           // the time we read the global finger, it has moved forward
           // past this object. In this case, the object will probably
           // be visited when a task is scanning the region and will also
           // be pushed on the stack. So, some duplicate work, but no
           // correctness problems.
-          if (is_below_finger(objAddr, global_finger)) {
+    if (is_below_finger(obj, global_finger)) {
             if (obj->is_typeArray()) {
               // Immediately process arrays of primitive types, rather
               // than pushing on the mark stack.  This keeps us from
               // adding humongous objects to the mark stack that might
               // be reclaimed before the entry is processed - see

@@ -348,16 +331,37 @@
               if (_cm->verbose_high()) {
                 gclog_or_tty->print_cr("[%u] below a finger (local: " PTR_FORMAT
                                        ", global: " PTR_FORMAT ") pushing "
                                        PTR_FORMAT " on mark stack",
                                        _worker_id, p2i(_finger),
-                                       p2i(global_finger), p2i(objAddr));
+                                 p2i(global_finger), p2i(obj));
               }
               push(obj);
             }
           }
         }
+}
+
+inline void CMTask::deal_with_reference(oop obj) {
+  if (_cm->verbose_high()) {
+    gclog_or_tty->print_cr("[%u] we're dealing with reference = "PTR_FORMAT,
+                           _worker_id, p2i((void*) obj));
+  }
+
+  increment_refs_reached();
+
+  HeapWord* objAddr = (HeapWord*) obj;
+  assert(obj->is_oop_or_null(true /* ignore mark word */), "Error");
+  if (_g1h->is_in_g1_reserved(objAddr)) {
+    assert(obj != NULL, "null check is implicit");
+    if (!_nextMarkBitMap->isMarked(objAddr)) {
+      // Only get the containing region if the object is not marked on the
+      // bitmap (otherwise, it's a waste of time since we won't do
+      // anything with it).
+      HeapRegion* hr = _g1h->heap_region_containing_raw(obj);
+      if (!hr->obj_allocated_since_next_marking(obj)) {
+        make_reference_grey(obj, hr);
       }
     }
   }
 }
 
< prev index next >