20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26
27 #include "classfile/classLoaderDataGraph.hpp"
28 #include "classfile/systemDictionary.hpp"
29 #include "code/codeBehaviours.hpp"
30 #include "code/codeCache.hpp"
31 #include "code/dependencyContext.hpp"
32 #include "gc/shared/gcBehaviours.hpp"
33 #include "gc/shared/suspendibleThreadSet.hpp"
34 #include "gc/shenandoah/shenandoahClosures.inline.hpp"
35 #include "gc/shenandoah/shenandoahCodeRoots.hpp"
36 #include "gc/shenandoah/shenandoahConcurrentRoots.hpp"
37 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
38 #include "gc/shenandoah/shenandoahNMethod.inline.hpp"
39 #include "gc/shenandoah/shenandoahLock.hpp"
40 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
41 #include "gc/shenandoah/shenandoahUnload.hpp"
42 #include "gc/shenandoah/shenandoahVerifier.hpp"
43 #include "memory/iterator.hpp"
44 #include "memory/resourceArea.hpp"
45 #include "oops/access.inline.hpp"
46
47 class ShenandoahIsUnloadingOopClosure : public OopClosure {
48 private:
49 ShenandoahMarkingContext* const _marking_context;
50 bool _is_unloading;
51
52 public:
53 ShenandoahIsUnloadingOopClosure() :
54 _marking_context(ShenandoahHeap::heap()->complete_marking_context()),
55 _is_unloading(false) {
56 }
57
58 virtual void do_oop(oop* p) {
59 if (_is_unloading) {
118 }
119 };
120
121 ShenandoahUnload::ShenandoahUnload() {
122 if (ShenandoahConcurrentRoots::can_do_concurrent_class_unloading()) {
123 static ShenandoahIsUnloadingBehaviour is_unloading_behaviour;
124 IsUnloadingBehaviour::set_current(&is_unloading_behaviour);
125
126 static ShenandoahCompiledICProtectionBehaviour ic_protection_behaviour;
127 CompiledICProtectionBehaviour::set_current(&ic_protection_behaviour);
128 }
129 }
130
131 void ShenandoahUnload::prepare() {
132 assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
133 assert(ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(), "Sanity");
134 CodeCache::increment_unloading_cycle();
135 DependencyContext::cleaning_start();
136 }
137
138 void ShenandoahUnload::unlink() {
139 SuspendibleThreadSetJoiner sts;
140 bool unloading_occurred;
141 ShenandoahHeap* const heap = ShenandoahHeap::heap();
142 {
143 MutexLocker cldg_ml(ClassLoaderDataGraph_lock);
144 unloading_occurred = SystemDictionary::do_unloading(heap->gc_timer());
145 }
146
147 Klass::clean_weak_klass_links(unloading_occurred);
148 ShenandoahCodeRoots::unlink(ShenandoahHeap::heap()->workers(), unloading_occurred);
149 DependencyContext::cleaning_end();
150 }
151
152 void ShenandoahUnload::purge() {
153 {
154 SuspendibleThreadSetJoiner sts;
155 ShenandoahCodeRoots::purge(ShenandoahHeap::heap()->workers());
156 }
157
158 ClassLoaderDataGraph::purge();
159 CodeCache::purge_exception_caches();
160 }
161
162 class ShenandoahUnloadRendezvousClosure : public HandshakeClosure {
163 public:
164 ShenandoahUnloadRendezvousClosure() : HandshakeClosure("ShenandoahUnloadRendezvous") {}
165 void do_thread(Thread* thread) {}
166 };
167
168 void ShenandoahUnload::unload() {
169 assert(ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(), "Why we here?");
170 if (!ShenandoahHeap::heap()->is_concurrent_weak_root_in_progress()) {
171 return;
172 }
173
174 // Unlink stale metadata and nmethods
175 unlink();
176
177 // Make sure stale metadata and nmethods are no longer observable
178 ShenandoahUnloadRendezvousClosure cl;
179 Handshake::execute(&cl);
180
181 // Purge stale metadata and nmethods that were unlinked
182 purge();
183 }
184
185 void ShenandoahUnload::finish() {
186 MetaspaceGC::compute_new_size();
187 MetaspaceUtils::verify_metrics();
188 }
|
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26
27 #include "classfile/classLoaderDataGraph.hpp"
28 #include "classfile/systemDictionary.hpp"
29 #include "code/codeBehaviours.hpp"
30 #include "code/codeCache.hpp"
31 #include "code/dependencyContext.hpp"
32 #include "gc/shared/gcBehaviours.hpp"
33 #include "gc/shared/suspendibleThreadSet.hpp"
34 #include "gc/shenandoah/shenandoahClosures.inline.hpp"
35 #include "gc/shenandoah/shenandoahCodeRoots.hpp"
36 #include "gc/shenandoah/shenandoahConcurrentRoots.hpp"
37 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
38 #include "gc/shenandoah/shenandoahNMethod.inline.hpp"
39 #include "gc/shenandoah/shenandoahLock.hpp"
40 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
41 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
42 #include "gc/shenandoah/shenandoahUnload.hpp"
43 #include "gc/shenandoah/shenandoahVerifier.hpp"
44 #include "memory/iterator.hpp"
45 #include "memory/resourceArea.hpp"
46 #include "oops/access.inline.hpp"
47
48 class ShenandoahIsUnloadingOopClosure : public OopClosure {
49 private:
50 ShenandoahMarkingContext* const _marking_context;
51 bool _is_unloading;
52
53 public:
54 ShenandoahIsUnloadingOopClosure() :
55 _marking_context(ShenandoahHeap::heap()->complete_marking_context()),
56 _is_unloading(false) {
57 }
58
59 virtual void do_oop(oop* p) {
60 if (_is_unloading) {
119 }
120 };
121
122 ShenandoahUnload::ShenandoahUnload() {
123 if (ShenandoahConcurrentRoots::can_do_concurrent_class_unloading()) {
124 static ShenandoahIsUnloadingBehaviour is_unloading_behaviour;
125 IsUnloadingBehaviour::set_current(&is_unloading_behaviour);
126
127 static ShenandoahCompiledICProtectionBehaviour ic_protection_behaviour;
128 CompiledICProtectionBehaviour::set_current(&ic_protection_behaviour);
129 }
130 }
131
132 void ShenandoahUnload::prepare() {
133 assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
134 assert(ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(), "Sanity");
135 CodeCache::increment_unloading_cycle();
136 DependencyContext::cleaning_start();
137 }
138
139 class ShenandoahUnloadRendezvousClosure : public HandshakeClosure {
140 public:
141 ShenandoahUnloadRendezvousClosure() : HandshakeClosure("ShenandoahUnloadRendezvous") {}
142 void do_thread(Thread* thread) {}
143 };
144
145 void ShenandoahUnload::unload() {
146 assert(ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(), "Why we here?");
147
148 ShenandoahHeap* heap = ShenandoahHeap::heap();
149
150 if (!heap->is_concurrent_weak_root_in_progress()) {
151 return;
152 }
153
154 // Unlink stale metadata and nmethods
155 {
156 ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_class_unload_unlink);
157
158 SuspendibleThreadSetJoiner sts;
159 bool unloadingOccurred;
160 {
161 ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_class_unload_unlink_sd);
162 MutexLocker cldgMl(ClassLoaderDataGraph_lock);
163 unloadingOccurred = SystemDictionary::do_unloading(heap->gc_timer());
164 }
165
166 {
167 ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_class_unload_unlink_weak_klass);
168 Klass::clean_weak_klass_links(unloadingOccurred);
169 }
170
171 {
172 ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_class_unload_unlink_code_roots);
173 ShenandoahCodeRoots::unlink(heap->workers(), unloadingOccurred);
174 }
175
176 DependencyContext::cleaning_end();
177 }
178
179 // Make sure stale metadata and nmethods are no longer observable
180 {
181 ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_class_unload_rendezvous);
182 ShenandoahUnloadRendezvousClosure cl;
183 Handshake::execute(&cl);
184 }
185
186 // Purge stale metadata and nmethods that were unlinked
187 {
188 ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_class_unload_purge);
189
190 {
191 ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_class_unload_purge_coderoots);
192 SuspendibleThreadSetJoiner sts;
193 ShenandoahCodeRoots::purge(heap->workers());
194 }
195
196 {
197 ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_class_unload_purge_cldg);
198 ClassLoaderDataGraph::purge();
199 }
200
201 {
202 ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_class_unload_purge_ec);
203 CodeCache::purge_exception_caches();
204 }
205 }
206 }
207
208 void ShenandoahUnload::finish() {
209 MetaspaceGC::compute_new_size();
210 MetaspaceUtils::verify_metrics();
211 }
|