1.1 --- a/src/share/vm/oops/method.hpp Thu Apr 04 21:15:43 2013 -0700 1.2 +++ b/src/share/vm/oops/method.hpp Tue Apr 09 17:17:41 2013 -0400 1.3 @@ -31,6 +31,7 @@ 1.4 #include "interpreter/invocationCounter.hpp" 1.5 #include "oops/annotations.hpp" 1.6 #include "oops/constantPool.hpp" 1.7 +#include "oops/methodCounters.hpp" 1.8 #include "oops/instanceKlass.hpp" 1.9 #include "oops/oop.hpp" 1.10 #include "oops/typeArrayOop.hpp" 1.11 @@ -100,6 +101,7 @@ 1.12 class LocalVariableTableElement; 1.13 class AdapterHandlerEntry; 1.14 class MethodData; 1.15 +class MethodCounters; 1.16 class ConstMethod; 1.17 class InlineTableSizes; 1.18 class KlassSizeStats; 1.19 @@ -109,7 +111,7 @@ 1.20 private: 1.21 ConstMethod* _constMethod; // Method read-only data. 1.22 MethodData* _method_data; 1.23 - int _interpreter_invocation_count; // Count of times invoked (reused as prev_event_count in tiered) 1.24 + MethodCounters* _method_counters; 1.25 AccessFlags _access_flags; // Access flags 1.26 int _vtable_index; // vtable index of this method (see VtableIndexFlag) 1.27 // note: can have vtables with >2**16 elements (because of inheritance) 1.28 @@ -124,15 +126,6 @@ 1.29 _hidden : 1, 1.30 _dont_inline : 1, 1.31 : 3; 1.32 - u2 _interpreter_throwout_count; // Count of times method was exited via exception while interpreting 1.33 - u2 _number_of_breakpoints; // fullspeed debugging support 1.34 - InvocationCounter _invocation_counter; // Incremented before each activation of the method - used to trigger frequency-based optimizations 1.35 - InvocationCounter _backedge_counter; // Incremented before each backedge taken - used to trigger frequencey-based optimizations 1.36 - 1.37 -#ifdef TIERED 1.38 - float _rate; // Events (invocation and backedge counter increments) per millisecond 1.39 - jlong _prev_time; // Previous time the rate was acquired 1.40 -#endif 1.41 1.42 #ifndef PRODUCT 1.43 int _compiled_invocation_count; // Number of nmethod invocations so far (for perf. debugging) 1.44 @@ -247,11 +240,31 @@ 1.45 void clear_all_breakpoints(); 1.46 // Tracking number of breakpoints, for fullspeed debugging. 1.47 // Only mutated by VM thread. 1.48 - u2 number_of_breakpoints() const { return _number_of_breakpoints; } 1.49 - void incr_number_of_breakpoints() { ++_number_of_breakpoints; } 1.50 - void decr_number_of_breakpoints() { --_number_of_breakpoints; } 1.51 + u2 number_of_breakpoints() const { 1.52 + if (method_counters() == NULL) { 1.53 + return 0; 1.54 + } else { 1.55 + return method_counters()->number_of_breakpoints(); 1.56 + } 1.57 + } 1.58 + void incr_number_of_breakpoints(TRAPS) { 1.59 + MethodCounters* mcs = get_method_counters(CHECK); 1.60 + if (mcs != NULL) { 1.61 + mcs->incr_number_of_breakpoints(); 1.62 + } 1.63 + } 1.64 + void decr_number_of_breakpoints(TRAPS) { 1.65 + MethodCounters* mcs = get_method_counters(CHECK); 1.66 + if (mcs != NULL) { 1.67 + mcs->decr_number_of_breakpoints(); 1.68 + } 1.69 + } 1.70 // Initialization only 1.71 - void clear_number_of_breakpoints() { _number_of_breakpoints = 0; } 1.72 + void clear_number_of_breakpoints() { 1.73 + if (method_counters() != NULL) { 1.74 + method_counters()->clear_number_of_breakpoints(); 1.75 + } 1.76 + } 1.77 1.78 // index into InstanceKlass methods() array 1.79 // note: also used by jfr 1.80 @@ -288,14 +301,20 @@ 1.81 void set_highest_osr_comp_level(int level); 1.82 1.83 // Count of times method was exited via exception while interpreting 1.84 - void interpreter_throwout_increment() { 1.85 - if (_interpreter_throwout_count < 65534) { 1.86 - _interpreter_throwout_count++; 1.87 + void interpreter_throwout_increment(TRAPS) { 1.88 + MethodCounters* mcs = get_method_counters(CHECK); 1.89 + if (mcs != NULL) { 1.90 + mcs->interpreter_throwout_increment(); 1.91 } 1.92 } 1.93 1.94 - int interpreter_throwout_count() const { return _interpreter_throwout_count; } 1.95 - void set_interpreter_throwout_count(int count) { _interpreter_throwout_count = count; } 1.96 + int interpreter_throwout_count() const { 1.97 + if (method_counters() == NULL) { 1.98 + return 0; 1.99 + } else { 1.100 + return method_counters()->interpreter_throwout_count(); 1.101 + } 1.102 + } 1.103 1.104 // size of parameters 1.105 int size_of_parameters() const { return constMethod()->size_of_parameters(); } 1.106 @@ -339,23 +358,54 @@ 1.107 MethodData* method_data() const { 1.108 return _method_data; 1.109 } 1.110 + 1.111 void set_method_data(MethodData* data) { 1.112 _method_data = data; 1.113 } 1.114 1.115 - // invocation counter 1.116 - InvocationCounter* invocation_counter() { return &_invocation_counter; } 1.117 - InvocationCounter* backedge_counter() { return &_backedge_counter; } 1.118 + MethodCounters* method_counters() const { 1.119 + return _method_counters; 1.120 + } 1.121 + 1.122 + 1.123 + void set_method_counters(MethodCounters* counters) { 1.124 + _method_counters = counters; 1.125 + } 1.126 1.127 #ifdef TIERED 1.128 // We are reusing interpreter_invocation_count as a holder for the previous event count! 1.129 // We can do that since interpreter_invocation_count is not used in tiered. 1.130 - int prev_event_count() const { return _interpreter_invocation_count; } 1.131 - void set_prev_event_count(int count) { _interpreter_invocation_count = count; } 1.132 - jlong prev_time() const { return _prev_time; } 1.133 - void set_prev_time(jlong time) { _prev_time = time; } 1.134 - float rate() const { return _rate; } 1.135 - void set_rate(float rate) { _rate = rate; } 1.136 + int prev_event_count() const { 1.137 + if (method_counters() == NULL) { 1.138 + return 0; 1.139 + } else { 1.140 + return method_counters()->interpreter_invocation_count(); 1.141 + } 1.142 + } 1.143 + void set_prev_event_count(int count, TRAPS) { 1.144 + MethodCounters* mcs = get_method_counters(CHECK); 1.145 + if (mcs != NULL) { 1.146 + mcs->set_interpreter_invocation_count(count); 1.147 + } 1.148 + } 1.149 + jlong prev_time() const { 1.150 + return method_counters() == NULL ? 0 : method_counters()->prev_time(); 1.151 + } 1.152 + void set_prev_time(jlong time, TRAPS) { 1.153 + MethodCounters* mcs = get_method_counters(CHECK); 1.154 + if (mcs != NULL) { 1.155 + mcs->set_prev_time(time); 1.156 + } 1.157 + } 1.158 + float rate() const { 1.159 + return method_counters() == NULL ? 0 : method_counters()->rate(); 1.160 + } 1.161 + void set_rate(float rate, TRAPS) { 1.162 + MethodCounters* mcs = get_method_counters(CHECK); 1.163 + if (mcs != NULL) { 1.164 + mcs->set_rate(rate); 1.165 + } 1.166 + } 1.167 #endif 1.168 1.169 int invocation_count(); 1.170 @@ -366,14 +416,17 @@ 1.171 1.172 static void build_interpreter_method_data(methodHandle method, TRAPS); 1.173 1.174 + static MethodCounters* build_method_counters(Method* m, TRAPS); 1.175 + 1.176 int interpreter_invocation_count() { 1.177 if (TieredCompilation) return invocation_count(); 1.178 - else return _interpreter_invocation_count; 1.179 + else return (method_counters() == NULL) ? 0 : 1.180 + method_counters()->interpreter_invocation_count(); 1.181 } 1.182 - void set_interpreter_invocation_count(int count) { _interpreter_invocation_count = count; } 1.183 - int increment_interpreter_invocation_count() { 1.184 + int increment_interpreter_invocation_count(TRAPS) { 1.185 if (TieredCompilation) ShouldNotReachHere(); 1.186 - return ++_interpreter_invocation_count; 1.187 + MethodCounters* mcs = get_method_counters(CHECK_0); 1.188 + return (mcs == NULL) ? 0 : mcs->increment_interpreter_invocation_count(); 1.189 } 1.190 1.191 #ifndef PRODUCT 1.192 @@ -582,12 +635,12 @@ 1.193 #endif /* CC_INTERP */ 1.194 static ByteSize from_compiled_offset() { return byte_offset_of(Method, _from_compiled_entry); } 1.195 static ByteSize code_offset() { return byte_offset_of(Method, _code); } 1.196 - static ByteSize invocation_counter_offset() { return byte_offset_of(Method, _invocation_counter); } 1.197 - static ByteSize backedge_counter_offset() { return byte_offset_of(Method, _backedge_counter); } 1.198 static ByteSize method_data_offset() { 1.199 return byte_offset_of(Method, _method_data); 1.200 } 1.201 - static ByteSize interpreter_invocation_counter_offset() { return byte_offset_of(Method, _interpreter_invocation_count); } 1.202 + static ByteSize method_counters_offset() { 1.203 + return byte_offset_of(Method, _method_counters); 1.204 + } 1.205 #ifndef PRODUCT 1.206 static ByteSize compiled_invocation_counter_offset() { return byte_offset_of(Method, _compiled_invocation_count); } 1.207 #endif // not PRODUCT 1.208 @@ -598,8 +651,6 @@ 1.209 1.210 // for code generation 1.211 static int method_data_offset_in_bytes() { return offset_of(Method, _method_data); } 1.212 - static int interpreter_invocation_counter_offset_in_bytes() 1.213 - { return offset_of(Method, _interpreter_invocation_count); } 1.214 static int intrinsic_id_offset_in_bytes() { return offset_of(Method, _intrinsic_id); } 1.215 static int intrinsic_id_size_in_bytes() { return sizeof(u1); } 1.216 1.217 @@ -757,6 +808,13 @@ 1.218 private: 1.219 void print_made_not_compilable(int comp_level, bool is_osr, bool report, const char* reason); 1.220 1.221 + MethodCounters* get_method_counters(TRAPS) { 1.222 + if (_method_counters == NULL) { 1.223 + build_method_counters(this, CHECK_AND_CLEAR_NULL); 1.224 + } 1.225 + return _method_counters; 1.226 + } 1.227 + 1.228 public: 1.229 bool is_not_c1_compilable() const { return access_flags().is_not_c1_compilable(); } 1.230 void set_not_c1_compilable() { _access_flags.set_not_c1_compilable(); }