< 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 >