# HG changeset patch # User kbarrett # Date 1428015851 14400 # Thu Apr 02 19:04:11 2015 -0400 # Node ID fb628aa6f1f1d38ef7f1622090766978f7fb44a2 # Parent b1456f32c12971bf0586e9ecea38844e5f6d27c2 [mq]: inc1 diff --git a/src/share/vm/gc_implementation/g1/concurrentMark.hpp b/src/share/vm/gc_implementation/g1/concurrentMark.hpp --- a/src/share/vm/gc_implementation/g1/concurrentMark.hpp +++ b/src/share/vm/gc_implementation/g1/concurrentMark.hpp @@ -1100,8 +1100,8 @@ void regular_clock_call(); bool concurrent() { return _concurrent; } - void deal_with_reference_below_finger( - oop obj, HeapWord* finger, bool is_global_finger); + // Helper for deal_with_reference(). + bool is_below_finger(HeapWord* objAddr, HeapWord* global_finger) const; public: // It resets the task; it should be called right at the beginning of diff --git a/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp b/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp --- a/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp +++ b/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp @@ -259,16 +259,36 @@ ++_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) { @@ -300,41 +320,28 @@ // 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); } } }