Mercurial > hg > truffle
comparison src/share/vm/oops/method.hpp @ 10408:836a62f43af9
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 19 Jun 2013 10:45:56 +0200 |
parents | 89e4d67fdd2a 603ca7e51354 |
children | cefad50507d8 |
comparison
equal
deleted
inserted
replaced
10086:e0fb8a213650 | 10408:836a62f43af9 |
---|---|
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" |
64 // | klass | | 65 // | klass | |
65 // |------------------------------------------------------| | 66 // |------------------------------------------------------| |
66 // | ConstMethod* (oop) | | 67 // | ConstMethod* (oop) | |
67 // |------------------------------------------------------| | 68 // |------------------------------------------------------| |
68 // | methodData (oop) | | 69 // | methodData (oop) | |
69 // | interp_invocation_count | | 70 // | methodCounters | |
70 // |------------------------------------------------------| | 71 // |------------------------------------------------------| |
71 // | access_flags | | 72 // | access_flags | |
72 // | vtable_index | | 73 // | vtable_index | |
73 // |------------------------------------------------------| | 74 // |------------------------------------------------------| |
74 // | result_index (C++ interpreter only) | | 75 // | result_index (C++ interpreter only) | |
75 // |------------------------------------------------------| | 76 // |------------------------------------------------------| |
76 // | method_size | intrinsic_id| flags | | 77 // | method_size | intrinsic_id| flags | |
77 // |------------------------------------------------------| | |
78 // | throwout_count | num_breakpoints | | |
79 // |------------------------------------------------------| | |
80 // | invocation_counter | | |
81 // | backedge_counter | | |
82 // |------------------------------------------------------| | |
83 // | prev_time (tiered only, 64 bit wide) | | |
84 // | | | |
85 // |------------------------------------------------------| | |
86 // | rate (tiered) | | |
87 // |------------------------------------------------------| | 78 // |------------------------------------------------------| |
88 // | code (pointer) | | 79 // | code (pointer) | |
89 // | i2i (pointer) | | 80 // | i2i (pointer) | |
90 // | adapter (pointer) | | 81 // | adapter (pointer) | |
91 // | from_compiled_entry (pointer) | | 82 // | from_compiled_entry (pointer) | |
98 | 89 |
99 class CheckedExceptionElement; | 90 class CheckedExceptionElement; |
100 class LocalVariableTableElement; | 91 class LocalVariableTableElement; |
101 class AdapterHandlerEntry; | 92 class AdapterHandlerEntry; |
102 class MethodData; | 93 class MethodData; |
94 class MethodCounters; | |
103 class ConstMethod; | 95 class ConstMethod; |
104 class InlineTableSizes; | 96 class InlineTableSizes; |
105 class KlassSizeStats; | 97 class KlassSizeStats; |
106 | 98 |
107 class Method : public Metadata { | 99 class Method : public Metadata { |
108 friend class VMStructs; | 100 friend class VMStructs; |
109 private: | 101 private: |
110 ConstMethod* _constMethod; // Method read-only data. | 102 ConstMethod* _constMethod; // Method read-only data. |
111 MethodData* _method_data; | 103 MethodData* _method_data; |
112 int _interpreter_invocation_count; // Count of times invoked (reused as prev_event_count in tiered) | 104 MethodCounters* _method_counters; |
113 AccessFlags _access_flags; // Access flags | 105 AccessFlags _access_flags; // Access flags |
114 int _vtable_index; // vtable index of this method (see VtableIndexFlag) | 106 int _vtable_index; // vtable index of this method (see VtableIndexFlag) |
115 // note: can have vtables with >2**16 elements (because of inheritance) | 107 // note: can have vtables with >2**16 elements (because of inheritance) |
116 #ifdef CC_INTERP | 108 #ifdef CC_INTERP |
117 int _result_index; // C++ interpreter needs for converting results to/from stack | 109 int _result_index; // C++ interpreter needs for converting results to/from stack |
122 _caller_sensitive : 1, | 114 _caller_sensitive : 1, |
123 _force_inline : 1, | 115 _force_inline : 1, |
124 _hidden : 1, | 116 _hidden : 1, |
125 _dont_inline : 1, | 117 _dont_inline : 1, |
126 : 3; | 118 : 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 GRAAL | |
133 jlong _graal_invocation_time; | |
134 int _graal_priority; | |
135 #endif | |
136 #ifdef TIERED | |
137 float _rate; // Events (invocation and backedge counter increments) per millisecond | |
138 jlong _prev_time; // Previous time the rate was acquired | |
139 #endif | |
140 | 119 |
141 #ifndef PRODUCT | 120 #ifndef PRODUCT |
142 int _compiled_invocation_count; // Number of nmethod invocations so far (for perf. debugging) | 121 int _compiled_invocation_count; // Number of nmethod invocations so far (for perf. debugging) |
143 #endif | 122 #endif |
144 // Entry point for calling both from and to the interpreter. | 123 // Entry point for calling both from and to the interpreter. |
249 void set_breakpoint(int bci); | 228 void set_breakpoint(int bci); |
250 void clear_breakpoint(int bci); | 229 void clear_breakpoint(int bci); |
251 void clear_all_breakpoints(); | 230 void clear_all_breakpoints(); |
252 // Tracking number of breakpoints, for fullspeed debugging. | 231 // Tracking number of breakpoints, for fullspeed debugging. |
253 // Only mutated by VM thread. | 232 // Only mutated by VM thread. |
254 u2 number_of_breakpoints() const { return _number_of_breakpoints; } | 233 u2 number_of_breakpoints() const { |
255 void incr_number_of_breakpoints() { ++_number_of_breakpoints; } | 234 if (method_counters() == NULL) { |
256 void decr_number_of_breakpoints() { --_number_of_breakpoints; } | 235 return 0; |
236 } else { | |
237 return method_counters()->number_of_breakpoints(); | |
238 } | |
239 } | |
240 void incr_number_of_breakpoints(TRAPS) { | |
241 MethodCounters* mcs = get_method_counters(CHECK); | |
242 if (mcs != NULL) { | |
243 mcs->incr_number_of_breakpoints(); | |
244 } | |
245 } | |
246 void decr_number_of_breakpoints(TRAPS) { | |
247 MethodCounters* mcs = get_method_counters(CHECK); | |
248 if (mcs != NULL) { | |
249 mcs->decr_number_of_breakpoints(); | |
250 } | |
251 } | |
257 // Initialization only | 252 // Initialization only |
258 void clear_number_of_breakpoints() { _number_of_breakpoints = 0; } | 253 void clear_number_of_breakpoints() { |
254 if (method_counters() != NULL) { | |
255 method_counters()->clear_number_of_breakpoints(); | |
256 } | |
257 } | |
259 | 258 |
260 // index into InstanceKlass methods() array | 259 // index into InstanceKlass methods() array |
261 // note: also used by jfr | 260 // note: also used by jfr |
262 u2 method_idnum() const { return constMethod()->method_idnum(); } | 261 u2 method_idnum() const { return constMethod()->method_idnum(); } |
263 void set_method_idnum(u2 idnum) { constMethod()->set_method_idnum(idnum); } | 262 void set_method_idnum(u2 idnum) { constMethod()->set_method_idnum(idnum); } |
290 void set_highest_comp_level(int level); | 289 void set_highest_comp_level(int level); |
291 int highest_osr_comp_level() const; | 290 int highest_osr_comp_level() const; |
292 void set_highest_osr_comp_level(int level); | 291 void set_highest_osr_comp_level(int level); |
293 | 292 |
294 // Count of times method was exited via exception while interpreting | 293 // Count of times method was exited via exception while interpreting |
295 void interpreter_throwout_increment() { | 294 void interpreter_throwout_increment(TRAPS) { |
296 if (_interpreter_throwout_count < 65534) { | 295 MethodCounters* mcs = get_method_counters(CHECK); |
297 _interpreter_throwout_count++; | 296 if (mcs != NULL) { |
298 } | 297 mcs->interpreter_throwout_increment(); |
299 } | 298 } |
300 | 299 } |
301 int interpreter_throwout_count() const { return _interpreter_throwout_count; } | 300 |
302 void set_interpreter_throwout_count(int count) { _interpreter_throwout_count = count; } | 301 int interpreter_throwout_count() const { |
302 if (method_counters() == NULL) { | |
303 return 0; | |
304 } else { | |
305 return method_counters()->interpreter_throwout_count(); | |
306 } | |
307 } | |
303 | 308 |
304 // size of parameters | 309 // size of parameters |
305 int size_of_parameters() const { return constMethod()->size_of_parameters(); } | 310 int size_of_parameters() const { return constMethod()->size_of_parameters(); } |
306 void set_size_of_parameters(int size) { constMethod()->set_size_of_parameters(size); } | 311 void set_size_of_parameters(int size) { constMethod()->set_size_of_parameters(size); } |
307 | 312 |
341 | 346 |
342 // method data access | 347 // method data access |
343 MethodData* method_data() const { | 348 MethodData* method_data() const { |
344 return _method_data; | 349 return _method_data; |
345 } | 350 } |
351 | |
346 void set_method_data(MethodData* data) { | 352 void set_method_data(MethodData* data) { |
347 _method_data = data; | 353 _method_data = data; |
348 } | 354 } |
349 | 355 |
350 // invocation counter | 356 MethodCounters* method_counters() const { |
351 InvocationCounter* invocation_counter() { return &_invocation_counter; } | 357 return _method_counters; |
352 InvocationCounter* backedge_counter() { return &_backedge_counter; } | 358 } |
359 | |
360 | |
361 void set_method_counters(MethodCounters* counters) { | |
362 _method_counters = counters; | |
363 } | |
353 | 364 |
354 #ifdef TIERED | 365 #ifdef TIERED |
355 // We are reusing interpreter_invocation_count as a holder for the previous event count! | 366 // We are reusing interpreter_invocation_count as a holder for the previous event count! |
356 // We can do that since interpreter_invocation_count is not used in tiered. | 367 // We can do that since interpreter_invocation_count is not used in tiered. |
357 int prev_event_count() const { return _interpreter_invocation_count; } | 368 int prev_event_count() const { |
358 void set_prev_event_count(int count) { _interpreter_invocation_count = count; } | 369 if (method_counters() == NULL) { |
359 jlong prev_time() const { return _prev_time; } | 370 return 0; |
360 void set_prev_time(jlong time) { _prev_time = time; } | 371 } else { |
361 float rate() const { return _rate; } | 372 return method_counters()->interpreter_invocation_count(); |
362 void set_rate(float rate) { _rate = rate; } | 373 } |
374 } | |
375 void set_prev_event_count(int count, TRAPS) { | |
376 MethodCounters* mcs = get_method_counters(CHECK); | |
377 if (mcs != NULL) { | |
378 mcs->set_interpreter_invocation_count(count); | |
379 } | |
380 } | |
381 jlong prev_time() const { | |
382 return method_counters() == NULL ? 0 : method_counters()->prev_time(); | |
383 } | |
384 void set_prev_time(jlong time, TRAPS) { | |
385 MethodCounters* mcs = get_method_counters(CHECK); | |
386 if (mcs != NULL) { | |
387 mcs->set_prev_time(time); | |
388 } | |
389 } | |
390 float rate() const { | |
391 return method_counters() == NULL ? 0 : method_counters()->rate(); | |
392 } | |
393 void set_rate(float rate, TRAPS) { | |
394 MethodCounters* mcs = get_method_counters(CHECK); | |
395 if (mcs != NULL) { | |
396 mcs->set_rate(rate); | |
397 } | |
398 } | |
363 #endif | 399 #endif |
364 | 400 |
365 int invocation_count(); | 401 int invocation_count(); |
366 int backedge_count(); | 402 int backedge_count(); |
367 | 403 |
368 #ifdef GRAAL | |
369 void set_graal_invocation_time(jlong time) { _graal_invocation_time = time; } | |
370 jlong graal_invocation_time() { return _graal_invocation_time; } | |
371 | |
372 void set_graal_priority(int prio) { _graal_priority = prio; } | |
373 int graal_priority() { return _graal_priority; } | |
374 | |
375 void reset_counters(); | |
376 #endif // GRAAL | |
377 | |
378 bool was_executed_more_than(int n); | 404 bool was_executed_more_than(int n); |
379 bool was_never_executed() { return !was_executed_more_than(0); } | 405 bool was_never_executed() { return !was_executed_more_than(0); } |
380 | 406 |
381 static void build_interpreter_method_data(methodHandle method, TRAPS); | 407 static void build_interpreter_method_data(methodHandle method, TRAPS); |
382 | 408 |
409 static MethodCounters* build_method_counters(Method* m, TRAPS); | |
410 | |
383 int interpreter_invocation_count() { | 411 int interpreter_invocation_count() { |
384 if (TieredCompilation) return invocation_count(); | 412 if (TieredCompilation) return invocation_count(); |
385 else return _interpreter_invocation_count; | 413 else return (method_counters() == NULL) ? 0 : |
386 } | 414 method_counters()->interpreter_invocation_count(); |
387 void set_interpreter_invocation_count(int count) { _interpreter_invocation_count = count; } | 415 } |
388 int increment_interpreter_invocation_count() { | 416 int increment_interpreter_invocation_count(TRAPS) { |
389 if (TieredCompilation) ShouldNotReachHere(); | 417 if (TieredCompilation) ShouldNotReachHere(); |
390 return ++_interpreter_invocation_count; | 418 MethodCounters* mcs = get_method_counters(CHECK_0); |
419 return (mcs == NULL) ? 0 : mcs->increment_interpreter_invocation_count(); | |
391 } | 420 } |
392 | 421 |
393 #ifndef PRODUCT | 422 #ifndef PRODUCT |
394 int compiled_invocation_count() const { return _compiled_invocation_count; } | 423 int compiled_invocation_count() const { return _compiled_invocation_count; } |
395 void set_compiled_invocation_count(int count) { _compiled_invocation_count = count; } | 424 void set_compiled_invocation_count(int count) { _compiled_invocation_count = count; } |
594 #ifdef CC_INTERP | 623 #ifdef CC_INTERP |
595 static ByteSize result_index_offset() { return byte_offset_of(Method, _result_index ); } | 624 static ByteSize result_index_offset() { return byte_offset_of(Method, _result_index ); } |
596 #endif /* CC_INTERP */ | 625 #endif /* CC_INTERP */ |
597 static ByteSize from_compiled_offset() { return byte_offset_of(Method, _from_compiled_entry); } | 626 static ByteSize from_compiled_offset() { return byte_offset_of(Method, _from_compiled_entry); } |
598 static ByteSize code_offset() { return byte_offset_of(Method, _code); } | 627 static ByteSize code_offset() { return byte_offset_of(Method, _code); } |
599 static ByteSize invocation_counter_offset() { return byte_offset_of(Method, _invocation_counter); } | |
600 static ByteSize backedge_counter_offset() { return byte_offset_of(Method, _backedge_counter); } | |
601 static ByteSize method_data_offset() { | 628 static ByteSize method_data_offset() { |
602 return byte_offset_of(Method, _method_data); | 629 return byte_offset_of(Method, _method_data); |
603 } | 630 } |
604 static ByteSize interpreter_invocation_counter_offset() { return byte_offset_of(Method, _interpreter_invocation_count); } | 631 static ByteSize method_counters_offset() { |
605 #ifdef GRAAL | 632 return byte_offset_of(Method, _method_counters); |
606 static ByteSize graal_invocation_time_offset() { return byte_offset_of(Method, _graal_invocation_time); } | 633 } |
607 static ByteSize graal_priority_offset() { return byte_offset_of(Method, _graal_priority); } | |
608 #endif | |
609 #ifndef PRODUCT | 634 #ifndef PRODUCT |
610 static ByteSize compiled_invocation_counter_offset() { return byte_offset_of(Method, _compiled_invocation_count); } | 635 static ByteSize compiled_invocation_counter_offset() { return byte_offset_of(Method, _compiled_invocation_count); } |
611 #endif // not PRODUCT | 636 #endif // not PRODUCT |
612 static ByteSize native_function_offset() { return in_ByteSize(sizeof(Method)); } | 637 static ByteSize native_function_offset() { return in_ByteSize(sizeof(Method)); } |
613 static ByteSize from_interpreted_offset() { return byte_offset_of(Method, _from_interpreted_entry ); } | 638 static ByteSize from_interpreted_offset() { return byte_offset_of(Method, _from_interpreted_entry ); } |
614 static ByteSize interpreter_entry_offset() { return byte_offset_of(Method, _i2i_entry ); } | 639 static ByteSize interpreter_entry_offset() { return byte_offset_of(Method, _i2i_entry ); } |
615 static ByteSize signature_handler_offset() { return in_ByteSize(sizeof(Method) + wordSize); } | 640 static ByteSize signature_handler_offset() { return in_ByteSize(sizeof(Method) + wordSize); } |
616 | 641 |
617 // for code generation | 642 // for code generation |
618 static int method_data_offset_in_bytes() { return offset_of(Method, _method_data); } | 643 static int method_data_offset_in_bytes() { return offset_of(Method, _method_data); } |
619 static int interpreter_invocation_counter_offset_in_bytes() | |
620 { return offset_of(Method, _interpreter_invocation_count); } | |
621 static int intrinsic_id_offset_in_bytes() { return offset_of(Method, _intrinsic_id); } | 644 static int intrinsic_id_offset_in_bytes() { return offset_of(Method, _intrinsic_id); } |
622 static int intrinsic_id_size_in_bytes() { return sizeof(u1); } | 645 static int intrinsic_id_size_in_bytes() { return sizeof(u1); } |
623 | 646 |
624 // Static methods that are used to implement member methods where an exposed this pointer | 647 // Static methods that are used to implement member methods where an exposed this pointer |
625 // is needed due to possible GCs | 648 // is needed due to possible GCs |
646 bool has_member_arg() const; // intrinsic_id() == vmIntrinsics::_linkToSpecial, etc. | 669 bool has_member_arg() const; // intrinsic_id() == vmIntrinsics::_linkToSpecial, etc. |
647 static methodHandle make_method_handle_intrinsic(vmIntrinsics::ID iid, // _invokeBasic, _linkToVirtual | 670 static methodHandle make_method_handle_intrinsic(vmIntrinsics::ID iid, // _invokeBasic, _linkToVirtual |
648 Symbol* signature, //anything at all | 671 Symbol* signature, //anything at all |
649 TRAPS); | 672 TRAPS); |
650 static Klass* check_non_bcp_klass(Klass* klass); | 673 static Klass* check_non_bcp_klass(Klass* klass); |
651 // these operate only on invoke methods: | 674 |
675 // How many extra stack entries for invokedynamic when it's enabled | |
676 static const int extra_stack_entries_for_jsr292 = 1; | |
677 | |
678 // this operates only on invoke methods: | |
652 // presize interpreter frames for extra interpreter stack entries, if needed | 679 // presize interpreter frames for extra interpreter stack entries, if needed |
653 // method handles want to be able to push a few extra values (e.g., a bound receiver), and | 680 // Account for the extra appendix argument for invokehandle/invokedynamic |
654 // invokedynamic sometimes needs to push a bootstrap method, call site, and arglist, | 681 static int extra_stack_entries() { return EnableInvokeDynamic ? extra_stack_entries_for_jsr292 : 0; } |
655 // all without checking for a stack overflow | 682 static int extra_stack_words(); // = extra_stack_entries() * Interpreter::stackElementSize |
656 static int extra_stack_entries() { return EnableInvokeDynamic ? 2 : 0; } | |
657 static int extra_stack_words(); // = extra_stack_entries() * Interpreter::stackElementSize() | |
658 | 683 |
659 // RedefineClasses() support: | 684 // RedefineClasses() support: |
660 bool is_old() const { return access_flags().is_old(); } | 685 bool is_old() const { return access_flags().is_old(); } |
661 void set_is_old() { _access_flags.set_is_old(); } | 686 void set_is_old() { _access_flags.set_is_old(); } |
662 bool is_obsolete() const { return access_flags().is_obsolete(); } | 687 bool is_obsolete() const { return access_flags().is_obsolete(); } |
772 set_not_osr_compilable(comp_level, false); | 797 set_not_osr_compilable(comp_level, false); |
773 } | 798 } |
774 | 799 |
775 private: | 800 private: |
776 void print_made_not_compilable(int comp_level, bool is_osr, bool report, const char* reason); | 801 void print_made_not_compilable(int comp_level, bool is_osr, bool report, const char* reason); |
802 | |
803 MethodCounters* get_method_counters(TRAPS) { | |
804 if (_method_counters == NULL) { | |
805 build_method_counters(this, CHECK_AND_CLEAR_NULL); | |
806 } | |
807 return _method_counters; | |
808 } | |
777 | 809 |
778 public: | 810 public: |
779 bool is_not_c1_compilable() const { return access_flags().is_not_c1_compilable(); } | 811 bool is_not_c1_compilable() const { return access_flags().is_not_c1_compilable(); } |
780 void set_not_c1_compilable() { _access_flags.set_not_c1_compilable(); } | 812 void set_not_c1_compilable() { _access_flags.set_not_c1_compilable(); } |
781 void clear_not_c1_compilable() { _access_flags.clear_not_c1_compilable(); } | 813 void clear_not_c1_compilable() { _access_flags.clear_not_c1_compilable(); } |
954 private: | 986 private: |
955 ExceptionTableElement* _table; | 987 ExceptionTableElement* _table; |
956 u2 _length; | 988 u2 _length; |
957 | 989 |
958 public: | 990 public: |
959 ExceptionTable(Method* m) { | 991 ExceptionTable(const Method* m) { |
960 if (m->has_exception_handler()) { | 992 if (m->has_exception_handler()) { |
961 _table = m->exception_table_start(); | 993 _table = m->exception_table_start(); |
962 _length = m->exception_table_length(); | 994 _length = m->exception_table_length(); |
963 } else { | 995 } else { |
964 _table = NULL; | 996 _table = NULL; |