696 float hit_prob) { |
696 float hit_prob) { |
697 return new PredictedDynamicCallGenerator(predicted_method_handle, if_missed, if_hit, hit_prob); |
697 return new PredictedDynamicCallGenerator(predicted_method_handle, if_missed, if_hit, hit_prob); |
698 } |
698 } |
699 |
699 |
700 |
700 |
|
701 CallGenerator* CallGenerator::for_method_handle_inline(Node* method_handle, JVMState* jvms, |
|
702 ciMethod* caller, ciMethod* callee, ciCallProfile profile) { |
|
703 if (method_handle->Opcode() == Op_ConP) { |
|
704 const TypeOopPtr* oop_ptr = method_handle->bottom_type()->is_oopptr(); |
|
705 ciObject* const_oop = oop_ptr->const_oop(); |
|
706 ciMethodHandle* method_handle = const_oop->as_method_handle(); |
|
707 |
|
708 // Set the callee to have access to the class and signature in |
|
709 // the MethodHandleCompiler. |
|
710 method_handle->set_callee(callee); |
|
711 method_handle->set_caller(caller); |
|
712 method_handle->set_call_profile(profile); |
|
713 |
|
714 // Get an adapter for the MethodHandle. |
|
715 ciMethod* target_method = method_handle->get_method_handle_adapter(); |
|
716 if (target_method != NULL) { |
|
717 CallGenerator* hit_cg = Compile::current()->call_generator(target_method, -1, false, jvms, true, 1); |
|
718 if (hit_cg != NULL && hit_cg->is_inline()) |
|
719 return hit_cg; |
|
720 } |
|
721 } else if (method_handle->Opcode() == Op_Phi && method_handle->req() == 3 && |
|
722 method_handle->in(1)->Opcode() == Op_ConP && method_handle->in(2)->Opcode() == Op_ConP) { |
|
723 // selectAlternative idiom merging two constant MethodHandles. |
|
724 // Generate a guard so that each can be inlined. We might want to |
|
725 // do more inputs at later point but this gets the most common |
|
726 // case. |
|
727 const TypeOopPtr* oop_ptr = method_handle->in(1)->bottom_type()->is_oopptr(); |
|
728 ciObject* const_oop = oop_ptr->const_oop(); |
|
729 ciMethodHandle* mh = const_oop->as_method_handle(); |
|
730 |
|
731 CallGenerator* cg1 = for_method_handle_inline(method_handle->in(1), jvms, caller, callee, profile); |
|
732 CallGenerator* cg2 = for_method_handle_inline(method_handle->in(2), jvms, caller, callee, profile); |
|
733 if (cg1 != NULL && cg2 != NULL) { |
|
734 return new PredictedDynamicCallGenerator(mh, cg2, cg1, PROB_FAIR); |
|
735 } |
|
736 } |
|
737 return NULL; |
|
738 } |
|
739 |
|
740 |
701 JVMState* PredictedDynamicCallGenerator::generate(JVMState* jvms) { |
741 JVMState* PredictedDynamicCallGenerator::generate(JVMState* jvms) { |
702 GraphKit kit(jvms); |
742 GraphKit kit(jvms); |
703 PhaseGVN& gvn = kit.gvn(); |
743 PhaseGVN& gvn = kit.gvn(); |
704 |
744 |
705 CompileLog* log = kit.C->log(); |
745 CompileLog* log = kit.C->log(); |
706 if (log != NULL) { |
746 if (log != NULL) { |
707 log->elem("predicted_dynamic_call bci='%d'", jvms->bci()); |
747 log->elem("predicted_dynamic_call bci='%d'", jvms->bci()); |
708 } |
748 } |
709 |
749 |
710 // Get the constant pool cache from the caller class. |
|
711 ciMethod* caller_method = jvms->method(); |
|
712 ciBytecodeStream str(caller_method); |
|
713 str.force_bci(jvms->bci()); // Set the stream to the invokedynamic bci. |
|
714 ciCPCache* cpcache = str.get_cpcache(); |
|
715 |
|
716 // Get the offset of the CallSite from the constant pool cache |
|
717 // pointer. |
|
718 int index = str.get_method_index(); |
|
719 size_t call_site_offset = cpcache->get_f1_offset(index); |
|
720 |
|
721 // Load the CallSite object from the constant pool cache. |
|
722 const TypeOopPtr* cpcache_ptr = TypeOopPtr::make_from_constant(cpcache); |
|
723 Node* cpcache_adr = kit.makecon(cpcache_ptr); |
|
724 Node* call_site_adr = kit.basic_plus_adr(cpcache_adr, cpcache_adr, call_site_offset); |
|
725 Node* call_site = kit.make_load(kit.control(), call_site_adr, TypeInstPtr::BOTTOM, T_OBJECT, Compile::AliasIdxRaw); |
|
726 |
|
727 // Load the target MethodHandle from the CallSite object. |
|
728 Node* target_adr = kit.basic_plus_adr(call_site, call_site, java_lang_invoke_CallSite::target_offset_in_bytes()); |
|
729 Node* target_mh = kit.make_load(kit.control(), target_adr, TypeInstPtr::BOTTOM, T_OBJECT); |
|
730 |
|
731 // Check if the MethodHandle is still the same. |
|
732 const TypeOopPtr* predicted_mh_ptr = TypeOopPtr::make_from_constant(_predicted_method_handle, true); |
750 const TypeOopPtr* predicted_mh_ptr = TypeOopPtr::make_from_constant(_predicted_method_handle, true); |
733 Node* predicted_mh = kit.makecon(predicted_mh_ptr); |
751 Node* predicted_mh = kit.makecon(predicted_mh_ptr); |
734 |
752 |
735 Node* cmp = gvn.transform(new(kit.C, 3) CmpPNode(target_mh, predicted_mh)); |
753 Node* bol = NULL; |
736 Node* bol = gvn.transform(new(kit.C, 2) BoolNode(cmp, BoolTest::eq) ); |
754 int bc = jvms->method()->java_code_at_bci(jvms->bci()); |
|
755 if (bc == Bytecodes::_invokespecial) { |
|
756 // This is the selectAlternative idiom for guardWithTest |
|
757 Node* receiver = kit.argument(0); |
|
758 |
|
759 // Check if the MethodHandle is the expected one |
|
760 Node* cmp = gvn.transform(new(kit.C, 3) CmpPNode(receiver, predicted_mh)); |
|
761 bol = gvn.transform(new(kit.C, 2) BoolNode(cmp, BoolTest::eq) ); |
|
762 } else { |
|
763 assert(bc == Bytecodes::_invokedynamic, "must be"); |
|
764 // Get the constant pool cache from the caller class. |
|
765 ciMethod* caller_method = jvms->method(); |
|
766 ciBytecodeStream str(caller_method); |
|
767 str.force_bci(jvms->bci()); // Set the stream to the invokedynamic bci. |
|
768 ciCPCache* cpcache = str.get_cpcache(); |
|
769 |
|
770 // Get the offset of the CallSite from the constant pool cache |
|
771 // pointer. |
|
772 int index = str.get_method_index(); |
|
773 size_t call_site_offset = cpcache->get_f1_offset(index); |
|
774 |
|
775 // Load the CallSite object from the constant pool cache. |
|
776 const TypeOopPtr* cpcache_ptr = TypeOopPtr::make_from_constant(cpcache); |
|
777 Node* cpcache_adr = kit.makecon(cpcache_ptr); |
|
778 Node* call_site_adr = kit.basic_plus_adr(cpcache_adr, cpcache_adr, call_site_offset); |
|
779 Node* call_site = kit.make_load(kit.control(), call_site_adr, TypeInstPtr::BOTTOM, T_OBJECT, Compile::AliasIdxRaw); |
|
780 |
|
781 // Load the target MethodHandle from the CallSite object. |
|
782 Node* target_adr = kit.basic_plus_adr(call_site, call_site, java_lang_invoke_CallSite::target_offset_in_bytes()); |
|
783 Node* target_mh = kit.make_load(kit.control(), target_adr, TypeInstPtr::BOTTOM, T_OBJECT); |
|
784 |
|
785 // Check if the MethodHandle is still the same. |
|
786 Node* cmp = gvn.transform(new(kit.C, 3) CmpPNode(target_mh, predicted_mh)); |
|
787 bol = gvn.transform(new(kit.C, 2) BoolNode(cmp, BoolTest::eq) ); |
|
788 } |
737 IfNode* iff = kit.create_and_xform_if(kit.control(), bol, _hit_prob, COUNT_UNKNOWN); |
789 IfNode* iff = kit.create_and_xform_if(kit.control(), bol, _hit_prob, COUNT_UNKNOWN); |
738 kit.set_control( gvn.transform(new(kit.C, 1) IfTrueNode (iff))); |
790 kit.set_control( gvn.transform(new(kit.C, 1) IfTrueNode (iff))); |
739 Node* slow_ctl = gvn.transform(new(kit.C, 1) IfFalseNode(iff)); |
791 Node* slow_ctl = gvn.transform(new(kit.C, 1) IfFalseNode(iff)); |
740 |
792 |
741 SafePointNode* slow_map = NULL; |
793 SafePointNode* slow_map = NULL; |