Mercurial > hg > truffle
comparison src/share/vm/opto/bytecodeInfo.cpp @ 14518:d8041d695d19
Merged with jdk9/dev/hotspot changeset 3812c088b945
author | twisti |
---|---|
date | Tue, 11 Mar 2014 18:45:59 -0700 |
parents | 096c224171c4 17ec2d5c43e8 |
children | 4ca6dc0799b6 |
comparison
equal
deleted
inserted
replaced
14141:f97c5ec83832 | 14518:d8041d695d19 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
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 _msg(NULL) |
52 { | 52 { |
53 NOT_PRODUCT(_count_inlines = 0;) | 53 #ifndef PRODUCT |
54 _count_inlines = 0; | |
55 _forced_inline = false; | |
56 #endif | |
54 if (_caller_jvms != NULL) { | 57 if (_caller_jvms != NULL) { |
55 // Keep a private copy of the caller_jvms: | 58 // Keep a private copy of the caller_jvms: |
56 _caller_jvms = new (C) JVMState(caller_jvms->method(), caller_tree->caller_jvms()); | 59 _caller_jvms = new (C) JVMState(caller_jvms->method(), caller_tree->caller_jvms()); |
57 _caller_jvms->set_bci(caller_jvms->bci()); | 60 _caller_jvms->set_bci(caller_jvms->bci()); |
58 assert(!caller_jvms->should_reexecute(), "there should be no reexecute bytecode with inlining"); | 61 assert(!caller_jvms->should_reexecute(), "there should be no reexecute bytecode with inlining"); |
59 } | 62 } |
60 assert(_caller_jvms->same_calls_as(caller_jvms), "consistent JVMS"); | 63 assert(_caller_jvms->same_calls_as(caller_jvms), "consistent JVMS"); |
61 assert((caller_tree == NULL ? 0 : caller_tree->stack_depth() + 1) == stack_depth(), "correct (redundant) depth parameter"); | 64 assert((caller_tree == NULL ? 0 : caller_tree->stack_depth() + 1) == stack_depth(), "correct (redundant) depth parameter"); |
62 assert(caller_bci == this->caller_bci(), "correct (redundant) bci parameter"); | 65 assert(caller_bci == this->caller_bci(), "correct (redundant) bci parameter"); |
63 if (UseOldInlining) { | 66 // Update hierarchical counts, count_inline_bcs() and count_inlines() |
64 // Update hierarchical counts, count_inline_bcs() and count_inlines() | 67 InlineTree *caller = (InlineTree *)caller_tree; |
65 InlineTree *caller = (InlineTree *)caller_tree; | 68 for( ; caller != NULL; caller = ((InlineTree *)(caller->caller_tree())) ) { |
66 for( ; caller != NULL; caller = ((InlineTree *)(caller->caller_tree())) ) { | 69 caller->_count_inline_bcs += count_inline_bcs(); |
67 caller->_count_inline_bcs += count_inline_bcs(); | 70 NOT_PRODUCT(caller->_count_inlines++;) |
68 NOT_PRODUCT(caller->_count_inlines++;) | 71 } |
69 } | |
70 } | |
71 } | |
72 | |
73 InlineTree::InlineTree(Compile* c, ciMethod* callee_method, JVMState* caller_jvms, | |
74 float site_invoke_ratio, int max_inline_level) : | |
75 C(c), | |
76 _caller_jvms(caller_jvms), | |
77 _caller_tree(NULL), | |
78 _method(callee_method), | |
79 _site_invoke_ratio(site_invoke_ratio), | |
80 _max_inline_level(max_inline_level), | |
81 _count_inline_bcs(method()->code_size()), | |
82 _msg(NULL) | |
83 { | |
84 NOT_PRODUCT(_count_inlines = 0;) | |
85 assert(!UseOldInlining, "do not use for old stuff"); | |
86 } | 72 } |
87 | 73 |
88 /** | 74 /** |
89 * Return true when EA is ON and a java constructor is called or | 75 * Return true when EA is ON and a java constructor is called or |
90 * a super constructor is called from an inlined java constructor. | 76 * a super constructor is called from an inlined java constructor. |
126 if (C->print_inlining() && Verbose) { | 112 if (C->print_inlining() && Verbose) { |
127 CompileTask::print_inline_indent(inline_level()); | 113 CompileTask::print_inline_indent(inline_level()); |
128 tty->print_cr("Inlined method is hot: "); | 114 tty->print_cr("Inlined method is hot: "); |
129 } | 115 } |
130 set_msg("force inline by CompilerOracle"); | 116 set_msg("force inline by CompilerOracle"); |
131 return true; | 117 _forced_inline = true; |
132 } | 118 return true; |
119 } | |
120 | |
121 #ifndef PRODUCT | |
122 int inline_depth = inline_level()+1; | |
123 if (ciReplay::should_inline(C->replay_inline_data(), callee_method, caller_bci, inline_depth)) { | |
124 set_msg("force inline by ciReplay"); | |
125 _forced_inline = true; | |
126 return true; | |
127 } | |
128 #endif | |
133 | 129 |
134 int size = callee_method->code_size_for_inlining(); | 130 int size = callee_method->code_size_for_inlining(); |
135 | 131 |
136 // Check for too many throws (and not too huge) | 132 // Check for too many throws (and not too huge) |
137 if(callee_method->interpreter_throwout_count() > InlineThrowCount && | 133 if(callee_method->interpreter_throwout_count() > InlineThrowCount && |
141 CompileTask::print_inline_indent(inline_level()); | 137 CompileTask::print_inline_indent(inline_level()); |
142 tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count()); | 138 tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count()); |
143 } | 139 } |
144 set_msg("many throws"); | 140 set_msg("many throws"); |
145 return true; | 141 return true; |
146 } | |
147 | |
148 if (!UseOldInlining) { | |
149 set_msg("!UseOldInlining"); | |
150 return true; // size and frequency are represented in a new way | |
151 } | 142 } |
152 | 143 |
153 int default_max_inline_size = C->max_inline_size(); | 144 int default_max_inline_size = C->max_inline_size(); |
154 int inline_small_code_size = InlineSmallCode / 4; | 145 int inline_small_code_size = InlineSmallCode / 4; |
155 int max_inline_size = default_max_inline_size; | 146 int max_inline_size = default_max_inline_size; |
211 fail_msg = "native method"; | 202 fail_msg = "native method"; |
212 } else if ( callee_method->dont_inline()) { | 203 } else if ( callee_method->dont_inline()) { |
213 fail_msg = "don't inline by annotation"; | 204 fail_msg = "don't inline by annotation"; |
214 } | 205 } |
215 | 206 |
216 if (!UseOldInlining) { | |
217 if (fail_msg != NULL) { | |
218 *wci_result = *(WarmCallInfo::always_cold()); | |
219 set_msg(fail_msg); | |
220 return true; | |
221 } | |
222 | |
223 if (callee_method->has_unloaded_classes_in_signature()) { | |
224 wci_result->set_profit(wci_result->profit() * 0.1); | |
225 } | |
226 | |
227 // don't inline exception code unless the top method belongs to an | |
228 // exception class | |
229 if (callee_method->holder()->is_subclass_of(C->env()->Throwable_klass())) { | |
230 ciMethod* top_method = jvms->caller() != NULL ? jvms->caller()->of_depth(1)->method() : method(); | |
231 if (!top_method->holder()->is_subclass_of(C->env()->Throwable_klass())) { | |
232 wci_result->set_profit(wci_result->profit() * 0.1); | |
233 } | |
234 } | |
235 | |
236 if (callee_method->has_compiled_code() && | |
237 callee_method->instructions_size() > InlineSmallCode) { | |
238 wci_result->set_profit(wci_result->profit() * 0.1); | |
239 // %%% adjust wci_result->size()? | |
240 } | |
241 | |
242 return false; | |
243 } | |
244 | |
245 // one more inlining restriction | 207 // one more inlining restriction |
246 if (fail_msg == NULL && callee_method->has_unloaded_classes_in_signature()) { | 208 if (fail_msg == NULL && callee_method->has_unloaded_classes_in_signature()) { |
247 fail_msg = "unloaded signature classes"; | 209 fail_msg = "unloaded signature classes"; |
248 } | 210 } |
249 | 211 |
262 set_msg("disallowed by CompilerOracle"); | 224 set_msg("disallowed by CompilerOracle"); |
263 return true; | 225 return true; |
264 } | 226 } |
265 | 227 |
266 #ifndef PRODUCT | 228 #ifndef PRODUCT |
229 int caller_bci = jvms->bci(); | |
230 int inline_depth = inline_level()+1; | |
231 if (ciReplay::should_inline(C->replay_inline_data(), callee_method, caller_bci, inline_depth)) { | |
232 set_msg("force inline by ciReplay"); | |
233 return false; | |
234 } | |
235 | |
236 if (ciReplay::should_not_inline(C->replay_inline_data(), callee_method, caller_bci, inline_depth)) { | |
237 set_msg("disallowed by ciReplay"); | |
238 return true; | |
239 } | |
240 | |
267 if (ciReplay::should_not_inline(callee_method)) { | 241 if (ciReplay::should_not_inline(callee_method)) { |
268 set_msg("disallowed by ciReplay"); | 242 set_msg("disallowed by ciReplay"); |
269 return true; | 243 return true; |
270 } | 244 } |
271 #endif | 245 #endif |
330 // Relocated from "InliningClosure::try_to_inline" | 304 // Relocated from "InliningClosure::try_to_inline" |
331 bool InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method, | 305 bool InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method, |
332 int caller_bci, JVMState* jvms, ciCallProfile& profile, | 306 int caller_bci, JVMState* jvms, ciCallProfile& profile, |
333 WarmCallInfo* wci_result, bool& should_delay) { | 307 WarmCallInfo* wci_result, bool& should_delay) { |
334 | 308 |
335 // Old algorithm had funny accumulating BC-size counters | 309 if (ClipInlining && (int)count_inline_bcs() >= DesiredMethodLimit) { |
336 if (UseOldInlining && ClipInlining | |
337 && (int)count_inline_bcs() >= DesiredMethodLimit) { | |
338 if (!callee_method->force_inline() || !IncrementalInline) { | 310 if (!callee_method->force_inline() || !IncrementalInline) { |
339 set_msg("size > DesiredMethodLimit"); | 311 set_msg("size > DesiredMethodLimit"); |
340 return false; | 312 return false; |
341 } else if (!C->inlining_incrementally()) { | 313 } else if (!C->inlining_incrementally()) { |
342 should_delay = true; | 314 should_delay = true; |
343 } | 315 } |
344 } | 316 } |
345 | 317 |
318 _forced_inline = false; // Reset | |
346 if (!should_inline(callee_method, caller_method, caller_bci, profile, | 319 if (!should_inline(callee_method, caller_method, caller_bci, profile, |
347 wci_result)) { | 320 wci_result)) { |
348 return false; | 321 return false; |
349 } | 322 } |
350 if (should_not_inline(callee_method, caller_method, jvms, wci_result)) { | 323 if (should_not_inline(callee_method, caller_method, jvms, wci_result)) { |
371 } | 344 } |
372 } | 345 } |
373 | 346 |
374 if ((!UseInterpreter || CompileTheWorld) && | 347 if ((!UseInterpreter || CompileTheWorld) && |
375 is_init_with_ea(callee_method, caller_method, C)) { | 348 is_init_with_ea(callee_method, caller_method, C)) { |
376 | |
377 // Escape Analysis stress testing when running Xcomp or CTW: | 349 // Escape Analysis stress testing when running Xcomp or CTW: |
378 // inline constructors even if they are not reached. | 350 // inline constructors even if they are not reached. |
379 | 351 } else if (forced_inline()) { |
352 // Inlining was forced by CompilerOracle or ciReplay | |
380 } else if (profile.count() == 0) { | 353 } else if (profile.count() == 0) { |
381 // don't inline unreached call sites | 354 // don't inline unreached call sites |
382 set_msg("call site not reached"); | 355 set_msg("call site not reached"); |
383 return false; | 356 return false; |
384 } | 357 } |
434 } | 407 } |
435 } | 408 } |
436 | 409 |
437 int size = callee_method->code_size_for_inlining(); | 410 int size = callee_method->code_size_for_inlining(); |
438 | 411 |
439 if (UseOldInlining && ClipInlining | 412 if (ClipInlining && (int)count_inline_bcs() + size >= DesiredMethodLimit) { |
440 && (int)count_inline_bcs() + size >= DesiredMethodLimit) { | |
441 if (!callee_method->force_inline() || !IncrementalInline) { | 413 if (!callee_method->force_inline() || !IncrementalInline) { |
442 set_msg("size > DesiredMethodLimit"); | 414 set_msg("size > DesiredMethodLimit"); |
443 return false; | 415 return false; |
444 } else if (!C->inlining_incrementally()) { | 416 } else if (!C->inlining_incrementally()) { |
445 should_delay = true; | 417 should_delay = true; |
553 WarmCallInfo wci = *(initial_wci); | 525 WarmCallInfo wci = *(initial_wci); |
554 bool success = try_to_inline(callee_method, caller_method, caller_bci, | 526 bool success = try_to_inline(callee_method, caller_method, caller_bci, |
555 jvms, profile, &wci, should_delay); | 527 jvms, profile, &wci, should_delay); |
556 | 528 |
557 #ifndef PRODUCT | 529 #ifndef PRODUCT |
558 if (UseOldInlining && InlineWarmCalls | 530 if (InlineWarmCalls && (PrintOpto || C->print_inlining())) { |
559 && (PrintOpto || C->print_inlining())) { | |
560 bool cold = wci.is_cold(); | 531 bool cold = wci.is_cold(); |
561 bool hot = !cold && wci.is_hot(); | 532 bool hot = !cold && wci.is_hot(); |
562 bool old_cold = !success; | 533 bool old_cold = !success; |
563 if (old_cold != cold || (Verbose || WizardMode)) { | 534 if (old_cold != cold || (Verbose || WizardMode)) { |
564 if (msg() == NULL) { | 535 if (msg() == NULL) { |
568 old_cold ? "cold" : "hot", msg()); | 539 old_cold ? "cold" : "hot", msg()); |
569 wci.print(); | 540 wci.print(); |
570 } | 541 } |
571 } | 542 } |
572 #endif | 543 #endif |
573 if (UseOldInlining) { | 544 if (success) { |
574 if (success) { | 545 wci = *(WarmCallInfo::always_hot()); |
575 wci = *(WarmCallInfo::always_hot()); | 546 } else { |
576 } else { | 547 wci = *(WarmCallInfo::always_cold()); |
577 wci = *(WarmCallInfo::always_cold()); | 548 } |
578 } | 549 |
579 } | |
580 if (!InlineWarmCalls) { | 550 if (!InlineWarmCalls) { |
581 if (!wci.is_cold() && !wci.is_hot()) { | 551 if (!wci.is_cold() && !wci.is_hot()) { |
582 // Do not inline the warm calls. | 552 // Do not inline the warm calls. |
583 wci = *(WarmCallInfo::always_cold()); | 553 wci = *(WarmCallInfo::always_cold()); |
584 } | 554 } |
588 // Inline! | 558 // Inline! |
589 if (msg() == NULL) { | 559 if (msg() == NULL) { |
590 set_msg("inline (hot)"); | 560 set_msg("inline (hot)"); |
591 } | 561 } |
592 print_inlining(callee_method, caller_bci, true /* success */); | 562 print_inlining(callee_method, caller_bci, true /* success */); |
593 if (UseOldInlining) | 563 build_inline_tree_for_callee(callee_method, jvms, caller_bci); |
594 build_inline_tree_for_callee(callee_method, jvms, caller_bci); | |
595 if (InlineWarmCalls && !wci.is_hot()) | 564 if (InlineWarmCalls && !wci.is_hot()) |
596 return new (C) WarmCallInfo(wci); // copy to heap | 565 return new (C) WarmCallInfo(wci); // copy to heap |
597 return WarmCallInfo::always_hot(); | 566 return WarmCallInfo::always_hot(); |
598 } | 567 } |
599 | 568 |
698 iltp = sub; | 667 iltp = sub; |
699 } | 668 } |
700 return iltp; | 669 return iltp; |
701 } | 670 } |
702 | 671 |
672 // Count number of nodes in this subtree | |
673 int InlineTree::count() const { | |
674 int result = 1; | |
675 for (int i = 0 ; i < _subtrees.length(); i++) { | |
676 result += _subtrees.at(i)->count(); | |
677 } | |
678 return result; | |
679 } | |
680 | |
681 void InlineTree::dump_replay_data(outputStream* out) { | |
682 out->print(" %d %d ", inline_level(), caller_bci()); | |
683 method()->dump_name_as_ascii(out); | |
684 for (int i = 0 ; i < _subtrees.length(); i++) { | |
685 _subtrees.at(i)->dump_replay_data(out); | |
686 } | |
687 } | |
703 | 688 |
704 | 689 |
705 #ifndef PRODUCT | 690 #ifndef PRODUCT |
706 void InlineTree::print_impl(outputStream* st, int indent) const { | 691 void InlineTree::print_impl(outputStream* st, int indent) const { |
707 for (int i = 0; i < indent; i++) st->print(" "); | 692 for (int i = 0; i < indent; i++) st->print(" "); |
708 st->print(" @ %d ", caller_bci()); | 693 st->print(" @ %d", caller_bci()); |
709 method()->print_short_name(st); | 694 method()->print_short_name(st); |
710 st->cr(); | 695 st->cr(); |
711 | 696 |
712 for (int i = 0 ; i < _subtrees.length(); i++) { | 697 for (int i = 0 ; i < _subtrees.length(); i++) { |
713 _subtrees.at(i)->print_impl(st, indent + 2); | 698 _subtrees.at(i)->print_impl(st, indent + 2); |