< prev index next >

src/hotspot/cpu/ppc/methodHandles_ppc.cpp

Print this page

290   if (iid == vmIntrinsics::_invokeBasic) {
291     generate_method_handle_dispatch(_masm, iid, tmp_mh, noreg, not_for_compiler_entry);
292 
293   } else {
294     // Adjust argument list by popping the trailing MemberName argument.
295     Register tmp_recv = noreg;
296     if (MethodHandles::ref_kind_has_receiver(ref_kind)) {
297       // Load the receiver (not the MH; the actual MemberName's receiver) up from the interpreter stack.
298       __ ld(tmp_recv = R30_tmp1, __ argument_offset(R7_param_size, R7_param_size, 0), R15_argbase);
299       DEBUG_ONLY(R7_param_size = noreg);
300     }
301     Register R19_member = R19_method;  // MemberName ptr; incoming method ptr is dead now
302     __ ld(R19_member, RegisterOrConstant((intptr_t)8), R15_argbase);
303     __ add(R15_argbase, Interpreter::stackElementSize, R15_argbase);
304     generate_method_handle_dispatch(_masm, iid, tmp_recv, R19_member, not_for_compiler_entry);
305   }
306 
307   return entry_point;
308 }
309 






310 void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
311                                                     vmIntrinsics::ID iid,
312                                                     Register receiver_reg,
313                                                     Register member_reg,
314                                                     bool for_compiler_entry) {
315   assert(is_signature_polymorphic(iid), "expected invoke iid");
316   Register temp1 = (for_compiler_entry ? R25_tmp5 : R31); // must be non-volatile due to runtime calls
317   Register temp2 = (for_compiler_entry ? R22_tmp2 : R8);
318   Register temp3 = (for_compiler_entry ? R23_tmp3 : R9);
319   Register temp4 = (for_compiler_entry ? R24_tmp4 : R10);
320   if (receiver_reg != noreg)  assert_different_registers(temp1, temp2, temp3, temp4, receiver_reg);
321   if (member_reg   != noreg)  assert_different_registers(temp1, temp2, temp3, temp4, member_reg);
322 
323   const MacroAssembler::PreservationLevel preservation_level = for_compiler_entry
324     ? MacroAssembler::PRESERVATION_FRAME_LR_GP_FP_REGS
325     : MacroAssembler::PRESERVATION_FRAME_LR;
326 
327   if (iid == vmIntrinsics::_invokeBasic || iid == vmIntrinsics::_linkToNative) {
328     if (iid == vmIntrinsics::_linkToNative) {
329       assert(for_compiler_entry, "only compiler entry is supported");
330     }
331     // indirect through MH.form.vmentry.vmtarget
332     jump_to_lambda_form(_masm, receiver_reg, R19_method, temp1, temp2, for_compiler_entry);



333   } else {
334     // The method is a member invoker used by direct method handles.
335     if (VerifyMethodHandles) {
336       // make sure the trailing argument really is a MemberName (caller responsibility)
337       verify_klass(_masm, member_reg, VM_CLASS_ID(MemberName_klass),
338                    temp1, temp2,
339                    "MemberName required for invokeVirtual etc.");
340     }
341 
342     Register temp1_recv_klass = temp1;
343     if (iid != vmIntrinsics::_linkToStatic) {
344       BLOCK_COMMENT("check_receiver {");
345       __ verify_oop(receiver_reg, FILE_AND_LINE);
346 
347       const int klass_offset = iid == vmIntrinsics::_linkToSpecial
348         ? -1                                  // enforce receiver null check
349         : oopDesc::klass_offset_in_bytes();   // regular null-checking behavior
350 
351       __ null_check_throw(receiver_reg, klass_offset, temp1, Interpreter::throw_NullPointerException_entry());
352 

290   if (iid == vmIntrinsics::_invokeBasic) {
291     generate_method_handle_dispatch(_masm, iid, tmp_mh, noreg, not_for_compiler_entry);
292 
293   } else {
294     // Adjust argument list by popping the trailing MemberName argument.
295     Register tmp_recv = noreg;
296     if (MethodHandles::ref_kind_has_receiver(ref_kind)) {
297       // Load the receiver (not the MH; the actual MemberName's receiver) up from the interpreter stack.
298       __ ld(tmp_recv = R30_tmp1, __ argument_offset(R7_param_size, R7_param_size, 0), R15_argbase);
299       DEBUG_ONLY(R7_param_size = noreg);
300     }
301     Register R19_member = R19_method;  // MemberName ptr; incoming method ptr is dead now
302     __ ld(R19_member, RegisterOrConstant((intptr_t)8), R15_argbase);
303     __ add(R15_argbase, Interpreter::stackElementSize, R15_argbase);
304     generate_method_handle_dispatch(_masm, iid, tmp_recv, R19_member, not_for_compiler_entry);
305   }
306 
307   return entry_point;
308 }
309 
310 void MethodHandles::jump_to_native_invoker(MacroAssembler* _masm, Register nep_reg, Register temp_target) {
311   BLOCK_COMMENT("jump_to_native_invoker {");
312   __ stop("Should not reach here");
313   BLOCK_COMMENT("} jump_to_native_invoker");
314 }
315 
316 void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
317                                                     vmIntrinsics::ID iid,
318                                                     Register receiver_reg,
319                                                     Register member_reg,
320                                                     bool for_compiler_entry) {
321   assert(is_signature_polymorphic(iid), "expected invoke iid");
322   Register temp1 = (for_compiler_entry ? R25_tmp5 : R31); // must be non-volatile due to runtime calls
323   Register temp2 = (for_compiler_entry ? R22_tmp2 : R8);
324   Register temp3 = (for_compiler_entry ? R23_tmp3 : R9);
325   Register temp4 = (for_compiler_entry ? R24_tmp4 : R10);
326   if (receiver_reg != noreg)  assert_different_registers(temp1, temp2, temp3, temp4, receiver_reg);
327   if (member_reg   != noreg)  assert_different_registers(temp1, temp2, temp3, temp4, member_reg);
328 
329   const MacroAssembler::PreservationLevel preservation_level = for_compiler_entry
330     ? MacroAssembler::PRESERVATION_FRAME_LR_GP_FP_REGS
331     : MacroAssembler::PRESERVATION_FRAME_LR;
332 
333   if (iid == vmIntrinsics::_invokeBasic) {



334     // indirect through MH.form.vmentry.vmtarget
335     jump_to_lambda_form(_masm, receiver_reg, R19_method, temp1, temp2, for_compiler_entry);
336   } else if (iid == vmIntrinsics::_linkToNative) {
337     assert(for_compiler_entry, "only compiler entry is supported");
338     jump_to_native_invoker(_masm, member_reg, temp1);
339   } else {
340     // The method is a member invoker used by direct method handles.
341     if (VerifyMethodHandles) {
342       // make sure the trailing argument really is a MemberName (caller responsibility)
343       verify_klass(_masm, member_reg, VM_CLASS_ID(MemberName_klass),
344                    temp1, temp2,
345                    "MemberName required for invokeVirtual etc.");
346     }
347 
348     Register temp1_recv_klass = temp1;
349     if (iid != vmIntrinsics::_linkToStatic) {
350       BLOCK_COMMENT("check_receiver {");
351       __ verify_oop(receiver_reg, FILE_AND_LINE);
352 
353       const int klass_offset = iid == vmIntrinsics::_linkToSpecial
354         ? -1                                  // enforce receiver null check
355         : oopDesc::klass_offset_in_bytes();   // regular null-checking behavior
356 
357       __ null_check_throw(receiver_reg, klass_offset, temp1, Interpreter::throw_NullPointerException_entry());
358 
< prev index next >