1 /*
  2  * Copyright (c) 2013, 2024, 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 "precompiled.hpp"
 26 #include "cds/cdsConfig.hpp"
 27 #include "compiler/compiler_globals.hpp"
 28 #include "compiler/compilerOracle.hpp"
 29 #include "memory/metaspaceClosure.hpp"
 30 #include "oops/method.hpp"
 31 #include "oops/methodCounters.hpp"
 32 #include "oops/trainingData.hpp"
 33 #include "runtime/handles.inline.hpp"
 34 #include "memory/resourceArea.hpp"
 35 
 36 MethodCounters::MethodCounters(const methodHandle& mh) :
 37   _method(mh()),
 38   _method_training_data(nullptr),
 39   _prev_time(0),
 40   _rate(0),
 41   _highest_comp_level(0),
 42   _highest_osr_comp_level(0),
 43   _training_data_lookup_failed(false)
 44 {
 45   set_interpreter_throwout_count(0);
 46   JVMTI_ONLY(clear_number_of_breakpoints());
 47   invocation_counter()->init();
 48   backedge_counter()->init();
 49 
 50   // Set per-method thresholds.
 51   double scale = 1.0;
 52   CompilerOracle::has_option_value(mh, CompileCommandEnum::CompileThresholdScaling, scale);
 53 
 54   _invoke_mask = right_n_bits(CompilerConfig::scaled_freq_log(Tier0InvokeNotifyFreqLog, scale)) << InvocationCounter::count_shift;
 55   _backedge_mask = right_n_bits(CompilerConfig::scaled_freq_log(Tier0BackedgeNotifyFreqLog, scale)) << InvocationCounter::count_shift;
 56 }
 57 
 58 MethodCounters::MethodCounters() {
 59   assert(CDSConfig::is_dumping_static_archive() || UseSharedSpaces, "only for CDS");
 60 }
 61 
 62 MethodCounters* MethodCounters::allocate_no_exception(const methodHandle& mh) {
 63   ClassLoaderData* loader_data = mh->method_holder()->class_loader_data();
 64   return new(loader_data, method_counters_size(), MetaspaceObj::MethodCountersType) MethodCounters(mh);
 65 }
 66 
 67 MethodCounters* MethodCounters::allocate_with_exception(const methodHandle& mh, TRAPS) {
 68   ClassLoaderData* loader_data = mh->method_holder()->class_loader_data();
 69   return new(loader_data, method_counters_size(), MetaspaceObj::MethodCountersType, THREAD) MethodCounters(mh);
 70 }
 71 
 72 void MethodCounters::clear_counters() {
 73   invocation_counter()->reset();
 74   backedge_counter()->reset();
 75   set_interpreter_throwout_count(0);
 76   set_prev_time(0);
 77   set_prev_event_count(0);
 78   set_rate(0);
 79   set_highest_comp_level(0);
 80   set_highest_osr_comp_level(0);
 81 }
 82 
 83 void MethodCounters::metaspace_pointers_do(MetaspaceClosure* it) {
 84   log_trace(cds)("Iter(MethodCounters): %p", this);
 85   it->push(&_method);
 86   it->push(&_method_training_data);
 87 }
 88 
 89 #if INCLUDE_CDS
 90 void MethodCounters::remove_unshareable_info() {
 91   _method_training_data = nullptr;
 92   _training_data_lookup_failed = false;
 93 }
 94 
 95 void MethodCounters::restore_unshareable_info(TRAPS) {
 96 }
 97 #endif // INCLUDE_CDS
 98 
 99 void MethodCounters::print_on(outputStream* st) const {
100   assert(is_methodCounters(), "should be method counters");
101   st->print("method counters");
102   print_data_on(st);
103 }
104 
105 void MethodCounters::print_data_on(outputStream* st) const {
106   ResourceMark rm;
107   st->print_cr("  - invocation_counter: %d carry=%d", _invocation_counter.count(), _invocation_counter.carry());
108   st->print_cr("  - backedge_counter: %d carry=%d",   _backedge_counter.count(), _backedge_counter.carry());
109   st->print_cr("  - prev_time: " JLONG_FORMAT,        _prev_time);
110   st->print_cr("  - rate: %.3f",             _rate);
111   st->print_cr("  - invoke_mask: %d",        _invoke_mask);
112   st->print_cr("  - backedge_mask: %d",      _backedge_mask);
113   st->print_cr("  - prev_event_count: %d",   _prev_event_count);
114 #if COMPILER2_OR_JVMCI
115   st->print_cr("  - interpreter_throwout_count: %u", _interpreter_throwout_count);
116 #endif
117 #if INCLUDE_JVMTI
118   st->print_cr("  - number_of_breakpoints: %u", _number_of_breakpoints);
119 #endif
120   st->print_cr("  - highest_comp_level: %u", _highest_comp_level);
121   st->print_cr("  - highest_osr_comp_level: %u", _highest_osr_comp_level);
122 }
123 
124 void MethodCounters::print_value_on(outputStream* st) const {
125   assert(is_methodCounters(), "must be methodCounters");
126   st->print("method counters");
127   print_address_on(st);
128 }
129 
130