19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 #include "precompiled.hpp"
25 #include "classfile/classLoaderDataGraph.hpp"
26 #include "classfile/systemDictionary.hpp"
27 #include "code/codeBehaviours.hpp"
28 #include "code/codeCache.hpp"
29 #include "code/dependencyContext.hpp"
30 #include "gc/shared/gcBehaviours.hpp"
31 #include "gc/shared/suspendibleThreadSet.hpp"
32 #include "gc/z/zLock.inline.hpp"
33 #include "gc/z/zNMethod.hpp"
34 #include "gc/z/zOopClosures.hpp"
35 #include "gc/z/zStat.hpp"
36 #include "gc/z/zUnload.hpp"
37 #include "oops/access.inline.hpp"
38
39 static const ZStatSubPhase ZSubPhaseConcurrentClassesUnload("Concurrent Classes Unload");
40
41 class ZIsUnloadingOopClosure : public OopClosure {
42 private:
43 ZPhantomIsAliveObjectClosure _is_alive;
44 bool _is_unloading;
45
46 public:
47 ZIsUnloadingOopClosure() :
48 _is_alive(),
49 _is_unloading(false) {}
50
51 virtual void do_oop(oop* p) {
52 const oop o = RawAccess<>::oop_load(p);
53 if (o != NULL && !_is_alive.do_object_b(o)) {
54 _is_unloading = true;
55 }
56 }
57
58 virtual void do_oop(narrowOop* p) {
59 ShouldNotReachHere();
109 return;
110 }
111
112 static ZIsUnloadingBehaviour is_unloading_behaviour;
113 IsUnloadingBehaviour::set_current(&is_unloading_behaviour);
114
115 static ZCompiledICProtectionBehaviour ic_protection_behaviour;
116 CompiledICProtectionBehaviour::set_current(&ic_protection_behaviour);
117 }
118
119 void ZUnload::prepare() {
120 if (!ClassUnloading) {
121 return;
122 }
123
124 CodeCache::increment_unloading_cycle();
125 DependencyContext::cleaning_start();
126 }
127
128 void ZUnload::unlink() {
129 SuspendibleThreadSetJoiner sts;
130 bool unloading_occurred;
131
132 {
133 MutexLocker ml(ClassLoaderDataGraph_lock);
134 unloading_occurred = SystemDictionary::do_unloading(ZStatPhase::timer());
135 }
136
137 Klass::clean_weak_klass_links(unloading_occurred);
138
139 ZNMethod::unlink(_workers, unloading_occurred);
140
141 DependencyContext::cleaning_end();
142 }
143
144 void ZUnload::purge() {
145 {
146 SuspendibleThreadSetJoiner sts;
147 ZNMethod::purge(_workers);
148 }
149
150 ClassLoaderDataGraph::purge();
151 CodeCache::purge_exception_caches();
152 }
153
154 class ZUnloadRendezvousClosure : public ThreadClosure {
155 public:
156 void do_thread(Thread* thread) {}
157 };
158
159 void ZUnload::unload() {
160 ZUnloadRendezvousClosure cl;
161 if (!ClassUnloading) {
162 // Even when we don't use class unloading, we want a handshake to
163 // close the resurrection block window.
164 Handshake::execute(&cl);
165 return;
166 }
167
168 ZStatTimer timer(ZSubPhaseConcurrentClassesUnload);
169
170 // Unlink stale metadata and nmethods
171 unlink();
172
173 // Make sure stale metadata and nmethods are no longer observable
174 Handshake::execute(&cl);
175
176 // Purge stale metadata and nmethods that were unlinked
177 purge();
178 }
179
180 void ZUnload::finish() {
181 // Resize and verify metaspace
182 MetaspaceGC::compute_new_size();
183 MetaspaceUtils::verify_metrics();
184 }
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 #include "precompiled.hpp"
25 #include "classfile/classLoaderDataGraph.hpp"
26 #include "classfile/systemDictionary.hpp"
27 #include "code/codeBehaviours.hpp"
28 #include "code/codeCache.hpp"
29 #include "code/dependencyContext.hpp"
30 #include "gc/shared/gcBehaviours.hpp"
31 #include "gc/shared/suspendibleThreadSet.hpp"
32 #include "gc/z/zLock.inline.hpp"
33 #include "gc/z/zNMethod.hpp"
34 #include "gc/z/zOopClosures.hpp"
35 #include "gc/z/zStat.hpp"
36 #include "gc/z/zUnload.hpp"
37 #include "oops/access.inline.hpp"
38
39 static const ZStatSubPhase ZSubPhaseConcurrentClassesUnlink("Concurrent Classes Unlink");
40 static const ZStatSubPhase ZSubPhaseConcurrentClassesPurge("Concurrent Classes Purge");
41
42 class ZIsUnloadingOopClosure : public OopClosure {
43 private:
44 ZPhantomIsAliveObjectClosure _is_alive;
45 bool _is_unloading;
46
47 public:
48 ZIsUnloadingOopClosure() :
49 _is_alive(),
50 _is_unloading(false) {}
51
52 virtual void do_oop(oop* p) {
53 const oop o = RawAccess<>::oop_load(p);
54 if (o != NULL && !_is_alive.do_object_b(o)) {
55 _is_unloading = true;
56 }
57 }
58
59 virtual void do_oop(narrowOop* p) {
60 ShouldNotReachHere();
110 return;
111 }
112
113 static ZIsUnloadingBehaviour is_unloading_behaviour;
114 IsUnloadingBehaviour::set_current(&is_unloading_behaviour);
115
116 static ZCompiledICProtectionBehaviour ic_protection_behaviour;
117 CompiledICProtectionBehaviour::set_current(&ic_protection_behaviour);
118 }
119
120 void ZUnload::prepare() {
121 if (!ClassUnloading) {
122 return;
123 }
124
125 CodeCache::increment_unloading_cycle();
126 DependencyContext::cleaning_start();
127 }
128
129 void ZUnload::unlink() {
130 if (!ClassUnloading) {
131 return;
132 }
133
134 ZStatTimer timer(ZSubPhaseConcurrentClassesUnlink);
135 SuspendibleThreadSetJoiner sts;
136 bool unloading_occurred;
137
138 {
139 MutexLocker ml(ClassLoaderDataGraph_lock);
140 unloading_occurred = SystemDictionary::do_unloading(ZStatPhase::timer());
141 }
142
143 Klass::clean_weak_klass_links(unloading_occurred);
144 ZNMethod::unlink(_workers, unloading_occurred);
145 DependencyContext::cleaning_end();
146 }
147
148 void ZUnload::purge() {
149 if (!ClassUnloading) {
150 return;
151 }
152
153 ZStatTimer timer(ZSubPhaseConcurrentClassesPurge);
154
155 {
156 SuspendibleThreadSetJoiner sts;
157 ZNMethod::purge(_workers);
158 }
159
160 ClassLoaderDataGraph::purge();
161 CodeCache::purge_exception_caches();
162 }
163
164 void ZUnload::finish() {
165 // Resize and verify metaspace
166 MetaspaceGC::compute_new_size();
167 MetaspaceUtils::verify_metrics();
168 }
|