comparison src/share/vm/opto/doCall.cpp @ 12966:b2ee5dc63353

8024070: C2 needs some form of type speculation Summary: record unused type profile information with type system, propagate and use it. Reviewed-by: kvn, twisti
author roland
date Wed, 23 Oct 2013 12:40:23 +0200
parents 3213ba4d3dff
children de6a9e811145
comparison
equal deleted inserted replaced
12965:8b4bbba322d3 12966:b2ee5dc63353
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
488 assert(jvms == this->jvms(), "still operating on the right JVMS"); 514 assert(jvms == this->jvms(), "still operating on the right JVMS");
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;
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 }
493 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
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, this)) == 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 }
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());