Mercurial > hg > truffle
comparison src/share/vm/opto/bytecodeInfo.cpp @ 8119:133bf557ef77
8007439: C2: adding successful message of inlining
Reviewed-by: kvn, vlivanov
author | iignatyev |
---|---|
date | Wed, 27 Feb 2013 05:58:48 -0800 |
parents | 60bba1398c51 |
children | 5fc51c1ecdeb 80208f353616 |
comparison
equal
deleted
inserted
replaced
8079:ad736b4683b4 | 8119:133bf557ef77 |
---|---|
45 _caller_tree((InlineTree*) caller_tree), | 45 _caller_tree((InlineTree*) caller_tree), |
46 _method(callee), | 46 _method(callee), |
47 _site_invoke_ratio(site_invoke_ratio), | 47 _site_invoke_ratio(site_invoke_ratio), |
48 _max_inline_level(max_inline_level), | 48 _max_inline_level(max_inline_level), |
49 _count_inline_bcs(method()->code_size_for_inlining()), | 49 _count_inline_bcs(method()->code_size_for_inlining()), |
50 _subtrees(c->comp_arena(), 2, 0, NULL) | 50 _subtrees(c->comp_arena(), 2, 0, NULL), |
51 _msg(NULL) | |
51 { | 52 { |
52 NOT_PRODUCT(_count_inlines = 0;) | 53 NOT_PRODUCT(_count_inlines = 0;) |
53 if (_caller_jvms != NULL) { | 54 if (_caller_jvms != NULL) { |
54 // Keep a private copy of the caller_jvms: | 55 // Keep a private copy of the caller_jvms: |
55 _caller_jvms = new (C) JVMState(caller_jvms->method(), caller_tree->caller_jvms()); | 56 _caller_jvms = new (C) JVMState(caller_jvms->method(), caller_tree->caller_jvms()); |
75 _caller_jvms(caller_jvms), | 76 _caller_jvms(caller_jvms), |
76 _caller_tree(NULL), | 77 _caller_tree(NULL), |
77 _method(callee_method), | 78 _method(callee_method), |
78 _site_invoke_ratio(site_invoke_ratio), | 79 _site_invoke_ratio(site_invoke_ratio), |
79 _max_inline_level(max_inline_level), | 80 _max_inline_level(max_inline_level), |
80 _count_inline_bcs(method()->code_size()) | 81 _count_inline_bcs(method()->code_size()), |
82 _msg(NULL) | |
81 { | 83 { |
82 NOT_PRODUCT(_count_inlines = 0;) | 84 NOT_PRODUCT(_count_inlines = 0;) |
83 assert(!UseOldInlining, "do not use for old stuff"); | 85 assert(!UseOldInlining, "do not use for old stuff"); |
84 } | 86 } |
85 | 87 |
93 caller_method != C->method() && | 95 caller_method != C->method() && |
94 caller_method->holder()->is_subclass_of(callee_method->holder())) | 96 caller_method->holder()->is_subclass_of(callee_method->holder())) |
95 ); | 97 ); |
96 } | 98 } |
97 | 99 |
98 // positive filter: should callee be inlined? returns NULL, if yes, or rejection msg | 100 // positive filter: should callee be inlined? |
99 const char* InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const { | 101 bool InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method, |
102 int caller_bci, ciCallProfile& profile, | |
103 WarmCallInfo* wci_result) { | |
100 // Allows targeted inlining | 104 // Allows targeted inlining |
101 if(callee_method->should_inline()) { | 105 if(callee_method->should_inline()) { |
102 *wci_result = *(WarmCallInfo::always_hot()); | 106 *wci_result = *(WarmCallInfo::always_hot()); |
103 if (PrintInlining && Verbose) { | 107 if (PrintInlining && Verbose) { |
104 CompileTask::print_inline_indent(inline_level()); | 108 CompileTask::print_inline_indent(inline_level()); |
105 tty->print_cr("Inlined method is hot: "); | 109 tty->print_cr("Inlined method is hot: "); |
106 } | 110 } |
107 return NULL; | 111 set_msg("force inline by CompilerOracle"); |
108 } | 112 return true; |
109 | 113 } |
110 // positive filter: should send be inlined? returns NULL (--> yes) | 114 |
111 // or rejection msg | |
112 int size = callee_method->code_size_for_inlining(); | 115 int size = callee_method->code_size_for_inlining(); |
113 | 116 |
114 // Check for too many throws (and not too huge) | 117 // Check for too many throws (and not too huge) |
115 if(callee_method->interpreter_throwout_count() > InlineThrowCount && | 118 if(callee_method->interpreter_throwout_count() > InlineThrowCount && |
116 size < InlineThrowMaxSize ) { | 119 size < InlineThrowMaxSize ) { |
117 wci_result->set_profit(wci_result->profit() * 100); | 120 wci_result->set_profit(wci_result->profit() * 100); |
118 if (PrintInlining && Verbose) { | 121 if (PrintInlining && Verbose) { |
119 CompileTask::print_inline_indent(inline_level()); | 122 CompileTask::print_inline_indent(inline_level()); |
120 tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count()); | 123 tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count()); |
121 } | 124 } |
122 return NULL; | 125 set_msg("many throws"); |
126 return true; | |
123 } | 127 } |
124 | 128 |
125 if (!UseOldInlining) { | 129 if (!UseOldInlining) { |
126 return NULL; // size and frequency are represented in a new way | 130 set_msg("!UseOldInlining"); |
131 return true; // size and frequency are represented in a new way | |
127 } | 132 } |
128 | 133 |
129 int default_max_inline_size = C->max_inline_size(); | 134 int default_max_inline_size = C->max_inline_size(); |
130 int inline_small_code_size = InlineSmallCode / 4; | 135 int inline_small_code_size = InlineSmallCode / 4; |
131 int max_inline_size = default_max_inline_size; | 136 int max_inline_size = default_max_inline_size; |
151 } | 156 } |
152 } else { | 157 } else { |
153 // Not hot. Check for medium-sized pre-existing nmethod at cold sites. | 158 // Not hot. Check for medium-sized pre-existing nmethod at cold sites. |
154 if (callee_method->has_compiled_code() && | 159 if (callee_method->has_compiled_code() && |
155 callee_method->instructions_size() > inline_small_code_size) | 160 callee_method->instructions_size() > inline_small_code_size) |
156 return "already compiled into a medium method"; | 161 set_msg("already compiled into a medium method"); |
162 return false; | |
157 } | 163 } |
158 if (size > max_inline_size) { | 164 if (size > max_inline_size) { |
159 if (max_inline_size > default_max_inline_size) | 165 if (max_inline_size > default_max_inline_size) { |
160 return "hot method too big"; | 166 set_msg("hot method too big"); |
161 return "too big"; | 167 } else { |
162 } | 168 set_msg("too big"); |
163 return NULL; | 169 } |
164 } | 170 return false; |
165 | 171 } |
166 | 172 return true; |
167 // negative filter: should callee NOT be inlined? returns NULL, ok to inline, or rejection msg | 173 } |
168 const char* InlineTree::should_not_inline(ciMethod *callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const { | 174 |
169 // negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg | 175 |
176 // negative filter: should callee NOT be inlined? | |
177 bool InlineTree::should_not_inline(ciMethod *callee_method, | |
178 ciMethod* caller_method, | |
179 WarmCallInfo* wci_result) { | |
180 | |
181 const char* fail_msg = NULL; | |
182 | |
183 // First check all inlining restrictions which are required for correctness | |
184 if ( callee_method->is_abstract()) { | |
185 fail_msg = "abstract method"; // // note: we allow ik->is_abstract() | |
186 } else if (!callee_method->holder()->is_initialized()) { | |
187 fail_msg = "method holder not initialized"; | |
188 } else if ( callee_method->is_native()) { | |
189 fail_msg = "native method"; | |
190 } else if ( callee_method->dont_inline()) { | |
191 fail_msg = "don't inline by annotation"; | |
192 } | |
193 | |
170 if (!UseOldInlining) { | 194 if (!UseOldInlining) { |
171 const char* fail = NULL; | 195 if (fail_msg != NULL) { |
172 if ( callee_method->is_abstract()) fail = "abstract method"; | |
173 // note: we allow ik->is_abstract() | |
174 if (!callee_method->holder()->is_initialized()) fail = "method holder not initialized"; | |
175 if ( callee_method->is_native()) fail = "native method"; | |
176 if ( callee_method->dont_inline()) fail = "don't inline by annotation"; | |
177 | |
178 if (fail) { | |
179 *wci_result = *(WarmCallInfo::always_cold()); | 196 *wci_result = *(WarmCallInfo::always_cold()); |
180 return fail; | 197 set_msg(fail_msg); |
198 return true; | |
181 } | 199 } |
182 | 200 |
183 if (callee_method->has_unloaded_classes_in_signature()) { | 201 if (callee_method->has_unloaded_classes_in_signature()) { |
184 wci_result->set_profit(wci_result->profit() * 0.1); | 202 wci_result->set_profit(wci_result->profit() * 0.1); |
185 } | 203 } |
197 callee_method->instructions_size() > InlineSmallCode) { | 215 callee_method->instructions_size() > InlineSmallCode) { |
198 wci_result->set_profit(wci_result->profit() * 0.1); | 216 wci_result->set_profit(wci_result->profit() * 0.1); |
199 // %%% adjust wci_result->size()? | 217 // %%% adjust wci_result->size()? |
200 } | 218 } |
201 | 219 |
202 return NULL; | 220 return false; |
203 } | 221 } |
204 | 222 |
205 // First check all inlining restrictions which are required for correctness | 223 // one more inlining restriction |
206 if ( callee_method->is_abstract()) return "abstract method"; | 224 if (fail_msg == NULL && callee_method->has_unloaded_classes_in_signature()) { |
207 // note: we allow ik->is_abstract() | 225 fail_msg = "unloaded signature classes"; |
208 if (!callee_method->holder()->is_initialized()) return "method holder not initialized"; | 226 } |
209 if ( callee_method->is_native()) return "native method"; | 227 |
210 if ( callee_method->dont_inline()) return "don't inline by annotation"; | 228 if (fail_msg != NULL) { |
211 if ( callee_method->has_unloaded_classes_in_signature()) return "unloaded signature classes"; | 229 set_msg(fail_msg); |
212 | 230 return true; |
231 } | |
232 | |
233 // ignore heuristic controls on inlining | |
213 if (callee_method->should_inline()) { | 234 if (callee_method->should_inline()) { |
214 // ignore heuristic controls on inlining | 235 set_msg("force inline by CompilerOracle"); |
215 return NULL; | 236 return false; |
216 } | 237 } |
217 | 238 |
218 // Now perform checks which are heuristic | 239 // Now perform checks which are heuristic |
219 | 240 |
220 if (!callee_method->force_inline()) { | 241 if (!callee_method->force_inline()) { |
221 if (callee_method->has_compiled_code() && | 242 if (callee_method->has_compiled_code() && |
222 callee_method->instructions_size() > InlineSmallCode) { | 243 callee_method->instructions_size() > InlineSmallCode) { |
223 return "already compiled into a big method"; | 244 set_msg("already compiled into a big method"); |
245 return true; | |
224 } | 246 } |
225 } | 247 } |
226 | 248 |
227 // don't inline exception code unless the top method belongs to an | 249 // don't inline exception code unless the top method belongs to an |
228 // exception class | 250 // exception class |
229 if (caller_tree() != NULL && | 251 if (caller_tree() != NULL && |
230 callee_method->holder()->is_subclass_of(C->env()->Throwable_klass())) { | 252 callee_method->holder()->is_subclass_of(C->env()->Throwable_klass())) { |
231 const InlineTree *top = this; | 253 const InlineTree *top = this; |
232 while (top->caller_tree() != NULL) top = top->caller_tree(); | 254 while (top->caller_tree() != NULL) top = top->caller_tree(); |
233 ciInstanceKlass* k = top->method()->holder(); | 255 ciInstanceKlass* k = top->method()->holder(); |
234 if (!k->is_subclass_of(C->env()->Throwable_klass())) | 256 if (!k->is_subclass_of(C->env()->Throwable_klass())) { |
235 return "exception method"; | 257 set_msg("exception method"); |
258 return true; | |
259 } | |
236 } | 260 } |
237 | 261 |
238 if (callee_method->should_not_inline()) { | 262 if (callee_method->should_not_inline()) { |
239 return "disallowed by CompilerOracle"; | 263 set_msg("disallowed by CompilerOracle"); |
264 return true; | |
240 } | 265 } |
241 | 266 |
242 #ifndef PRODUCT | 267 #ifndef PRODUCT |
243 if (ciReplay::should_not_inline(callee_method)) { | 268 if (ciReplay::should_not_inline(callee_method)) { |
244 return "disallowed by ciReplay"; | 269 set_msg("disallowed by ciReplay"); |
270 return true; | |
245 } | 271 } |
246 #endif | 272 #endif |
247 | 273 |
248 if (UseStringCache) { | 274 if (UseStringCache) { |
249 // Do not inline StringCache::profile() method used only at the beginning. | 275 // Do not inline StringCache::profile() method used only at the beginning. |
250 if (callee_method->name() == ciSymbol::profile_name() && | 276 if (callee_method->name() == ciSymbol::profile_name() && |
251 callee_method->holder()->name() == ciSymbol::java_lang_StringCache()) { | 277 callee_method->holder()->name() == ciSymbol::java_lang_StringCache()) { |
252 return "profiling method"; | 278 set_msg("profiling method"); |
279 return true; | |
253 } | 280 } |
254 } | 281 } |
255 | 282 |
256 // use frequency-based objections only for non-trivial methods | 283 // use frequency-based objections only for non-trivial methods |
257 if (callee_method->code_size() <= MaxTrivialSize) return NULL; | 284 if (callee_method->code_size() <= MaxTrivialSize) { |
285 return false; | |
286 } | |
258 | 287 |
259 // don't use counts with -Xcomp or CTW | 288 // don't use counts with -Xcomp or CTW |
260 if (UseInterpreter && !CompileTheWorld) { | 289 if (UseInterpreter && !CompileTheWorld) { |
261 | 290 |
262 if (!callee_method->has_compiled_code() && | 291 if (!callee_method->has_compiled_code() && |
263 !callee_method->was_executed_more_than(0)) { | 292 !callee_method->was_executed_more_than(0)) { |
264 return "never executed"; | 293 set_msg("never executed"); |
294 return true; | |
265 } | 295 } |
266 | 296 |
267 if (is_init_with_ea(callee_method, caller_method, C)) { | 297 if (is_init_with_ea(callee_method, caller_method, C)) { |
268 | 298 |
269 // Escape Analysis: inline all executed constructors | 299 // Escape Analysis: inline all executed constructors |
270 | 300 |
271 } else if (!callee_method->was_executed_more_than(MIN2(MinInliningThreshold, | 301 } else if (!callee_method->was_executed_more_than(MIN2(MinInliningThreshold, |
272 CompileThreshold >> 1))) { | 302 CompileThreshold >> 1))) { |
273 return "executed < MinInliningThreshold times"; | 303 set_msg("executed < MinInliningThreshold times"); |
274 } | 304 return true; |
275 } | 305 } |
276 | 306 } |
277 return NULL; | 307 |
308 return false; | |
278 } | 309 } |
279 | 310 |
280 //-----------------------------try_to_inline----------------------------------- | 311 //-----------------------------try_to_inline----------------------------------- |
281 // return NULL if ok, reason for not inlining otherwise | 312 // return true if ok |
282 // Relocated from "InliningClosure::try_to_inline" | 313 // Relocated from "InliningClosure::try_to_inline" |
283 const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result, bool& should_delay) { | 314 bool InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method, |
284 // Old algorithm had funny accumulating BC-size counters | 315 int caller_bci, ciCallProfile& profile, |
316 WarmCallInfo* wci_result, bool& should_delay) { | |
317 | |
318 // Old algorithm had funny accumulating BC-size counters | |
285 if (UseOldInlining && ClipInlining | 319 if (UseOldInlining && ClipInlining |
286 && (int)count_inline_bcs() >= DesiredMethodLimit) { | 320 && (int)count_inline_bcs() >= DesiredMethodLimit) { |
287 if (!callee_method->force_inline() || !IncrementalInline) { | 321 if (!callee_method->force_inline() || !IncrementalInline) { |
288 return "size > DesiredMethodLimit"; | 322 set_msg("size > DesiredMethodLimit"); |
323 return false; | |
289 } else if (!C->inlining_incrementally()) { | 324 } else if (!C->inlining_incrementally()) { |
290 should_delay = true; | 325 should_delay = true; |
291 } | 326 } |
292 } | 327 } |
293 | 328 |
294 const char *msg = NULL; | 329 if (!should_inline(callee_method, caller_method, caller_bci, profile, |
295 msg = should_inline(callee_method, caller_method, caller_bci, profile, wci_result); | 330 wci_result)) { |
296 if (msg != NULL) | 331 return false; |
297 return msg; | 332 } |
298 | 333 if (should_not_inline(callee_method, caller_method, wci_result)) { |
299 msg = should_not_inline(callee_method, caller_method, wci_result); | 334 return false; |
300 if (msg != NULL) | 335 } |
301 return msg; | |
302 | 336 |
303 if (InlineAccessors && callee_method->is_accessor()) { | 337 if (InlineAccessors && callee_method->is_accessor()) { |
304 // accessor methods are not subject to any of the following limits. | 338 // accessor methods are not subject to any of the following limits. |
305 return NULL; | 339 set_msg("accessor"); |
340 return true; | |
306 } | 341 } |
307 | 342 |
308 // suppress a few checks for accessors and trivial methods | 343 // suppress a few checks for accessors and trivial methods |
309 if (callee_method->code_size() > MaxTrivialSize) { | 344 if (callee_method->code_size() > MaxTrivialSize) { |
310 | 345 |
311 // don't inline into giant methods | 346 // don't inline into giant methods |
312 if (C->over_inlining_cutoff()) { | 347 if (C->over_inlining_cutoff()) { |
313 if ((!callee_method->force_inline() && !caller_method->is_compiled_lambda_form()) | 348 if ((!callee_method->force_inline() && !caller_method->is_compiled_lambda_form()) |
314 || !IncrementalInline) { | 349 || !IncrementalInline) { |
315 return "NodeCountInliningCutoff"; | 350 set_msg("NodeCountInliningCutoff"); |
351 return false; | |
316 } else { | 352 } else { |
317 should_delay = true; | 353 should_delay = true; |
318 } | 354 } |
319 } | 355 } |
320 | 356 |
324 // Escape Analysis stress testing when running Xcomp or CTW: | 360 // Escape Analysis stress testing when running Xcomp or CTW: |
325 // inline constructors even if they are not reached. | 361 // inline constructors even if they are not reached. |
326 | 362 |
327 } else if (profile.count() == 0) { | 363 } else if (profile.count() == 0) { |
328 // don't inline unreached call sites | 364 // don't inline unreached call sites |
329 return "call site not reached"; | 365 set_msg("call site not reached"); |
366 return false; | |
330 } | 367 } |
331 } | 368 } |
332 | 369 |
333 if (!C->do_inlining() && InlineAccessors) { | 370 if (!C->do_inlining() && InlineAccessors) { |
334 return "not an accessor"; | 371 set_msg("not an accessor"); |
372 return false; | |
335 } | 373 } |
336 if (inline_level() > _max_inline_level) { | 374 if (inline_level() > _max_inline_level) { |
337 if (!callee_method->force_inline() || !IncrementalInline) { | 375 if (!callee_method->force_inline() || !IncrementalInline) { |
338 return "inlining too deep"; | 376 set_msg("inlining too deep"); |
377 return false; | |
339 } else if (!C->inlining_incrementally()) { | 378 } else if (!C->inlining_incrementally()) { |
340 should_delay = true; | 379 should_delay = true; |
341 } | 380 } |
342 } | 381 } |
343 | 382 |
344 // detect direct and indirect recursive inlining | 383 // detect direct and indirect recursive inlining |
345 if (!callee_method->is_compiled_lambda_form()) { | 384 if (!callee_method->is_compiled_lambda_form()) { |
346 // count the current method and the callee | 385 // count the current method and the callee |
347 int inline_level = (method() == callee_method) ? 1 : 0; | 386 int inline_level = (method() == callee_method) ? 1 : 0; |
348 if (inline_level > MaxRecursiveInlineLevel) | 387 if (inline_level > MaxRecursiveInlineLevel) { |
349 return "recursively inlining too deep"; | 388 set_msg("recursively inlining too deep"); |
389 return false; | |
390 } | |
350 // count callers of current method and callee | 391 // count callers of current method and callee |
351 JVMState* jvms = caller_jvms(); | 392 JVMState* jvms = caller_jvms(); |
352 while (jvms != NULL && jvms->has_method()) { | 393 while (jvms != NULL && jvms->has_method()) { |
353 if (jvms->method() == callee_method) { | 394 if (jvms->method() == callee_method) { |
354 inline_level++; | 395 inline_level++; |
355 if (inline_level > MaxRecursiveInlineLevel) | 396 if (inline_level > MaxRecursiveInlineLevel) { |
356 return "recursively inlining too deep"; | 397 set_msg("recursively inlining too deep"); |
398 return false; | |
399 } | |
357 } | 400 } |
358 jvms = jvms->caller(); | 401 jvms = jvms->caller(); |
359 } | 402 } |
360 } | 403 } |
361 | 404 |
362 int size = callee_method->code_size_for_inlining(); | 405 int size = callee_method->code_size_for_inlining(); |
363 | 406 |
364 if (UseOldInlining && ClipInlining | 407 if (UseOldInlining && ClipInlining |
365 && (int)count_inline_bcs() + size >= DesiredMethodLimit) { | 408 && (int)count_inline_bcs() + size >= DesiredMethodLimit) { |
366 if (!callee_method->force_inline() || !IncrementalInline) { | 409 if (!callee_method->force_inline() || !IncrementalInline) { |
367 return "size > DesiredMethodLimit"; | 410 set_msg("size > DesiredMethodLimit"); |
411 return false; | |
368 } else if (!C->inlining_incrementally()) { | 412 } else if (!C->inlining_incrementally()) { |
369 should_delay = true; | 413 should_delay = true; |
370 } | 414 } |
371 } | 415 } |
372 | 416 |
373 // ok, inline this method | 417 // ok, inline this method |
374 return NULL; | 418 return true; |
375 } | 419 } |
376 | 420 |
377 //------------------------------pass_initial_checks---------------------------- | 421 //------------------------------pass_initial_checks---------------------------- |
378 bool pass_initial_checks(ciMethod* caller_method, int caller_bci, ciMethod* callee_method) { | 422 bool pass_initial_checks(ciMethod* caller_method, int caller_bci, ciMethod* callee_method) { |
379 ciInstanceKlass *callee_holder = callee_method ? callee_method->holder() : NULL; | 423 ciInstanceKlass *callee_holder = callee_method ? callee_method->holder() : NULL; |
419 return NULL; | 463 return NULL; |
420 } | 464 } |
421 | 465 |
422 //------------------------------print_inlining--------------------------------- | 466 //------------------------------print_inlining--------------------------------- |
423 void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci, | 467 void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci, |
424 const char* msg, bool success) const { | 468 bool success) const { |
425 assert(msg != NULL, "just checking"); | 469 const char* inline_msg = msg(); |
470 assert(inline_msg != NULL, "just checking"); | |
426 if (C->log() != NULL) { | 471 if (C->log() != NULL) { |
427 if (success) { | 472 if (success) { |
428 C->log()->inline_success(msg); | 473 C->log()->inline_success(inline_msg); |
429 } else { | 474 } else { |
430 C->log()->inline_fail(msg); | 475 C->log()->inline_fail(inline_msg); |
431 } | 476 } |
432 } | 477 } |
433 if (PrintInlining) { | 478 if (PrintInlining) { |
434 C->print_inlining(callee_method, inline_level(), caller_bci, msg); | 479 C->print_inlining(callee_method, inline_level(), caller_bci, inline_msg); |
435 if (callee_method == NULL) tty->print(" callee not monotonic or profiled"); | 480 if (callee_method == NULL) tty->print(" callee not monotonic or profiled"); |
436 if (Verbose && callee_method) { | 481 if (Verbose && callee_method) { |
437 const InlineTree *top = this; | 482 const InlineTree *top = this; |
438 while( top->caller_tree() != NULL ) { top = top->caller_tree(); } | 483 while( top->caller_tree() != NULL ) { top = top->caller_tree(); } |
439 //tty->print(" bcs: %d+%d invoked: %d", top->count_inline_bcs(), callee_method->code_size(), callee_method->interpreter_invocation_count()); | 484 //tty->print(" bcs: %d+%d invoked: %d", top->count_inline_bcs(), callee_method->code_size(), callee_method->interpreter_invocation_count()); |
453 } else { | 498 } else { |
454 assert(_caller_jvms->same_calls_as(jvms->caller()), "redundant instance state"); | 499 assert(_caller_jvms->same_calls_as(jvms->caller()), "redundant instance state"); |
455 } | 500 } |
456 assert(_method == jvms->method(), "redundant instance state"); | 501 assert(_method == jvms->method(), "redundant instance state"); |
457 #endif | 502 #endif |
458 const char *failure_msg = NULL; | |
459 int caller_bci = jvms->bci(); | 503 int caller_bci = jvms->bci(); |
460 ciMethod *caller_method = jvms->method(); | 504 ciMethod* caller_method = jvms->method(); |
461 | 505 |
462 // Do some initial checks. | 506 // Do some initial checks. |
463 if (!pass_initial_checks(caller_method, caller_bci, callee_method)) { | 507 if (!pass_initial_checks(caller_method, caller_bci, callee_method)) { |
464 print_inlining(callee_method, caller_bci, "failed initial checks", | 508 set_msg("failed initial checks"); |
465 false /* !success */); | 509 print_inlining(callee_method, caller_bci, false /* !success */); |
466 return NULL; | 510 return NULL; |
467 } | 511 } |
468 | 512 |
469 // Do some parse checks. | 513 // Do some parse checks. |
470 failure_msg = check_can_parse(callee_method); | 514 set_msg(check_can_parse(callee_method)); |
471 if (failure_msg != NULL) { | 515 if (msg() != NULL) { |
472 print_inlining(callee_method, caller_bci, failure_msg, | 516 print_inlining(callee_method, caller_bci, false /* !success */); |
473 false /* !success */); | |
474 return NULL; | 517 return NULL; |
475 } | 518 } |
476 | 519 |
477 // Check if inlining policy says no. | 520 // Check if inlining policy says no. |
478 WarmCallInfo wci = *(initial_wci); | 521 WarmCallInfo wci = *(initial_wci); |
479 failure_msg = try_to_inline(callee_method, caller_method, caller_bci, profile, | 522 bool success = try_to_inline(callee_method, caller_method, caller_bci, |
480 &wci, should_delay); | 523 profile, &wci, should_delay); |
481 | 524 |
482 #ifndef PRODUCT | 525 #ifndef PRODUCT |
483 if (UseOldInlining && InlineWarmCalls | 526 if (UseOldInlining && InlineWarmCalls |
484 && (PrintOpto || PrintOptoInlining || PrintInlining)) { | 527 && (PrintOpto || PrintOptoInlining || PrintInlining)) { |
485 bool cold = wci.is_cold(); | 528 bool cold = wci.is_cold(); |
486 bool hot = !cold && wci.is_hot(); | 529 bool hot = !cold && wci.is_hot(); |
487 bool old_cold = (failure_msg != NULL); | 530 bool old_cold = !success; |
488 if (old_cold != cold || (Verbose || WizardMode)) { | 531 if (old_cold != cold || (Verbose || WizardMode)) { |
532 if (msg() == NULL) { | |
533 set_msg("OK"); | |
534 } | |
489 tty->print(" OldInlining= %4s : %s\n WCI=", | 535 tty->print(" OldInlining= %4s : %s\n WCI=", |
490 old_cold ? "cold" : "hot", failure_msg ? failure_msg : "OK"); | 536 old_cold ? "cold" : "hot", msg()); |
491 wci.print(); | 537 wci.print(); |
492 } | 538 } |
493 } | 539 } |
494 #endif | 540 #endif |
495 if (UseOldInlining) { | 541 if (UseOldInlining) { |
496 if (failure_msg == NULL) | 542 if (success) { |
497 wci = *(WarmCallInfo::always_hot()); | 543 wci = *(WarmCallInfo::always_hot()); |
498 else | 544 } else { |
499 wci = *(WarmCallInfo::always_cold()); | 545 wci = *(WarmCallInfo::always_cold()); |
500 } | 546 } |
547 } | |
501 if (!InlineWarmCalls) { | 548 if (!InlineWarmCalls) { |
502 if (!wci.is_cold() && !wci.is_hot()) { | 549 if (!wci.is_cold() && !wci.is_hot()) { |
503 // Do not inline the warm calls. | 550 // Do not inline the warm calls. |
504 wci = *(WarmCallInfo::always_cold()); | 551 wci = *(WarmCallInfo::always_cold()); |
505 } | 552 } |
506 } | 553 } |
507 | 554 |
508 if (!wci.is_cold()) { | 555 if (!wci.is_cold()) { |
509 // Inline! | 556 // Inline! |
510 print_inlining(callee_method, caller_bci, | 557 if (msg() == NULL) { |
511 failure_msg ? failure_msg : "inline (hot)", | 558 set_msg("inline (hot)"); |
512 true /* success */); | 559 } |
560 print_inlining(callee_method, caller_bci, true /* success */); | |
513 if (UseOldInlining) | 561 if (UseOldInlining) |
514 build_inline_tree_for_callee(callee_method, jvms, caller_bci); | 562 build_inline_tree_for_callee(callee_method, jvms, caller_bci); |
515 if (InlineWarmCalls && !wci.is_hot()) | 563 if (InlineWarmCalls && !wci.is_hot()) |
516 return new (C) WarmCallInfo(wci); // copy to heap | 564 return new (C) WarmCallInfo(wci); // copy to heap |
517 return WarmCallInfo::always_hot(); | 565 return WarmCallInfo::always_hot(); |
518 } | 566 } |
519 | 567 |
520 // Do not inline | 568 // Do not inline |
521 print_inlining(callee_method, caller_bci, | 569 if (msg() == NULL) { |
522 failure_msg ? failure_msg : "too cold to inline", | 570 set_msg("too cold to inline"); |
523 false /* !success */ ); | 571 } |
572 print_inlining(callee_method, caller_bci, false /* !success */ ); | |
524 return NULL; | 573 return NULL; |
525 } | 574 } |
526 | 575 |
527 //------------------------------compute_callee_frequency----------------------- | 576 //------------------------------compute_callee_frequency----------------------- |
528 float InlineTree::compute_callee_frequency( int caller_bci ) const { | 577 float InlineTree::compute_callee_frequency( int caller_bci ) const { |