hotspot/src/cpu/x86/vm/methodHandles_x86.cpp
changeset 13881 a326d528f3e1
parent 13743 154102966e74
child 13968 8c9029c01470
equal deleted inserted replaced
13751:7fd047780d47 13881:a326d528f3e1
   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