Mercurial > hg > truffle
comparison src/share/vm/opto/doCall.cpp @ 13086:096c224171c4
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 20 Nov 2013 00:10:38 +0100 |
parents | b2ee5dc63353 |
children | de6a9e811145 |
comparison
equal
deleted
inserted
replaced
12782:92b7ec34ddfa | 13086:096c224171c4 |
---|---|
61 } | 61 } |
62 } | 62 } |
63 | 63 |
64 CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool call_does_dispatch, | 64 CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool call_does_dispatch, |
65 JVMState* jvms, bool allow_inline, | 65 JVMState* jvms, bool allow_inline, |
66 float prof_factor, bool allow_intrinsics, bool delayed_forbidden) { | 66 float prof_factor, ciKlass* speculative_receiver_type, |
67 bool allow_intrinsics, bool delayed_forbidden) { | |
67 ciMethod* caller = jvms->method(); | 68 ciMethod* caller = jvms->method(); |
68 int bci = jvms->bci(); | 69 int bci = jvms->bci(); |
69 Bytecodes::Code bytecode = caller->java_code_at_bci(bci); | 70 Bytecodes::Code bytecode = caller->java_code_at_bci(bci); |
70 guarantee(callee != NULL, "failed method resolution"); | 71 guarantee(callee != NULL, "failed method resolution"); |
71 | 72 |
115 CallGenerator* cg = find_intrinsic(callee, call_does_dispatch); | 116 CallGenerator* cg = find_intrinsic(callee, call_does_dispatch); |
116 if (cg != NULL) { | 117 if (cg != NULL) { |
117 if (cg->is_predicted()) { | 118 if (cg->is_predicted()) { |
118 // Code without intrinsic but, hopefully, inlined. | 119 // Code without intrinsic but, hopefully, inlined. |
119 CallGenerator* inline_cg = this->call_generator(callee, | 120 CallGenerator* inline_cg = this->call_generator(callee, |
120 vtable_index, call_does_dispatch, jvms, allow_inline, prof_factor, false); | 121 vtable_index, call_does_dispatch, jvms, allow_inline, prof_factor, speculative_receiver_type, false); |
121 if (inline_cg != NULL) { | 122 if (inline_cg != NULL) { |
122 cg = CallGenerator::for_predicted_intrinsic(cg, inline_cg); | 123 cg = CallGenerator::for_predicted_intrinsic(cg, inline_cg); |
123 } | 124 } |
124 } | 125 } |
125 | 126 |
210 // Try using the type profile. | 211 // Try using the type profile. |
211 if (call_does_dispatch && site_count > 0 && receiver_count > 0) { | 212 if (call_does_dispatch && site_count > 0 && receiver_count > 0) { |
212 // The major receiver's count >= TypeProfileMajorReceiverPercent of site_count. | 213 // The major receiver's count >= TypeProfileMajorReceiverPercent of site_count. |
213 bool have_major_receiver = (100.*profile.receiver_prob(0) >= (float)TypeProfileMajorReceiverPercent); | 214 bool have_major_receiver = (100.*profile.receiver_prob(0) >= (float)TypeProfileMajorReceiverPercent); |
214 ciMethod* receiver_method = NULL; | 215 ciMethod* receiver_method = NULL; |
215 if (have_major_receiver || profile.morphism() == 1 || | 216 |
216 (profile.morphism() == 2 && UseBimorphicInlining)) { | 217 int morphism = profile.morphism(); |
218 if (speculative_receiver_type != NULL) { | |
219 // We have a speculative type, we should be able to resolve | |
220 // the call. We do that before looking at the profiling at | |
221 // this invoke because it may lead to bimorphic inlining which | |
222 // a speculative type should help us avoid. | |
223 receiver_method = callee->resolve_invoke(jvms->method()->holder(), | |
224 speculative_receiver_type); | |
225 if (receiver_method == NULL) { | |
226 speculative_receiver_type = NULL; | |
227 } else { | |
228 morphism = 1; | |
229 } | |
230 } | |
231 if (receiver_method == NULL && | |
232 (have_major_receiver || morphism == 1 || | |
233 (morphism == 2 && UseBimorphicInlining))) { | |
217 // receiver_method = profile.method(); | 234 // receiver_method = profile.method(); |
218 // Profiles do not suggest methods now. Look it up in the major receiver. | 235 // Profiles do not suggest methods now. Look it up in the major receiver. |
219 receiver_method = callee->resolve_invoke(jvms->method()->holder(), | 236 receiver_method = callee->resolve_invoke(jvms->method()->holder(), |
220 profile.receiver(0)); | 237 profile.receiver(0)); |
221 } | 238 } |
225 vtable_index, !call_does_dispatch, jvms, allow_inline, prof_factor); | 242 vtable_index, !call_does_dispatch, jvms, allow_inline, prof_factor); |
226 if (hit_cg != NULL) { | 243 if (hit_cg != NULL) { |
227 // Look up second receiver. | 244 // Look up second receiver. |
228 CallGenerator* next_hit_cg = NULL; | 245 CallGenerator* next_hit_cg = NULL; |
229 ciMethod* next_receiver_method = NULL; | 246 ciMethod* next_receiver_method = NULL; |
230 if (profile.morphism() == 2 && UseBimorphicInlining) { | 247 if (morphism == 2 && UseBimorphicInlining) { |
231 next_receiver_method = callee->resolve_invoke(jvms->method()->holder(), | 248 next_receiver_method = callee->resolve_invoke(jvms->method()->holder(), |
232 profile.receiver(1)); | 249 profile.receiver(1)); |
233 if (next_receiver_method != NULL) { | 250 if (next_receiver_method != NULL) { |
234 next_hit_cg = this->call_generator(next_receiver_method, | 251 next_hit_cg = this->call_generator(next_receiver_method, |
235 vtable_index, !call_does_dispatch, jvms, | 252 vtable_index, !call_does_dispatch, jvms, |
240 next_hit_cg = NULL; | 257 next_hit_cg = NULL; |
241 } | 258 } |
242 } | 259 } |
243 } | 260 } |
244 CallGenerator* miss_cg; | 261 CallGenerator* miss_cg; |
245 Deoptimization::DeoptReason reason = (profile.morphism() == 2) ? | 262 Deoptimization::DeoptReason reason = morphism == 2 ? |
246 Deoptimization::Reason_bimorphic : | 263 Deoptimization::Reason_bimorphic : |
247 Deoptimization::Reason_class_check; | 264 Deoptimization::Reason_class_check; |
248 if (( profile.morphism() == 1 || | 265 if ((morphism == 1 || (morphism == 2 && next_hit_cg != NULL)) && |
249 (profile.morphism() == 2 && next_hit_cg != NULL) ) && | |
250 !too_many_traps(jvms->method(), jvms->bci(), reason) | 266 !too_many_traps(jvms->method(), jvms->bci(), reason) |
251 ) { | 267 ) { |
252 // Generate uncommon trap for class check failure path | 268 // Generate uncommon trap for class check failure path |
253 // in case of monomorphic or bimorphic virtual call site. | 269 // in case of monomorphic or bimorphic virtual call site. |
254 miss_cg = CallGenerator::for_uncommon_trap(callee, reason, | 270 miss_cg = CallGenerator::for_uncommon_trap(callee, reason, |
258 // in case of polymorphic virtual call site. | 274 // in case of polymorphic virtual call site. |
259 miss_cg = CallGenerator::for_virtual_call(callee, vtable_index); | 275 miss_cg = CallGenerator::for_virtual_call(callee, vtable_index); |
260 } | 276 } |
261 if (miss_cg != NULL) { | 277 if (miss_cg != NULL) { |
262 if (next_hit_cg != NULL) { | 278 if (next_hit_cg != NULL) { |
279 assert(speculative_receiver_type == NULL, "shouldn't end up here if we used speculation"); | |
263 trace_type_profile(C, jvms->method(), jvms->depth() - 1, jvms->bci(), next_receiver_method, profile.receiver(1), site_count, profile.receiver_count(1)); | 280 trace_type_profile(C, jvms->method(), jvms->depth() - 1, jvms->bci(), next_receiver_method, profile.receiver(1), site_count, profile.receiver_count(1)); |
264 // We don't need to record dependency on a receiver here and below. | 281 // We don't need to record dependency on a receiver here and below. |
265 // Whenever we inline, the dependency is added by Parse::Parse(). | 282 // Whenever we inline, the dependency is added by Parse::Parse(). |
266 miss_cg = CallGenerator::for_predicted_call(profile.receiver(1), miss_cg, next_hit_cg, PROB_MAX); | 283 miss_cg = CallGenerator::for_predicted_call(profile.receiver(1), miss_cg, next_hit_cg, PROB_MAX); |
267 } | 284 } |
268 if (miss_cg != NULL) { | 285 if (miss_cg != NULL) { |
269 trace_type_profile(C, jvms->method(), jvms->depth() - 1, jvms->bci(), receiver_method, profile.receiver(0), site_count, receiver_count); | 286 trace_type_profile(C, jvms->method(), jvms->depth() - 1, jvms->bci(), receiver_method, profile.receiver(0), site_count, receiver_count); |
270 CallGenerator* cg = CallGenerator::for_predicted_call(profile.receiver(0), miss_cg, hit_cg, profile.receiver_prob(0)); | 287 ciKlass* k = speculative_receiver_type != NULL ? speculative_receiver_type : profile.receiver(0); |
288 float hit_prob = speculative_receiver_type != NULL ? 1.0 : profile.receiver_prob(0); | |
289 CallGenerator* cg = CallGenerator::for_predicted_call(k, miss_cg, hit_cg, hit_prob); | |
271 if (cg != NULL) return cg; | 290 if (cg != NULL) return cg; |
272 } | 291 } |
273 } | 292 } |
274 } | 293 } |
275 } | 294 } |
444 // Try to get the most accurate receiver type | 463 // Try to get the most accurate receiver type |
445 ciMethod* callee = orig_callee; | 464 ciMethod* callee = orig_callee; |
446 int vtable_index = Method::invalid_vtable_index; | 465 int vtable_index = Method::invalid_vtable_index; |
447 bool call_does_dispatch = false; | 466 bool call_does_dispatch = false; |
448 | 467 |
468 // Speculative type of the receiver if any | |
469 ciKlass* speculative_receiver_type = NULL; | |
449 if (is_virtual_or_interface) { | 470 if (is_virtual_or_interface) { |
450 Node* receiver_node = stack(sp() - nargs); | 471 Node* receiver_node = stack(sp() - nargs); |
451 const TypeOopPtr* receiver_type = _gvn.type(receiver_node)->isa_oopptr(); | 472 const TypeOopPtr* receiver_type = _gvn.type(receiver_node)->isa_oopptr(); |
452 // call_does_dispatch and vtable_index are out-parameters. They might be changed. | 473 // call_does_dispatch and vtable_index are out-parameters. They might be changed. |
453 callee = C->optimize_virtual_call(method(), bci(), klass, orig_callee, receiver_type, | 474 callee = C->optimize_virtual_call(method(), bci(), klass, orig_callee, receiver_type, |
454 is_virtual, | 475 is_virtual, |
455 call_does_dispatch, vtable_index); // out-parameters | 476 call_does_dispatch, vtable_index); // out-parameters |
477 speculative_receiver_type = receiver_type != NULL ? receiver_type->speculative_type() : NULL; | |
456 } | 478 } |
457 | 479 |
458 // Note: It's OK to try to inline a virtual call. | 480 // Note: It's OK to try to inline a virtual call. |
459 // The call generator will not attempt to inline a polymorphic call | 481 // The call generator will not attempt to inline a polymorphic call |
460 // unless it knows how to optimize the receiver dispatch. | 482 // unless it knows how to optimize the receiver dispatch. |
466 | 488 |
467 // --------------------- | 489 // --------------------- |
468 // Decide call tactic. | 490 // Decide call tactic. |
469 // This call checks with CHA, the interpreter profile, intrinsics table, etc. | 491 // This call checks with CHA, the interpreter profile, intrinsics table, etc. |
470 // It decides whether inlining is desirable or not. | 492 // It decides whether inlining is desirable or not. |
471 CallGenerator* cg = C->call_generator(callee, vtable_index, call_does_dispatch, jvms, try_inline, prof_factor()); | 493 CallGenerator* cg = C->call_generator(callee, vtable_index, call_does_dispatch, jvms, try_inline, prof_factor(), speculative_receiver_type); |
472 | 494 |
473 // NOTE: Don't use orig_callee and callee after this point! Use cg->method() instead. | 495 // NOTE: Don't use orig_callee and callee after this point! Use cg->method() instead. |
474 orig_callee = callee = NULL; | 496 orig_callee = callee = NULL; |
475 | 497 |
476 // --------------------- | 498 // --------------------- |
477 // Round double arguments before call | 499 // Round double arguments before call |
478 round_double_arguments(cg->method()); | 500 round_double_arguments(cg->method()); |
479 | 501 |
502 // Feed profiling data for arguments to the type system so it can | |
503 // propagate it as speculative types | |
504 record_profiled_arguments_for_speculation(cg->method(), bc()); | |
505 | |
480 #ifndef PRODUCT | 506 #ifndef PRODUCT |
481 // bump global counters for calls | 507 // bump global counters for calls |
482 count_compiled_calls(/*at_method_entry*/ false, cg->is_inline()); | 508 count_compiled_calls(/*at_method_entry*/ false, cg->is_inline()); |
483 | 509 |
484 // Record first part of parsing work for this call | 510 // Record first part of parsing work for this call |
489 assert(jvms_in_sync(), "jvms must carry full info into CG"); | 515 assert(jvms_in_sync(), "jvms must carry full info into CG"); |
490 | 516 |
491 // save across call, for a subsequent cast_not_null. | 517 // save across call, for a subsequent cast_not_null. |
492 Node* receiver = has_receiver ? argument(0) : NULL; | 518 Node* receiver = has_receiver ? argument(0) : NULL; |
493 | 519 |
520 // The extra CheckCastPP for speculative types mess with PhaseStringOpts | |
521 if (receiver != NULL && !call_does_dispatch && !cg->is_string_late_inline()) { | |
522 // Feed profiling data for a single receiver to the type system so | |
523 // it can propagate it as a speculative type | |
524 receiver = record_profiled_receiver_for_speculation(receiver); | |
525 } | |
526 | |
494 // Bump method data counters (We profile *before* the call is made | 527 // Bump method data counters (We profile *before* the call is made |
495 // because exceptions don't return to the call site.) | 528 // because exceptions don't return to the call site.) |
496 profile_call(receiver); | 529 profile_call(receiver); |
497 | 530 |
498 JVMState* new_jvms = cg->generate(jvms); | 531 JVMState* new_jvms = cg->generate(jvms, this); |
499 if (new_jvms == NULL) { | 532 if (new_jvms == NULL) { |
500 // When inlining attempt fails (e.g., too many arguments), | 533 // When inlining attempt fails (e.g., too many arguments), |
501 // it may contaminate the current compile state, making it | 534 // it may contaminate the current compile state, making it |
502 // impossible to pull back and try again. Once we call | 535 // impossible to pull back and try again. Once we call |
503 // cg->generate(), we are committed. If it fails, the whole | 536 // cg->generate(), we are committed. If it fails, the whole |
506 | 539 |
507 // This can happen if a library intrinsic is available, but refuses | 540 // This can happen if a library intrinsic is available, but refuses |
508 // the call site, perhaps because it did not match a pattern the | 541 // the call site, perhaps because it did not match a pattern the |
509 // intrinsic was expecting to optimize. Should always be possible to | 542 // intrinsic was expecting to optimize. Should always be possible to |
510 // get a normal java call that may inline in that case | 543 // get a normal java call that may inline in that case |
511 cg = C->call_generator(cg->method(), vtable_index, call_does_dispatch, jvms, try_inline, prof_factor(), /* allow_intrinsics= */ false); | 544 cg = C->call_generator(cg->method(), vtable_index, call_does_dispatch, jvms, try_inline, prof_factor(), speculative_receiver_type, /* allow_intrinsics= */ false); |
512 if ((new_jvms = cg->generate(jvms)) == NULL) { | 545 if ((new_jvms = cg->generate(jvms, this)) == NULL) { |
513 guarantee(failing(), "call failed to generate: calls should work"); | 546 guarantee(failing(), "call failed to generate: calls should work"); |
514 return; | 547 return; |
515 } | 548 } |
516 } | 549 } |
517 | 550 |
605 // If there is going to be a trap, put it at the next bytecode: | 638 // If there is going to be a trap, put it at the next bytecode: |
606 set_bci(iter().next_bci()); | 639 set_bci(iter().next_bci()); |
607 null_assert(peek()); | 640 null_assert(peek()); |
608 set_bci(iter().cur_bci()); // put it back | 641 set_bci(iter().cur_bci()); // put it back |
609 } | 642 } |
643 BasicType ct = ctype->basic_type(); | |
644 if (ct == T_OBJECT || ct == T_ARRAY) { | |
645 ciKlass* better_type = method()->return_profiled_type(bci()); | |
646 if (UseTypeSpeculation && better_type != NULL) { | |
647 // If profiling reports a single type for the return value, | |
648 // feed it to the type system so it can propagate it as a | |
649 // speculative type | |
650 record_profile_for_speculation(stack(sp()-1), better_type); | |
651 } | |
652 } | |
610 } | 653 } |
611 | 654 |
612 // Restart record of parsing work after possible inlining of call | 655 // Restart record of parsing work after possible inlining of call |
613 #ifndef PRODUCT | 656 #ifndef PRODUCT |
614 parse_histogram()->set_initial_state(bc()); | 657 parse_histogram()->set_initial_state(bc()); |