src/share/vm/opto/bytecodeInfo.cpp

changeset 2898
e2a92dd0d3d2
parent 2877
bad7ecd0b6ed
child 2981
aabf25fa3f05
equal deleted inserted replaced
2897:3cfb240033d1 2898:e2a92dd0d3d2
87 caller_method->holder()->is_subclass_of(callee_method->holder())) 87 caller_method->holder()->is_subclass_of(callee_method->holder()))
88 ); 88 );
89 } 89 }
90 90
91 // positive filter: should send be inlined? returns NULL, if yes, or rejection msg 91 // positive filter: should send be inlined? returns NULL, if yes, or rejection msg
92 const char* InlineTree::shouldInline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const { 92 const char* InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const {
93 // Allows targeted inlining 93 // Allows targeted inlining
94 if(callee_method->should_inline()) { 94 if(callee_method->should_inline()) {
95 *wci_result = *(WarmCallInfo::always_hot()); 95 *wci_result = *(WarmCallInfo::always_hot());
96 if (PrintInlining && Verbose) { 96 if (PrintInlining && Verbose) {
97 CompileTask::print_inline_indent(inline_depth()); 97 CompileTask::print_inline_indent(inline_depth());
100 return NULL; 100 return NULL;
101 } 101 }
102 102
103 // positive filter: should send be inlined? returns NULL (--> yes) 103 // positive filter: should send be inlined? returns NULL (--> yes)
104 // or rejection msg 104 // or rejection msg
105 int max_size = C->max_inline_size(); 105 int size = callee_method->code_size();
106 int size = callee_method->code_size();
107 106
108 // Check for too many throws (and not too huge) 107 // Check for too many throws (and not too huge)
109 if(callee_method->interpreter_throwout_count() > InlineThrowCount && 108 if(callee_method->interpreter_throwout_count() > InlineThrowCount &&
110 size < InlineThrowMaxSize ) { 109 size < InlineThrowMaxSize ) {
111 wci_result->set_profit(wci_result->profit() * 100); 110 wci_result->set_profit(wci_result->profit() * 100);
118 117
119 if (!UseOldInlining) { 118 if (!UseOldInlining) {
120 return NULL; // size and frequency are represented in a new way 119 return NULL; // size and frequency are represented in a new way
121 } 120 }
122 121
122 int default_max_inline_size = C->max_inline_size();
123 int inline_small_code_size = InlineSmallCode / 4;
124 int max_inline_size = default_max_inline_size;
125
123 int call_site_count = method()->scale_count(profile.count()); 126 int call_site_count = method()->scale_count(profile.count());
124 int invoke_count = method()->interpreter_invocation_count(); 127 int invoke_count = method()->interpreter_invocation_count();
125 assert( invoke_count != 0, "Require invokation count greater than zero"); 128
126 int freq = call_site_count/invoke_count; 129 // Bytecoded method handle adapters do not have interpreter
130 // profiling data but only made up MDO data. Get the counter from
131 // there.
132 if (caller_method->is_method_handle_adapter()) {
133 assert(method()->method_data_or_null(), "must have an MDO");
134 ciMethodData* mdo = method()->method_data();
135 ciProfileData* mha_profile = mdo->bci_to_data(caller_bci);
136 assert(mha_profile, "must exist");
137 CounterData* cd = mha_profile->as_CounterData();
138 invoke_count = cd->count();
139 call_site_count = invoke_count; // use the same value
140 }
141
142 assert(invoke_count != 0, "require invocation count greater than zero");
143 int freq = call_site_count / invoke_count;
127 144
128 // bump the max size if the call is frequent 145 // bump the max size if the call is frequent
129 if ((freq >= InlineFrequencyRatio) || 146 if ((freq >= InlineFrequencyRatio) ||
130 (call_site_count >= InlineFrequencyCount) || 147 (call_site_count >= InlineFrequencyCount) ||
131 is_init_with_ea(callee_method, caller_method, C)) { 148 is_init_with_ea(callee_method, caller_method, C)) {
132 149
133 max_size = C->freq_inline_size(); 150 max_inline_size = C->freq_inline_size();
134 if (size <= max_size && TraceFrequencyInlining) { 151 if (size <= max_inline_size && TraceFrequencyInlining) {
135 CompileTask::print_inline_indent(inline_depth()); 152 CompileTask::print_inline_indent(inline_depth());
136 tty->print_cr("Inlined frequent method (freq=%d count=%d):", freq, call_site_count); 153 tty->print_cr("Inlined frequent method (freq=%d count=%d):", freq, call_site_count);
137 CompileTask::print_inline_indent(inline_depth()); 154 CompileTask::print_inline_indent(inline_depth());
138 callee_method->print(); 155 callee_method->print();
139 tty->cr(); 156 tty->cr();
140 } 157 }
141 } else { 158 } else {
142 // Not hot. Check for medium-sized pre-existing nmethod at cold sites. 159 // Not hot. Check for medium-sized pre-existing nmethod at cold sites.
143 if (callee_method->has_compiled_code() && 160 if (callee_method->has_compiled_code() &&
144 callee_method->instructions_size(CompLevel_full_optimization) > InlineSmallCode/4) 161 callee_method->instructions_size(CompLevel_full_optimization) > inline_small_code_size)
145 return "already compiled into a medium method"; 162 return "already compiled into a medium method";
146 } 163 }
147 if (size > max_size) { 164 if (size > max_inline_size) {
148 if (max_size > C->max_inline_size()) 165 if (max_inline_size > default_max_inline_size)
149 return "hot method too big"; 166 return "hot method too big";
150 return "too big"; 167 return "too big";
151 } 168 }
152 return NULL; 169 return NULL;
153 } 170 }
154 171
155 172
156 // negative filter: should send NOT be inlined? returns NULL, ok to inline, or rejection msg 173 // negative filter: should send NOT be inlined? returns NULL, ok to inline, or rejection msg
157 const char* InlineTree::shouldNotInline(ciMethod *callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const { 174 const char* InlineTree::should_not_inline(ciMethod *callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const {
158 // negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg 175 // negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg
159 if (!UseOldInlining) { 176 if (!UseOldInlining) {
160 const char* fail = NULL; 177 const char* fail = NULL;
161 if (callee_method->is_abstract()) fail = "abstract method"; 178 if (callee_method->is_abstract()) fail = "abstract method";
162 // note: we allow ik->is_abstract() 179 // note: we allow ik->is_abstract()
267 && (int)count_inline_bcs() >= DesiredMethodLimit) { 284 && (int)count_inline_bcs() >= DesiredMethodLimit) {
268 return "size > DesiredMethodLimit"; 285 return "size > DesiredMethodLimit";
269 } 286 }
270 287
271 const char *msg = NULL; 288 const char *msg = NULL;
272 if ((msg = shouldInline(callee_method, caller_method, caller_bci, 289 msg = should_inline(callee_method, caller_method, caller_bci, profile, wci_result);
273 profile, wci_result)) != NULL) { 290 if (msg != NULL)
274 return msg; 291 return msg;
275 } 292
276 if ((msg = shouldNotInline(callee_method, caller_method, 293 msg = should_not_inline(callee_method, caller_method, wci_result);
277 wci_result)) != NULL) { 294 if (msg != NULL)
278 return msg; 295 return msg;
279 }
280 296
281 if (InlineAccessors && callee_method->is_accessor()) { 297 if (InlineAccessors && callee_method->is_accessor()) {
282 // accessor methods are not subject to any of the following limits. 298 // accessor methods are not subject to any of the following limits.
283 return NULL; 299 return NULL;
284 } 300 }
490 new_depth_adjust -= 1; // don't count actions in MH or indy adapter frames 506 new_depth_adjust -= 1; // don't count actions in MH or indy adapter frames
491 else if (callee_method->is_method_handle_invoke()) { 507 else if (callee_method->is_method_handle_invoke()) {
492 new_depth_adjust -= 1; // don't count method handle calls from java.lang.invoke implem 508 new_depth_adjust -= 1; // don't count method handle calls from java.lang.invoke implem
493 } 509 }
494 if (new_depth_adjust != 0 && PrintInlining) { 510 if (new_depth_adjust != 0 && PrintInlining) {
495 stringStream nm1; caller_jvms->method()->print_name(&nm1); 511 CompileTask::print_inline_indent(inline_depth());
496 stringStream nm2; callee_method->print_name(&nm2); 512 tty->print_cr(" \\-> discounting inline depth");
497 tty->print_cr("discounting inlining depth from %s to %s", nm1.base(), nm2.base());
498 } 513 }
499 if (new_depth_adjust != 0 && C->log()) { 514 if (new_depth_adjust != 0 && C->log()) {
500 int id1 = C->log()->identify(caller_jvms->method()); 515 int id1 = C->log()->identify(caller_jvms->method());
501 int id2 = C->log()->identify(callee_method); 516 int id2 = C->log()->identify(callee_method);
502 C->log()->elem("inline_depth_discount caller='%d' callee='%d'", id1, id2); 517 C->log()->elem("inline_depth_discount caller='%d' callee='%d'", id1, id2);

mercurial