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 } |