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