552 // Unloaded code, just make it a zombie 553 if (PrintMethodFlushing && Verbose) { 554 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), nm); 555 } 556 if (nm->is_osr_method()) { 557 SWEEP(nm); 558 // No inline caches will ever point to osr methods, so we can just remove it 559 freed_memory = nm->total_size(); 560 if (nm->is_compiled_by_c2()) { 561 _total_nof_c2_methods_reclaimed++; 562 } 563 release_nmethod(nm); 564 _flushed_count++; 565 } else { 566 // Code cache state change is tracked in make_zombie() 567 nm->make_zombie(); 568 _zombified_count++; 569 SWEEP(nm); 570 } 571 } else { 572 if (UseCodeCacheFlushing) { 573 if (!nm->is_locked_by_vm() && !nm->is_osr_method() && !nm->is_native_method()) { 574 // Do not make native methods and OSR-methods not-entrant 575 nm->dec_hotness_counter(); 576 // Get the initial value of the hotness counter. This value depends on the 577 // ReservedCodeCacheSize 578 int reset_val = hotness_counter_reset_val(); 579 int time_since_reset = reset_val - nm->hotness_counter(); 580 double threshold = -reset_val + (CodeCache::reverse_free_ratio() * NmethodSweepActivity); 581 // The less free space in the code cache we have - the bigger reverse_free_ratio() is. 582 // I.e., 'threshold' increases with lower available space in the code cache and a higher 583 // NmethodSweepActivity. If the current hotness counter - which decreases from its initial 584 // value until it is reset by stack walking - is smaller than the computed threshold, the 585 // corresponding nmethod is considered for removal. 586 if ((NmethodSweepActivity > 0) && (nm->hotness_counter() < threshold) && (time_since_reset > 10)) { 587 // A method is marked as not-entrant if the method is 588 // 1) 'old enough': nm->hotness_counter() < threshold 589 // 2) The method was in_use for a minimum amount of time: (time_since_reset > 10) 590 // The second condition is necessary if we are dealing with very small code cache 591 // sizes (e.g., <10m) and the code cache size is too small to hold all hot methods. 592 // The second condition ensures that methods are not immediately made not-entrant 593 // after compilation. 594 nm->make_not_entrant(); 595 // Code cache state change is tracked in make_not_entrant() 596 if (PrintMethodFlushing && Verbose) { 597 tty->print_cr("### Nmethod %d/" PTR_FORMAT "made not-entrant: hotness counter %d/%d threshold %f", 598 nm->compile_id(), nm, nm->hotness_counter(), reset_val, threshold); 599 } 600 } 601 } 602 } 603 // Clean-up all inline caches that point to zombie/non-reentrant methods 604 MutexLocker cl(CompiledIC_lock); 605 nm->cleanup_inline_caches(); 606 SWEEP(nm); 607 } 608 return freed_memory; 609 } 610 611 // Print out some state information about the current sweep and the 612 // state of the code cache if it's requested. 613 void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) { 614 if (PrintMethodFlushing) { 615 stringStream s; 616 // Dump code cache state into a buffer before locking the tty, 617 // because log_state() will use locks causing lock conflicts. 618 CodeCache::log_state(&s); 619 620 ttyLocker ttyl; 621 tty->print("### sweeper: %s ", msg); 622 if (format != NULL) { 623 va_list ap; 624 va_start(ap, format); 625 tty->vprint(format, ap); 626 va_end(ap); 627 } 628 tty->print_cr(s.as_string()); | 552 // Unloaded code, just make it a zombie 553 if (PrintMethodFlushing && Verbose) { 554 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), nm); 555 } 556 if (nm->is_osr_method()) { 557 SWEEP(nm); 558 // No inline caches will ever point to osr methods, so we can just remove it 559 freed_memory = nm->total_size(); 560 if (nm->is_compiled_by_c2()) { 561 _total_nof_c2_methods_reclaimed++; 562 } 563 release_nmethod(nm); 564 _flushed_count++; 565 } else { 566 // Code cache state change is tracked in make_zombie() 567 nm->make_zombie(); 568 _zombified_count++; 569 SWEEP(nm); 570 } 571 } else { 572 possibly_flush(nm); 573 // Clean-up all inline caches that point to zombie/non-reentrant methods 574 MutexLocker cl(CompiledIC_lock); 575 nm->cleanup_inline_caches(); 576 SWEEP(nm); 577 } 578 return freed_memory; 579 } 580 581 582 void NMethodSweeper::possibly_flush(nmethod* nm) { 583 if (UseCodeCacheFlushing) { 584 if (!nm->is_locked_by_vm() && !nm->is_osr_method() && !nm->is_native_method()) { 585 bool make_not_entrant = false; 586 587 // Do not make native methods and OSR-methods not-entrant 588 nm->dec_hotness_counter(); 589 // Get the initial value of the hotness counter. This value depends on the 590 // ReservedCodeCacheSize 591 int reset_val = hotness_counter_reset_val(); 592 int time_since_reset = reset_val - nm->hotness_counter(); 593 double threshold = -reset_val + (CodeCache::reverse_free_ratio() * NmethodSweepActivity); 594 // The less free space in the code cache we have - the bigger reverse_free_ratio() is. 595 // I.e., 'threshold' increases with lower available space in the code cache and a higher 596 // NmethodSweepActivity. If the current hotness counter - which decreases from its initial 597 // value until it is reset by stack walking - is smaller than the computed threshold, the 598 // corresponding nmethod is considered for removal. 599 if ((NmethodSweepActivity > 0) && (nm->hotness_counter() < threshold) && (time_since_reset > MinPassesBeforeFlush)) { 600 // A method is marked as not-entrant if the method is 601 // 1) 'old enough': nm->hotness_counter() < threshold 602 // 2) The method was in_use for a minimum amount of time: (time_since_reset > MinPassesBeforeFlush) 603 // The second condition is necessary if we are dealing with very small code cache 604 // sizes (e.g., <10m) and the code cache size is too small to hold all hot methods. 605 // The second condition ensures that methods are not immediately made not-entrant 606 // after compilation. 607 make_not_entrant = true; 608 } 609 610 // The stack-scanning low-cost detection didn't see the method used (which can happen for 611 // flat profiles). Check the age counter for possible data. 612 if (UseCodeAging && make_not_entrant && (nm->is_compiled_by_c2() || nm->is_compiled_by_c1())) { 613 MethodCounters* mc = nm->method()->method_counters(); 614 if (mc != NULL) { 615 // Snapshot the value as it's changed concurrently 616 int age = mc->nmethod_age(); 617 if (MethodCounters::is_nmethod_hot(age)) { 618 // The method has gone through flushing, and it became relatively hot that it deopted 619 // before we could take a look at it. 620 if (time_since_reset > MinPassesBeforeFlush * 2) { 621 // It's been long enough, we still haven't seen it on stack. 622 // Try to flush it, but enable counters the next time. 623 mc->reset_nmethod_age(); 624 } else { 625 make_not_entrant = false; 626 } 627 } else if (MethodCounters::is_nmethod_warm(age)) { 628 // Method has counters enabled, and the method was used within 629 // previous 10 sweeps. Reset the counter. Stay in the existing 630 // compiled state. 631 mc->reset_nmethod_age(); 632 // delay the next check 633 nm->set_hotness_counter(NMethodSweeper::hotness_counter_reset_val()); 634 make_not_entrant = false; 635 } else if (MethodCounters::is_nmethod_age_unset(age)) { 636 // No counters were used before. Set the counters to the detection 637 // limit value. If the method is going to be used again it will be compiled 638 // with counters that we're going to use for analysis the the next time. 639 mc->reset_nmethod_age(); 640 } else { 641 // Method was totally idle for 10 sweeps 642 // The counter already has the initial value, flush it and may be recompile 643 // later with counters 644 } 645 } 646 } 647 648 if (make_not_entrant) { 649 nm->make_not_entrant(); 650 651 // Code cache state change is tracked in make_not_entrant() 652 if (PrintMethodFlushing && Verbose) { 653 tty->print_cr("### Nmethod %d/" PTR_FORMAT "made not-entrant: hotness counter %d/%d threshold %f", 654 nm->compile_id(), nm, nm->hotness_counter(), reset_val, threshold); 655 } 656 } 657 } 658 } 659 } 660 661 // Print out some state information about the current sweep and the 662 // state of the code cache if it's requested. 663 void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) { 664 if (PrintMethodFlushing) { 665 stringStream s; 666 // Dump code cache state into a buffer before locking the tty, 667 // because log_state() will use locks causing lock conflicts. 668 CodeCache::log_state(&s); 669 670 ttyLocker ttyl; 671 tty->print("### sweeper: %s ", msg); 672 if (format != NULL) { 673 va_list ap; 674 va_start(ap, format); 675 tty->vprint(format, ap); 676 va_end(ap); 677 } 678 tty->print_cr(s.as_string()); |