29 #include "code/compressedStream.hpp" |
29 #include "code/compressedStream.hpp" |
30 #include "compiler/oopMap.hpp" |
30 #include "compiler/oopMap.hpp" |
31 #include "interpreter/invocationCounter.hpp" |
31 #include "interpreter/invocationCounter.hpp" |
32 #include "oops/annotations.hpp" |
32 #include "oops/annotations.hpp" |
33 #include "oops/constantPool.hpp" |
33 #include "oops/constantPool.hpp" |
|
34 #include "oops/methodCounters.hpp" |
34 #include "oops/instanceKlass.hpp" |
35 #include "oops/instanceKlass.hpp" |
35 #include "oops/oop.hpp" |
36 #include "oops/oop.hpp" |
36 #include "oops/typeArrayOop.hpp" |
37 #include "oops/typeArrayOop.hpp" |
37 #include "utilities/accessFlags.hpp" |
38 #include "utilities/accessFlags.hpp" |
38 #include "utilities/growableArray.hpp" |
39 #include "utilities/growableArray.hpp" |
98 |
99 |
99 class CheckedExceptionElement; |
100 class CheckedExceptionElement; |
100 class LocalVariableTableElement; |
101 class LocalVariableTableElement; |
101 class AdapterHandlerEntry; |
102 class AdapterHandlerEntry; |
102 class MethodData; |
103 class MethodData; |
|
104 class MethodCounters; |
103 class ConstMethod; |
105 class ConstMethod; |
104 class InlineTableSizes; |
106 class InlineTableSizes; |
105 class KlassSizeStats; |
107 class KlassSizeStats; |
106 |
108 |
107 class Method : public Metadata { |
109 class Method : public Metadata { |
108 friend class VMStructs; |
110 friend class VMStructs; |
109 private: |
111 private: |
110 ConstMethod* _constMethod; // Method read-only data. |
112 ConstMethod* _constMethod; // Method read-only data. |
111 MethodData* _method_data; |
113 MethodData* _method_data; |
112 int _interpreter_invocation_count; // Count of times invoked (reused as prev_event_count in tiered) |
114 MethodCounters* _method_counters; |
113 AccessFlags _access_flags; // Access flags |
115 AccessFlags _access_flags; // Access flags |
114 int _vtable_index; // vtable index of this method (see VtableIndexFlag) |
116 int _vtable_index; // vtable index of this method (see VtableIndexFlag) |
115 // note: can have vtables with >2**16 elements (because of inheritance) |
117 // note: can have vtables with >2**16 elements (because of inheritance) |
116 #ifdef CC_INTERP |
118 #ifdef CC_INTERP |
117 int _result_index; // C++ interpreter needs for converting results to/from stack |
119 int _result_index; // C++ interpreter needs for converting results to/from stack |
122 _caller_sensitive : 1, |
124 _caller_sensitive : 1, |
123 _force_inline : 1, |
125 _force_inline : 1, |
124 _hidden : 1, |
126 _hidden : 1, |
125 _dont_inline : 1, |
127 _dont_inline : 1, |
126 : 3; |
128 : 3; |
127 u2 _interpreter_throwout_count; // Count of times method was exited via exception while interpreting |
|
128 u2 _number_of_breakpoints; // fullspeed debugging support |
|
129 InvocationCounter _invocation_counter; // Incremented before each activation of the method - used to trigger frequency-based optimizations |
|
130 InvocationCounter _backedge_counter; // Incremented before each backedge taken - used to trigger frequencey-based optimizations |
|
131 |
|
132 #ifdef TIERED |
|
133 float _rate; // Events (invocation and backedge counter increments) per millisecond |
|
134 jlong _prev_time; // Previous time the rate was acquired |
|
135 #endif |
|
136 |
129 |
137 #ifndef PRODUCT |
130 #ifndef PRODUCT |
138 int _compiled_invocation_count; // Number of nmethod invocations so far (for perf. debugging) |
131 int _compiled_invocation_count; // Number of nmethod invocations so far (for perf. debugging) |
139 #endif |
132 #endif |
140 // Entry point for calling both from and to the interpreter. |
133 // Entry point for calling both from and to the interpreter. |
245 void set_breakpoint(int bci); |
238 void set_breakpoint(int bci); |
246 void clear_breakpoint(int bci); |
239 void clear_breakpoint(int bci); |
247 void clear_all_breakpoints(); |
240 void clear_all_breakpoints(); |
248 // Tracking number of breakpoints, for fullspeed debugging. |
241 // Tracking number of breakpoints, for fullspeed debugging. |
249 // Only mutated by VM thread. |
242 // Only mutated by VM thread. |
250 u2 number_of_breakpoints() const { return _number_of_breakpoints; } |
243 u2 number_of_breakpoints() const { |
251 void incr_number_of_breakpoints() { ++_number_of_breakpoints; } |
244 if (method_counters() == NULL) { |
252 void decr_number_of_breakpoints() { --_number_of_breakpoints; } |
245 return 0; |
|
246 } else { |
|
247 return method_counters()->number_of_breakpoints(); |
|
248 } |
|
249 } |
|
250 void incr_number_of_breakpoints(TRAPS) { |
|
251 MethodCounters* mcs = get_method_counters(CHECK); |
|
252 if (mcs != NULL) { |
|
253 mcs->incr_number_of_breakpoints(); |
|
254 } |
|
255 } |
|
256 void decr_number_of_breakpoints(TRAPS) { |
|
257 MethodCounters* mcs = get_method_counters(CHECK); |
|
258 if (mcs != NULL) { |
|
259 mcs->decr_number_of_breakpoints(); |
|
260 } |
|
261 } |
253 // Initialization only |
262 // Initialization only |
254 void clear_number_of_breakpoints() { _number_of_breakpoints = 0; } |
263 void clear_number_of_breakpoints() { |
|
264 if (method_counters() != NULL) { |
|
265 method_counters()->clear_number_of_breakpoints(); |
|
266 } |
|
267 } |
255 |
268 |
256 // index into InstanceKlass methods() array |
269 // index into InstanceKlass methods() array |
257 // note: also used by jfr |
270 // note: also used by jfr |
258 u2 method_idnum() const { return constMethod()->method_idnum(); } |
271 u2 method_idnum() const { return constMethod()->method_idnum(); } |
259 void set_method_idnum(u2 idnum) { constMethod()->set_method_idnum(idnum); } |
272 void set_method_idnum(u2 idnum) { constMethod()->set_method_idnum(idnum); } |
286 void set_highest_comp_level(int level); |
299 void set_highest_comp_level(int level); |
287 int highest_osr_comp_level() const; |
300 int highest_osr_comp_level() const; |
288 void set_highest_osr_comp_level(int level); |
301 void set_highest_osr_comp_level(int level); |
289 |
302 |
290 // Count of times method was exited via exception while interpreting |
303 // Count of times method was exited via exception while interpreting |
291 void interpreter_throwout_increment() { |
304 void interpreter_throwout_increment(TRAPS) { |
292 if (_interpreter_throwout_count < 65534) { |
305 MethodCounters* mcs = get_method_counters(CHECK); |
293 _interpreter_throwout_count++; |
306 if (mcs != NULL) { |
294 } |
307 mcs->interpreter_throwout_increment(); |
295 } |
308 } |
296 |
309 } |
297 int interpreter_throwout_count() const { return _interpreter_throwout_count; } |
310 |
298 void set_interpreter_throwout_count(int count) { _interpreter_throwout_count = count; } |
311 int interpreter_throwout_count() const { |
|
312 if (method_counters() == NULL) { |
|
313 return 0; |
|
314 } else { |
|
315 return method_counters()->interpreter_throwout_count(); |
|
316 } |
|
317 } |
299 |
318 |
300 // size of parameters |
319 // size of parameters |
301 int size_of_parameters() const { return constMethod()->size_of_parameters(); } |
320 int size_of_parameters() const { return constMethod()->size_of_parameters(); } |
302 void set_size_of_parameters(int size) { constMethod()->set_size_of_parameters(size); } |
321 void set_size_of_parameters(int size) { constMethod()->set_size_of_parameters(size); } |
303 |
322 |
337 |
356 |
338 // method data access |
357 // method data access |
339 MethodData* method_data() const { |
358 MethodData* method_data() const { |
340 return _method_data; |
359 return _method_data; |
341 } |
360 } |
|
361 |
342 void set_method_data(MethodData* data) { |
362 void set_method_data(MethodData* data) { |
343 _method_data = data; |
363 _method_data = data; |
344 } |
364 } |
345 |
365 |
346 // invocation counter |
366 MethodCounters* method_counters() const { |
347 InvocationCounter* invocation_counter() { return &_invocation_counter; } |
367 return _method_counters; |
348 InvocationCounter* backedge_counter() { return &_backedge_counter; } |
368 } |
|
369 |
|
370 |
|
371 void set_method_counters(MethodCounters* counters) { |
|
372 _method_counters = counters; |
|
373 } |
349 |
374 |
350 #ifdef TIERED |
375 #ifdef TIERED |
351 // We are reusing interpreter_invocation_count as a holder for the previous event count! |
376 // We are reusing interpreter_invocation_count as a holder for the previous event count! |
352 // We can do that since interpreter_invocation_count is not used in tiered. |
377 // We can do that since interpreter_invocation_count is not used in tiered. |
353 int prev_event_count() const { return _interpreter_invocation_count; } |
378 int prev_event_count() const { |
354 void set_prev_event_count(int count) { _interpreter_invocation_count = count; } |
379 if (method_counters() == NULL) { |
355 jlong prev_time() const { return _prev_time; } |
380 return 0; |
356 void set_prev_time(jlong time) { _prev_time = time; } |
381 } else { |
357 float rate() const { return _rate; } |
382 return method_counters()->interpreter_invocation_count(); |
358 void set_rate(float rate) { _rate = rate; } |
383 } |
|
384 } |
|
385 void set_prev_event_count(int count, TRAPS) { |
|
386 MethodCounters* mcs = get_method_counters(CHECK); |
|
387 if (mcs != NULL) { |
|
388 mcs->set_interpreter_invocation_count(count); |
|
389 } |
|
390 } |
|
391 jlong prev_time() const { |
|
392 return method_counters() == NULL ? 0 : method_counters()->prev_time(); |
|
393 } |
|
394 void set_prev_time(jlong time, TRAPS) { |
|
395 MethodCounters* mcs = get_method_counters(CHECK); |
|
396 if (mcs != NULL) { |
|
397 mcs->set_prev_time(time); |
|
398 } |
|
399 } |
|
400 float rate() const { |
|
401 return method_counters() == NULL ? 0 : method_counters()->rate(); |
|
402 } |
|
403 void set_rate(float rate, TRAPS) { |
|
404 MethodCounters* mcs = get_method_counters(CHECK); |
|
405 if (mcs != NULL) { |
|
406 mcs->set_rate(rate); |
|
407 } |
|
408 } |
359 #endif |
409 #endif |
360 |
410 |
361 int invocation_count(); |
411 int invocation_count(); |
362 int backedge_count(); |
412 int backedge_count(); |
363 |
413 |
364 bool was_executed_more_than(int n); |
414 bool was_executed_more_than(int n); |
365 bool was_never_executed() { return !was_executed_more_than(0); } |
415 bool was_never_executed() { return !was_executed_more_than(0); } |
366 |
416 |
367 static void build_interpreter_method_data(methodHandle method, TRAPS); |
417 static void build_interpreter_method_data(methodHandle method, TRAPS); |
368 |
418 |
|
419 static MethodCounters* build_method_counters(Method* m, TRAPS); |
|
420 |
369 int interpreter_invocation_count() { |
421 int interpreter_invocation_count() { |
370 if (TieredCompilation) return invocation_count(); |
422 if (TieredCompilation) return invocation_count(); |
371 else return _interpreter_invocation_count; |
423 else return (method_counters() == NULL) ? 0 : |
372 } |
424 method_counters()->interpreter_invocation_count(); |
373 void set_interpreter_invocation_count(int count) { _interpreter_invocation_count = count; } |
425 } |
374 int increment_interpreter_invocation_count() { |
426 int increment_interpreter_invocation_count(TRAPS) { |
375 if (TieredCompilation) ShouldNotReachHere(); |
427 if (TieredCompilation) ShouldNotReachHere(); |
376 return ++_interpreter_invocation_count; |
428 MethodCounters* mcs = get_method_counters(CHECK_0); |
|
429 return (mcs == NULL) ? 0 : mcs->increment_interpreter_invocation_count(); |
377 } |
430 } |
378 |
431 |
379 #ifndef PRODUCT |
432 #ifndef PRODUCT |
380 int compiled_invocation_count() const { return _compiled_invocation_count; } |
433 int compiled_invocation_count() const { return _compiled_invocation_count; } |
381 void set_compiled_invocation_count(int count) { _compiled_invocation_count = count; } |
434 void set_compiled_invocation_count(int count) { _compiled_invocation_count = count; } |
580 #ifdef CC_INTERP |
633 #ifdef CC_INTERP |
581 static ByteSize result_index_offset() { return byte_offset_of(Method, _result_index ); } |
634 static ByteSize result_index_offset() { return byte_offset_of(Method, _result_index ); } |
582 #endif /* CC_INTERP */ |
635 #endif /* CC_INTERP */ |
583 static ByteSize from_compiled_offset() { return byte_offset_of(Method, _from_compiled_entry); } |
636 static ByteSize from_compiled_offset() { return byte_offset_of(Method, _from_compiled_entry); } |
584 static ByteSize code_offset() { return byte_offset_of(Method, _code); } |
637 static ByteSize code_offset() { return byte_offset_of(Method, _code); } |
585 static ByteSize invocation_counter_offset() { return byte_offset_of(Method, _invocation_counter); } |
|
586 static ByteSize backedge_counter_offset() { return byte_offset_of(Method, _backedge_counter); } |
|
587 static ByteSize method_data_offset() { |
638 static ByteSize method_data_offset() { |
588 return byte_offset_of(Method, _method_data); |
639 return byte_offset_of(Method, _method_data); |
589 } |
640 } |
590 static ByteSize interpreter_invocation_counter_offset() { return byte_offset_of(Method, _interpreter_invocation_count); } |
641 static ByteSize method_counters_offset() { |
|
642 return byte_offset_of(Method, _method_counters); |
|
643 } |
591 #ifndef PRODUCT |
644 #ifndef PRODUCT |
592 static ByteSize compiled_invocation_counter_offset() { return byte_offset_of(Method, _compiled_invocation_count); } |
645 static ByteSize compiled_invocation_counter_offset() { return byte_offset_of(Method, _compiled_invocation_count); } |
593 #endif // not PRODUCT |
646 #endif // not PRODUCT |
594 static ByteSize native_function_offset() { return in_ByteSize(sizeof(Method)); } |
647 static ByteSize native_function_offset() { return in_ByteSize(sizeof(Method)); } |
595 static ByteSize from_interpreted_offset() { return byte_offset_of(Method, _from_interpreted_entry ); } |
648 static ByteSize from_interpreted_offset() { return byte_offset_of(Method, _from_interpreted_entry ); } |
596 static ByteSize interpreter_entry_offset() { return byte_offset_of(Method, _i2i_entry ); } |
649 static ByteSize interpreter_entry_offset() { return byte_offset_of(Method, _i2i_entry ); } |
597 static ByteSize signature_handler_offset() { return in_ByteSize(sizeof(Method) + wordSize); } |
650 static ByteSize signature_handler_offset() { return in_ByteSize(sizeof(Method) + wordSize); } |
598 |
651 |
599 // for code generation |
652 // for code generation |
600 static int method_data_offset_in_bytes() { return offset_of(Method, _method_data); } |
653 static int method_data_offset_in_bytes() { return offset_of(Method, _method_data); } |
601 static int interpreter_invocation_counter_offset_in_bytes() |
|
602 { return offset_of(Method, _interpreter_invocation_count); } |
|
603 static int intrinsic_id_offset_in_bytes() { return offset_of(Method, _intrinsic_id); } |
654 static int intrinsic_id_offset_in_bytes() { return offset_of(Method, _intrinsic_id); } |
604 static int intrinsic_id_size_in_bytes() { return sizeof(u1); } |
655 static int intrinsic_id_size_in_bytes() { return sizeof(u1); } |
605 |
656 |
606 // Static methods that are used to implement member methods where an exposed this pointer |
657 // Static methods that are used to implement member methods where an exposed this pointer |
607 // is needed due to possible GCs |
658 // is needed due to possible GCs |
754 set_not_osr_compilable(comp_level, false); |
805 set_not_osr_compilable(comp_level, false); |
755 } |
806 } |
756 |
807 |
757 private: |
808 private: |
758 void print_made_not_compilable(int comp_level, bool is_osr, bool report, const char* reason); |
809 void print_made_not_compilable(int comp_level, bool is_osr, bool report, const char* reason); |
|
810 |
|
811 MethodCounters* get_method_counters(TRAPS) { |
|
812 if (_method_counters == NULL) { |
|
813 build_method_counters(this, CHECK_AND_CLEAR_NULL); |
|
814 } |
|
815 return _method_counters; |
|
816 } |
759 |
817 |
760 public: |
818 public: |
761 bool is_not_c1_compilable() const { return access_flags().is_not_c1_compilable(); } |
819 bool is_not_c1_compilable() const { return access_flags().is_not_c1_compilable(); } |
762 void set_not_c1_compilable() { _access_flags.set_not_c1_compilable(); } |
820 void set_not_c1_compilable() { _access_flags.set_not_c1_compilable(); } |
763 bool is_not_c2_compilable() const { return access_flags().is_not_c2_compilable(); } |
821 bool is_not_c2_compilable() const { return access_flags().is_not_c2_compilable(); } |