Mercurial > hg > truffle
comparison src/share/vm/runtime/sweeper.cpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | d2a62e0f25eb |
children | e522a00b91aa 0cfa93c2fcc4 |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
22 * | 22 * |
23 */ | 23 */ |
24 | 24 |
25 #include "precompiled.hpp" | 25 #include "precompiled.hpp" |
26 #include "code/codeCache.hpp" | 26 #include "code/codeCache.hpp" |
27 #include "code/compiledIC.hpp" | |
28 #include "code/icBuffer.hpp" | |
27 #include "code/nmethod.hpp" | 29 #include "code/nmethod.hpp" |
28 #include "compiler/compileBroker.hpp" | 30 #include "compiler/compileBroker.hpp" |
29 #include "memory/resourceArea.hpp" | 31 #include "memory/resourceArea.hpp" |
30 #include "oops/methodOop.hpp" | 32 #include "oops/method.hpp" |
31 #include "runtime/atomic.hpp" | 33 #include "runtime/atomic.hpp" |
32 #include "runtime/compilationPolicy.hpp" | 34 #include "runtime/compilationPolicy.hpp" |
33 #include "runtime/mutexLocker.hpp" | 35 #include "runtime/mutexLocker.hpp" |
34 #include "runtime/os.hpp" | 36 #include "runtime/os.hpp" |
35 #include "runtime/sweeper.hpp" | 37 #include "runtime/sweeper.hpp" |
322 private: | 324 private: |
323 CompilerThread* _thread; | 325 CompilerThread* _thread; |
324 public: | 326 public: |
325 NMethodMarker(nmethod* nm) { | 327 NMethodMarker(nmethod* nm) { |
326 _thread = CompilerThread::current(); | 328 _thread = CompilerThread::current(); |
329 if (!nm->is_zombie() && !nm->is_unloaded()) { | |
330 // Only expose live nmethods for scanning | |
327 _thread->set_scanned_nmethod(nm); | 331 _thread->set_scanned_nmethod(nm); |
332 } | |
328 } | 333 } |
329 ~NMethodMarker() { | 334 ~NMethodMarker() { |
330 _thread->set_scanned_nmethod(NULL); | 335 _thread->set_scanned_nmethod(NULL); |
331 } | 336 } |
332 }; | 337 }; |
333 | 338 |
339 void NMethodSweeper::release_nmethod(nmethod *nm) { | |
340 // Clean up any CompiledICHolders | |
341 { | |
342 ResourceMark rm; | |
343 MutexLocker ml_patch(CompiledIC_lock); | |
344 RelocIterator iter(nm); | |
345 while (iter.next()) { | |
346 if (iter.type() == relocInfo::virtual_call_type) { | |
347 CompiledIC::cleanup_call_site(iter.virtual_call_reloc()); | |
348 } | |
349 } | |
350 } | |
351 | |
352 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); | |
353 nm->flush(); | |
354 } | |
334 | 355 |
335 void NMethodSweeper::process_nmethod(nmethod *nm) { | 356 void NMethodSweeper::process_nmethod(nmethod *nm) { |
336 assert(!CodeCache_lock->owned_by_self(), "just checking"); | 357 assert(!CodeCache_lock->owned_by_self(), "just checking"); |
337 | 358 |
338 // Make sure this nmethod doesn't get unloaded during the scan, | 359 // Make sure this nmethod doesn't get unloaded during the scan, |
363 if (nm->is_marked_for_reclamation()) { | 384 if (nm->is_marked_for_reclamation()) { |
364 assert(!nm->is_locked_by_vm(), "must not flush locked nmethods"); | 385 assert(!nm->is_locked_by_vm(), "must not flush locked nmethods"); |
365 if (PrintMethodFlushing && Verbose) { | 386 if (PrintMethodFlushing && Verbose) { |
366 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm); | 387 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm); |
367 } | 388 } |
368 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); | 389 release_nmethod(nm); |
369 nm->flush(); | |
370 } else { | 390 } else { |
371 if (PrintMethodFlushing && Verbose) { | 391 if (PrintMethodFlushing && Verbose) { |
372 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), nm); | 392 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), nm); |
373 } | 393 } |
374 nm->mark_for_reclamation(); | 394 nm->mark_for_reclamation(); |
398 } else if (nm->is_unloaded()) { | 418 } else if (nm->is_unloaded()) { |
399 // Unloaded code, just make it a zombie | 419 // Unloaded code, just make it a zombie |
400 if (PrintMethodFlushing && Verbose) | 420 if (PrintMethodFlushing && Verbose) |
401 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), nm); | 421 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), nm); |
402 if (nm->is_osr_method()) { | 422 if (nm->is_osr_method()) { |
423 SWEEP(nm); | |
403 // No inline caches will ever point to osr methods, so we can just remove it | 424 // No inline caches will ever point to osr methods, so we can just remove it |
404 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); | 425 release_nmethod(nm); |
405 SWEEP(nm); | |
406 nm->flush(); | |
407 } else { | 426 } else { |
408 nm->make_zombie(); | 427 nm->make_zombie(); |
409 _rescan = true; | 428 _rescan = true; |
410 SWEEP(nm); | 429 SWEEP(nm); |
411 } | 430 } |
432 // they will call a vm op that comes here. This code attempts to speculatively | 451 // they will call a vm op that comes here. This code attempts to speculatively |
433 // unload the oldest half of the nmethods (based on the compile job id) by | 452 // unload the oldest half of the nmethods (based on the compile job id) by |
434 // saving the old code in a list in the CodeCache. Then | 453 // saving the old code in a list in the CodeCache. Then |
435 // execution resumes. If a method so marked is not called by the second sweeper | 454 // execution resumes. If a method so marked is not called by the second sweeper |
436 // stack traversal after the current one, the nmethod will be marked non-entrant and | 455 // stack traversal after the current one, the nmethod will be marked non-entrant and |
437 // got rid of by normal sweeping. If the method is called, the methodOop's | 456 // got rid of by normal sweeping. If the method is called, the Method*'s |
438 // _code field is restored and the methodOop/nmethod | 457 // _code field is restored and the Method*/nmethod |
439 // go back to their normal state. | 458 // go back to their normal state. |
440 void NMethodSweeper::handle_full_code_cache(bool is_full) { | 459 void NMethodSweeper::handle_full_code_cache(bool is_full) { |
441 // Only the first one to notice can advise us to start early cleaning | 460 // Only the first one to notice can advise us to start early cleaning |
442 if (!is_full){ | 461 if (!is_full){ |
443 jint old = Atomic::cmpxchg( 1, &_advise_to_sweep, 0 ); | 462 jint old = Atomic::cmpxchg( 1, &_advise_to_sweep, 0 ); |