--- old/src/share/vm/gc/g1/heapRegion.cpp 2016-09-29 18:05:37.655247628 -0400 +++ new/src/share/vm/gc/g1/heapRegion.cpp 2016-09-29 18:05:37.551247112 -0400 @@ -352,7 +352,46 @@ _prev_marked_bytes = marked_bytes; } -bool HeapRegion::oops_on_card_seq_iterate_careful(MemRegion mr, +// Humongous objects are allocated directly in the old-gen. Need +// special handling for concurrent processing encountering an +// in-progress allocation. +static void do_oops_on_card_in_humongous(MemRegion mr, + FilterOutOfRegionClosure* cl, + HeapRegion* hr, + G1CollectedHeap* g1h) { + assert(hr->is_humongous(), "precondition"); + HeapRegion* sr = hr->humongous_start_region(); + oop obj = oop(sr->bottom()); + + // If concurrent and klass_or_null is NULL, then space has been + // allocated but the object has not yet been published by setting + // the klass. That can only happen if the card is stale, since + // there can't have been object stores into the incomplete object. + // In that case, we can ignore the card. + if (g1h->is_gc_active() || (obj->klass_or_null_acquire() != NULL)) { + // Only filler objects follow a humongous object in the containing + // regions, and we can ignore those. So only process the one + // humongous object. + if (!g1h->is_obj_dead(obj, sr)) { + if (obj->is_objArray() || (sr->bottom() < mr.start())) { + // objArrays are always marked precisely, so limit processing + // with mr. Non-objArrays might be precisely marked, and since + // it's humongous it's worthwhile avoiding full processing. + // However, the card could be stale and only cover filler + // objects. That should be rare, so not worth checking for; + // instead let it fall out from the bounded iteration. + obj->oop_iterate(cl, mr); + } else { + // If obj is not an objArray and mr contains the start of the + // obj, then this could be an imprecise mark, and we need to + // process the entire object. + obj->oop_iterate(cl); + } + } + } +} + +void HeapRegion::oops_on_card_seq_iterate_careful(MemRegion mr, FilterOutOfRegionClosure* cl, jbyte* card_ptr) { assert(card_ptr != NULL, "pre-condition"); @@ -367,7 +406,7 @@ mr = mr.intersection(used_region()); } if (mr.is_empty()) { - return true; + return; } // Otherwise, find the obj that extends onto mr.start(). @@ -378,7 +417,7 @@ // is_young tag on the region before allocating. Thus we // safely know if this region is young. if (is_young()) { - return true; + return; } // We can only clean the card here, after we make the decision that @@ -387,54 +426,51 @@ // We must complete this write before we do any of the reads below. OrderAccess::storeload(); + // Special handling for humongous regions. + if (is_humongous()) { + return do_oops_on_card_in_humongous(mr, cl, this, g1h); + } + + // During GC we limit mr by scan_top. So we never get here with an + // mr covering objects allocated during GC. Non-humongous objects + // only reach the old-gen during GC. So the parts of the heap that + // may be examined here are always parsable; there's no need to use + // klass_or_null here to detect in-progress allocations. + // Cache the boundaries of the memory region in some const locals HeapWord* const start = mr.start(); HeapWord* const end = mr.end(); - // Update BOT as needed while finding start of (potential) object. + // Update BOT as needed while finding start of (possibly dead) + // object containing the start of the region. HeapWord* cur = block_start(start); - assert(cur <= start, "Postcondition"); - - oop obj; - HeapWord* next = cur; - do { - cur = next; - obj = oop(cur); - if (obj->klass_or_null() == NULL) { - // Ran into an unparseable point. - assert(!g1h->is_gc_active(), - "Unparsable heap during GC at " PTR_FORMAT, p2i(cur)); - return false; - } - // Otherwise... - next = cur + block_size(cur); - } while (next <= start); - - // If we finish the above loop...We have a parseable object that - // begins on or before the start of the memory region, and ends - // inside or spans the entire region. - assert(cur <= start, "Loop postcondition"); - assert(obj->klass_or_null() != NULL, "Loop postcondition"); +#ifdef ASSERT + { + assert(cur <= start, + "cur: " PTR_FORMAT ", start: " PTR_FORMAT, p2i(cur), p2i(start)); + HeapWord* next = cur + block_size(cur); + assert(start < next, + "start: " PTR_FORMAT ", next: " PTR_FORMAT, p2i(start), p2i(next)); + } +#endif do { - obj = oop(cur); - assert((cur + block_size(cur)) > (HeapWord*)obj, "Loop invariant"); - if (obj->klass_or_null() == NULL) { - // Ran into an unparseable point. - assert(!g1h->is_gc_active(), - "Unparsable heap during GC at " PTR_FORMAT, p2i(cur)); - return false; - } - - // Advance the current pointer. "obj" still points to the object to iterate. - cur = cur + block_size(cur); - - if (!g1h->is_obj_dead(obj)) { - // Non-objArrays are sometimes marked imprecise at the object start. We - // always need to iterate over them in full. - // We only iterate over object arrays in full if they are completely contained - // in the memory region. + oop obj = oop(cur); + assert(obj->is_oop(true), "Not an oop at " PTR_FORMAT, p2i(cur)); + assert(obj->klass_or_null() != NULL, + "Unparsable heap at " PTR_FORMAT, p2i(cur)); + + if (g1h->is_obj_dead(obj, this)) { + // Carefully step over dead object. + cur += block_size(cur); + } else { + // Step over live object, and process its references. + cur += obj->size(); + // Non-objArrays are usually marked imprecise at the object + // start, in which case we need to iterate over them in full. + // objArrays are precisely marked, but can still be iterated + // over in full if completely covered. if (!obj->is_objArray() || (((HeapWord*)obj) >= start && cur <= end)) { obj->oop_iterate(cl); } else { @@ -442,8 +478,6 @@ } } } while (cur < end); - - return true; } // Code roots support