1 /* 2 * Copyright (c) 2013, 2016, 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 #ifndef SHARE_VM_OOPS_METHODCOUNTERS_HPP 26 #define SHARE_VM_OOPS_METHODCOUNTERS_HPP 27 28 #include "oops/metadata.hpp" 29 #include "compiler/compilerOracle.hpp" 30 #include "interpreter/invocationCounter.hpp" 31 #include "runtime/arguments.hpp" 32 33 class MethodCounters: public MetaspaceObj { 34 friend class VMStructs; 35 friend class JVMCIVMStructs; 36 private: 37 Method* _method; // Back link to Method 38 #if defined(COMPILER2) || INCLUDE_JVMCI 39 int _interpreter_invocation_count; // Count of times invoked (reused as prev_event_count in tiered) 40 u2 _interpreter_throwout_count; // Count of times method was exited via exception while interpreting 41 #endif 42 #if INCLUDE_JVMTI 43 u2 _number_of_breakpoints; // fullspeed debugging support 44 #endif 45 InvocationCounter _invocation_counter; // Incremented before each activation of the method - used to trigger frequency-based optimizations 46 InvocationCounter _backedge_counter; // Incremented before each backedge taken - used to trigger frequencey-based optimizations 47 // NMethod age is a counter for warm methods detection in the code cache sweeper. 48 // The counter is reset by the sweeper and is decremented by some of the compiled 49 // code. The counter values are interpreted as follows: 50 // 1. (HotMethodDetection..INT_MAX] - initial value, no counters inserted 51 // 2. [1..HotMethodDetectionLimit) - the method is warm, the counter is used 52 // to figure out which methods can be flushed. 53 // 3. (INT_MIN..0] - method is hot and will deopt and get 54 // recompiled without the counters 55 int _nmethod_age; 56 int _interpreter_invocation_limit; // per-method InterpreterInvocationLimit 57 int _interpreter_backward_branch_limit; // per-method InterpreterBackwardBranchLimit 58 int _interpreter_profile_limit; // per-method InterpreterProfileLimit 59 int _invoke_mask; // per-method Tier0InvokeNotifyFreqLog 60 int _backedge_mask; // per-method Tier0BackedgeNotifyFreqLog 61 #ifdef TIERED 62 float _rate; // Events (invocation and backedge counter increments) per millisecond 63 jlong _prev_time; // Previous time the rate was acquired 64 u1 _highest_comp_level; // Highest compile level this method has ever seen. 65 u1 _highest_osr_comp_level; // Same for OSR level 66 #endif 67 68 MethodCounters(methodHandle mh) : _method(mh()), 69 _nmethod_age(INT_MAX) 70 #ifdef TIERED 71 , _rate(0), 72 _prev_time(0), 73 _highest_comp_level(0), 74 _highest_osr_comp_level(0) 75 #endif 76 { 77 set_interpreter_invocation_count(0); 78 set_interpreter_throwout_count(0); 79 JVMTI_ONLY(clear_number_of_breakpoints()); 80 invocation_counter()->init(); 81 backedge_counter()->init(); 82 83 if (StressCodeAging) { 84 set_nmethod_age(HotMethodDetectionLimit); 85 } 86 87 // Set per-method thresholds. 88 double scale = 1.0; 89 CompilerOracle::has_option_value(mh, "CompileThresholdScaling", scale); 90 91 int compile_threshold = Arguments::scaled_compile_threshold(CompileThreshold, scale); 92 _interpreter_invocation_limit = compile_threshold << InvocationCounter::count_shift; 93 if (ProfileInterpreter) { 94 // If interpreter profiling is enabled, the backward branch limit 95 // is compared against the method data counter rather than an invocation 96 // counter, therefore no shifting of bits is required. 97 _interpreter_backward_branch_limit = (compile_threshold * (OnStackReplacePercentage - InterpreterProfilePercentage)) / 100; 98 } else { 99 _interpreter_backward_branch_limit = ((compile_threshold * OnStackReplacePercentage) / 100) << InvocationCounter::count_shift; 100 } 101 _interpreter_profile_limit = ((compile_threshold * InterpreterProfilePercentage) / 100) << InvocationCounter::count_shift; 102 _invoke_mask = right_n_bits(Arguments::scaled_freq_log(Tier0InvokeNotifyFreqLog, scale)) << InvocationCounter::count_shift; 103 _backedge_mask = right_n_bits(Arguments::scaled_freq_log(Tier0BackedgeNotifyFreqLog, scale)) << InvocationCounter::count_shift; 104 } 105 106 public: 107 static MethodCounters* allocate(methodHandle mh, TRAPS); 108 109 void deallocate_contents(ClassLoaderData* loader_data) {} 110 DEBUG_ONLY(bool on_stack() { return false; }) // for template 111 112 Method* method() const { return _method; } 113 114 static int size() { return sizeof(MethodCounters) / wordSize; } 115 116 bool is_klass() const { return false; } 117 118 void clear_counters(); 119 120 #if defined(COMPILER2) || INCLUDE_JVMCI 121 122 int interpreter_invocation_count() { 123 return _interpreter_invocation_count; 124 } 125 void set_interpreter_invocation_count(int count) { 126 _interpreter_invocation_count = count; 127 } 128 int increment_interpreter_invocation_count() { 129 return ++_interpreter_invocation_count; 130 } 131 132 void interpreter_throwout_increment() { 133 if (_interpreter_throwout_count < 65534) { 134 _interpreter_throwout_count++; 135 } 136 } 137 int interpreter_throwout_count() const { 138 return _interpreter_throwout_count; 139 } 140 void set_interpreter_throwout_count(int count) { 141 _interpreter_throwout_count = count; 142 } 143 144 #else // defined(COMPILER2) || INCLUDE_JVMCI 145 146 int interpreter_invocation_count() { 147 return 0; 148 } 149 void set_interpreter_invocation_count(int count) { 150 assert(count == 0, "count must be 0"); 151 } 152 153 int interpreter_throwout_count() const { 154 return 0; 155 } 156 void set_interpreter_throwout_count(int count) { 157 assert(count == 0, "count must be 0"); 158 } 159 160 #endif // defined(COMPILER2) || INCLUDE_JVMCI 161 162 #if INCLUDE_JVMTI 163 u2 number_of_breakpoints() const { return _number_of_breakpoints; } 164 void incr_number_of_breakpoints() { ++_number_of_breakpoints; } 165 void decr_number_of_breakpoints() { --_number_of_breakpoints; } 166 void clear_number_of_breakpoints() { _number_of_breakpoints = 0; } 167 #endif 168 169 #ifdef TIERED 170 jlong prev_time() const { return _prev_time; } 171 void set_prev_time(jlong time) { _prev_time = time; } 172 float rate() const { return _rate; } 173 void set_rate(float rate) { _rate = rate; } 174 #endif 175 176 int highest_comp_level() const; 177 void set_highest_comp_level(int level); 178 int highest_osr_comp_level() const; 179 void set_highest_osr_comp_level(int level); 180 181 // invocation counter 182 InvocationCounter* invocation_counter() { return &_invocation_counter; } 183 InvocationCounter* backedge_counter() { return &_backedge_counter; } 184 185 int nmethod_age() { 186 return _nmethod_age; 187 } 188 void set_nmethod_age(int age) { 189 _nmethod_age = age; 190 } 191 void reset_nmethod_age() { 192 set_nmethod_age(HotMethodDetectionLimit); 193 } 194 195 static bool is_nmethod_hot(int age) { return age <= 0; } 196 static bool is_nmethod_warm(int age) { return age < HotMethodDetectionLimit; } 197 static bool is_nmethod_age_unset(int age) { return age > HotMethodDetectionLimit; } 198 199 static ByteSize nmethod_age_offset() { 200 return byte_offset_of(MethodCounters, _nmethod_age); 201 } 202 203 #if defined(COMPILER2) || INCLUDE_JVMCI 204 205 static ByteSize interpreter_invocation_counter_offset() { 206 return byte_offset_of(MethodCounters, _interpreter_invocation_count); 207 } 208 209 static int interpreter_invocation_counter_offset_in_bytes() { 210 return offset_of(MethodCounters, _interpreter_invocation_count); 211 } 212 213 #else // defined(COMPILER2) || INCLUDE_JVMCI 214 215 static ByteSize interpreter_invocation_counter_offset() { 216 ShouldNotReachHere(); 217 return in_ByteSize(0); 218 } 219 220 #endif // defined(COMPILER2) || INCLUDE_JVMCI 221 222 static ByteSize invocation_counter_offset() { 223 return byte_offset_of(MethodCounters, _invocation_counter); 224 } 225 226 static ByteSize backedge_counter_offset() { 227 return byte_offset_of(MethodCounters, _backedge_counter); 228 } 229 230 static ByteSize interpreter_invocation_limit_offset() { 231 return byte_offset_of(MethodCounters, _interpreter_invocation_limit); 232 } 233 234 static ByteSize interpreter_backward_branch_limit_offset() { 235 return byte_offset_of(MethodCounters, _interpreter_backward_branch_limit); 236 } 237 238 static ByteSize interpreter_profile_limit_offset() { 239 return byte_offset_of(MethodCounters, _interpreter_profile_limit); 240 } 241 242 static ByteSize invoke_mask_offset() { 243 return byte_offset_of(MethodCounters, _invoke_mask); 244 } 245 246 static ByteSize backedge_mask_offset() { 247 return byte_offset_of(MethodCounters, _backedge_mask); 248 } 249 }; 250 #endif //SHARE_VM_OOPS_METHODCOUNTERS_HPP