421 _current.next(); |
421 _current.next(); |
422 |
422 |
423 // Now ready to process nmethod and give up CodeCache_lock |
423 // Now ready to process nmethod and give up CodeCache_lock |
424 { |
424 { |
425 MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
425 MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
|
426 // Save information before potentially flushing the nmethod |
426 int size = nm->total_size(); |
427 int size = nm->total_size(); |
427 bool is_c2_method = nm->is_compiled_by_c2(); |
428 bool is_c2_method = nm->is_compiled_by_c2(); |
|
429 bool is_osr = nm->is_osr_method(); |
|
430 int compile_id = nm->compile_id(); |
|
431 intptr_t address = p2i(nm); |
|
432 const char* state_before = nm->state(); |
|
433 const char* state_after = ""; |
428 |
434 |
429 MethodStateChange type = process_nmethod(nm); |
435 MethodStateChange type = process_nmethod(nm); |
430 switch (type) { |
436 switch (type) { |
431 case Flushed: |
437 case Flushed: |
|
438 state_after = "flushed"; |
432 freed_memory += size; |
439 freed_memory += size; |
433 ++flushed_count; |
440 ++flushed_count; |
434 if (is_c2_method) { |
441 if (is_c2_method) { |
435 ++flushed_c2_count; |
442 ++flushed_c2_count; |
436 } |
443 } |
437 break; |
444 break; |
438 case MarkedForReclamation: |
445 case MarkedForReclamation: |
|
446 state_after = "marked for reclamation"; |
439 ++marked_for_reclamation_count; |
447 ++marked_for_reclamation_count; |
440 break; |
448 break; |
441 case MadeZombie: |
449 case MadeZombie: |
|
450 state_after = "made zombie"; |
442 ++zombified_count; |
451 ++zombified_count; |
443 break; |
452 break; |
444 case None: |
453 case None: |
445 break; |
454 break; |
446 default: |
455 default: |
447 ShouldNotReachHere(); |
456 ShouldNotReachHere(); |
448 } |
457 } |
|
458 if (PrintMethodFlushing && Verbose && type != None) { |
|
459 tty->print_cr("### %s nmethod %3d/" PTR_FORMAT " (%s) %s", is_osr ? "osr" : "", compile_id, address, state_before, state_after); |
|
460 } |
449 } |
461 } |
|
462 |
450 _seen++; |
463 _seen++; |
451 handle_safepoint_request(); |
464 handle_safepoint_request(); |
452 } |
465 } |
453 } |
466 } |
454 |
467 |
587 // If it is the first time we see nmethod then we mark it. Otherwise, |
604 // If it is the first time we see nmethod then we mark it. Otherwise, |
588 // we reclaim it. When we have seen a zombie method twice, we know that |
605 // we reclaim it. When we have seen a zombie method twice, we know that |
589 // there are no inline caches that refer to it. |
606 // there are no inline caches that refer to it. |
590 if (nm->is_marked_for_reclamation()) { |
607 if (nm->is_marked_for_reclamation()) { |
591 assert(!nm->is_locked_by_vm(), "must not flush locked nmethods"); |
608 assert(!nm->is_locked_by_vm(), "must not flush locked nmethods"); |
592 if (PrintMethodFlushing && Verbose) { |
|
593 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), p2i(nm)); |
|
594 } |
|
595 release_nmethod(nm); |
609 release_nmethod(nm); |
596 assert(result == None, "sanity"); |
610 assert(result == None, "sanity"); |
597 result = Flushed; |
611 result = Flushed; |
598 } else { |
612 } else { |
599 if (PrintMethodFlushing && Verbose) { |
|
600 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), p2i(nm)); |
|
601 } |
|
602 nm->mark_for_reclamation(); |
613 nm->mark_for_reclamation(); |
603 // Keep track of code cache state change |
614 // Keep track of code cache state change |
604 _bytes_changed += nm->total_size(); |
615 _bytes_changed += nm->total_size(); |
605 SWEEP(nm); |
616 SWEEP(nm); |
606 assert(result == None, "sanity"); |
617 assert(result == None, "sanity"); |
607 result = MarkedForReclamation; |
618 result = MarkedForReclamation; |
|
619 assert(nm->is_marked_for_reclamation(), "nmethod must be marked for reclamation"); |
608 } |
620 } |
609 } else if (nm->is_not_entrant()) { |
621 } else if (nm->is_not_entrant()) { |
610 // If there are no current activations of this method on the |
622 // If there are no current activations of this method on the |
611 // stack we can safely convert it to a zombie method |
623 // stack we can safely convert it to a zombie method |
612 if (nm->can_convert_to_zombie()) { |
624 if (nm->can_convert_to_zombie()) { |
613 // Clear ICStubs to prevent back patching stubs of zombie or unloaded |
625 // Clear ICStubs to prevent back patching stubs of zombie or flushed |
614 // nmethods during the next safepoint (see ICStub::finalize). |
626 // nmethods during the next safepoint (see ICStub::finalize). |
615 { |
627 { |
616 MutexLocker cl(CompiledIC_lock); |
628 MutexLocker cl(CompiledIC_lock); |
617 nm->clear_ic_stubs(); |
629 nm->clear_ic_stubs(); |
618 } |
630 } |
619 if (PrintMethodFlushing && Verbose) { |
|
620 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (not entrant) being made zombie", nm->compile_id(), p2i(nm)); |
|
621 } |
|
622 // Code cache state change is tracked in make_zombie() |
631 // Code cache state change is tracked in make_zombie() |
623 nm->make_zombie(); |
632 nm->make_zombie(); |
624 SWEEP(nm); |
633 SWEEP(nm); |
625 assert(result == None, "sanity"); |
634 if (nm->is_osr_method()) { |
626 result = MadeZombie; |
635 // No inline caches will ever point to osr methods, so we can just remove it. |
627 assert(nm->is_zombie(), "nmethod must be zombie"); |
636 // Make sure that we unregistered the nmethod with the heap and flushed all |
|
637 // dependencies before removing the nmethod (done in make_zombie()). |
|
638 assert(nm->is_zombie(), "nmethod must be unregistered"); |
|
639 release_nmethod(nm); |
|
640 assert(result == None, "sanity"); |
|
641 result = Flushed; |
|
642 } else { |
|
643 assert(result == None, "sanity"); |
|
644 result = MadeZombie; |
|
645 assert(nm->is_zombie(), "nmethod must be zombie"); |
|
646 } |
628 } else { |
647 } else { |
629 // Still alive, clean up its inline caches |
648 // Still alive, clean up its inline caches |
630 MutexLocker cl(CompiledIC_lock); |
649 MutexLocker cl(CompiledIC_lock); |
631 nm->cleanup_inline_caches(); |
650 nm->cleanup_inline_caches(); |
632 SWEEP(nm); |
651 SWEEP(nm); |
633 } |
652 } |
634 } else if (nm->is_unloaded()) { |
653 } else if (nm->is_unloaded()) { |
635 // Unloaded code, just make it a zombie |
654 // Code is unloaded, so there are no activations on the stack. |
636 if (PrintMethodFlushing && Verbose) { |
655 // Convert the nmethod to zombie or flush it directly in the OSR case. |
637 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), p2i(nm)); |
656 { |
|
657 // Clean ICs of unloaded nmethods as well because they may reference other |
|
658 // unloaded nmethods that may be flushed earlier in the sweeper cycle. |
|
659 MutexLocker cl(CompiledIC_lock); |
|
660 nm->cleanup_inline_caches(); |
638 } |
661 } |
639 if (nm->is_osr_method()) { |
662 if (nm->is_osr_method()) { |
640 SWEEP(nm); |
663 SWEEP(nm); |
641 // No inline caches will ever point to osr methods, so we can just remove it |
664 // No inline caches will ever point to osr methods, so we can just remove it |
642 release_nmethod(nm); |
665 release_nmethod(nm); |
643 assert(result == None, "sanity"); |
666 assert(result == None, "sanity"); |
644 result = Flushed; |
667 result = Flushed; |
645 } else { |
668 } else { |
646 { |
|
647 // Clean ICs of unloaded nmethods as well because they may reference other |
|
648 // unloaded nmethods that may be flushed earlier in the sweeper cycle. |
|
649 MutexLocker cl(CompiledIC_lock); |
|
650 nm->cleanup_inline_caches(); |
|
651 } |
|
652 // Code cache state change is tracked in make_zombie() |
669 // Code cache state change is tracked in make_zombie() |
653 nm->make_zombie(); |
670 nm->make_zombie(); |
654 SWEEP(nm); |
671 SWEEP(nm); |
655 assert(result == None, "sanity"); |
672 assert(result == None, "sanity"); |
656 result = MadeZombie; |
673 result = MadeZombie; |
657 } |
674 } |
658 } else { |
675 } else { |
659 possibly_flush(nm); |
676 possibly_flush(nm); |
660 // Clean-up all inline caches that point to zombie/non-reentrant methods |
677 // Clean inline caches that point to zombie/non-entrant/unloaded nmethods |
661 MutexLocker cl(CompiledIC_lock); |
678 MutexLocker cl(CompiledIC_lock); |
662 nm->cleanup_inline_caches(); |
679 nm->cleanup_inline_caches(); |
663 SWEEP(nm); |
680 SWEEP(nm); |
664 } |
681 } |
665 return result; |
682 return result; |
666 } |
683 } |
667 |
684 |
668 |
685 |
669 void NMethodSweeper::possibly_flush(nmethod* nm) { |
686 void NMethodSweeper::possibly_flush(nmethod* nm) { |
670 if (UseCodeCacheFlushing) { |
687 if (UseCodeCacheFlushing) { |
671 if (!nm->is_locked_by_vm() && !nm->is_osr_method() && !nm->is_native_method()) { |
688 if (!nm->is_locked_by_vm() && !nm->is_native_method()) { |
672 bool make_not_entrant = false; |
689 bool make_not_entrant = false; |
673 |
690 |
674 // Do not make native methods and OSR-methods not-entrant |
691 // Do not make native methods not-entrant |
675 nm->dec_hotness_counter(); |
692 nm->dec_hotness_counter(); |
676 // Get the initial value of the hotness counter. This value depends on the |
693 // Get the initial value of the hotness counter. This value depends on the |
677 // ReservedCodeCacheSize |
694 // ReservedCodeCacheSize |
678 int reset_val = hotness_counter_reset_val(); |
695 int reset_val = hotness_counter_reset_val(); |
679 int time_since_reset = reset_val - nm->hotness_counter(); |
696 int time_since_reset = reset_val - nm->hotness_counter(); |