Mercurial > hg > graal-compiler
comparison src/share/vm/opto/bytecodeInfo.cpp @ 3458:393e144bb99b
7057587: JSR 292 - crash with jruby in test/test_respond_to.rb
Summary: don't skip receiver when GC'ing compiled invokedynamic callsites
Reviewed-by: twisti, kvn, jrose
author | never |
---|---|
date | Wed, 22 Jun 2011 14:45:37 -0700 |
parents | e2a92dd0d3d2 |
children | de847cac9235 |
comparison
equal
deleted
inserted
replaced
3457:a3081a3a2b54 | 3458:393e144bb99b |
---|---|
33 #include "opto/parse.hpp" | 33 #include "opto/parse.hpp" |
34 #include "runtime/handles.inline.hpp" | 34 #include "runtime/handles.inline.hpp" |
35 | 35 |
36 //============================================================================= | 36 //============================================================================= |
37 //------------------------------InlineTree------------------------------------- | 37 //------------------------------InlineTree------------------------------------- |
38 InlineTree::InlineTree( Compile* c, | 38 InlineTree::InlineTree(Compile* c, |
39 const InlineTree *caller_tree, ciMethod* callee, | 39 const InlineTree *caller_tree, ciMethod* callee, |
40 JVMState* caller_jvms, int caller_bci, | 40 JVMState* caller_jvms, int caller_bci, |
41 float site_invoke_ratio, int site_depth_adjust) | 41 float site_invoke_ratio, int max_inline_level) : |
42 : C(c), _caller_jvms(caller_jvms), | 42 C(c), |
43 _caller_tree((InlineTree*)caller_tree), | 43 _caller_jvms(caller_jvms), |
44 _method(callee), _site_invoke_ratio(site_invoke_ratio), | 44 _caller_tree((InlineTree*) caller_tree), |
45 _site_depth_adjust(site_depth_adjust), | 45 _method(callee), |
46 _site_invoke_ratio(site_invoke_ratio), | |
47 _max_inline_level(max_inline_level), | |
46 _count_inline_bcs(method()->code_size()) | 48 _count_inline_bcs(method()->code_size()) |
47 { | 49 { |
48 NOT_PRODUCT(_count_inlines = 0;) | 50 NOT_PRODUCT(_count_inlines = 0;) |
49 if (_caller_jvms != NULL) { | 51 if (_caller_jvms != NULL) { |
50 // Keep a private copy of the caller_jvms: | 52 // Keep a private copy of the caller_jvms: |
64 } | 66 } |
65 } | 67 } |
66 } | 68 } |
67 | 69 |
68 InlineTree::InlineTree(Compile* c, ciMethod* callee_method, JVMState* caller_jvms, | 70 InlineTree::InlineTree(Compile* c, ciMethod* callee_method, JVMState* caller_jvms, |
69 float site_invoke_ratio, int site_depth_adjust) | 71 float site_invoke_ratio, int max_inline_level) : |
70 : C(c), _caller_jvms(caller_jvms), _caller_tree(NULL), | 72 C(c), |
71 _method(callee_method), _site_invoke_ratio(site_invoke_ratio), | 73 _caller_jvms(caller_jvms), |
72 _site_depth_adjust(site_depth_adjust), | 74 _caller_tree(NULL), |
75 _method(callee_method), | |
76 _site_invoke_ratio(site_invoke_ratio), | |
77 _max_inline_level(max_inline_level), | |
73 _count_inline_bcs(method()->code_size()) | 78 _count_inline_bcs(method()->code_size()) |
74 { | 79 { |
75 NOT_PRODUCT(_count_inlines = 0;) | 80 NOT_PRODUCT(_count_inlines = 0;) |
76 assert(!UseOldInlining, "do not use for old stuff"); | 81 assert(!UseOldInlining, "do not use for old stuff"); |
77 } | 82 } |
92 const char* InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const { | 97 const char* InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const { |
93 // Allows targeted inlining | 98 // Allows targeted inlining |
94 if(callee_method->should_inline()) { | 99 if(callee_method->should_inline()) { |
95 *wci_result = *(WarmCallInfo::always_hot()); | 100 *wci_result = *(WarmCallInfo::always_hot()); |
96 if (PrintInlining && Verbose) { | 101 if (PrintInlining && Verbose) { |
97 CompileTask::print_inline_indent(inline_depth()); | 102 CompileTask::print_inline_indent(inline_level()); |
98 tty->print_cr("Inlined method is hot: "); | 103 tty->print_cr("Inlined method is hot: "); |
99 } | 104 } |
100 return NULL; | 105 return NULL; |
101 } | 106 } |
102 | 107 |
107 // Check for too many throws (and not too huge) | 112 // Check for too many throws (and not too huge) |
108 if(callee_method->interpreter_throwout_count() > InlineThrowCount && | 113 if(callee_method->interpreter_throwout_count() > InlineThrowCount && |
109 size < InlineThrowMaxSize ) { | 114 size < InlineThrowMaxSize ) { |
110 wci_result->set_profit(wci_result->profit() * 100); | 115 wci_result->set_profit(wci_result->profit() * 100); |
111 if (PrintInlining && Verbose) { | 116 if (PrintInlining && Verbose) { |
112 CompileTask::print_inline_indent(inline_depth()); | 117 CompileTask::print_inline_indent(inline_level()); |
113 tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count()); | 118 tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count()); |
114 } | 119 } |
115 return NULL; | 120 return NULL; |
116 } | 121 } |
117 | 122 |
147 (call_site_count >= InlineFrequencyCount) || | 152 (call_site_count >= InlineFrequencyCount) || |
148 is_init_with_ea(callee_method, caller_method, C)) { | 153 is_init_with_ea(callee_method, caller_method, C)) { |
149 | 154 |
150 max_inline_size = C->freq_inline_size(); | 155 max_inline_size = C->freq_inline_size(); |
151 if (size <= max_inline_size && TraceFrequencyInlining) { | 156 if (size <= max_inline_size && TraceFrequencyInlining) { |
152 CompileTask::print_inline_indent(inline_depth()); | 157 CompileTask::print_inline_indent(inline_level()); |
153 tty->print_cr("Inlined frequent method (freq=%d count=%d):", freq, call_site_count); | 158 tty->print_cr("Inlined frequent method (freq=%d count=%d):", freq, call_site_count); |
154 CompileTask::print_inline_indent(inline_depth()); | 159 CompileTask::print_inline_indent(inline_level()); |
155 callee_method->print(); | 160 callee_method->print(); |
156 tty->cr(); | 161 tty->cr(); |
157 } | 162 } |
158 } else { | 163 } else { |
159 // Not hot. Check for medium-sized pre-existing nmethod at cold sites. | 164 // Not hot. Check for medium-sized pre-existing nmethod at cold sites. |
320 } | 325 } |
321 | 326 |
322 if (!C->do_inlining() && InlineAccessors) { | 327 if (!C->do_inlining() && InlineAccessors) { |
323 return "not an accessor"; | 328 return "not an accessor"; |
324 } | 329 } |
325 if( inline_depth() > MaxInlineLevel ) { | 330 if (inline_level() > _max_inline_level) { |
326 return "inlining too deep"; | 331 return "inlining too deep"; |
327 } | 332 } |
328 | 333 |
329 // detect direct and indirect recursive inlining | 334 // detect direct and indirect recursive inlining |
330 { | 335 { |
390 } | 395 } |
391 | 396 |
392 //------------------------------print_inlining--------------------------------- | 397 //------------------------------print_inlining--------------------------------- |
393 // Really, the failure_msg can be a success message also. | 398 // Really, the failure_msg can be a success message also. |
394 void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci, const char* failure_msg) const { | 399 void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci, const char* failure_msg) const { |
395 CompileTask::print_inlining(callee_method, inline_depth(), caller_bci, failure_msg ? failure_msg : "inline"); | 400 CompileTask::print_inlining(callee_method, inline_level(), caller_bci, failure_msg ? failure_msg : "inline"); |
396 if (callee_method == NULL) tty->print(" callee not monotonic or profiled"); | 401 if (callee_method == NULL) tty->print(" callee not monotonic or profiled"); |
397 if (Verbose && callee_method) { | 402 if (Verbose && callee_method) { |
398 const InlineTree *top = this; | 403 const InlineTree *top = this; |
399 while( top->caller_tree() != NULL ) { top = top->caller_tree(); } | 404 while( top->caller_tree() != NULL ) { top = top->caller_tree(); } |
400 tty->print(" bcs: %d+%d invoked: %d", top->count_inline_bcs(), callee_method->code_size(), callee_method->interpreter_invocation_count()); | 405 tty->print(" bcs: %d+%d invoked: %d", top->count_inline_bcs(), callee_method->code_size(), callee_method->interpreter_invocation_count()); |
498 // Attempt inlining. | 503 // Attempt inlining. |
499 InlineTree* old_ilt = callee_at(caller_bci, callee_method); | 504 InlineTree* old_ilt = callee_at(caller_bci, callee_method); |
500 if (old_ilt != NULL) { | 505 if (old_ilt != NULL) { |
501 return old_ilt; | 506 return old_ilt; |
502 } | 507 } |
503 int new_depth_adjust = 0; | 508 int max_inline_level_adjust = 0; |
504 if (caller_jvms->method() != NULL) { | 509 if (caller_jvms->method() != NULL) { |
505 if (caller_jvms->method()->is_method_handle_adapter()) | 510 if (caller_jvms->method()->is_method_handle_adapter()) |
506 new_depth_adjust -= 1; // don't count actions in MH or indy adapter frames | 511 max_inline_level_adjust += 1; // don't count actions in MH or indy adapter frames |
507 else if (callee_method->is_method_handle_invoke()) { | 512 else if (callee_method->is_method_handle_invoke()) { |
508 new_depth_adjust -= 1; // don't count method handle calls from java.lang.invoke implem | 513 max_inline_level_adjust += 1; // don't count method handle calls from java.lang.invoke implem |
509 } | 514 } |
510 if (new_depth_adjust != 0 && PrintInlining) { | 515 if (max_inline_level_adjust != 0 && PrintInlining && (Verbose || WizardMode)) { |
511 CompileTask::print_inline_indent(inline_depth()); | 516 CompileTask::print_inline_indent(inline_level()); |
512 tty->print_cr(" \\-> discounting inline depth"); | 517 tty->print_cr(" \\-> discounting inline depth"); |
513 } | 518 } |
514 if (new_depth_adjust != 0 && C->log()) { | 519 if (max_inline_level_adjust != 0 && C->log()) { |
515 int id1 = C->log()->identify(caller_jvms->method()); | 520 int id1 = C->log()->identify(caller_jvms->method()); |
516 int id2 = C->log()->identify(callee_method); | 521 int id2 = C->log()->identify(callee_method); |
517 C->log()->elem("inline_depth_discount caller='%d' callee='%d'", id1, id2); | 522 C->log()->elem("inline_level_discount caller='%d' callee='%d'", id1, id2); |
518 } | 523 } |
519 } | 524 } |
520 InlineTree *ilt = new InlineTree(C, this, callee_method, caller_jvms, caller_bci, recur_frequency, _site_depth_adjust + new_depth_adjust); | 525 InlineTree* ilt = new InlineTree(C, this, callee_method, caller_jvms, caller_bci, recur_frequency, _max_inline_level + max_inline_level_adjust); |
521 _subtrees.append( ilt ); | 526 _subtrees.append(ilt); |
522 | 527 |
523 NOT_PRODUCT( _count_inlines += 1; ) | 528 NOT_PRODUCT( _count_inlines += 1; ) |
524 | 529 |
525 return ilt; | 530 return ilt; |
526 } | 531 } |
541 //------------------------------build_inline_tree_root------------------------- | 546 //------------------------------build_inline_tree_root------------------------- |
542 InlineTree *InlineTree::build_inline_tree_root() { | 547 InlineTree *InlineTree::build_inline_tree_root() { |
543 Compile* C = Compile::current(); | 548 Compile* C = Compile::current(); |
544 | 549 |
545 // Root of inline tree | 550 // Root of inline tree |
546 InlineTree *ilt = new InlineTree(C, NULL, C->method(), NULL, -1, 1.0F, 0); | 551 InlineTree* ilt = new InlineTree(C, NULL, C->method(), NULL, -1, 1.0F, MaxInlineLevel); |
547 | 552 |
548 return ilt; | 553 return ilt; |
549 } | 554 } |
550 | 555 |
551 | 556 |