comparison src/share/vm/opto/callGenerator.cpp @ 7478:5698813d45eb

8005418: JSR 292: virtual dispatch bug in 292 impl Reviewed-by: jrose, kvn
author twisti
date Wed, 09 Jan 2013 15:37:23 -0800
parents d092d1b31229
children 8bd61471a109
comparison
equal deleted inserted replaced
7477:038dd2875b94 7478:5698813d45eb
715 715
716 if (IncrementalInline && call_site_count > 0 && 716 if (IncrementalInline && call_site_count > 0 &&
717 (input_not_const || !C->inlining_incrementally() || C->over_inlining_cutoff())) { 717 (input_not_const || !C->inlining_incrementally() || C->over_inlining_cutoff())) {
718 return CallGenerator::for_mh_late_inline(caller, callee, input_not_const); 718 return CallGenerator::for_mh_late_inline(caller, callee, input_not_const);
719 } else { 719 } else {
720 // Out-of-line call.
720 return CallGenerator::for_direct_call(callee); 721 return CallGenerator::for_direct_call(callee);
721 } 722 }
722 } 723 }
723 724
724 CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* caller, ciMethod* callee, bool& input_not_const) { 725 CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* caller, ciMethod* callee, bool& input_not_const) {
737 const TypeOopPtr* oop_ptr = receiver->bottom_type()->is_oopptr(); 738 const TypeOopPtr* oop_ptr = receiver->bottom_type()->is_oopptr();
738 ciMethod* target = oop_ptr->const_oop()->as_method_handle()->get_vmtarget(); 739 ciMethod* target = oop_ptr->const_oop()->as_method_handle()->get_vmtarget();
739 guarantee(!target->is_method_handle_intrinsic(), "should not happen"); // XXX remove 740 guarantee(!target->is_method_handle_intrinsic(), "should not happen"); // XXX remove
740 const int vtable_index = Method::invalid_vtable_index; 741 const int vtable_index = Method::invalid_vtable_index;
741 CallGenerator* cg = C->call_generator(target, vtable_index, false, jvms, true, PROB_ALWAYS, true, true); 742 CallGenerator* cg = C->call_generator(target, vtable_index, false, jvms, true, PROB_ALWAYS, true, true);
742 assert (!cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here"); 743 assert(!cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here");
743 if (cg != NULL && cg->is_inline()) 744 if (cg != NULL && cg->is_inline())
744 return cg; 745 return cg;
745 } 746 }
746 } 747 }
747 break; 748 break;
785 Node* cast_obj = gvn.transform(new (C) CheckCastPPNode(kit.control(), arg, sig_type)); 786 Node* cast_obj = gvn.transform(new (C) CheckCastPPNode(kit.control(), arg, sig_type));
786 kit.set_argument(receiver_skip + i, cast_obj); 787 kit.set_argument(receiver_skip + i, cast_obj);
787 } 788 }
788 } 789 }
789 } 790 }
790 const int vtable_index = Method::invalid_vtable_index; 791
791 const bool call_is_virtual = target->is_abstract(); // FIXME workaround 792 // Try to get the most accurate receiver type
792 CallGenerator* cg = C->call_generator(target, vtable_index, call_is_virtual, jvms, true, PROB_ALWAYS, true, true); 793 const bool is_virtual = (iid == vmIntrinsics::_linkToVirtual);
793 assert (!cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here"); 794 const bool is_virtual_or_interface = (is_virtual || iid == vmIntrinsics::_linkToInterface);
795 int vtable_index = Method::invalid_vtable_index;
796 bool call_does_dispatch = false;
797
798 if (is_virtual_or_interface) {
799 ciInstanceKlass* klass = target->holder();
800 Node* receiver_node = kit.argument(0);
801 const TypeOopPtr* receiver_type = gvn.type(receiver_node)->isa_oopptr();
802 // call_does_dispatch and vtable_index are out-parameters. They might be changed.
803 target = C->optimize_virtual_call(caller, jvms->bci(), klass, target, receiver_type,
804 is_virtual,
805 call_does_dispatch, vtable_index); // out-parameters
806 }
807
808 CallGenerator* cg = C->call_generator(target, vtable_index, call_does_dispatch, jvms, true, PROB_ALWAYS, true, true);
809 assert(!cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here");
794 if (cg != NULL && cg->is_inline()) 810 if (cg != NULL && cg->is_inline())
795 return cg; 811 return cg;
796 } 812 }
797 } 813 }
798 break; 814 break;