Mercurial > hg > graal-jvmci-8
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; |