< prev index next >

src/hotspot/cpu/ppc/methodHandles_ppc.cpp

Print this page

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






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



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

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



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