comparison src/share/vm/opto/doCall.cpp @ 1138:dd57230ba8fe

6893268: additional dynamic language related optimizations in C2 Summary: C2 needs some additional optimizations to be able to handle MethodHandle invokes and invokedynamic instructions at the best performance. Reviewed-by: kvn, never
author twisti
date Tue, 05 Jan 2010 15:21:25 +0100
parents 97125851f396
children c3b315a0d58a
comparison
equal deleted inserted replaced
1137:97125851f396 1138:dd57230ba8fe
222 } 222 }
223 } 223 }
224 } 224 }
225 } 225 }
226 226
227 // Do MethodHandle calls.
228 if (call_method->is_method_handle_invoke()) {
229 if (jvms->method()->java_code_at_bci(jvms->bci()) != Bytecodes::_invokedynamic) {
230 GraphKit kit(jvms);
231 Node* n = kit.argument(0);
232
233 if (n->Opcode() == Op_ConP) {
234 const TypeOopPtr* oop_ptr = n->bottom_type()->is_oopptr();
235 ciObject* const_oop = oop_ptr->const_oop();
236 ciMethodHandle* method_handle = const_oop->as_method_handle();
237
238 // Set the actually called method to have access to the class
239 // and signature in the MethodHandleCompiler.
240 method_handle->set_callee(call_method);
241
242 // Get an adapter for the MethodHandle.
243 ciMethod* target_method = method_handle->get_method_handle_adapter();
244
245 CallGenerator* hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor);
246 if (hit_cg != NULL && hit_cg->is_inline())
247 return hit_cg;
248 }
249
250 return CallGenerator::for_direct_call(call_method);
251 }
252 else {
253 // Get the MethodHandle from the CallSite.
254 ciMethod* caller_method = jvms->method();
255 ciBytecodeStream str(caller_method);
256 str.force_bci(jvms->bci()); // Set the stream to the invokedynamic bci.
257 ciCallSite* call_site = str.get_call_site();
258 ciMethodHandle* method_handle = call_site->get_target();
259
260 // Set the actually called method to have access to the class
261 // and signature in the MethodHandleCompiler.
262 method_handle->set_callee(call_method);
263
264 // Get an adapter for the MethodHandle.
265 ciMethod* target_method = method_handle->get_invokedynamic_adapter();
266
267 CallGenerator* hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor);
268 if (hit_cg != NULL && hit_cg->is_inline()) {
269 CallGenerator* miss_cg = CallGenerator::for_dynamic_call(call_method);
270 return CallGenerator::for_predicted_dynamic_call(method_handle, miss_cg, hit_cg, prof_factor);
271 }
272
273 // If something failed, generate a normal dynamic call.
274 return CallGenerator::for_dynamic_call(call_method);
275 }
276 }
277
227 // There was no special inlining tactic, or it bailed out. 278 // There was no special inlining tactic, or it bailed out.
228 // Use a more generic tactic, like a simple call. 279 // Use a more generic tactic, like a simple call.
229 if (call_is_virtual) { 280 if (call_is_virtual) {
230 return CallGenerator::for_virtual_call(call_method, vtable_index); 281 return CallGenerator::for_virtual_call(call_method, vtable_index);
231 } else if (call_method->is_method_handle_invoke()) {
232 if (jvms->method()->java_code_at_bci(jvms->bci()) == Bytecodes::_invokedynamic)
233 return CallGenerator::for_dynamic_call(call_method);
234 else
235 // %%% if the target MH is a compile-time constant, we should try to inline it
236 return CallGenerator::for_direct_call(call_method);
237 } else { 282 } else {
238 // Class Hierarchy Analysis or Type Profile reveals a unique target, 283 // Class Hierarchy Analysis or Type Profile reveals a unique target,
239 // or it is a static or special call. 284 // or it is a static or special call.
240 return CallGenerator::for_direct_call(call_method, should_delay_inlining(call_method, jvms)); 285 return CallGenerator::for_direct_call(call_method, should_delay_inlining(call_method, jvms));
241 } 286 }