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()); |
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); |