--- old/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp 2020-04-03 22:13:07.543243900 +0200 +++ new/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp 2020-04-03 22:13:07.438244598 +0200 @@ -183,26 +183,32 @@ class ShenandoahSATBAndRemarkCodeRootsThreadsClosure : public ThreadClosure { private: ShenandoahSATBBufferClosure* _satb_cl; + OopClosure* const _cl; MarkingCodeBlobClosure* _code_cl; uintx _claim_token; public: - ShenandoahSATBAndRemarkCodeRootsThreadsClosure(ShenandoahSATBBufferClosure* satb_cl, MarkingCodeBlobClosure* code_cl) : - _satb_cl(satb_cl), _code_cl(code_cl), + ShenandoahSATBAndRemarkCodeRootsThreadsClosure(ShenandoahSATBBufferClosure* satb_cl, OopClosure* cl, MarkingCodeBlobClosure* code_cl) : + _satb_cl(satb_cl), _cl(cl), _code_cl(code_cl), _claim_token(Threads::thread_claim_token()) {} void do_thread(Thread* thread) { if (thread->claim_threads_do(true, _claim_token)) { ShenandoahThreadLocalData::satb_mark_queue(thread).apply_closure_and_empty(_satb_cl); - if (_code_cl != NULL && thread->is_Java_thread()) { - // In theory it should not be neccessary to explicitly walk the nmethods to find roots for concurrent marking - // however the liveness of oops reachable from nmethods have very complex lifecycles: - // * Alive if on the stack of an executing method - // * Weakly reachable otherwise - // Some objects reachable from nmethods, such as the class loader (or klass_holder) of the receiver should be - // live by the SATB invariant but other oops recorded in nmethods may behave differently. - JavaThread* jt = (JavaThread*)thread; - jt->nmethods_do(_code_cl); + if (thread->is_Java_thread()) { + if (_cl != NULL) { + ResourceMark rm; + thread->oops_do(_cl, _code_cl); + } else if (_code_cl != NULL) { + // In theory it should not be neccessary to explicitly walk the nmethods to find roots for concurrent marking + // however the liveness of oops reachable from nmethods have very complex lifecycles: + // * Alive if on the stack of an executing method + // * Weakly reachable otherwise + // Some objects reachable from nmethods, such as the class loader (or klass_holder) of the receiver should be + // live by the SATB invariant but other oops recorded in nmethods may behave differently. + JavaThread* jt = (JavaThread*)thread; + jt->nmethods_do(_code_cl); + } } } } @@ -242,21 +248,20 @@ ShenandoahSATBBufferClosure cl(q); SATBMarkQueueSet& satb_mq_set = ShenandoahBarrierSet::satb_mark_queue_set(); while (satb_mq_set.apply_closure_to_completed_buffer(&cl)); - - if (heap->unload_classes() && !ShenandoahConcurrentRoots::can_do_concurrent_class_unloading()) { - if (heap->has_forwarded_objects()) { - ShenandoahMarkResolveRefsClosure resolve_mark_cl(q, rp); - MarkingCodeBlobClosure blobsCl(&resolve_mark_cl, !CodeBlobToOopClosure::FixRelocations); - ShenandoahSATBAndRemarkCodeRootsThreadsClosure tc(&cl, &blobsCl); - Threads::threads_do(&tc); - } else { - ShenandoahMarkRefsClosure mark_cl(q, rp); - MarkingCodeBlobClosure blobsCl(&mark_cl, !CodeBlobToOopClosure::FixRelocations); - ShenandoahSATBAndRemarkCodeRootsThreadsClosure tc(&cl, &blobsCl); - Threads::threads_do(&tc); - } + bool do_nmethods = heap->unload_classes() && !ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(); + if (heap->has_forwarded_objects()) { + ShenandoahMarkResolveRefsClosure resolve_mark_cl(q, rp); + MarkingCodeBlobClosure blobsCl(&resolve_mark_cl, !CodeBlobToOopClosure::FixRelocations); + ShenandoahSATBAndRemarkCodeRootsThreadsClosure tc(&cl, + ShenandoahStoreValEnqueueBarrier ? &resolve_mark_cl : NULL, + do_nmethods ? &blobsCl : NULL); + Threads::threads_do(&tc); } else { - ShenandoahSATBAndRemarkCodeRootsThreadsClosure tc(&cl, NULL); + ShenandoahMarkRefsClosure mark_cl(q, rp); + MarkingCodeBlobClosure blobsCl(&mark_cl, !CodeBlobToOopClosure::FixRelocations); + ShenandoahSATBAndRemarkCodeRootsThreadsClosure tc(&cl, + ShenandoahStoreValEnqueueBarrier ? &mark_cl : NULL, + do_nmethods ? &blobsCl : NULL); Threads::threads_do(&tc); } }