Mercurial > hg > truffle
comparison src/share/vm/opto/callGenerator.cpp @ 3905:c26de9aef2ed
7071307: MethodHandle bimorphic inlining should consider the frequency
Reviewed-by: twisti, roland, kvn, iveresov
author | never |
---|---|
date | Fri, 02 Sep 2011 20:58:21 -0700 |
parents | aa67216400d3 |
children | 83d0b5cd1438 |
comparison
equal
deleted
inserted
replaced
3902:11a4af030e4b | 3905:c26de9aef2ed |
---|---|
147 } | 147 } |
148 // Mark the call node as virtual, sort of: | 148 // Mark the call node as virtual, sort of: |
149 call->set_optimized_virtual(true); | 149 call->set_optimized_virtual(true); |
150 if (method()->is_method_handle_invoke()) { | 150 if (method()->is_method_handle_invoke()) { |
151 call->set_method_handle_invoke(true); | 151 call->set_method_handle_invoke(true); |
152 kit.C->set_has_method_handle_invokes(true); | |
153 } | 152 } |
154 } | 153 } |
155 kit.set_arguments_for_java_call(call); | 154 kit.set_arguments_for_java_call(call); |
156 kit.set_edges_for_java_call(call, false, _separate_io_proj); | 155 kit.set_edges_for_java_call(call, false, _separate_io_proj); |
157 Node* ret = kit.set_results_for_java_call(call, _separate_io_proj); | 156 Node* ret = kit.set_results_for_java_call(call, _separate_io_proj); |
205 CallStaticJavaNode *call = new (kit.C, tf()->domain()->cnt()) CallStaticJavaNode(tf(), resolve_stub, method(), kit.bci()); | 204 CallStaticJavaNode *call = new (kit.C, tf()->domain()->cnt()) CallStaticJavaNode(tf(), resolve_stub, method(), kit.bci()); |
206 // invokedynamic is treated as an optimized invokevirtual. | 205 // invokedynamic is treated as an optimized invokevirtual. |
207 call->set_optimized_virtual(true); | 206 call->set_optimized_virtual(true); |
208 // Take extra care (in the presence of argument motion) not to trash the SP: | 207 // Take extra care (in the presence of argument motion) not to trash the SP: |
209 call->set_method_handle_invoke(true); | 208 call->set_method_handle_invoke(true); |
210 kit.C->set_has_method_handle_invokes(true); | |
211 | 209 |
212 // Pass the target MethodHandle as first argument and shift the | 210 // Pass the target MethodHandle as first argument and shift the |
213 // other arguments. | 211 // other arguments. |
214 call->init_req(0 + TypeFunc::Parms, target_mh); | 212 call->init_req(0 + TypeFunc::Parms, target_mh); |
215 uint nargs = call->method()->arg_size(); | 213 uint nargs = call->method()->arg_size(); |
704 if (cg != NULL && cg->is_inline()) | 702 if (cg != NULL && cg->is_inline()) |
705 return cg; | 703 return cg; |
706 } | 704 } |
707 } else if (method_handle->Opcode() == Op_Phi && method_handle->req() == 3 && | 705 } else if (method_handle->Opcode() == Op_Phi && method_handle->req() == 3 && |
708 method_handle->in(1)->Opcode() == Op_ConP && method_handle->in(2)->Opcode() == Op_ConP) { | 706 method_handle->in(1)->Opcode() == Op_ConP && method_handle->in(2)->Opcode() == Op_ConP) { |
707 float prob = PROB_FAIR; | |
708 Node* meth_region = method_handle->in(0); | |
709 if (meth_region->is_Region() && | |
710 meth_region->in(1)->is_Proj() && meth_region->in(2)->is_Proj() && | |
711 meth_region->in(1)->in(0) == meth_region->in(2)->in(0) && | |
712 meth_region->in(1)->in(0)->is_If()) { | |
713 // If diamond, so grab the probability of the test to drive the inlining below | |
714 prob = meth_region->in(1)->in(0)->as_If()->_prob; | |
715 if (meth_region->in(1)->is_IfTrue()) { | |
716 prob = 1 - prob; | |
717 } | |
718 } | |
719 | |
709 // selectAlternative idiom merging two constant MethodHandles. | 720 // selectAlternative idiom merging two constant MethodHandles. |
710 // Generate a guard so that each can be inlined. We might want to | 721 // Generate a guard so that each can be inlined. We might want to |
711 // do more inputs at later point but this gets the most common | 722 // do more inputs at later point but this gets the most common |
712 // case. | 723 // case. |
713 const TypeOopPtr* oop_ptr = method_handle->in(1)->bottom_type()->is_oopptr(); | 724 CallGenerator* cg1 = for_method_handle_inline(method_handle->in(1), jvms, caller, callee, profile.rescale(1.0 - prob)); |
714 ciObject* const_oop = oop_ptr->const_oop(); | 725 CallGenerator* cg2 = for_method_handle_inline(method_handle->in(2), jvms, caller, callee, profile.rescale(prob)); |
715 ciMethodHandle* mh = const_oop->as_method_handle(); | |
716 | |
717 CallGenerator* cg1 = for_method_handle_inline(method_handle->in(1), jvms, caller, callee, profile); | |
718 CallGenerator* cg2 = for_method_handle_inline(method_handle->in(2), jvms, caller, callee, profile); | |
719 if (cg1 != NULL && cg2 != NULL) { | 726 if (cg1 != NULL && cg2 != NULL) { |
720 return new PredictedDynamicCallGenerator(mh, cg2, cg1, PROB_FAIR); | 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 return new PredictedDynamicCallGenerator(mh, cg2, cg1, prob); | |
721 } | 731 } |
722 } | 732 } |
723 return NULL; | 733 return NULL; |
724 } | 734 } |
725 | 735 |