325 assert_different_registers(temp1, rcx, rdx); |
325 assert_different_registers(temp1, rcx, rdx); |
326 assert_different_registers(temp2, rcx, rdx); |
326 assert_different_registers(temp2, rcx, rdx); |
327 assert_different_registers(temp3, rcx, rdx); |
327 assert_different_registers(temp3, rcx, rdx); |
328 } |
328 } |
329 #endif |
329 #endif |
|
330 else { |
|
331 assert_different_registers(temp1, temp2, temp3, saved_last_sp_register()); // don't trash lastSP |
|
332 } |
330 assert_different_registers(temp1, temp2, temp3, receiver_reg); |
333 assert_different_registers(temp1, temp2, temp3, receiver_reg); |
331 assert_different_registers(temp1, temp2, temp3, member_reg); |
334 assert_different_registers(temp1, temp2, temp3, member_reg); |
332 if (!for_compiler_entry) |
|
333 assert_different_registers(temp1, temp2, temp3, saved_last_sp_register()); // don't trash lastSP |
|
334 |
335 |
335 if (iid == vmIntrinsics::_invokeBasic) { |
336 if (iid == vmIntrinsics::_invokeBasic) { |
336 // indirect through MH.form.vmentry.vmtarget |
337 // indirect through MH.form.vmentry.vmtarget |
337 jump_to_lambda_form(_masm, receiver_reg, rbx_method, temp1, for_compiler_entry); |
338 jump_to_lambda_form(_masm, receiver_reg, rbx_method, temp1, for_compiler_entry); |
338 |
339 |
390 // member_reg - MemberName that was the trailing argument |
391 // member_reg - MemberName that was the trailing argument |
391 // temp1_recv_klass - klass of stacked receiver, if needed |
392 // temp1_recv_klass - klass of stacked receiver, if needed |
392 // rsi/r13 - interpreter linkage (if interpreted) |
393 // rsi/r13 - interpreter linkage (if interpreted) |
393 // rcx, rdx, rsi, rdi, r8, r8 - compiler arguments (if compiled) |
394 // rcx, rdx, rsi, rdi, r8, r8 - compiler arguments (if compiled) |
394 |
395 |
395 bool method_is_live = false; |
396 Label L_incompatible_class_change_error; |
396 switch (iid) { |
397 switch (iid) { |
397 case vmIntrinsics::_linkToSpecial: |
398 case vmIntrinsics::_linkToSpecial: |
398 if (VerifyMethodHandles) { |
399 if (VerifyMethodHandles) { |
399 verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3); |
400 verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3); |
400 } |
401 } |
401 __ movptr(rbx_method, member_vmtarget); |
402 __ movptr(rbx_method, member_vmtarget); |
402 method_is_live = true; |
|
403 break; |
403 break; |
404 |
404 |
405 case vmIntrinsics::_linkToStatic: |
405 case vmIntrinsics::_linkToStatic: |
406 if (VerifyMethodHandles) { |
406 if (VerifyMethodHandles) { |
407 verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3); |
407 verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3); |
408 } |
408 } |
409 __ movptr(rbx_method, member_vmtarget); |
409 __ movptr(rbx_method, member_vmtarget); |
410 method_is_live = true; |
|
411 break; |
410 break; |
412 |
411 |
413 case vmIntrinsics::_linkToVirtual: |
412 case vmIntrinsics::_linkToVirtual: |
414 { |
413 { |
415 // same as TemplateTable::invokevirtual, |
414 // same as TemplateTable::invokevirtual, |
434 // Note: The verifier invariants allow us to ignore MemberName.clazz and vmtarget |
433 // Note: The verifier invariants allow us to ignore MemberName.clazz and vmtarget |
435 // at this point. And VerifyMethodHandles has already checked clazz, if needed. |
434 // at this point. And VerifyMethodHandles has already checked clazz, if needed. |
436 |
435 |
437 // get target Method* & entry point |
436 // get target Method* & entry point |
438 __ lookup_virtual_method(temp1_recv_klass, temp2_index, rbx_method); |
437 __ lookup_virtual_method(temp1_recv_klass, temp2_index, rbx_method); |
439 method_is_live = true; |
|
440 break; |
438 break; |
441 } |
439 } |
442 |
440 |
443 case vmIntrinsics::_linkToInterface: |
441 case vmIntrinsics::_linkToInterface: |
444 { |
442 { |
462 __ STOP("invalid vtable index for MH.invokeInterface"); |
460 __ STOP("invalid vtable index for MH.invokeInterface"); |
463 __ bind(L); |
461 __ bind(L); |
464 } |
462 } |
465 |
463 |
466 // given intf, index, and recv klass, dispatch to the implementation method |
464 // given intf, index, and recv klass, dispatch to the implementation method |
467 Label L_no_such_interface; |
|
468 __ lookup_interface_method(temp1_recv_klass, temp3_intf, |
465 __ lookup_interface_method(temp1_recv_klass, temp3_intf, |
469 // note: next two args must be the same: |
466 // note: next two args must be the same: |
470 rbx_index, rbx_method, |
467 rbx_index, rbx_method, |
471 temp2, |
468 temp2, |
472 L_no_such_interface); |
469 L_incompatible_class_change_error); |
473 |
470 break; |
474 __ verify_method_ptr(rbx_method); |
471 } |
475 jump_from_method_handle(_masm, rbx_method, temp2, for_compiler_entry); |
472 |
476 __ hlt(); |
473 default: |
477 |
474 fatal(err_msg_res("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid))); |
478 __ bind(L_no_such_interface); |
475 break; |
|
476 } |
|
477 |
|
478 // Live at this point: |
|
479 // rbx_method |
|
480 // rsi/r13 (if interpreted) |
|
481 |
|
482 // After figuring out which concrete method to call, jump into it. |
|
483 // Note that this works in the interpreter with no data motion. |
|
484 // But the compiled version will require that rcx_recv be shifted out. |
|
485 __ verify_method_ptr(rbx_method); |
|
486 jump_from_method_handle(_masm, rbx_method, temp1, for_compiler_entry); |
|
487 |
|
488 if (iid == vmIntrinsics::_linkToInterface) { |
|
489 __ bind(L_incompatible_class_change_error); |
479 __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry())); |
490 __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry())); |
480 break; |
|
481 } |
|
482 |
|
483 default: |
|
484 fatal(err_msg("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid))); |
|
485 break; |
|
486 } |
|
487 |
|
488 if (method_is_live) { |
|
489 // live at this point: rbx_method, rsi/r13 (if interpreted) |
|
490 |
|
491 // After figuring out which concrete method to call, jump into it. |
|
492 // Note that this works in the interpreter with no data motion. |
|
493 // But the compiled version will require that rcx_recv be shifted out. |
|
494 __ verify_method_ptr(rbx_method); |
|
495 jump_from_method_handle(_masm, rbx_method, temp1, for_compiler_entry); |
|
496 } |
491 } |
497 } |
492 } |
498 } |
493 } |
499 |
494 |
500 #ifndef PRODUCT |
495 #ifndef PRODUCT |