< prev index next >

src/hotspot/cpu/aarch64/methodHandles_aarch64.cpp

Print this page
rev 50376 : [mq]: JDK-8203172.patch


 124                                         Register recv, Register method_temp,
 125                                         Register temp2,
 126                                         bool for_compiler_entry) {
 127   BLOCK_COMMENT("jump_to_lambda_form {");
 128   // This is the initial entry point of a lazy method handle.
 129   // After type checking, it picks up the invoker from the LambdaForm.
 130   assert_different_registers(recv, method_temp, temp2);
 131   assert(recv != noreg, "required register");
 132   assert(method_temp == rmethod, "required register for loading method");
 133 
 134   //NOT_PRODUCT({ FlagSetting fs(TraceMethodHandles, true); trace_method_handle(_masm, "LZMH"); });
 135 
 136   // Load the invoker, as MH -> MH.form -> LF.vmentry
 137   __ verify_oop(recv);
 138   __ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())), temp2);
 139   __ verify_oop(method_temp);
 140   __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())), temp2);
 141   __ verify_oop(method_temp);
 142   __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes())), temp2);
 143   __ verify_oop(method_temp);
 144   __ ldr(method_temp, Address(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes())));
 145 
 146   if (VerifyMethodHandles && !for_compiler_entry) {
 147     // make sure recv is already on stack
 148     __ ldr(temp2, Address(method_temp, Method::const_offset()));
 149     __ load_sized_value(temp2,
 150                         Address(temp2, ConstMethod::size_of_parameters_offset()),
 151                         sizeof(u2), /*is_signed*/ false);
 152     // assert(sizeof(u2) == sizeof(Method::_size_of_parameters), "");
 153     Label L;
 154     __ ldr(rscratch1, __ argument_address(temp2, -1));
 155     __ cmp(recv, rscratch1);
 156     __ br(Assembler::EQ, L);
 157     __ ldr(r0, __ argument_address(temp2, -1));
 158     __ hlt(0);
 159     __ BIND(L);
 160   }
 161 
 162   jump_from_method_handle(_masm, method_temp, temp2, for_compiler_entry);
 163   BLOCK_COMMENT("} jump_to_lambda_form");
 164 }


 323       BLOCK_COMMENT("} check_receiver");
 324     }
 325     if (iid == vmIntrinsics::_linkToSpecial ||
 326         iid == vmIntrinsics::_linkToStatic) {
 327       DEBUG_ONLY(temp1_recv_klass = noreg);  // these guys didn't load the recv_klass
 328     }
 329 
 330     // Live registers at this point:
 331     //  member_reg - MemberName that was the trailing argument
 332     //  temp1_recv_klass - klass of stacked receiver, if needed
 333     //  r13 - interpreter linkage (if interpreted)  ??? FIXME
 334     //  r1 ... r0 - compiler arguments (if compiled)
 335 
 336     Label L_incompatible_class_change_error;
 337     switch (iid) {
 338     case vmIntrinsics::_linkToSpecial:
 339       if (VerifyMethodHandles) {
 340         verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3);
 341       }
 342       __ load_heap_oop(rmethod, member_vmtarget);
 343       __ ldr(rmethod, vmtarget_method);
 344       break;
 345 
 346     case vmIntrinsics::_linkToStatic:
 347       if (VerifyMethodHandles) {
 348         verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3);
 349       }
 350       __ load_heap_oop(rmethod, member_vmtarget);
 351       __ ldr(rmethod, vmtarget_method);
 352       break;
 353 
 354     case vmIntrinsics::_linkToVirtual:
 355     {
 356       // same as TemplateTable::invokevirtual,
 357       // minus the CP setup and profiling:
 358 
 359       if (VerifyMethodHandles) {
 360         verify_ref_kind(_masm, JVM_REF_invokeVirtual, member_reg, temp3);
 361       }
 362 
 363       // pick out the vtable index from the MemberName, and then we can discard it:
 364       Register temp2_index = temp2;
 365       __ ldr(temp2_index, member_vmindex);
 366 
 367       if (VerifyMethodHandles) {
 368         Label L_index_ok;
 369         __ cmpw(temp2_index, 0U);
 370         __ br(Assembler::GE, L_index_ok);
 371         __ hlt(0);
 372         __ BIND(L_index_ok);
 373       }
 374 
 375       // Note:  The verifier invariants allow us to ignore MemberName.clazz and vmtarget
 376       // at this point.  And VerifyMethodHandles has already checked clazz, if needed.
 377 
 378       // get target Method* & entry point
 379       __ lookup_virtual_method(temp1_recv_klass, temp2_index, rmethod);
 380       break;
 381     }
 382 
 383     case vmIntrinsics::_linkToInterface:
 384     {
 385       // same as TemplateTable::invokeinterface
 386       // (minus the CP setup and profiling, with different argument motion)
 387       if (VerifyMethodHandles) {
 388         verify_ref_kind(_masm, JVM_REF_invokeInterface, member_reg, temp3);
 389       }
 390 
 391       Register temp3_intf = temp3;
 392       __ load_heap_oop(temp3_intf, member_clazz);
 393       load_klass_from_Class(_masm, temp3_intf);
 394       __ verify_klass_ptr(temp3_intf);
 395 
 396       Register rindex = rmethod;
 397       __ ldr(rindex, member_vmindex);
 398       if (VerifyMethodHandles) {
 399         Label L;
 400         __ cmpw(rindex, 0U);
 401         __ br(Assembler::GE, L);
 402         __ hlt(0);
 403         __ bind(L);
 404       }
 405 
 406       // given intf, index, and recv klass, dispatch to the implementation method
 407       __ lookup_interface_method(temp1_recv_klass, temp3_intf,
 408                                  // note: next two args must be the same:
 409                                  rindex, rmethod,
 410                                  temp2,
 411                                  L_incompatible_class_change_error);
 412       break;
 413     }
 414 
 415     default:
 416       fatal("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid));
 417       break;




 124                                         Register recv, Register method_temp,
 125                                         Register temp2,
 126                                         bool for_compiler_entry) {
 127   BLOCK_COMMENT("jump_to_lambda_form {");
 128   // This is the initial entry point of a lazy method handle.
 129   // After type checking, it picks up the invoker from the LambdaForm.
 130   assert_different_registers(recv, method_temp, temp2);
 131   assert(recv != noreg, "required register");
 132   assert(method_temp == rmethod, "required register for loading method");
 133 
 134   //NOT_PRODUCT({ FlagSetting fs(TraceMethodHandles, true); trace_method_handle(_masm, "LZMH"); });
 135 
 136   // Load the invoker, as MH -> MH.form -> LF.vmentry
 137   __ verify_oop(recv);
 138   __ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())), temp2);
 139   __ verify_oop(method_temp);
 140   __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())), temp2);
 141   __ verify_oop(method_temp);
 142   __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes())), temp2);
 143   __ verify_oop(method_temp);
 144   __ access_load_at(T_ADDRESS, IN_HEAP, method_temp, Address(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes())), noreg, noreg);
 145 
 146   if (VerifyMethodHandles && !for_compiler_entry) {
 147     // make sure recv is already on stack
 148     __ ldr(temp2, Address(method_temp, Method::const_offset()));
 149     __ load_sized_value(temp2,
 150                         Address(temp2, ConstMethod::size_of_parameters_offset()),
 151                         sizeof(u2), /*is_signed*/ false);
 152     // assert(sizeof(u2) == sizeof(Method::_size_of_parameters), "");
 153     Label L;
 154     __ ldr(rscratch1, __ argument_address(temp2, -1));
 155     __ cmp(recv, rscratch1);
 156     __ br(Assembler::EQ, L);
 157     __ ldr(r0, __ argument_address(temp2, -1));
 158     __ hlt(0);
 159     __ BIND(L);
 160   }
 161 
 162   jump_from_method_handle(_masm, method_temp, temp2, for_compiler_entry);
 163   BLOCK_COMMENT("} jump_to_lambda_form");
 164 }


 323       BLOCK_COMMENT("} check_receiver");
 324     }
 325     if (iid == vmIntrinsics::_linkToSpecial ||
 326         iid == vmIntrinsics::_linkToStatic) {
 327       DEBUG_ONLY(temp1_recv_klass = noreg);  // these guys didn't load the recv_klass
 328     }
 329 
 330     // Live registers at this point:
 331     //  member_reg - MemberName that was the trailing argument
 332     //  temp1_recv_klass - klass of stacked receiver, if needed
 333     //  r13 - interpreter linkage (if interpreted)  ??? FIXME
 334     //  r1 ... r0 - compiler arguments (if compiled)
 335 
 336     Label L_incompatible_class_change_error;
 337     switch (iid) {
 338     case vmIntrinsics::_linkToSpecial:
 339       if (VerifyMethodHandles) {
 340         verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3);
 341       }
 342       __ load_heap_oop(rmethod, member_vmtarget);
 343       __ access_load_at(T_ADDRESS, IN_HEAP, rmethod, vmtarget_method, noreg, noreg);
 344       break;
 345 
 346     case vmIntrinsics::_linkToStatic:
 347       if (VerifyMethodHandles) {
 348         verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3);
 349       }
 350       __ load_heap_oop(rmethod, member_vmtarget);
 351       __ access_load_at(T_ADDRESS, IN_HEAP, rmethod, vmtarget_method, noreg, noreg);
 352       break;
 353 
 354     case vmIntrinsics::_linkToVirtual:
 355     {
 356       // same as TemplateTable::invokevirtual,
 357       // minus the CP setup and profiling:
 358 
 359       if (VerifyMethodHandles) {
 360         verify_ref_kind(_masm, JVM_REF_invokeVirtual, member_reg, temp3);
 361       }
 362 
 363       // pick out the vtable index from the MemberName, and then we can discard it:
 364       Register temp2_index = temp2;
 365       __ access_load_at(T_ADDRESS, IN_HEAP, temp2_index, member_vmindex, noreg, noreg);
 366 
 367       if (VerifyMethodHandles) {
 368         Label L_index_ok;
 369         __ cmpw(temp2_index, 0U);
 370         __ br(Assembler::GE, L_index_ok);
 371         __ hlt(0);
 372         __ BIND(L_index_ok);
 373       }
 374 
 375       // Note:  The verifier invariants allow us to ignore MemberName.clazz and vmtarget
 376       // at this point.  And VerifyMethodHandles has already checked clazz, if needed.
 377 
 378       // get target Method* & entry point
 379       __ lookup_virtual_method(temp1_recv_klass, temp2_index, rmethod);
 380       break;
 381     }
 382 
 383     case vmIntrinsics::_linkToInterface:
 384     {
 385       // same as TemplateTable::invokeinterface
 386       // (minus the CP setup and profiling, with different argument motion)
 387       if (VerifyMethodHandles) {
 388         verify_ref_kind(_masm, JVM_REF_invokeInterface, member_reg, temp3);
 389       }
 390 
 391       Register temp3_intf = temp3;
 392       __ load_heap_oop(temp3_intf, member_clazz);
 393       load_klass_from_Class(_masm, temp3_intf);
 394       __ verify_klass_ptr(temp3_intf);
 395 
 396       Register rindex = rmethod;
 397       __ access_load_at(T_ADDRESS, IN_HEAP, rindex, member_vmindex, noreg, noreg);
 398       if (VerifyMethodHandles) {
 399         Label L;
 400         __ cmpw(rindex, 0U);
 401         __ br(Assembler::GE, L);
 402         __ hlt(0);
 403         __ bind(L);
 404       }
 405 
 406       // given intf, index, and recv klass, dispatch to the implementation method
 407       __ lookup_interface_method(temp1_recv_klass, temp3_intf,
 408                                  // note: next two args must be the same:
 409                                  rindex, rmethod,
 410                                  temp2,
 411                                  L_incompatible_class_change_error);
 412       break;
 413     }
 414 
 415     default:
 416       fatal("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid));
 417       break;


< prev index next >