comparison src/share/vm/opto/bytecodeInfo.cpp @ 2405:3d58a4983660

7022998: JSR 292 recursive method handle calls inline themselves infinitely Reviewed-by: never, kvn
author twisti
date Mon, 28 Mar 2011 03:58:07 -0700
parents 8033953d67ff
children b21ecca7ccc4
comparison
equal deleted inserted replaced
2404:b40d4fa697bf 2405:3d58a4983660
23 */ 23 */
24 24
25 #include "precompiled.hpp" 25 #include "precompiled.hpp"
26 #include "classfile/systemDictionary.hpp" 26 #include "classfile/systemDictionary.hpp"
27 #include "classfile/vmSymbols.hpp" 27 #include "classfile/vmSymbols.hpp"
28 #include "compiler/compileBroker.hpp"
28 #include "compiler/compileLog.hpp" 29 #include "compiler/compileLog.hpp"
29 #include "interpreter/linkResolver.hpp" 30 #include "interpreter/linkResolver.hpp"
30 #include "oops/objArrayKlass.hpp" 31 #include "oops/objArrayKlass.hpp"
31 #include "opto/callGenerator.hpp" 32 #include "opto/callGenerator.hpp"
32 #include "opto/parse.hpp" 33 #include "opto/parse.hpp"
73 { 74 {
74 NOT_PRODUCT(_count_inlines = 0;) 75 NOT_PRODUCT(_count_inlines = 0;)
75 assert(!UseOldInlining, "do not use for old stuff"); 76 assert(!UseOldInlining, "do not use for old stuff");
76 } 77 }
77 78
78
79
80 static void print_indent(int depth) {
81 tty->print(" ");
82 for (int i = depth; i != 0; --i) tty->print(" ");
83 }
84
85 static bool is_init_with_ea(ciMethod* callee_method, 79 static bool is_init_with_ea(ciMethod* callee_method,
86 ciMethod* caller_method, Compile* C) { 80 ciMethod* caller_method, Compile* C) {
87 // True when EA is ON and a java constructor is called or 81 // True when EA is ON and a java constructor is called or
88 // a super constructor is called from an inlined java constructor. 82 // a super constructor is called from an inlined java constructor.
89 return C->do_escape_analysis() && EliminateAllocations && 83 return C->do_escape_analysis() && EliminateAllocations &&
98 const char* InlineTree::shouldInline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const { 92 const char* InlineTree::shouldInline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const {
99 // Allows targeted inlining 93 // Allows targeted inlining
100 if(callee_method->should_inline()) { 94 if(callee_method->should_inline()) {
101 *wci_result = *(WarmCallInfo::always_hot()); 95 *wci_result = *(WarmCallInfo::always_hot());
102 if (PrintInlining && Verbose) { 96 if (PrintInlining && Verbose) {
103 print_indent(inline_depth()); 97 CompileTask::print_inline_indent(inline_depth());
104 tty->print_cr("Inlined method is hot: "); 98 tty->print_cr("Inlined method is hot: ");
105 } 99 }
106 return NULL; 100 return NULL;
107 } 101 }
108 102
114 // Check for too many throws (and not too huge) 108 // Check for too many throws (and not too huge)
115 if(callee_method->interpreter_throwout_count() > InlineThrowCount && 109 if(callee_method->interpreter_throwout_count() > InlineThrowCount &&
116 size < InlineThrowMaxSize ) { 110 size < InlineThrowMaxSize ) {
117 wci_result->set_profit(wci_result->profit() * 100); 111 wci_result->set_profit(wci_result->profit() * 100);
118 if (PrintInlining && Verbose) { 112 if (PrintInlining && Verbose) {
119 print_indent(inline_depth()); 113 CompileTask::print_inline_indent(inline_depth());
120 tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count()); 114 tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count());
121 } 115 }
122 return NULL; 116 return NULL;
123 } 117 }
124 118
136 (call_site_count >= InlineFrequencyCount) || 130 (call_site_count >= InlineFrequencyCount) ||
137 is_init_with_ea(callee_method, caller_method, C)) { 131 is_init_with_ea(callee_method, caller_method, C)) {
138 132
139 max_size = C->freq_inline_size(); 133 max_size = C->freq_inline_size();
140 if (size <= max_size && TraceFrequencyInlining) { 134 if (size <= max_size && TraceFrequencyInlining) {
141 print_indent(inline_depth()); 135 CompileTask::print_inline_indent(inline_depth());
142 tty->print_cr("Inlined frequent method (freq=%d count=%d):", freq, call_site_count); 136 tty->print_cr("Inlined frequent method (freq=%d count=%d):", freq, call_site_count);
143 print_indent(inline_depth()); 137 CompileTask::print_inline_indent(inline_depth());
144 callee_method->print(); 138 callee_method->print();
145 tty->cr(); 139 tty->cr();
146 } 140 }
147 } else { 141 } else {
148 // Not hot. Check for medium-sized pre-existing nmethod at cold sites. 142 // Not hot. Check for medium-sized pre-existing nmethod at cold sites.
313 return "not an accessor"; 307 return "not an accessor";
314 } 308 }
315 if( inline_depth() > MaxInlineLevel ) { 309 if( inline_depth() > MaxInlineLevel ) {
316 return "inlining too deep"; 310 return "inlining too deep";
317 } 311 }
318 if( method() == callee_method && 312
319 inline_depth() > MaxRecursiveInlineLevel ) { 313 // We need to detect recursive inlining of method handle targets: if
314 // the current method is a method handle adapter and one of the
315 // callers is the same method as the callee, we bail out if
316 // MaxRecursiveInlineLevel is hit.
317 if (method()->is_method_handle_adapter()) {
318 JVMState* jvms = caller_jvms();
319 int inline_level = 0;
320 while (jvms != NULL && jvms->has_method()) {
321 if (jvms->method() == callee_method) {
322 inline_level++;
323 if (inline_level > MaxRecursiveInlineLevel)
324 return "recursively inlining too deep";
325 }
326 jvms = jvms->caller();
327 }
328 }
329
330 if (method() == callee_method && inline_depth() > MaxRecursiveInlineLevel) {
320 return "recursively inlining too deep"; 331 return "recursively inlining too deep";
321 } 332 }
322 333
323 int size = callee_method->code_size(); 334 int size = callee_method->code_size();
324 335
366 } 377 }
367 378
368 #ifndef PRODUCT 379 #ifndef PRODUCT
369 //------------------------------print_inlining--------------------------------- 380 //------------------------------print_inlining---------------------------------
370 // Really, the failure_msg can be a success message also. 381 // Really, the failure_msg can be a success message also.
371 void InlineTree::print_inlining(ciMethod *callee_method, int caller_bci, const char *failure_msg) const { 382 void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci, const char* failure_msg) const {
372 print_indent(inline_depth()); 383 CompileTask::print_inlining(callee_method, inline_depth(), caller_bci, failure_msg ? failure_msg : "inline");
373 tty->print("@ %d ", caller_bci); 384 if (callee_method == NULL) tty->print(" callee not monotonic or profiled");
374 if( callee_method ) callee_method->print_short_name(); 385 if (Verbose && callee_method) {
375 else tty->print(" callee not monotonic or profiled");
376 tty->print(" %s", (failure_msg ? failure_msg : "inline"));
377 if( Verbose && callee_method ) {
378 const InlineTree *top = this; 386 const InlineTree *top = this;
379 while( top->caller_tree() != NULL ) { top = top->caller_tree(); } 387 while( top->caller_tree() != NULL ) { top = top->caller_tree(); }
380 tty->print(" bcs: %d+%d invoked: %d", top->count_inline_bcs(), callee_method->code_size(), callee_method->interpreter_invocation_count()); 388 tty->print(" bcs: %d+%d invoked: %d", top->count_inline_bcs(), callee_method->code_size(), callee_method->interpreter_invocation_count());
381 } 389 }
382 tty->cr();
383 } 390 }
384 #endif 391 #endif
385 392
386 //------------------------------ok_to_inline----------------------------------- 393 //------------------------------ok_to_inline-----------------------------------
387 WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms, ciCallProfile& profile, WarmCallInfo* initial_wci) { 394 WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms, ciCallProfile& profile, WarmCallInfo* initial_wci) {