9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #include "precompiled.hpp"
25 #include "code/codeCache.hpp"
26 #include "code/icBuffer.hpp"
27 #include "code/nmethod.hpp"
28 #include "gc/shenandoah/shenandoahCodeRoots.hpp"
29 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
30 #include "gc/shenandoah/shenandoahNMethod.inline.hpp"
31 #include "gc/shenandoah/shenandoahUtils.hpp"
32 #include "memory/resourceArea.hpp"
33 #include "memory/universe.hpp"
34 #include "runtime/atomic.hpp"
35
36 ShenandoahParallelCodeCacheIterator::ShenandoahParallelCodeCacheIterator(const GrowableArray<CodeHeap*>* heaps) {
37 _length = heaps->length();
38 _iters = NEW_C_HEAP_ARRAY(ShenandoahParallelCodeHeapIterator, _length, mtGC);
39 for (int h = 0; h < _length; h++) {
40 _iters[h] = ShenandoahParallelCodeHeapIterator(heaps->at(h));
41 }
42 }
43
44 ShenandoahParallelCodeCacheIterator::~ShenandoahParallelCodeCacheIterator() {
45 FREE_C_HEAP_ARRAY(ParallelCodeHeapIterator, _iters);
46 }
47
48 void ShenandoahParallelCodeCacheIterator::parallel_blobs_do(CodeBlobClosure* f) {
204 if (failed()) {
205 return;
206 }
207
208 ShenandoahNMethod* nm_data = ShenandoahNMethod::gc_data(nm);
209 assert(!nm_data->is_unregistered(), "Should not see unregistered entry");
210
211 if (!nm->is_alive()) {
212 return;
213 }
214
215 if (nm->is_unloading()) {
216 ShenandoahReentrantLocker locker(nm_data->lock());
217 unlink(nm);
218 return;
219 }
220
221 ShenandoahReentrantLocker locker(nm_data->lock());
222
223 // Heal oops and disarm
224 ShenandoahEvacOOMScope scope;
225 ShenandoahNMethod::heal_nmethod(nm);
226 ShenandoahNMethod::disarm_nmethod(nm);
227
228 // Clear compiled ICs and exception caches
229 if (!nm->unload_nmethod_caches(_unloading_occurred)) {
230 set_failed();
231 }
232 }
233
234 bool failed() const {
235 return Atomic::load(&_failed);
236 }
237 };
238
239 class ShenandoahUnlinkTask : public AbstractGangTask {
240 private:
241 ShenandoahNMethodUnlinkClosure _cl;
242 ICRefillVerifier* _verifier;
243 ShenandoahConcurrentNMethodIterator _iterator;
244
245 public:
246 ShenandoahUnlinkTask(bool unloading_occurred, ICRefillVerifier* verifier) :
247 AbstractGangTask("ShenandoahNMethodUnlinkTask"),
248 _cl(unloading_occurred),
249 _verifier(verifier),
250 _iterator(ShenandoahCodeRoots::table()) {
251 MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
252 _iterator.nmethods_do_begin();
253 }
254
255 ~ShenandoahUnlinkTask() {
256 MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
257 _iterator.nmethods_do_end();
258 }
259
260 virtual void work(uint worker_id) {
261 ICRefillVerifierMark mark(_verifier);
262 _iterator.nmethods_do(&_cl);
263 }
264
265 bool success() const {
266 return !_cl.failed();
267 }
268 };
269
270 void ShenandoahCodeRoots::unlink(WorkGang* workers, bool unloading_occurred) {
271 assert(ShenandoahConcurrentRoots::should_do_concurrent_class_unloading(),
272 "Only when running concurrent class unloading");
273
274 for (;;) {
275 ICRefillVerifier verifier;
276
277 {
278 ShenandoahUnlinkTask task(unloading_occurred, &verifier);
279 workers->run_task(&task);
280 if (task.success()) {
|
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #include "precompiled.hpp"
25 #include "code/codeCache.hpp"
26 #include "code/icBuffer.hpp"
27 #include "code/nmethod.hpp"
28 #include "gc/shenandoah/shenandoahCodeRoots.hpp"
29 #include "gc/shenandoah/shenandoahEvacOOMHandler.hpp"
30 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
31 #include "gc/shenandoah/shenandoahNMethod.inline.hpp"
32 #include "gc/shenandoah/shenandoahUtils.hpp"
33 #include "memory/resourceArea.hpp"
34 #include "memory/universe.hpp"
35 #include "runtime/atomic.hpp"
36
37 ShenandoahParallelCodeCacheIterator::ShenandoahParallelCodeCacheIterator(const GrowableArray<CodeHeap*>* heaps) {
38 _length = heaps->length();
39 _iters = NEW_C_HEAP_ARRAY(ShenandoahParallelCodeHeapIterator, _length, mtGC);
40 for (int h = 0; h < _length; h++) {
41 _iters[h] = ShenandoahParallelCodeHeapIterator(heaps->at(h));
42 }
43 }
44
45 ShenandoahParallelCodeCacheIterator::~ShenandoahParallelCodeCacheIterator() {
46 FREE_C_HEAP_ARRAY(ParallelCodeHeapIterator, _iters);
47 }
48
49 void ShenandoahParallelCodeCacheIterator::parallel_blobs_do(CodeBlobClosure* f) {
205 if (failed()) {
206 return;
207 }
208
209 ShenandoahNMethod* nm_data = ShenandoahNMethod::gc_data(nm);
210 assert(!nm_data->is_unregistered(), "Should not see unregistered entry");
211
212 if (!nm->is_alive()) {
213 return;
214 }
215
216 if (nm->is_unloading()) {
217 ShenandoahReentrantLocker locker(nm_data->lock());
218 unlink(nm);
219 return;
220 }
221
222 ShenandoahReentrantLocker locker(nm_data->lock());
223
224 // Heal oops and disarm
225 ShenandoahNMethod::heal_nmethod(nm);
226 ShenandoahNMethod::disarm_nmethod(nm);
227
228 // Clear compiled ICs and exception caches
229 if (!nm->unload_nmethod_caches(_unloading_occurred)) {
230 set_failed();
231 }
232 }
233
234 bool failed() const {
235 return Atomic::load(&_failed);
236 }
237 };
238
239 class ShenandoahUnlinkTask : public AbstractGangTask {
240 private:
241 ShenandoahNMethodUnlinkClosure _cl;
242 ICRefillVerifier* _verifier;
243 ShenandoahConcurrentNMethodIterator _iterator;
244
245 public:
246 ShenandoahUnlinkTask(bool unloading_occurred, ICRefillVerifier* verifier) :
247 AbstractGangTask("ShenandoahNMethodUnlinkTask"),
248 _cl(unloading_occurred),
249 _verifier(verifier),
250 _iterator(ShenandoahCodeRoots::table()) {
251 MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
252 _iterator.nmethods_do_begin();
253 }
254
255 ~ShenandoahUnlinkTask() {
256 MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
257 _iterator.nmethods_do_end();
258 }
259
260 virtual void work(uint worker_id) {
261 ShenandoahEvacOOMScope evac_scope;
262 ICRefillVerifierMark mark(_verifier);
263 _iterator.nmethods_do(&_cl);
264 }
265
266 bool success() const {
267 return !_cl.failed();
268 }
269 };
270
271 void ShenandoahCodeRoots::unlink(WorkGang* workers, bool unloading_occurred) {
272 assert(ShenandoahConcurrentRoots::should_do_concurrent_class_unloading(),
273 "Only when running concurrent class unloading");
274
275 for (;;) {
276 ICRefillVerifier verifier;
277
278 {
279 ShenandoahUnlinkTask task(unloading_occurred, &verifier);
280 workers->run_task(&task);
281 if (task.success()) {
|