62 if (!CompressedOops::is_null(o) &&
63 _marking_context->is_complete() &&
64 !_marking_context->is_marked(o)) {
65 _is_unloading = true;
66 }
67 }
68
69 virtual void do_oop(narrowOop* p) {
70 ShouldNotReachHere();
71 }
72
73 bool is_unloading() const {
74 return _is_unloading;
75 }
76 };
77
78 class ShenandoahIsUnloadingBehaviour : public IsUnloadingBehaviour {
79 public:
80 virtual bool is_unloading(CompiledMethod* method) const {
81 nmethod* const nm = method->as_nmethod();
82 guarantee(ShenandoahHeap::heap()->is_evacuation_in_progress(), "Only this phase");
83 ShenandoahNMethod* data = ShenandoahNMethod::gc_data(nm);
84 ShenandoahReentrantLocker locker(data->lock());
85 ShenandoahIsUnloadingOopClosure cl;
86 data->oops_do(&cl);
87 return cl.is_unloading();
88 }
89 };
90
91 class ShenandoahCompiledICProtectionBehaviour : public CompiledICProtectionBehaviour {
92 public:
93 virtual bool lock(CompiledMethod* method) {
94 nmethod* const nm = method->as_nmethod();
95 ShenandoahReentrantLock* const lock = ShenandoahNMethod::lock_for_nmethod(nm);
96 assert(lock != NULL, "Not yet registered?");
97 lock->lock();
98 return true;
99 }
100
101 virtual void unlock(CompiledMethod* method) {
102 nmethod* const nm = method->as_nmethod();
149 }
150
151 void ShenandoahUnload::purge() {
152 {
153 SuspendibleThreadSetJoiner sts;
154 ShenandoahCodeRoots::purge(ShenandoahHeap::heap()->workers());
155 }
156
157 ClassLoaderDataGraph::purge();
158 CodeCache::purge_exception_caches();
159 }
160
161 class ShenandoahUnloadRendezvousClosure : public HandshakeClosure {
162 public:
163 ShenandoahUnloadRendezvousClosure() : HandshakeClosure("ShenandoahUnloadRendezvous") {}
164 void do_thread(Thread* thread) {}
165 };
166
167 void ShenandoahUnload::unload() {
168 assert(ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(), "Why we here?");
169 if (!ShenandoahHeap::heap()->is_evacuation_in_progress()) {
170 return;
171 }
172
173 // Unlink stale metadata and nmethods
174 unlink();
175
176 // Make sure stale metadata and nmethods are no longer observable
177 ShenandoahUnloadRendezvousClosure cl;
178 Handshake::execute(&cl);
179
180 // Purge stale metadata and nmethods that were unlinked
181 purge();
182 }
183
184 void ShenandoahUnload::finish() {
185 MetaspaceGC::compute_new_size();
186 MetaspaceUtils::verify_metrics();
187 }
|
62 if (!CompressedOops::is_null(o) &&
63 _marking_context->is_complete() &&
64 !_marking_context->is_marked(o)) {
65 _is_unloading = true;
66 }
67 }
68
69 virtual void do_oop(narrowOop* p) {
70 ShouldNotReachHere();
71 }
72
73 bool is_unloading() const {
74 return _is_unloading;
75 }
76 };
77
78 class ShenandoahIsUnloadingBehaviour : public IsUnloadingBehaviour {
79 public:
80 virtual bool is_unloading(CompiledMethod* method) const {
81 nmethod* const nm = method->as_nmethod();
82 guarantee(ShenandoahHeap::heap()->is_concurrent_root_in_progress(), "Only this phase");
83 ShenandoahNMethod* data = ShenandoahNMethod::gc_data(nm);
84 ShenandoahReentrantLocker locker(data->lock());
85 ShenandoahIsUnloadingOopClosure cl;
86 data->oops_do(&cl);
87 return cl.is_unloading();
88 }
89 };
90
91 class ShenandoahCompiledICProtectionBehaviour : public CompiledICProtectionBehaviour {
92 public:
93 virtual bool lock(CompiledMethod* method) {
94 nmethod* const nm = method->as_nmethod();
95 ShenandoahReentrantLock* const lock = ShenandoahNMethod::lock_for_nmethod(nm);
96 assert(lock != NULL, "Not yet registered?");
97 lock->lock();
98 return true;
99 }
100
101 virtual void unlock(CompiledMethod* method) {
102 nmethod* const nm = method->as_nmethod();
149 }
150
151 void ShenandoahUnload::purge() {
152 {
153 SuspendibleThreadSetJoiner sts;
154 ShenandoahCodeRoots::purge(ShenandoahHeap::heap()->workers());
155 }
156
157 ClassLoaderDataGraph::purge();
158 CodeCache::purge_exception_caches();
159 }
160
161 class ShenandoahUnloadRendezvousClosure : public HandshakeClosure {
162 public:
163 ShenandoahUnloadRendezvousClosure() : HandshakeClosure("ShenandoahUnloadRendezvous") {}
164 void do_thread(Thread* thread) {}
165 };
166
167 void ShenandoahUnload::unload() {
168 assert(ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(), "Why we here?");
169 if (!ShenandoahHeap::heap()->is_concurrent_root_in_progress()) {
170 return;
171 }
172
173 // Unlink stale metadata and nmethods
174 unlink();
175
176 // Make sure stale metadata and nmethods are no longer observable
177 ShenandoahUnloadRendezvousClosure cl;
178 Handshake::execute(&cl);
179
180 // Purge stale metadata and nmethods that were unlinked
181 purge();
182 }
183
184 void ShenandoahUnload::finish() {
185 MetaspaceGC::compute_new_size();
186 MetaspaceUtils::verify_metrics();
187 }
|