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