< prev index next >

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

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

*** 257,349 **** _local_max_size = tmp_size; } ++_local_pushes ); } ! // This determines whether the method below will check both the local ! // and global fingers when determining whether to push on the stack a ! // gray object (value 1) or whether it will only check the global one ! // (value 0). The tradeoffs are that the former will be a bit more ! // accurate and possibly push less on the stack, but it might also be ! // a little bit slower. ! ! #define _CHECK_BOTH_FINGERS_ 1 ! ! 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; - 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)); } - // 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(); ! #if _CHECK_BOTH_FINGERS_ ! // we will check both the local and global fingers ! ! if (_finger != NULL && objAddr < _finger) { ! if (_cm->verbose_high()) { ! gclog_or_tty->print_cr("[%u] below the local finger ("PTR_FORMAT"), " ! "pushing it", _worker_id, p2i(_finger)); ! } ! push(obj); ! } else if (_curr_region != NULL && objAddr < _region_limit) { ! // do nothing ! } else if (objAddr < global_finger) { // 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 // 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 (_cm->verbose_high()) { ! gclog_or_tty->print_cr("[%u] below the global finger " ! "("PTR_FORMAT"), pushing it", ! _worker_id, p2i(global_finger)); } push(obj); - } else { - // do nothing } - #else // _CHECK_BOTH_FINGERS_ - // we will only check the global finger - - if (objAddr < global_finger) { - // see long comment above - - if (_cm->verbose_high()) { - gclog_or_tty->print_cr("[%u] below the global finger " - "("PTR_FORMAT"), pushing it", - _worker_id, p2i(global_finger)); } - push(obj); } ! #endif // _CHECK_BOTH_FINGERS_ } } } } } --- 257,367 ---- _local_max_size = tmp_size; } ++_local_pushes ); } ! 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 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 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; ! } // Else check global finger. } + // Check global finger. + return objAddr < global_finger; + } ! inline void CMTask::make_reference_grey(oop obj, HeapRegion* hr) { ! if (_cm->par_mark_and_count(obj, hr, _marked_bytes_array, _card_bm)) { if (_cm->verbose_high()) { ! gclog_or_tty->print_cr("[%u] marked object " PTR_FORMAT, ! _worker_id, p2i(obj)); } // 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 ! // 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 ! // 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(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 ! // selection of candidates for eager reclaim of humongous ! // objects. The cost of the additional type test is ! // mitigated by avoiding a trip through the mark stack, ! // by only doing a bookkeeping update and avoiding the ! // actual scan of the object - a typeArray contains no ! // references, and the metadata is built-in. ! process_grey_object<false>(obj); ! } else { 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(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 >