comparison src/share/vm/opto/bytecodeInfo.cpp @ 41:874b2c4f43d1

6667605: (Escape Analysis) inline java constructors when EA is on Summary: java constructors should be inlined to be able scalar replace a new object Reviewed-by: rasbold
author kvn
date Fri, 07 Mar 2008 11:09:13 -0800
parents a61af66fc99e
children d1605aabd0a1 524eca34ea76
comparison
equal deleted inserted replaced
40:7c1f32ae4a20 41:874b2c4f43d1
77 static void print_indent(int depth) { 77 static void print_indent(int depth) {
78 tty->print(" "); 78 tty->print(" ");
79 for (int i = depth; i != 0; --i) tty->print(" "); 79 for (int i = depth; i != 0; --i) tty->print(" ");
80 } 80 }
81 81
82 static bool is_init_with_ea(ciMethod* callee_method,
83 ciMethod* caller_method, Compile* C) {
84 // True when EA is ON and a java constructor is called or
85 // a super constructor is called from an inlined java constructor.
86 return DoEscapeAnalysis && EliminateAllocations &&
87 ( callee_method->is_initializer() ||
88 (caller_method->is_initializer() &&
89 caller_method != C->method() &&
90 caller_method->holder()->is_subclass_of(callee_method->holder()))
91 );
92 }
93
82 // positive filter: should send be inlined? returns NULL, if yes, or rejection msg 94 // positive filter: should send be inlined? returns NULL, if yes, or rejection msg
83 const char* InlineTree::shouldInline(ciMethod* callee_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const { 95 const char* InlineTree::shouldInline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const {
84 // Allows targeted inlining 96 // Allows targeted inlining
85 if(callee_method->should_inline()) { 97 if(callee_method->should_inline()) {
86 *wci_result = *(WarmCallInfo::always_hot()); 98 *wci_result = *(WarmCallInfo::always_hot());
87 if (PrintInlining && Verbose) { 99 if (PrintInlining && Verbose) {
88 print_indent(inline_depth()); 100 print_indent(inline_depth());
95 // or rejection msg 107 // or rejection msg
96 int max_size = C->max_inline_size(); 108 int max_size = C->max_inline_size();
97 int size = callee_method->code_size(); 109 int size = callee_method->code_size();
98 110
99 // Check for too many throws (and not too huge) 111 // Check for too many throws (and not too huge)
100 if(callee_method->interpreter_throwout_count() > InlineThrowCount && size < InlineThrowMaxSize ) { 112 if(callee_method->interpreter_throwout_count() > InlineThrowCount &&
113 size < InlineThrowMaxSize ) {
101 wci_result->set_profit(wci_result->profit() * 100); 114 wci_result->set_profit(wci_result->profit() * 100);
102 if (PrintInlining && Verbose) { 115 if (PrintInlining && Verbose) {
103 print_indent(inline_depth()); 116 print_indent(inline_depth());
104 tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count()); 117 tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count());
105 } 118 }
112 125
113 int call_site_count = method()->scale_count(profile.count()); 126 int call_site_count = method()->scale_count(profile.count());
114 int invoke_count = method()->interpreter_invocation_count(); 127 int invoke_count = method()->interpreter_invocation_count();
115 assert( invoke_count != 0, "Require invokation count greater than zero"); 128 assert( invoke_count != 0, "Require invokation count greater than zero");
116 int freq = call_site_count/invoke_count; 129 int freq = call_site_count/invoke_count;
130
117 // bump the max size if the call is frequent 131 // bump the max size if the call is frequent
118 if ((freq >= InlineFrequencyRatio) || (call_site_count >= InlineFrequencyCount)) { 132 if ((freq >= InlineFrequencyRatio) ||
133 (call_site_count >= InlineFrequencyCount) ||
134 is_init_with_ea(callee_method, caller_method, C)) {
135
119 max_size = C->freq_inline_size(); 136 max_size = C->freq_inline_size();
120 if (size <= max_size && TraceFrequencyInlining) { 137 if (size <= max_size && TraceFrequencyInlining) {
121 print_indent(inline_depth()); 138 print_indent(inline_depth());
122 tty->print_cr("Inlined frequent method (freq=%d count=%d):", freq, call_site_count); 139 tty->print_cr("Inlined frequent method (freq=%d count=%d):", freq, call_site_count);
123 print_indent(inline_depth()); 140 print_indent(inline_depth());
124 callee_method->print(); 141 callee_method->print();
125 tty->cr(); 142 tty->cr();
126 } 143 }
127 } else { 144 } else {
128 // Not hot. Check for medium-sized pre-existing nmethod at cold sites. 145 // Not hot. Check for medium-sized pre-existing nmethod at cold sites.
129 if (callee_method->has_compiled_code() && callee_method->instructions_size() > InlineSmallCode/4) 146 if (callee_method->has_compiled_code() &&
147 callee_method->instructions_size() > InlineSmallCode/4)
130 return "already compiled into a medium method"; 148 return "already compiled into a medium method";
131 } 149 }
132 if (size > max_size) { 150 if (size > max_size) {
133 if (max_size > C->max_inline_size()) 151 if (max_size > C->max_inline_size())
134 return "hot method too big"; 152 return "hot method too big";
137 return NULL; 155 return NULL;
138 } 156 }
139 157
140 158
141 // negative filter: should send NOT be inlined? returns NULL, ok to inline, or rejection msg 159 // negative filter: should send NOT be inlined? returns NULL, ok to inline, or rejection msg
142 const char* InlineTree::shouldNotInline(ciMethod *callee_method, WarmCallInfo* wci_result) const { 160 const char* InlineTree::shouldNotInline(ciMethod *callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const {
143 // negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg 161 // negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg
144 if (!UseOldInlining) { 162 if (!UseOldInlining) {
145 const char* fail = NULL; 163 const char* fail = NULL;
146 if (callee_method->is_abstract()) fail = "abstract method"; 164 if (callee_method->is_abstract()) fail = "abstract method";
147 // note: we allow ik->is_abstract() 165 // note: we allow ik->is_abstract()
202 return "exception method"; 220 return "exception method";
203 } 221 }
204 222
205 // use frequency-based objections only for non-trivial methods 223 // use frequency-based objections only for non-trivial methods
206 if (callee_method->code_size() <= MaxTrivialSize) return NULL; 224 if (callee_method->code_size() <= MaxTrivialSize) return NULL;
207 if (UseInterpreter && !CompileTheWorld) { // don't use counts with -Xcomp or CTW 225
208 if (!callee_method->has_compiled_code() && !callee_method->was_executed_more_than(0)) return "never executed"; 226 // don't use counts with -Xcomp or CTW
209 if (!callee_method->was_executed_more_than(MIN2(MinInliningThreshold, CompileThreshold >> 1))) return "executed < MinInliningThreshold times"; 227 if (UseInterpreter && !CompileTheWorld) {
228
229 if (!callee_method->has_compiled_code() &&
230 !callee_method->was_executed_more_than(0)) {
231 return "never executed";
232 }
233
234 if (is_init_with_ea(callee_method, caller_method, C)) {
235
236 // Escape Analysis: inline all executed constructors
237
238 } else if (!callee_method->was_executed_more_than(MIN2(MinInliningThreshold,
239 CompileThreshold >> 1))) {
240 return "executed < MinInliningThreshold times";
241 }
210 } 242 }
211 243
212 if (callee_method->should_not_inline()) { 244 if (callee_method->should_not_inline()) {
213 return "disallowed by CompilerOracle"; 245 return "disallowed by CompilerOracle";
214 } 246 }
217 } 249 }
218 250
219 //-----------------------------try_to_inline----------------------------------- 251 //-----------------------------try_to_inline-----------------------------------
220 // return NULL if ok, reason for not inlining otherwise 252 // return NULL if ok, reason for not inlining otherwise
221 // Relocated from "InliningClosure::try_to_inline" 253 // Relocated from "InliningClosure::try_to_inline"
222 const char* InlineTree::try_to_inline(ciMethod* callee_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) { 254 const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) {
223 ciMethod* caller_method = method();
224 255
225 // Old algorithm had funny accumulating BC-size counters 256 // Old algorithm had funny accumulating BC-size counters
226 if (UseOldInlining && ClipInlining 257 if (UseOldInlining && ClipInlining
227 && (int)count_inline_bcs() >= DesiredMethodLimit) { 258 && (int)count_inline_bcs() >= DesiredMethodLimit) {
228 return "size > DesiredMethodLimit"; 259 return "size > DesiredMethodLimit";
229 } 260 }
230 261
231 const char *msg = NULL; 262 const char *msg = NULL;
232 if ((msg = shouldInline(callee_method, caller_bci, profile, wci_result)) != NULL) return msg; 263 if ((msg = shouldInline(callee_method, caller_method, caller_bci,
233 if ((msg = shouldNotInline(callee_method, wci_result)) != NULL) return msg; 264 profile, wci_result)) != NULL) {
265 return msg;
266 }
267 if ((msg = shouldNotInline(callee_method, caller_method,
268 wci_result)) != NULL) {
269 return msg;
270 }
234 271
235 bool is_accessor = InlineAccessors && callee_method->is_accessor(); 272 bool is_accessor = InlineAccessors && callee_method->is_accessor();
236 273
237 // suppress a few checks for accessors and trivial methods 274 // suppress a few checks for accessors and trivial methods
238 if (!is_accessor && callee_method->code_size() > MaxTrivialSize) { 275 if (!is_accessor && callee_method->code_size() > MaxTrivialSize) {
276
239 // don't inline into giant methods 277 // don't inline into giant methods
240 if (C->unique() > (uint)NodeCountInliningCutoff) return "NodeCountInliningCutoff"; 278 if (C->unique() > (uint)NodeCountInliningCutoff) {
241 279 return "NodeCountInliningCutoff";
242 // don't inline unreached call sites 280 }
243 if (profile.count() == 0) return "call site not reached"; 281
244 } 282 if ((!UseInterpreter || CompileTheWorld) &&
245 283 is_init_with_ea(callee_method, caller_method, C)) {
246 if (!C->do_inlining() && InlineAccessors && !is_accessor) return "not an accessor"; 284
247 285 // Escape Analysis stress testing when running Xcomp or CTW:
248 if( inline_depth() > MaxInlineLevel ) return "inlining too deep"; 286 // inline constructors even if they are not reached.
287
288 } else if (profile.count() == 0) {
289 // don't inline unreached call sites
290 return "call site not reached";
291 }
292 }
293
294 if (!C->do_inlining() && InlineAccessors && !is_accessor) {
295 return "not an accessor";
296 }
297 if( inline_depth() > MaxInlineLevel ) {
298 return "inlining too deep";
299 }
249 if( method() == callee_method && 300 if( method() == callee_method &&
250 inline_depth() > MaxRecursiveInlineLevel ) return "recursively inlining too deep"; 301 inline_depth() > MaxRecursiveInlineLevel ) {
302 return "recursively inlining too deep";
303 }
251 304
252 int size = callee_method->code_size(); 305 int size = callee_method->code_size();
253 306
254 if (UseOldInlining && ClipInlining 307 if (UseOldInlining && ClipInlining
255 && (int)count_inline_bcs() + size >= DesiredMethodLimit) { 308 && (int)count_inline_bcs() + size >= DesiredMethodLimit) {
334 return NULL; 387 return NULL;
335 } 388 }
336 389
337 // Check if inlining policy says no. 390 // Check if inlining policy says no.
338 WarmCallInfo wci = *(initial_wci); 391 WarmCallInfo wci = *(initial_wci);
339 failure_msg = try_to_inline(callee_method, caller_bci, profile, &wci); 392 failure_msg = try_to_inline(callee_method, caller_method, caller_bci, profile, &wci);
340 if (failure_msg != NULL && C->log() != NULL) { 393 if (failure_msg != NULL && C->log() != NULL) {
341 C->log()->begin_elem("inline_fail reason='"); 394 C->log()->begin_elem("inline_fail reason='");
342 C->log()->text("%s", failure_msg); 395 C->log()->text("%s", failure_msg);
343 C->log()->end_elem("'"); 396 C->log()->end_elem("'");
344 } 397 }