34 #include "gc/z/zOopClosures.hpp" |
34 #include "gc/z/zOopClosures.hpp" |
35 #include "gc/z/zStat.hpp" |
35 #include "gc/z/zStat.hpp" |
36 #include "gc/z/zUnload.hpp" |
36 #include "gc/z/zUnload.hpp" |
37 #include "oops/access.inline.hpp" |
37 #include "oops/access.inline.hpp" |
38 |
38 |
39 static const ZStatSubPhase ZSubPhaseConcurrentClassesUnload("Concurrent Classes Unload"); |
39 static const ZStatSubPhase ZSubPhaseConcurrentClassesUnlink("Concurrent Classes Unlink"); |
|
40 static const ZStatSubPhase ZSubPhaseConcurrentClassesPurge("Concurrent Classes Purge"); |
40 |
41 |
41 class ZIsUnloadingOopClosure : public OopClosure { |
42 class ZIsUnloadingOopClosure : public OopClosure { |
42 private: |
43 private: |
43 ZPhantomIsAliveObjectClosure _is_alive; |
44 ZPhantomIsAliveObjectClosure _is_alive; |
44 bool _is_unloading; |
45 bool _is_unloading; |
124 CodeCache::increment_unloading_cycle(); |
125 CodeCache::increment_unloading_cycle(); |
125 DependencyContext::cleaning_start(); |
126 DependencyContext::cleaning_start(); |
126 } |
127 } |
127 |
128 |
128 void ZUnload::unlink() { |
129 void ZUnload::unlink() { |
|
130 if (!ClassUnloading) { |
|
131 return; |
|
132 } |
|
133 |
|
134 ZStatTimer timer(ZSubPhaseConcurrentClassesUnlink); |
129 SuspendibleThreadSetJoiner sts; |
135 SuspendibleThreadSetJoiner sts; |
130 bool unloading_occurred; |
136 bool unloading_occurred; |
131 |
137 |
132 { |
138 { |
133 MutexLocker ml(ClassLoaderDataGraph_lock); |
139 MutexLocker ml(ClassLoaderDataGraph_lock); |
134 unloading_occurred = SystemDictionary::do_unloading(ZStatPhase::timer()); |
140 unloading_occurred = SystemDictionary::do_unloading(ZStatPhase::timer()); |
135 } |
141 } |
136 |
142 |
137 Klass::clean_weak_klass_links(unloading_occurred); |
143 Klass::clean_weak_klass_links(unloading_occurred); |
138 |
|
139 ZNMethod::unlink(_workers, unloading_occurred); |
144 ZNMethod::unlink(_workers, unloading_occurred); |
140 |
|
141 DependencyContext::cleaning_end(); |
145 DependencyContext::cleaning_end(); |
142 } |
146 } |
143 |
147 |
144 void ZUnload::purge() { |
148 void ZUnload::purge() { |
|
149 if (!ClassUnloading) { |
|
150 return; |
|
151 } |
|
152 |
|
153 ZStatTimer timer(ZSubPhaseConcurrentClassesPurge); |
|
154 |
145 { |
155 { |
146 SuspendibleThreadSetJoiner sts; |
156 SuspendibleThreadSetJoiner sts; |
147 ZNMethod::purge(_workers); |
157 ZNMethod::purge(_workers); |
148 } |
158 } |
149 |
159 |
150 ClassLoaderDataGraph::purge(); |
160 ClassLoaderDataGraph::purge(); |
151 CodeCache::purge_exception_caches(); |
161 CodeCache::purge_exception_caches(); |
152 } |
162 } |
153 |
163 |
154 class ZUnloadRendezvousClosure : public ThreadClosure { |
|
155 public: |
|
156 void do_thread(Thread* thread) {} |
|
157 }; |
|
158 |
|
159 void ZUnload::unload() { |
|
160 if (!ClassUnloading) { |
|
161 return; |
|
162 } |
|
163 |
|
164 ZStatTimer timer(ZSubPhaseConcurrentClassesUnload); |
|
165 |
|
166 // Unlink stale metadata and nmethods |
|
167 unlink(); |
|
168 |
|
169 // Make sure stale metadata and nmethods are no longer observable |
|
170 ZUnloadRendezvousClosure cl; |
|
171 Handshake::execute(&cl); |
|
172 |
|
173 // Purge stale metadata and nmethods that were unlinked |
|
174 purge(); |
|
175 } |
|
176 |
|
177 void ZUnload::finish() { |
164 void ZUnload::finish() { |
178 // Resize and verify metaspace |
165 // Resize and verify metaspace |
179 MetaspaceGC::compute_new_size(); |
166 MetaspaceGC::compute_new_size(); |
180 MetaspaceUtils::verify_metrics(); |
167 MetaspaceUtils::verify_metrics(); |
181 } |
168 } |