Mercurial > hg > truffle
comparison src/share/vm/opto/bytecodeInfo.cpp @ 1162:d749b1813f40
Merge
author | trims |
---|---|
date | Fri, 15 Jan 2010 14:25:44 -0800 |
parents | c3b315a0d58a |
children | cd5dbf694d45 |
comparison
equal
deleted
inserted
replaced
1130:1bc68593a110 | 1162:d749b1813f40 |
---|---|
25 #include "incls/_precompiled.incl" | 25 #include "incls/_precompiled.incl" |
26 #include "incls/_bytecodeInfo.cpp.incl" | 26 #include "incls/_bytecodeInfo.cpp.incl" |
27 | 27 |
28 //============================================================================= | 28 //============================================================================= |
29 //------------------------------InlineTree------------------------------------- | 29 //------------------------------InlineTree------------------------------------- |
30 InlineTree::InlineTree( Compile* c, const InlineTree *caller_tree, ciMethod* callee, JVMState* caller_jvms, int caller_bci, float site_invoke_ratio ) | 30 InlineTree::InlineTree( Compile* c, |
31 const InlineTree *caller_tree, ciMethod* callee, | |
32 JVMState* caller_jvms, int caller_bci, | |
33 float site_invoke_ratio, int site_depth_adjust) | |
31 : C(c), _caller_jvms(caller_jvms), | 34 : C(c), _caller_jvms(caller_jvms), |
32 _caller_tree((InlineTree*)caller_tree), | 35 _caller_tree((InlineTree*)caller_tree), |
33 _method(callee), _site_invoke_ratio(site_invoke_ratio), | 36 _method(callee), _site_invoke_ratio(site_invoke_ratio), |
34 _count_inline_bcs(method()->code_size()) { | 37 _site_depth_adjust(site_depth_adjust), |
38 _count_inline_bcs(method()->code_size()) | |
39 { | |
35 NOT_PRODUCT(_count_inlines = 0;) | 40 NOT_PRODUCT(_count_inlines = 0;) |
36 if (_caller_jvms != NULL) { | 41 if (_caller_jvms != NULL) { |
37 // Keep a private copy of the caller_jvms: | 42 // Keep a private copy of the caller_jvms: |
38 _caller_jvms = new (C) JVMState(caller_jvms->method(), caller_tree->caller_jvms()); | 43 _caller_jvms = new (C) JVMState(caller_jvms->method(), caller_tree->caller_jvms()); |
39 _caller_jvms->set_bci(caller_jvms->bci()); | 44 _caller_jvms->set_bci(caller_jvms->bci()); |
40 assert(!caller_jvms->should_reexecute(), "there should be no reexecute bytecode with inlining"); | 45 assert(!caller_jvms->should_reexecute(), "there should be no reexecute bytecode with inlining"); |
41 } | 46 } |
42 assert(_caller_jvms->same_calls_as(caller_jvms), "consistent JVMS"); | 47 assert(_caller_jvms->same_calls_as(caller_jvms), "consistent JVMS"); |
43 assert((caller_tree == NULL ? 0 : caller_tree->inline_depth() + 1) == inline_depth(), "correct (redundant) depth parameter"); | 48 assert((caller_tree == NULL ? 0 : caller_tree->stack_depth() + 1) == stack_depth(), "correct (redundant) depth parameter"); |
44 assert(caller_bci == this->caller_bci(), "correct (redundant) bci parameter"); | 49 assert(caller_bci == this->caller_bci(), "correct (redundant) bci parameter"); |
45 if (UseOldInlining) { | 50 if (UseOldInlining) { |
46 // Update hierarchical counts, count_inline_bcs() and count_inlines() | 51 // Update hierarchical counts, count_inline_bcs() and count_inlines() |
47 InlineTree *caller = (InlineTree *)caller_tree; | 52 InlineTree *caller = (InlineTree *)caller_tree; |
48 for( ; caller != NULL; caller = ((InlineTree *)(caller->caller_tree())) ) { | 53 for( ; caller != NULL; caller = ((InlineTree *)(caller->caller_tree())) ) { |
50 NOT_PRODUCT(caller->_count_inlines++;) | 55 NOT_PRODUCT(caller->_count_inlines++;) |
51 } | 56 } |
52 } | 57 } |
53 } | 58 } |
54 | 59 |
55 InlineTree::InlineTree(Compile* c, ciMethod* callee_method, JVMState* caller_jvms, float site_invoke_ratio) | 60 InlineTree::InlineTree(Compile* c, ciMethod* callee_method, JVMState* caller_jvms, |
61 float site_invoke_ratio, int site_depth_adjust) | |
56 : C(c), _caller_jvms(caller_jvms), _caller_tree(NULL), | 62 : C(c), _caller_jvms(caller_jvms), _caller_tree(NULL), |
57 _method(callee_method), _site_invoke_ratio(site_invoke_ratio), | 63 _method(callee_method), _site_invoke_ratio(site_invoke_ratio), |
58 _count_inline_bcs(method()->code_size()) { | 64 _site_depth_adjust(site_depth_adjust), |
65 _count_inline_bcs(method()->code_size()) | |
66 { | |
59 NOT_PRODUCT(_count_inlines = 0;) | 67 NOT_PRODUCT(_count_inlines = 0;) |
60 assert(!UseOldInlining, "do not use for old stuff"); | 68 assert(!UseOldInlining, "do not use for old stuff"); |
61 } | 69 } |
62 | 70 |
63 | 71 |
178 } | 186 } |
179 | 187 |
180 return NULL; | 188 return NULL; |
181 } | 189 } |
182 | 190 |
191 // Always inline MethodHandle methods. | |
192 if (callee_method->is_method_handle_invoke()) | |
193 return NULL; | |
194 | |
183 // First check all inlining restrictions which are required for correctness | 195 // First check all inlining restrictions which are required for correctness |
184 if (callee_method->is_abstract()) return "abstract method"; | 196 if (callee_method->is_abstract()) return "abstract method"; |
185 // note: we allow ik->is_abstract() | 197 // note: we allow ik->is_abstract() |
186 if (!callee_method->holder()->is_initialized()) return "method holder not initialized"; | 198 if (!callee_method->holder()->is_initialized()) return "method holder not initialized"; |
187 if (callee_method->is_native()) return "native method"; | 199 if (callee_method->is_native()) return "native method"; |
263 if ((msg = shouldNotInline(callee_method, caller_method, | 275 if ((msg = shouldNotInline(callee_method, caller_method, |
264 wci_result)) != NULL) { | 276 wci_result)) != NULL) { |
265 return msg; | 277 return msg; |
266 } | 278 } |
267 | 279 |
268 bool is_accessor = InlineAccessors && callee_method->is_accessor(); | 280 if (InlineAccessors && callee_method->is_accessor()) { |
281 // accessor methods are not subject to any of the following limits. | |
282 return NULL; | |
283 } | |
269 | 284 |
270 // suppress a few checks for accessors and trivial methods | 285 // suppress a few checks for accessors and trivial methods |
271 if (!is_accessor && callee_method->code_size() > MaxTrivialSize) { | 286 if (callee_method->code_size() > MaxTrivialSize) { |
272 | 287 |
273 // don't inline into giant methods | 288 // don't inline into giant methods |
274 if (C->unique() > (uint)NodeCountInliningCutoff) { | 289 if (C->unique() > (uint)NodeCountInliningCutoff) { |
275 return "NodeCountInliningCutoff"; | 290 return "NodeCountInliningCutoff"; |
276 } | 291 } |
285 // don't inline unreached call sites | 300 // don't inline unreached call sites |
286 return "call site not reached"; | 301 return "call site not reached"; |
287 } | 302 } |
288 } | 303 } |
289 | 304 |
290 if (!C->do_inlining() && InlineAccessors && !is_accessor) { | 305 if (!C->do_inlining() && InlineAccessors) { |
291 return "not an accessor"; | 306 return "not an accessor"; |
292 } | 307 } |
293 if( inline_depth() > MaxInlineLevel ) { | 308 if( inline_depth() > MaxInlineLevel ) { |
294 return "inlining too deep"; | 309 return "inlining too deep"; |
295 } | 310 } |
320 if( !UseInterpreter || CompileTheWorld /* running Xcomp or CTW */ ) { | 335 if( !UseInterpreter || CompileTheWorld /* running Xcomp or CTW */ ) { |
321 // Checks that constant pool's call site has been visited | 336 // Checks that constant pool's call site has been visited |
322 // stricter than callee_holder->is_initialized() | 337 // stricter than callee_holder->is_initialized() |
323 ciBytecodeStream iter(caller_method); | 338 ciBytecodeStream iter(caller_method); |
324 iter.force_bci(caller_bci); | 339 iter.force_bci(caller_bci); |
325 int index = iter.get_index_int(); | |
326 if( !caller_method->is_klass_loaded(index, true) ) { | |
327 return false; | |
328 } | |
329 // Try to do constant pool resolution if running Xcomp | |
330 Bytecodes::Code call_bc = iter.cur_bc(); | 340 Bytecodes::Code call_bc = iter.cur_bc(); |
331 if( !caller_method->check_call(index, call_bc == Bytecodes::_invokestatic) ) { | 341 // An invokedynamic instruction does not have a klass. |
332 return false; | 342 if (call_bc != Bytecodes::_invokedynamic) { |
343 int index = iter.get_index_int(); | |
344 if (!caller_method->is_klass_loaded(index, true)) { | |
345 return false; | |
346 } | |
347 // Try to do constant pool resolution if running Xcomp | |
348 if( !caller_method->check_call(index, call_bc == Bytecodes::_invokestatic) ) { | |
349 return false; | |
350 } | |
333 } | 351 } |
334 } | 352 } |
335 // We will attempt to see if a class/field/etc got properly loaded. If it | 353 // We will attempt to see if a class/field/etc got properly loaded. If it |
336 // did not, it may attempt to throw an exception during our probing. Catch | 354 // did not, it may attempt to throw an exception during our probing. Catch |
337 // and ignore such exceptions and do not attempt to compile the method. | 355 // and ignore such exceptions and do not attempt to compile the method. |
455 // Attempt inlining. | 473 // Attempt inlining. |
456 InlineTree* old_ilt = callee_at(caller_bci, callee_method); | 474 InlineTree* old_ilt = callee_at(caller_bci, callee_method); |
457 if (old_ilt != NULL) { | 475 if (old_ilt != NULL) { |
458 return old_ilt; | 476 return old_ilt; |
459 } | 477 } |
460 InlineTree *ilt = new InlineTree( C, this, callee_method, caller_jvms, caller_bci, recur_frequency ); | 478 int new_depth_adjust = 0; |
479 if (caller_jvms->method() != NULL) { | |
480 if ((caller_jvms->method()->name() == ciSymbol::invoke_name() && | |
481 caller_jvms->method()->holder()->name() == ciSymbol::java_dyn_MethodHandle()) | |
482 || caller_jvms->method()->holder()->name() == ciSymbol::java_dyn_InvokeDynamic()) | |
483 /* @@@ FIXME: | |
484 if (caller_jvms->method()->is_method_handle_adapter()) | |
485 */ | |
486 new_depth_adjust -= 1; // don't count actions in MH or indy adapter frames | |
487 else if (callee_method->is_method_handle_invoke()) { | |
488 new_depth_adjust -= 1; // don't count method handle calls from java.dyn implem | |
489 } | |
490 if (new_depth_adjust != 0 && PrintInlining) { | |
491 stringStream nm1; caller_jvms->method()->print_name(&nm1); | |
492 stringStream nm2; callee_method->print_name(&nm2); | |
493 tty->print_cr("discounting inlining depth from %s to %s", nm1.base(), nm2.base()); | |
494 } | |
495 if (new_depth_adjust != 0 && C->log()) { | |
496 int id1 = C->log()->identify(caller_jvms->method()); | |
497 int id2 = C->log()->identify(callee_method); | |
498 C->log()->elem("inline_depth_discount caller='%d' callee='%d'", id1, id2); | |
499 } | |
500 } | |
501 InlineTree *ilt = new InlineTree(C, this, callee_method, caller_jvms, caller_bci, recur_frequency, _site_depth_adjust + new_depth_adjust); | |
461 _subtrees.append( ilt ); | 502 _subtrees.append( ilt ); |
462 | 503 |
463 NOT_PRODUCT( _count_inlines += 1; ) | 504 NOT_PRODUCT( _count_inlines += 1; ) |
464 | 505 |
465 return ilt; | 506 return ilt; |
481 //------------------------------build_inline_tree_root------------------------- | 522 //------------------------------build_inline_tree_root------------------------- |
482 InlineTree *InlineTree::build_inline_tree_root() { | 523 InlineTree *InlineTree::build_inline_tree_root() { |
483 Compile* C = Compile::current(); | 524 Compile* C = Compile::current(); |
484 | 525 |
485 // Root of inline tree | 526 // Root of inline tree |
486 InlineTree *ilt = new InlineTree(C, NULL, C->method(), NULL, -1, 1.0F); | 527 InlineTree *ilt = new InlineTree(C, NULL, C->method(), NULL, -1, 1.0F, 0); |
487 | 528 |
488 return ilt; | 529 return ilt; |
489 } | 530 } |
490 | 531 |
491 | 532 |