< prev index next >

src/hotspot/cpu/aarch64/methodHandles_aarch64.cpp

Print this page

241   trace_method_handle_interpreter_entry(_masm, iid);
242   if (iid == vmIntrinsics::_invokeBasic) {
243     generate_method_handle_dispatch(_masm, iid, mh, noreg, not_for_compiler_entry);
244 
245   } else {
246     // Adjust argument list by popping the trailing MemberName argument.
247     Register recv = noreg;
248     if (MethodHandles::ref_kind_has_receiver(ref_kind)) {
249       // Load the receiver (not the MH; the actual MemberName's receiver) up from the interpreter stack.
250       __ ldr(recv = r2, r3_first_arg_addr);
251     }
252     DEBUG_ONLY(argp = noreg);
253     Register rmember = rmethod;  // MemberName ptr; incoming method ptr is dead now
254     __ pop(rmember);             // extract last argument
255     generate_method_handle_dispatch(_masm, iid, recv, rmember, not_for_compiler_entry);
256   }
257 
258   return entry_point;
259 }
260 















261 
262 void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
263                                                     vmIntrinsics::ID iid,
264                                                     Register receiver_reg,
265                                                     Register member_reg,
266                                                     bool for_compiler_entry) {
267   assert(is_signature_polymorphic(iid), "expected invoke iid");
268   // temps used in this code are not used in *either* compiled or interpreted calling sequences
269   Register temp1 = r10;
270   Register temp2 = r11;
271   Register temp3 = r14;  // r13 is live by this point: it contains the sender SP
272   if (for_compiler_entry) {
273     assert(receiver_reg == (iid == vmIntrinsics::_linkToStatic ? noreg : j_rarg0), "only valid assignment");
274     assert_different_registers(temp1,        j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5, j_rarg6, j_rarg7);
275     assert_different_registers(temp2,        j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5, j_rarg6, j_rarg7);
276     assert_different_registers(temp3,        j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5, j_rarg6, j_rarg7);
277   }
278 
279   assert_different_registers(temp1, temp2, temp3, receiver_reg);
280   assert_different_registers(temp1, temp2, temp3, member_reg);
281 
282   if (iid == vmIntrinsics::_invokeBasic || iid == vmIntrinsics::_linkToNative) {
283     if (iid == vmIntrinsics::_linkToNative) {
284       assert(for_compiler_entry, "only compiler entry is supported");
285     }
286     // indirect through MH.form.vmentry.vmtarget
287     jump_to_lambda_form(_masm, receiver_reg, rmethod, temp1, for_compiler_entry);
288 



289   } else {
290     // The method is a member invoker used by direct method handles.
291     if (VerifyMethodHandles) {
292       // make sure the trailing argument really is a MemberName (caller responsibility)
293       verify_klass(_masm, member_reg, VM_CLASS_ID(java_lang_invoke_MemberName),
294                    "MemberName required for invokeVirtual etc.");
295     }
296 
297     Address member_clazz(    member_reg, NONZERO(java_lang_invoke_MemberName::clazz_offset()));
298     Address member_vmindex(  member_reg, NONZERO(java_lang_invoke_MemberName::vmindex_offset()));
299     Address member_vmtarget( member_reg, NONZERO(java_lang_invoke_MemberName::method_offset()));
300     Address vmtarget_method( rmethod, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset()));
301 
302     Register temp1_recv_klass = temp1;
303     if (iid != vmIntrinsics::_linkToStatic) {
304       __ verify_oop(receiver_reg);
305       if (iid == vmIntrinsics::_linkToSpecial) {
306         // Don't actually load the klass; just null-check the receiver.
307         __ null_check(receiver_reg);
308       } else {

241   trace_method_handle_interpreter_entry(_masm, iid);
242   if (iid == vmIntrinsics::_invokeBasic) {
243     generate_method_handle_dispatch(_masm, iid, mh, noreg, not_for_compiler_entry);
244 
245   } else {
246     // Adjust argument list by popping the trailing MemberName argument.
247     Register recv = noreg;
248     if (MethodHandles::ref_kind_has_receiver(ref_kind)) {
249       // Load the receiver (not the MH; the actual MemberName's receiver) up from the interpreter stack.
250       __ ldr(recv = r2, r3_first_arg_addr);
251     }
252     DEBUG_ONLY(argp = noreg);
253     Register rmember = rmethod;  // MemberName ptr; incoming method ptr is dead now
254     __ pop(rmember);             // extract last argument
255     generate_method_handle_dispatch(_masm, iid, recv, rmember, not_for_compiler_entry);
256   }
257 
258   return entry_point;
259 }
260 
261 void MethodHandles::jump_to_native_invoker(MacroAssembler* _masm, Register nep_reg, Register temp_target) {
262   BLOCK_COMMENT("jump_to_native_invoker {");
263   assert_different_registers(nep_reg, temp_target);
264   assert(nep_reg != noreg, "required register");
265 
266   // Load the invoker, as NEP -> .invoker
267   __ verify_oop(nep_reg);
268   __ access_load_at(T_ADDRESS, IN_HEAP, temp_target,
269                     Address(nep_reg, NONZERO(jdk_internal_invoke_NativeEntryPoint::invoker_offset_in_bytes())),
270                     noreg, noreg);
271 
272   __ br(temp_target);
273   BLOCK_COMMENT("} jump_to_native_invoker");
274 }
275 
276 
277 void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
278                                                     vmIntrinsics::ID iid,
279                                                     Register receiver_reg,
280                                                     Register member_reg,
281                                                     bool for_compiler_entry) {
282   assert(is_signature_polymorphic(iid), "expected invoke iid");
283   // temps used in this code are not used in *either* compiled or interpreted calling sequences
284   Register temp1 = r10;
285   Register temp2 = r11;
286   Register temp3 = r14;  // r13 is live by this point: it contains the sender SP
287   if (for_compiler_entry) {
288     assert(receiver_reg == (iid == vmIntrinsics::_linkToStatic || iid == vmIntrinsics::_linkToNative ? noreg : j_rarg0), "only valid assignment");
289     assert_different_registers(temp1,        j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5, j_rarg6, j_rarg7);
290     assert_different_registers(temp2,        j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5, j_rarg6, j_rarg7);
291     assert_different_registers(temp3,        j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5, j_rarg6, j_rarg7);
292   }
293 
294   assert_different_registers(temp1, temp2, temp3, receiver_reg);
295   assert_different_registers(temp1, temp2, temp3, member_reg);
296 
297   if (iid == vmIntrinsics::_invokeBasic) {



298     // indirect through MH.form.vmentry.vmtarget
299     jump_to_lambda_form(_masm, receiver_reg, rmethod, temp1, for_compiler_entry);
300 
301   } else if (iid == vmIntrinsics::_linkToNative) {
302     assert(for_compiler_entry, "only compiler entry is supported");
303     jump_to_native_invoker(_masm, member_reg, temp1);
304   } else {
305     // The method is a member invoker used by direct method handles.
306     if (VerifyMethodHandles) {
307       // make sure the trailing argument really is a MemberName (caller responsibility)
308       verify_klass(_masm, member_reg, VM_CLASS_ID(java_lang_invoke_MemberName),
309                    "MemberName required for invokeVirtual etc.");
310     }
311 
312     Address member_clazz(    member_reg, NONZERO(java_lang_invoke_MemberName::clazz_offset()));
313     Address member_vmindex(  member_reg, NONZERO(java_lang_invoke_MemberName::vmindex_offset()));
314     Address member_vmtarget( member_reg, NONZERO(java_lang_invoke_MemberName::method_offset()));
315     Address vmtarget_method( rmethod, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset()));
316 
317     Register temp1_recv_klass = temp1;
318     if (iid != vmIntrinsics::_linkToStatic) {
319       __ verify_oop(receiver_reg);
320       if (iid == vmIntrinsics::_linkToSpecial) {
321         // Don't actually load the klass; just null-check the receiver.
322         __ null_check(receiver_reg);
323       } else {
< prev index next >