diff -r eb6ebd9816cf src/share/vm/gc/shenandoah/shenandoahCollectorPolicy.cpp --- a/src/share/vm/gc/shenandoah/shenandoahCollectorPolicy.cpp Thu Mar 30 15:13:50 2017 +0200 +++ b/src/share/vm/gc/shenandoah/shenandoahCollectorPolicy.cpp Thu Mar 30 21:21:43 2017 +0200 @@ -73,6 +73,7 @@ size_t _bytes_allocated_after_last_gc; + bool _cm_happened; uint _cancelled_cm_cycles_in_a_row; uint _successful_cm_cycles_in_a_row; @@ -121,6 +122,7 @@ } virtual void record_cm_success() { + _cm_happened = true; _cancelled_cm_cycles_in_a_row = 0; _successful_cm_cycles_in_a_row++; } @@ -170,6 +172,7 @@ _bytes_in_cset(0), _cancelled_cm_cycles_in_a_row(0), _successful_cm_cycles_in_a_row(0), + _cm_happened(false), _region_garbage(NULL), _region_garbage_size(0) { @@ -436,6 +439,7 @@ private: uintx _free_threshold; TruncatedSeq* _cset_history; + bool _cm_happened; public: AdaptiveHeuristics() : @@ -684,12 +688,15 @@ virtual ~PartialHeuristics() {} - bool should_start_concurrent_mark(size_t used, size_t capacity) const { - // Never do concurrent GCs. - return false; + bool update_refs_early() { + return true; } bool should_start_partial_gc() { + if (!ShenandoahHeuristics::_cm_happened) { + return false; + } + ShenandoahHeap* heap = ShenandoahHeap::heap(); size_t capacity = heap->capacity(); diff -r eb6ebd9816cf src/share/vm/gc/shenandoah/shenandoahHeap.cpp --- a/src/share/vm/gc/shenandoah/shenandoahHeap.cpp Thu Mar 30 15:13:50 2017 +0200 +++ b/src/share/vm/gc/shenandoah/shenandoahHeap.cpp Thu Mar 30 21:21:43 2017 +0200 @@ -2637,6 +2637,7 @@ set_evacuation_in_progress_at_safepoint(false); set_update_refs_in_progress(true); ensure_parsability(true); + connection_matrix()->clear_all(); for (uint i = 0; i < _num_regions; i++) { ShenandoahHeapRegion* r = _ordered_regions->get(i); r->set_concurrent_iteration_safe_limit(r->top()); diff -r eb6ebd9816cf src/share/vm/gc/shenandoah/shenandoahOopClosures.inline.hpp --- a/src/share/vm/gc/shenandoah/shenandoahOopClosures.inline.hpp Thu Mar 30 15:13:50 2017 +0200 +++ b/src/share/vm/gc/shenandoah/shenandoahOopClosures.inline.hpp Thu Mar 30 21:21:43 2017 +0200 @@ -34,7 +34,10 @@ template inline void ShenandoahUpdateHeapRefsClosure::do_oop_nv(T* p) { - _heap->maybe_update_oop_ref(p); + oop obj = _heap->maybe_update_oop_ref(p); + if (! oopDesc::is_null(obj)) { + _heap->connection_matrix()->set_connected(p, obj); + } } #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHOOPCLOSURES_INLINE_HPP diff -r eb6ebd9816cf src/share/vm/gc/shenandoah/shenandoahPartialGC.cpp --- a/src/share/vm/gc/shenandoah/shenandoahPartialGC.cpp Thu Mar 30 15:13:50 2017 +0200 +++ b/src/share/vm/gc/shenandoah/shenandoahPartialGC.cpp Thu Mar 30 21:21:43 2017 +0200 @@ -106,7 +106,7 @@ ShenandoahHeapRegion* r = _root_regions->claim_next(); while (r != NULL) { assert(r->is_root(), "must be root region"); - r->oop_iterate(&cl); + _heap->marked_object_oop_iterate(r, &cl); r->set_root(false); if (check_and_handle_cancelled_gc()) return; r = _root_regions->claim_next(); @@ -299,6 +299,11 @@ for (size_t i = 0; i < num_cset; i++) { ShenandoahHeapRegion* r = _heap->collection_set()->get(i); _heap->decrease_used(r->used()); + HeapWord* bottom = r->bottom(); + HeapWord* top = _heap->complete_top_at_mark_start(r->bottom()); + if (top > bottom) { + _heap->complete_mark_bit_map()->clear_range_large(MemRegion(bottom, top)); + } r->recycle(); _heap->free_regions()->add_region(r); } @@ -343,7 +348,7 @@ if (UPDATE_MATRIX) { #ifdef ASSERT oop forw = ShenandoahBarrierSet::resolve_oop_static_not_null(obj); - assert(oopDesc::unsafe_equals(obj, forw) || _heap->cancelled_concgc(), "must not be evacuated"); + assert(oopDesc::unsafe_equals(obj, forw) || _heap->cancelled_concgc(), "must not be evacuated: "PTR_FORMAT" -> "PTR_FORMAT, p2i(obj), p2i(forw)); #endif _matrix->set_connected(p, obj); }