1 /*
  2  * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  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
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #include "cds/cdsConfig.hpp"
 26 #include "code/aotCodeCache.hpp"
 27 #include "compiler/compiler_globals.hpp"
 28 #include "compiler/compilerOracle.hpp"
 29 #include "memory/metaspaceClosure.hpp"
 30 #include "memory/resourceArea.hpp"
 31 #include "oops/method.hpp"
 32 #include "oops/methodCounters.hpp"
 33 #include "oops/trainingData.hpp"
 34 #include "runtime/handles.inline.hpp"
 35 
 36 MethodCounters::MethodCounters(const methodHandle& mh) :
 37   _method(mh()),
 38   _method_training_data(method_training_data_sentinel()),
 39   _prev_time(0),
 40   _rate(0),
 41   _highest_comp_level(0),
 42   _highest_osr_comp_level(0)
 43 {
 44 #if INCLUDE_CDS
 45   set_aot_code_invocation_count(0);
 46   set_aot_preload_code_entry(nullptr);
 47 #endif
 48   set_interpreter_throwout_count(0);
 49   JVMTI_ONLY(clear_number_of_breakpoints());
 50   invocation_counter()->init();
 51   backedge_counter()->init();
 52 
 53   // Set per-method thresholds.
 54   double scale = 1.0;
 55   CompilerOracle::has_option_value(mh, CompileCommandEnum::CompileThresholdScaling, scale);
 56 
 57   _invoke_mask = right_n_bits(CompilerConfig::scaled_freq_log(Tier0InvokeNotifyFreqLog, scale)) << InvocationCounter::count_shift;
 58   _backedge_mask = right_n_bits(CompilerConfig::scaled_freq_log(Tier0BackedgeNotifyFreqLog, scale)) << InvocationCounter::count_shift;
 59 }
 60 
 61 #if INCLUDE_CDS
 62 MethodCounters::MethodCounters() {
 63   // Used by cppVtables.cpp only
 64   assert(CDSConfig::is_dumping_static_archive() || UseSharedSpaces, "only for CDS");
 65 }
 66 #endif
 67 
 68 MethodCounters* MethodCounters::allocate_no_exception(const methodHandle& mh) {
 69   ClassLoaderData* loader_data = mh->method_holder()->class_loader_data();
 70   return new(loader_data, method_counters_size(), MetaspaceObj::MethodCountersType) MethodCounters(mh);
 71 }
 72 
 73 MethodCounters* MethodCounters::allocate_with_exception(const methodHandle& mh, TRAPS) {
 74   ClassLoaderData* loader_data = mh->method_holder()->class_loader_data();
 75   return new(loader_data, method_counters_size(), MetaspaceObj::MethodCountersType, THREAD) MethodCounters(mh);
 76 }
 77 
 78 void MethodCounters::clear_counters() {
 79   invocation_counter()->reset();
 80   backedge_counter()->reset();
 81 #if INCLUDE_CDS
 82   set_aot_code_invocation_count(0);
 83   if (aot_preload_code_entry() != nullptr) {
 84     AOTCodeCache::invalidate(aot_preload_code_entry());
 85     set_aot_preload_code_entry(nullptr);
 86   }
 87 #endif
 88   set_interpreter_throwout_count(0);
 89   set_prev_time(0);
 90   set_prev_event_count(0);
 91   set_rate(0);
 92   set_highest_comp_level(0);
 93   set_highest_osr_comp_level(0);
 94 }
 95 
 96 #if INCLUDE_CDS
 97 void MethodCounters::deallocate_contents(ClassLoaderData* loader_data) {
 98   if (aot_preload_code_entry() != nullptr) {
 99     AOTCodeCache::invalidate(aot_preload_code_entry());
100     set_aot_preload_code_entry(nullptr);
101   }
102 }
103 #endif
104 
105 void MethodCounters::metaspace_pointers_do(MetaspaceClosure* it) {
106   log_trace(aot, training)("Iter(MethodCounters): %p", this);
107   it->push(&_method);
108   it->push(&_method_training_data);
109 }
110 
111 #if INCLUDE_CDS
112 void MethodCounters::set_aot_preload_code_entry(AOTCodeEntry* entry) {
113   precond(entry == nullptr || entry->for_preload());
114   _aot_preload_code_entry = entry;
115 }
116 
117 void MethodCounters::remove_unshareable_info() {
118 }
119 void MethodCounters::restore_unshareable_info(TRAPS) {
120   _method_training_data = method_training_data_sentinel();
121 }
122 #endif // INCLUDE_CDS
123 
124 void MethodCounters::print_on(outputStream* st) const {
125   assert(is_methodCounters(), "should be method counters");
126   st->print("method counters");
127   print_data_on(st);
128 }
129 
130 void MethodCounters::print_data_on(outputStream* st) const {
131   ResourceMark rm;
132   st->print_cr("  - invocation_counter: %d carry=%d", _invocation_counter.count(), _invocation_counter.carry());
133   st->print_cr("  - backedge_counter: %d carry=%d",   _backedge_counter.count(), _backedge_counter.carry());
134   st->print_cr("  - prev_time: " JLONG_FORMAT,        _prev_time);
135   st->print_cr("  - rate: %.3f",             _rate);
136   st->print_cr("  - invoke_mask: %d",        _invoke_mask);
137   st->print_cr("  - backedge_mask: %d",      _backedge_mask);
138   st->print_cr("  - prev_event_count: %d",   _prev_event_count);
139 #if COMPILER2_OR_JVMCI
140   st->print_cr("  - interpreter_throwout_count: %u", _interpreter_throwout_count);
141 #endif
142 #if INCLUDE_JVMTI
143   st->print_cr("  - number_of_breakpoints: %u", _number_of_breakpoints);
144 #endif
145   st->print_cr("  - highest_comp_level: %u", _highest_comp_level);
146   st->print_cr("  - highest_osr_comp_level: %u", _highest_osr_comp_level);
147 }
148 
149 void MethodCounters::print_value_on(outputStream* st) const {
150   assert(is_methodCounters(), "must be methodCounters");
151   st->print("method counters");
152   print_address_on(st);
153 }
154 
155