< prev index next >
src/share/vm/gc/shenandoah/shenandoahHeap.cpp
Print this page
@@ -2404,64 +2404,81 @@
T cl;
ShenandoahHeap* _heap;
ShenandoahHeapRegionSet* _regions;
public:
- ShenandoahUpdateHeapRefsTask() :
+ ShenandoahUpdateHeapRefsTask(ShenandoahHeapRegionSet* regions) :
AbstractGangTask("Concurrent Update References Task"),
cl(T()),
_heap(ShenandoahHeap::heap()),
- _regions(ShenandoahHeap::heap()->regions()) {
- _regions->clear_current_index();
+ _regions(regions) {
}
void work(uint worker_id) {
ShenandoahHeapRegion* r = _regions->claim_next();
- while (r != NULL && ! _heap->cancelled_concgc()) {
+ while (r != NULL) {
if (! _heap->in_collection_set(r) &&
! r->is_empty()) {
_heap->marked_object_oop_safe_iterate(r, &cl);
} else if (_heap->in_collection_set(r)) {
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));
}
}
+ if (_heap->cancelled_concgc()) {
+ return;
+ }
r = _regions->claim_next();
}
}
};
-void ShenandoahHeap::concurrent_update_heap_references() {
- _shenandoah_policy->record_phase_start(ShenandoahCollectorPolicy::conc_update_refs);
+void ShenandoahHeap::update_heap_references(ShenandoahHeapRegionSet* update_regions) {
if (UseShenandoahMatrix) {
- ShenandoahUpdateHeapRefsTask<ShenandoahUpdateHeapRefsMatrixClosure> task;
+ ShenandoahUpdateHeapRefsTask<ShenandoahUpdateHeapRefsMatrixClosure> task(update_regions);
workers()->run_task(&task);
} else {
- ShenandoahUpdateHeapRefsTask<ShenandoahUpdateHeapRefsClosure> task;
+ ShenandoahUpdateHeapRefsTask<ShenandoahUpdateHeapRefsClosure> task(update_regions);
workers()->run_task(&task);
}
+}
+
+void ShenandoahHeap::concurrent_update_heap_references() {
+ _shenandoah_policy->record_phase_start(ShenandoahCollectorPolicy::conc_update_refs);
+ ShenandoahHeapRegionSet* update_regions = regions();
+ update_regions->clear_current_index();
+ update_heap_references(update_regions);
_shenandoah_policy->record_phase_end(ShenandoahCollectorPolicy::conc_update_refs);
}
void ShenandoahHeap::prepare_update_refs() {
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
set_evacuation_in_progress_at_safepoint(false);
set_update_refs_in_progress(true);
ensure_parsability(true);
+ if (UseShenandoahMatrix) {
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());
}
}
void ShenandoahHeap::finish_update_refs() {
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
- if (! cancelled_concgc()) {
+ if (cancelled_concgc()) {
+ // Finish updating references where we left off.
+ clear_cancelled_concgc();
+ ShenandoahHeapRegionSet* update_regions = regions();
+ update_heap_references(update_regions);
+ }
+
+ assert(! cancelled_concgc(), "Should have been done right before");
concurrentMark()->update_roots(ShenandoahCollectorPolicy::final_update_refs_roots);
recycle_dirty_regions();
set_need_update_refs(false);
if (ShenandoahVerify) {
@@ -2479,11 +2496,10 @@
assert (!in_collection_set(r), "collection set should be clear");
_free_regions->add_region(r);
}
}
}
- }
set_update_refs_in_progress(false);
}
class ShenandoahVerifyUpdateRefsClosure : public ExtendedOopClosure {
private:
< prev index next >