1.1 --- a/src/share/vm/opto/callGenerator.cpp Tue Jan 08 11:30:51 2013 -0800 1.2 +++ b/src/share/vm/opto/callGenerator.cpp Wed Jan 09 15:37:23 2013 -0800 1.3 @@ -717,6 +717,7 @@ 1.4 (input_not_const || !C->inlining_incrementally() || C->over_inlining_cutoff())) { 1.5 return CallGenerator::for_mh_late_inline(caller, callee, input_not_const); 1.6 } else { 1.7 + // Out-of-line call. 1.8 return CallGenerator::for_direct_call(callee); 1.9 } 1.10 } 1.11 @@ -739,7 +740,7 @@ 1.12 guarantee(!target->is_method_handle_intrinsic(), "should not happen"); // XXX remove 1.13 const int vtable_index = Method::invalid_vtable_index; 1.14 CallGenerator* cg = C->call_generator(target, vtable_index, false, jvms, true, PROB_ALWAYS, true, true); 1.15 - assert (!cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here"); 1.16 + assert(!cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here"); 1.17 if (cg != NULL && cg->is_inline()) 1.18 return cg; 1.19 } 1.20 @@ -787,10 +788,25 @@ 1.21 } 1.22 } 1.23 } 1.24 - const int vtable_index = Method::invalid_vtable_index; 1.25 - const bool call_is_virtual = target->is_abstract(); // FIXME workaround 1.26 - CallGenerator* cg = C->call_generator(target, vtable_index, call_is_virtual, jvms, true, PROB_ALWAYS, true, true); 1.27 - assert (!cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here"); 1.28 + 1.29 + // Try to get the most accurate receiver type 1.30 + const bool is_virtual = (iid == vmIntrinsics::_linkToVirtual); 1.31 + const bool is_virtual_or_interface = (is_virtual || iid == vmIntrinsics::_linkToInterface); 1.32 + int vtable_index = Method::invalid_vtable_index; 1.33 + bool call_does_dispatch = false; 1.34 + 1.35 + if (is_virtual_or_interface) { 1.36 + ciInstanceKlass* klass = target->holder(); 1.37 + Node* receiver_node = kit.argument(0); 1.38 + const TypeOopPtr* receiver_type = gvn.type(receiver_node)->isa_oopptr(); 1.39 + // call_does_dispatch and vtable_index are out-parameters. They might be changed. 1.40 + target = C->optimize_virtual_call(caller, jvms->bci(), klass, target, receiver_type, 1.41 + is_virtual, 1.42 + call_does_dispatch, vtable_index); // out-parameters 1.43 + } 1.44 + 1.45 + CallGenerator* cg = C->call_generator(target, vtable_index, call_does_dispatch, jvms, true, PROB_ALWAYS, true, true); 1.46 + assert(!cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here"); 1.47 if (cg != NULL && cg->is_inline()) 1.48 return cg; 1.49 }