< prev index next >

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

Print this page
rev 8040 : [mq]: inc1

@@ -257,20 +257,40 @@
                _local_max_size = tmp_size;
              }
              ++_local_pushes );
 }
 
-inline void CMTask::deal_with_reference_below_finger(
-  oop obj, HeapWord* finger, bool is_global_finger)
-{
-  if (_cm->verbose_high()) {
-    gclog_or_tty->print_cr(
-      "[%u] below the %s finger (" PTR_FORMAT ") pushing " PTR_FORMAT,
-      _worker_id, (is_global_finger ? "global" : "local"),
-      p2i(finger), p2i((void*)obj));
+inline bool CMTask::is_below_finger(HeapWord* objAddr,
+                                    HeapWord* global_finger) const {
+  // Test whether objAddr might have already been passed over by the
+  // mark bitmap scan, and so needs to be pushed onto the mark stack.
+  // If objAddr 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
+  // 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 is also be a little slower.
+  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
+    // the region limit and the global finger.
+    if (objAddr < _finger) {
+      return true;
+    } else if (objAddr < _region_limit) {
+      return false;
+    } // Else check global finger.
   }
-  push(obj);
+  // 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,

@@ -298,45 +318,32 @@
         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();
 
-          // If we have a current region, check against it first to
-          // decide whether to push a freshly grey object on the mark
-          // stack or leave it to the mark bit processor.  The
-          // tradeoff vs only checking the global finger is that the
-          // local check will be a bit more accurate and possibly push
-          // less on the stack, but might also be a little bit slower.
-          if (_finger != NULL) {
-            // We have a current region.
-            assert(_curr_region != NULL, "invariant");
-            assert(_region_limit != NULL, "invariant");
-            // If object is before the local finger, push it onto the
-            // mark stack.  If it's between the local finger and the
-            // end of the region, leave it to mark bit processing to
-            // take care of.  Otherwise, check against the global
-            // finger.
-            if (objAddr < _finger) {
-              deal_with_reference_below_finger(obj, _finger, false);
-              return;
-            } else if (objAddr < _region_limit) {
-              return;
-            }
-          }
-          // No current region, or object is after the current region.
-          // Push onto mark stack if below global finger.
+          // We only need to push a newly grey object on the mark
+          // stack if it is in a section of memory the mark bitmap
+          // scan has already examined.  Mark bitmap scanning
+          // maintains progress "fingers" for determining that.
           //
           // Notice that the global finger might be moving forward
           // concurrently. This is not a problem. In the worst case, we
           // mark the object while it is above the global finger and, by
           // the time we read the global finger, it has moved forward
-          // passed this object. In this case, the object will probably
+          // 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 (objAddr < global_finger) {
-            deal_with_reference_below_finger(obj, global_finger, true);
+          if (is_below_finger(objAddr, global_finger)) {
+            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));
+            }
+            push(obj);
           }
         }
       }
     }
   }
< prev index next >