599 double threshold = -reset_val + (CodeCache::reverse_free_ratio(code_blob_type) * NmethodSweepActivity);
600 // The less free space in the code cache we have - the bigger reverse_free_ratio() is.
601 // I.e., 'threshold' increases with lower available space in the code cache and a higher
602 // NmethodSweepActivity. If the current hotness counter - which decreases from its initial
603 // value until it is reset by stack walking - is smaller than the computed threshold, the
604 // corresponding nmethod is considered for removal.
605 if ((NmethodSweepActivity > 0) && (nm->hotness_counter() < threshold) && (time_since_reset > MinPassesBeforeFlush)) {
606 // A method is marked as not-entrant if the method is
607 // 1) 'old enough': nm->hotness_counter() < threshold
608 // 2) The method was in_use for a minimum amount of time: (time_since_reset > MinPassesBeforeFlush)
609 // The second condition is necessary if we are dealing with very small code cache
610 // sizes (e.g., <10m) and the code cache size is too small to hold all hot methods.
611 // The second condition ensures that methods are not immediately made not-entrant
612 // after compilation.
613 make_not_entrant = true;
614 }
615
616 // The stack-scanning low-cost detection may not see the method was used (which can happen for
617 // flat profiles). Check the age counter for possible data.
618 if (UseCodeAging && make_not_entrant && (nm->is_compiled_by_c2() || nm->is_compiled_by_c1())) {
619 MethodCounters* mc = nm->method()->method_counters();
620 if (mc == NULL) {
621 // Sometimes we can get here without MethodCounters. For example if we run with -Xcomp.
622 // Try to allocate them.
623 mc = nm->method()->get_method_counters(Thread::current());
624 }
625 if (mc != NULL) {
626 // Snapshot the value as it's changed concurrently
627 int age = mc->nmethod_age();
628 if (MethodCounters::is_nmethod_hot(age)) {
629 // The method has gone through flushing, and it became relatively hot that it deopted
630 // before we could take a look at it. Give it more time to appear in the stack traces,
631 // proportional to the number of deopts.
632 MethodData* md = nm->method()->method_data();
633 if (md != NULL && time_since_reset > (int)(MinPassesBeforeFlush * (md->tenure_traps() + 1))) {
634 // It's been long enough, we still haven't seen it on stack.
635 // Try to flush it, but enable counters the next time.
636 mc->reset_nmethod_age();
637 } else {
638 make_not_entrant = false;
639 }
640 } else if (MethodCounters::is_nmethod_warm(age)) {
641 // Method has counters enabled, and the method was used within
642 // previous MinPassesBeforeFlush sweeps. Reset the counter. Stay in the existing
643 // compiled state.
644 mc->reset_nmethod_age();
|
599 double threshold = -reset_val + (CodeCache::reverse_free_ratio(code_blob_type) * NmethodSweepActivity);
600 // The less free space in the code cache we have - the bigger reverse_free_ratio() is.
601 // I.e., 'threshold' increases with lower available space in the code cache and a higher
602 // NmethodSweepActivity. If the current hotness counter - which decreases from its initial
603 // value until it is reset by stack walking - is smaller than the computed threshold, the
604 // corresponding nmethod is considered for removal.
605 if ((NmethodSweepActivity > 0) && (nm->hotness_counter() < threshold) && (time_since_reset > MinPassesBeforeFlush)) {
606 // A method is marked as not-entrant if the method is
607 // 1) 'old enough': nm->hotness_counter() < threshold
608 // 2) The method was in_use for a minimum amount of time: (time_since_reset > MinPassesBeforeFlush)
609 // The second condition is necessary if we are dealing with very small code cache
610 // sizes (e.g., <10m) and the code cache size is too small to hold all hot methods.
611 // The second condition ensures that methods are not immediately made not-entrant
612 // after compilation.
613 make_not_entrant = true;
614 }
615
616 // The stack-scanning low-cost detection may not see the method was used (which can happen for
617 // flat profiles). Check the age counter for possible data.
618 if (UseCodeAging && make_not_entrant && (nm->is_compiled_by_c2() || nm->is_compiled_by_c1())) {
619 MethodCounters* mc = nm->method()->get_method_counters(Thread::current());
620 if (mc != NULL) {
621 // Snapshot the value as it's changed concurrently
622 int age = mc->nmethod_age();
623 if (MethodCounters::is_nmethod_hot(age)) {
624 // The method has gone through flushing, and it became relatively hot that it deopted
625 // before we could take a look at it. Give it more time to appear in the stack traces,
626 // proportional to the number of deopts.
627 MethodData* md = nm->method()->method_data();
628 if (md != NULL && time_since_reset > (int)(MinPassesBeforeFlush * (md->tenure_traps() + 1))) {
629 // It's been long enough, we still haven't seen it on stack.
630 // Try to flush it, but enable counters the next time.
631 mc->reset_nmethod_age();
632 } else {
633 make_not_entrant = false;
634 }
635 } else if (MethodCounters::is_nmethod_warm(age)) {
636 // Method has counters enabled, and the method was used within
637 // previous MinPassesBeforeFlush sweeps. Reset the counter. Stay in the existing
638 // compiled state.
639 mc->reset_nmethod_age();
|