|
35 | 35 | #include "gc/shenandoah/shenandoahUtils.hpp"
|
36 | 36 | #include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp"
|
37 | 37 | #include "memory/resourceArea.hpp"
|
| 38 | +#include "runtime/mutexLocker.hpp" |
38 | 39 | #include "runtime/safepoint.hpp"
|
39 | 40 |
|
40 | 41 | template <bool CONCURRENT>
|
@@ -81,43 +82,49 @@ ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::ShenandoahClassLoad
|
81 | 82 | if (!SINGLE_THREADED) {
|
82 | 83 | ClassLoaderDataGraph::clear_claimed_marks();
|
83 | 84 | }
|
84 |
| - if (CONCURRENT) { |
| 85 | + if (CONCURRENT && !SINGLE_THREADED) { |
85 | 86 | ClassLoaderDataGraph_lock->lock();
|
86 | 87 | }
|
| 88 | + |
| 89 | + // Non-concurrent mode only runs at safepoints by VM thread |
| 90 | + assert(CONCURRENT || SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); |
| 91 | + assert(CONCURRENT || Thread::current()->is_VM_thread(), "Can only be done by VM thread"); |
87 | 92 | }
|
88 | 93 |
|
89 | 94 | template <bool CONCURRENT, bool SINGLE_THREADED>
|
90 | 95 | ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::~ShenandoahClassLoaderDataRoots() {
|
91 |
| - if (CONCURRENT) { |
| 96 | + if (CONCURRENT && !SINGLE_THREADED) { |
92 | 97 | ClassLoaderDataGraph_lock->unlock();
|
93 | 98 | }
|
94 | 99 | }
|
95 | 100 |
|
| 101 | +template <bool CONCURRENT, bool SINGLE_THREADED> |
| 102 | +void ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::cld_do_impl(CldDo f, CLDClosure* clds, uint worker_id) { |
| 103 | + if (CONCURRENT) { |
| 104 | + if (_semaphore.try_acquire()) { |
| 105 | + ShenandoahWorkerTimingsTracker timer(_phase, ShenandoahPhaseTimings::CLDGRoots, worker_id); |
| 106 | + if (SINGLE_THREADED){ |
| 107 | + MutexLocker ml(ClassLoaderDataGraph_lock, Mutex::_no_safepoint_check_flag); |
| 108 | + f(clds); |
| 109 | + } else { |
| 110 | + f(clds); |
| 111 | + } |
| 112 | + _semaphore.claim_all(); |
| 113 | + } |
| 114 | + } else { |
| 115 | + f(clds); |
| 116 | + } |
| 117 | +} |
| 118 | + |
96 | 119 |
|
97 | 120 | template <bool CONCURRENT, bool SINGLE_THREADED>
|
98 | 121 | void ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::always_strong_cld_do(CLDClosure* clds, uint worker_id) {
|
99 |
| - if (SINGLE_THREADED) { |
100 |
| - assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); |
101 |
| - assert(Thread::current()->is_VM_thread(), "Single threaded CLDG iteration can only be done by VM thread"); |
102 |
| - ClassLoaderDataGraph::always_strong_cld_do(clds); |
103 |
| - } else if (_semaphore.try_acquire()) { |
104 |
| - ShenandoahWorkerTimingsTracker timer(_phase, ShenandoahPhaseTimings::CLDGRoots, worker_id); |
105 |
| - ClassLoaderDataGraph::always_strong_cld_do(clds); |
106 |
| - _semaphore.claim_all(); |
107 |
| - } |
| 122 | + cld_do_impl(&ClassLoaderDataGraph::always_strong_cld_do, clds, worker_id); |
108 | 123 | }
|
109 | 124 |
|
110 | 125 | template <bool CONCURRENT, bool SINGLE_THREADED>
|
111 | 126 | void ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::cld_do(CLDClosure* clds, uint worker_id) {
|
112 |
| - if (SINGLE_THREADED) { |
113 |
| - assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); |
114 |
| - assert(Thread::current()->is_VM_thread(), "Single threaded CLDG iteration can only be done by VM thread"); |
115 |
| - ClassLoaderDataGraph::cld_do(clds); |
116 |
| - } else if (_semaphore.try_acquire()) { |
117 |
| - ShenandoahWorkerTimingsTracker timer(_phase, ShenandoahPhaseTimings::CLDGRoots, worker_id); |
118 |
| - ClassLoaderDataGraph::cld_do(clds); |
119 |
| - _semaphore.claim_all(); |
120 |
| - } |
| 127 | + cld_do_impl(&ClassLoaderDataGraph::cld_do, clds, worker_id); |
121 | 128 | }
|
122 | 129 |
|
123 | 130 | class ShenandoahParallelOopsDoThreadClosure : public ThreadClosure {
|
|
0 commit comments