< prev index next >
src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp
Print this page
*** 194,207 ****
ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CodeCacheRoots, worker_id);
_cset_coderoots->possibly_parallel_blobs_do(&code_cl);
} else {
_rp->process_all_roots(&roots_cl, &cld_cl, &code_cl, NULL, worker_id);
}
- if (ShenandoahStringDedup::is_enabled()) {
- AlwaysTrueClosure is_alive;
- ShenandoahStringDedup::parallel_oops_do(&is_alive, &roots_cl, worker_id);
- }
}
}
};
class ShenandoahConcurrentTraversalCollectionTask : public AbstractGangTask {
--- 194,203 ----
*** 597,610 ****
if (!_heap->cancelled_gc() && _heap->process_references()) {
weak_refs_work();
}
if (!_heap->cancelled_gc()) {
- fixup_roots();
if (_heap->unload_classes()) {
_heap->unload_classes_and_cleanup_tables(false);
}
}
if (!_heap->cancelled_gc()) {
assert(_task_queues->is_empty(), "queues must be empty after traversal GC");
TASKQUEUE_STATS_ONLY(_task_queues->print_taskqueue_stats());
--- 593,607 ----
if (!_heap->cancelled_gc() && _heap->process_references()) {
weak_refs_work();
}
if (!_heap->cancelled_gc()) {
if (_heap->unload_classes()) {
_heap->unload_classes_and_cleanup_tables(false);
}
+
+ fixup_roots();
}
if (!_heap->cancelled_gc()) {
assert(_task_queues->is_empty(), "queues must be empty after traversal GC");
TASKQUEUE_STATS_ONLY(_task_queues->print_taskqueue_stats());
*** 770,779 ****
--- 767,799 ----
void do_oop(narrowOop* p) { do_oop_work(p); }
void do_oop(oop* p) { do_oop_work(p); }
};
+ class ShenandoahTraversalWeakUpdateClosure : public OopClosure {
+ private:
+ template <class T>
+ inline void do_oop_work(T* p) {
+ // Cannot call maybe_update_with_forwarded, because on traversal-degen
+ // path the collection set is already dropped. Instead, do the unguarded store.
+ // TODO: This can be fixed after degen-traversal stops dropping cset.
+ T o = RawAccess<>::oop_load(p);
+ if (!CompressedOops::is_null(o)) {
+ oop obj = CompressedOops::decode_not_null(o);
+ obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
+ shenandoah_assert_marked(p, obj);
+ RawAccess<IS_NOT_NULL>::oop_store(p, obj);
+ }
+ }
+
+ public:
+ ShenandoahTraversalWeakUpdateClosure() {}
+
+ void do_oop(narrowOop* p) { do_oop_work(p); }
+ void do_oop(oop* p) { do_oop_work(p); }
+ };
+
class ShenandoahTraversalKeepAliveUpdateDegenClosure : public OopClosure {
private:
ShenandoahObjToScanQueue* _queue;
Thread* _thread;
ShenandoahTraversalGC* _traversal_gc;
*** 1082,1089 ****
--- 1102,1119 ----
rp->process_discovered_references(&is_alive, &keep_alive,
&complete_gc, &executor,
&pt);
}
+ {
+ ShenandoahGCPhase phase(phase_process);
+ ShenandoahTerminationTracker termination(ShenandoahPhaseTimings::weakrefs_termination);
+
+ // Process leftover weak oops (using parallel version)
+ ShenandoahTraversalWeakUpdateClosure cl;
+ WeakProcessor::weak_oops_do(workers, &is_alive, &cl, 1);
+
pt.print_all_references();
+
assert(task_queues()->is_empty() || _heap->cancelled_gc(), "Should be empty");
+ }
}
< prev index next >