Mercurial > hg > truffle
comparison src/share/vm/opto/bytecodeInfo.cpp @ 3366:e2a92dd0d3d2
7042122: JSR 292: adjust various inline thresholds for JSR 292 API methods and method handle adapters
Reviewed-by: jrose, never, kvn
author | twisti |
---|---|
date | Tue, 10 May 2011 00:45:03 -0700 |
parents | bad7ecd0b6ed |
children | 393e144bb99b |
comparison
equal
deleted
inserted
replaced
3365:3cfb240033d1 | 3366:e2a92dd0d3d2 |
---|---|
87 caller_method->holder()->is_subclass_of(callee_method->holder())) | 87 caller_method->holder()->is_subclass_of(callee_method->holder())) |
88 ); | 88 ); |
89 } | 89 } |
90 | 90 |
91 // positive filter: should send be inlined? returns NULL, if yes, or rejection msg | 91 // positive filter: should send be inlined? returns NULL, if yes, or rejection msg |
92 const char* InlineTree::shouldInline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const { | 92 const char* InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const { |
93 // Allows targeted inlining | 93 // Allows targeted inlining |
94 if(callee_method->should_inline()) { | 94 if(callee_method->should_inline()) { |
95 *wci_result = *(WarmCallInfo::always_hot()); | 95 *wci_result = *(WarmCallInfo::always_hot()); |
96 if (PrintInlining && Verbose) { | 96 if (PrintInlining && Verbose) { |
97 CompileTask::print_inline_indent(inline_depth()); | 97 CompileTask::print_inline_indent(inline_depth()); |
100 return NULL; | 100 return NULL; |
101 } | 101 } |
102 | 102 |
103 // positive filter: should send be inlined? returns NULL (--> yes) | 103 // positive filter: should send be inlined? returns NULL (--> yes) |
104 // or rejection msg | 104 // or rejection msg |
105 int max_size = C->max_inline_size(); | 105 int size = callee_method->code_size(); |
106 int size = callee_method->code_size(); | |
107 | 106 |
108 // Check for too many throws (and not too huge) | 107 // Check for too many throws (and not too huge) |
109 if(callee_method->interpreter_throwout_count() > InlineThrowCount && | 108 if(callee_method->interpreter_throwout_count() > InlineThrowCount && |
110 size < InlineThrowMaxSize ) { | 109 size < InlineThrowMaxSize ) { |
111 wci_result->set_profit(wci_result->profit() * 100); | 110 wci_result->set_profit(wci_result->profit() * 100); |
118 | 117 |
119 if (!UseOldInlining) { | 118 if (!UseOldInlining) { |
120 return NULL; // size and frequency are represented in a new way | 119 return NULL; // size and frequency are represented in a new way |
121 } | 120 } |
122 | 121 |
122 int default_max_inline_size = C->max_inline_size(); | |
123 int inline_small_code_size = InlineSmallCode / 4; | |
124 int max_inline_size = default_max_inline_size; | |
125 | |
123 int call_site_count = method()->scale_count(profile.count()); | 126 int call_site_count = method()->scale_count(profile.count()); |
124 int invoke_count = method()->interpreter_invocation_count(); | 127 int invoke_count = method()->interpreter_invocation_count(); |
125 assert( invoke_count != 0, "Require invokation count greater than zero"); | 128 |
126 int freq = call_site_count/invoke_count; | 129 // Bytecoded method handle adapters do not have interpreter |
130 // profiling data but only made up MDO data. Get the counter from | |
131 // there. | |
132 if (caller_method->is_method_handle_adapter()) { | |
133 assert(method()->method_data_or_null(), "must have an MDO"); | |
134 ciMethodData* mdo = method()->method_data(); | |
135 ciProfileData* mha_profile = mdo->bci_to_data(caller_bci); | |
136 assert(mha_profile, "must exist"); | |
137 CounterData* cd = mha_profile->as_CounterData(); | |
138 invoke_count = cd->count(); | |
139 call_site_count = invoke_count; // use the same value | |
140 } | |
141 | |
142 assert(invoke_count != 0, "require invocation count greater than zero"); | |
143 int freq = call_site_count / invoke_count; | |
127 | 144 |
128 // bump the max size if the call is frequent | 145 // bump the max size if the call is frequent |
129 if ((freq >= InlineFrequencyRatio) || | 146 if ((freq >= InlineFrequencyRatio) || |
130 (call_site_count >= InlineFrequencyCount) || | 147 (call_site_count >= InlineFrequencyCount) || |
131 is_init_with_ea(callee_method, caller_method, C)) { | 148 is_init_with_ea(callee_method, caller_method, C)) { |
132 | 149 |
133 max_size = C->freq_inline_size(); | 150 max_inline_size = C->freq_inline_size(); |
134 if (size <= max_size && TraceFrequencyInlining) { | 151 if (size <= max_inline_size && TraceFrequencyInlining) { |
135 CompileTask::print_inline_indent(inline_depth()); | 152 CompileTask::print_inline_indent(inline_depth()); |
136 tty->print_cr("Inlined frequent method (freq=%d count=%d):", freq, call_site_count); | 153 tty->print_cr("Inlined frequent method (freq=%d count=%d):", freq, call_site_count); |
137 CompileTask::print_inline_indent(inline_depth()); | 154 CompileTask::print_inline_indent(inline_depth()); |
138 callee_method->print(); | 155 callee_method->print(); |
139 tty->cr(); | 156 tty->cr(); |
140 } | 157 } |
141 } else { | 158 } else { |
142 // Not hot. Check for medium-sized pre-existing nmethod at cold sites. | 159 // Not hot. Check for medium-sized pre-existing nmethod at cold sites. |
143 if (callee_method->has_compiled_code() && | 160 if (callee_method->has_compiled_code() && |
144 callee_method->instructions_size(CompLevel_full_optimization) > InlineSmallCode/4) | 161 callee_method->instructions_size(CompLevel_full_optimization) > inline_small_code_size) |
145 return "already compiled into a medium method"; | 162 return "already compiled into a medium method"; |
146 } | 163 } |
147 if (size > max_size) { | 164 if (size > max_inline_size) { |
148 if (max_size > C->max_inline_size()) | 165 if (max_inline_size > default_max_inline_size) |
149 return "hot method too big"; | 166 return "hot method too big"; |
150 return "too big"; | 167 return "too big"; |
151 } | 168 } |
152 return NULL; | 169 return NULL; |
153 } | 170 } |
154 | 171 |
155 | 172 |
156 // negative filter: should send NOT be inlined? returns NULL, ok to inline, or rejection msg | 173 // negative filter: should send NOT be inlined? returns NULL, ok to inline, or rejection msg |
157 const char* InlineTree::shouldNotInline(ciMethod *callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const { | 174 const char* InlineTree::should_not_inline(ciMethod *callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const { |
158 // negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg | 175 // negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg |
159 if (!UseOldInlining) { | 176 if (!UseOldInlining) { |
160 const char* fail = NULL; | 177 const char* fail = NULL; |
161 if (callee_method->is_abstract()) fail = "abstract method"; | 178 if (callee_method->is_abstract()) fail = "abstract method"; |
162 // note: we allow ik->is_abstract() | 179 // note: we allow ik->is_abstract() |
267 && (int)count_inline_bcs() >= DesiredMethodLimit) { | 284 && (int)count_inline_bcs() >= DesiredMethodLimit) { |
268 return "size > DesiredMethodLimit"; | 285 return "size > DesiredMethodLimit"; |
269 } | 286 } |
270 | 287 |
271 const char *msg = NULL; | 288 const char *msg = NULL; |
272 if ((msg = shouldInline(callee_method, caller_method, caller_bci, | 289 msg = should_inline(callee_method, caller_method, caller_bci, profile, wci_result); |
273 profile, wci_result)) != NULL) { | 290 if (msg != NULL) |
274 return msg; | 291 return msg; |
275 } | 292 |
276 if ((msg = shouldNotInline(callee_method, caller_method, | 293 msg = should_not_inline(callee_method, caller_method, wci_result); |
277 wci_result)) != NULL) { | 294 if (msg != NULL) |
278 return msg; | 295 return msg; |
279 } | |
280 | 296 |
281 if (InlineAccessors && callee_method->is_accessor()) { | 297 if (InlineAccessors && callee_method->is_accessor()) { |
282 // accessor methods are not subject to any of the following limits. | 298 // accessor methods are not subject to any of the following limits. |
283 return NULL; | 299 return NULL; |
284 } | 300 } |
490 new_depth_adjust -= 1; // don't count actions in MH or indy adapter frames | 506 new_depth_adjust -= 1; // don't count actions in MH or indy adapter frames |
491 else if (callee_method->is_method_handle_invoke()) { | 507 else if (callee_method->is_method_handle_invoke()) { |
492 new_depth_adjust -= 1; // don't count method handle calls from java.lang.invoke implem | 508 new_depth_adjust -= 1; // don't count method handle calls from java.lang.invoke implem |
493 } | 509 } |
494 if (new_depth_adjust != 0 && PrintInlining) { | 510 if (new_depth_adjust != 0 && PrintInlining) { |
495 stringStream nm1; caller_jvms->method()->print_name(&nm1); | 511 CompileTask::print_inline_indent(inline_depth()); |
496 stringStream nm2; callee_method->print_name(&nm2); | 512 tty->print_cr(" \\-> discounting inline depth"); |
497 tty->print_cr("discounting inlining depth from %s to %s", nm1.base(), nm2.base()); | |
498 } | 513 } |
499 if (new_depth_adjust != 0 && C->log()) { | 514 if (new_depth_adjust != 0 && C->log()) { |
500 int id1 = C->log()->identify(caller_jvms->method()); | 515 int id1 = C->log()->identify(caller_jvms->method()); |
501 int id2 = C->log()->identify(callee_method); | 516 int id2 = C->log()->identify(callee_method); |
502 C->log()->elem("inline_depth_discount caller='%d' callee='%d'", id1, id2); | 517 C->log()->elem("inline_depth_discount caller='%d' callee='%d'", id1, id2); |