< prev index next >

src/hotspot/cpu/x86/methodHandles_x86.cpp

Print this page
rev 50081 : [mq]: primitives2.patch


 150   __ jmp(Address(method, entry_offset));
 151 
 152   __ bind(L_no_such_method);
 153   __ jump(RuntimeAddress(StubRoutines::throw_AbstractMethodError_entry()));
 154 }
 155 
 156 void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
 157                                         Register recv, Register method_temp,
 158                                         Register temp2,
 159                                         bool for_compiler_entry) {
 160   BLOCK_COMMENT("jump_to_lambda_form {");
 161   // This is the initial entry point of a lazy method handle.
 162   // After type checking, it picks up the invoker from the LambdaForm.
 163   assert_different_registers(recv, method_temp, temp2);
 164   assert(recv != noreg, "required register");
 165   assert(method_temp == rbx, "required register for loading method");
 166 
 167   //NOT_PRODUCT({ FlagSetting fs(TraceMethodHandles, true); trace_method_handle(_masm, "LZMH"); });
 168 
 169   // Load the invoker, as MH -> MH.form -> LF.vmentry
 170   __ resolve_for_read(0, recv);
 171   __ verify_oop(recv);
 172   __ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())), temp2);
 173   __ resolve_for_read(0, method_temp);
 174   __ verify_oop(method_temp);
 175   __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())), temp2);
 176   __ resolve_for_read(0, method_temp);
 177   __ verify_oop(method_temp);
 178   __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes())), temp2);
 179   __ resolve_for_read(OOP_NOT_NULL, method_temp);
 180   __ verify_oop(method_temp);
 181   __ movptr(method_temp, Address(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes())));


 182 
 183   if (VerifyMethodHandles && !for_compiler_entry) {
 184     // make sure recv is already on stack
 185     __ movptr(temp2, Address(method_temp, Method::const_offset()));
 186     __ load_sized_value(temp2,
 187                         Address(temp2, ConstMethod::size_of_parameters_offset()),
 188                         sizeof(u2), /*is_signed*/ false);
 189     // assert(sizeof(u2) == sizeof(Method::_size_of_parameters), "");
 190     __ movptr(temp2, __ argument_address(temp2, -1));
 191     Label L;
 192     __ cmpoop(recv, temp2);
 193     __ jcc(Assembler::equal, L);
 194     __ movptr(rax, temp2);
 195     __ STOP("receiver not on stack");
 196     __ BIND(L);
 197   }
 198 
 199   jump_from_method_handle(_masm, method_temp, temp2, for_compiler_entry);
 200   BLOCK_COMMENT("} jump_to_lambda_form");
 201 }


 370         load_klass_from_Class(_masm, temp2_defc);
 371         __ verify_klass_ptr(temp2_defc);
 372         __ check_klass_subtype(temp1_recv_klass, temp2_defc, temp3, L_ok);
 373         // If we get here, the type check failed!
 374         __ STOP("receiver class disagrees with MemberName.clazz");
 375         __ bind(L_ok);
 376       }
 377       BLOCK_COMMENT("} check_receiver");
 378     }
 379     if (iid == vmIntrinsics::_linkToSpecial ||
 380         iid == vmIntrinsics::_linkToStatic) {
 381       DEBUG_ONLY(temp1_recv_klass = noreg);  // these guys didn't load the recv_klass
 382     }
 383 
 384     // Live registers at this point:
 385     //  member_reg - MemberName that was the trailing argument
 386     //  temp1_recv_klass - klass of stacked receiver, if needed
 387     //  rsi/r13 - interpreter linkage (if interpreted)
 388     //  rcx, rdx, rsi, rdi, r8 - compiler arguments (if compiled)
 389 
 390     __ resolve_for_read(0, member_reg);
 391     Label L_incompatible_class_change_error;
 392     switch (iid) {
 393     case vmIntrinsics::_linkToSpecial:
 394       if (VerifyMethodHandles) {
 395         verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3);
 396       }
 397       __ load_heap_oop(rbx_method, member_vmtarget);
 398       __ resolve_for_read(0, rbx_method);
 399       __ movptr(rbx_method, vmtarget_method);
 400       break;
 401 
 402     case vmIntrinsics::_linkToStatic:
 403       if (VerifyMethodHandles) {
 404         verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3);
 405       }
 406       __ load_heap_oop(rbx_method, member_vmtarget);
 407       __ resolve_for_read(0, rbx_method);
 408       __ movptr(rbx_method, vmtarget_method);
 409       break;
 410 
 411     case vmIntrinsics::_linkToVirtual:
 412     {
 413       // same as TemplateTable::invokevirtual,
 414       // minus the CP setup and profiling:
 415 
 416       if (VerifyMethodHandles) {
 417         verify_ref_kind(_masm, JVM_REF_invokeVirtual, member_reg, temp3);
 418       }
 419 
 420       // pick out the vtable index from the MemberName, and then we can discard it:
 421       Register temp2_index = temp2;
 422       __ movptr(temp2_index, member_vmindex);
 423 
 424       if (VerifyMethodHandles) {
 425         Label L_index_ok;
 426         __ cmpl(temp2_index, 0);
 427         __ jcc(Assembler::greaterEqual, L_index_ok);
 428         __ STOP("no virtual index");
 429         __ BIND(L_index_ok);
 430       }
 431 
 432       // Note:  The verifier invariants allow us to ignore MemberName.clazz and vmtarget
 433       // at this point.  And VerifyMethodHandles has already checked clazz, if needed.
 434 
 435       // get target Method* & entry point
 436       __ lookup_virtual_method(temp1_recv_klass, temp2_index, rbx_method);
 437       break;
 438     }
 439 
 440     case vmIntrinsics::_linkToInterface:
 441     {
 442       // same as TemplateTable::invokeinterface
 443       // (minus the CP setup and profiling, with different argument motion)
 444       if (VerifyMethodHandles) {
 445         verify_ref_kind(_masm, JVM_REF_invokeInterface, member_reg, temp3);
 446       }
 447 
 448       Register temp3_intf = temp3;
 449       __ load_heap_oop(temp3_intf, member_clazz);
 450       load_klass_from_Class(_masm, temp3_intf);
 451       __ verify_klass_ptr(temp3_intf);
 452 
 453       Register rbx_index = rbx_method;
 454       __ movptr(rbx_index, member_vmindex);
 455       if (VerifyMethodHandles) {
 456         Label L;
 457         __ cmpl(rbx_index, 0);
 458         __ jcc(Assembler::greaterEqual, L);
 459         __ STOP("invalid vtable index for MH.invokeInterface");
 460         __ bind(L);
 461       }
 462 
 463       // given intf, index, and recv klass, dispatch to the implementation method
 464       __ lookup_interface_method(temp1_recv_klass, temp3_intf,
 465                                  // note: next two args must be the same:
 466                                  rbx_index, rbx_method,
 467                                  temp2,
 468                                  L_incompatible_class_change_error);
 469       break;
 470     }
 471 
 472     default:
 473       fatal("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid));
 474       break;




 150   __ jmp(Address(method, entry_offset));
 151 
 152   __ bind(L_no_such_method);
 153   __ jump(RuntimeAddress(StubRoutines::throw_AbstractMethodError_entry()));
 154 }
 155 
 156 void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
 157                                         Register recv, Register method_temp,
 158                                         Register temp2,
 159                                         bool for_compiler_entry) {
 160   BLOCK_COMMENT("jump_to_lambda_form {");
 161   // This is the initial entry point of a lazy method handle.
 162   // After type checking, it picks up the invoker from the LambdaForm.
 163   assert_different_registers(recv, method_temp, temp2);
 164   assert(recv != noreg, "required register");
 165   assert(method_temp == rbx, "required register for loading method");
 166 
 167   //NOT_PRODUCT({ FlagSetting fs(TraceMethodHandles, true); trace_method_handle(_masm, "LZMH"); });
 168 
 169   // Load the invoker, as MH -> MH.form -> LF.vmentry

 170   __ verify_oop(recv);
 171   __ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())), temp2);

 172   __ verify_oop(method_temp);
 173   __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())), temp2);

 174   __ verify_oop(method_temp);
 175   __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes())), temp2);

 176   __ verify_oop(method_temp);
 177   __ access_load_at(T_ADDRESS, IN_HEAP, method_temp,
 178                     Address(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes())),
 179                     noreg, noreg);
 180 
 181   if (VerifyMethodHandles && !for_compiler_entry) {
 182     // make sure recv is already on stack
 183     __ movptr(temp2, Address(method_temp, Method::const_offset()));
 184     __ load_sized_value(temp2,
 185                         Address(temp2, ConstMethod::size_of_parameters_offset()),
 186                         sizeof(u2), /*is_signed*/ false);
 187     // assert(sizeof(u2) == sizeof(Method::_size_of_parameters), "");
 188     __ movptr(temp2, __ argument_address(temp2, -1));
 189     Label L;
 190     __ cmpoop(recv, temp2);
 191     __ jcc(Assembler::equal, L);
 192     __ movptr(rax, temp2);
 193     __ STOP("receiver not on stack");
 194     __ BIND(L);
 195   }
 196 
 197   jump_from_method_handle(_masm, method_temp, temp2, for_compiler_entry);
 198   BLOCK_COMMENT("} jump_to_lambda_form");
 199 }


 368         load_klass_from_Class(_masm, temp2_defc);
 369         __ verify_klass_ptr(temp2_defc);
 370         __ check_klass_subtype(temp1_recv_klass, temp2_defc, temp3, L_ok);
 371         // If we get here, the type check failed!
 372         __ STOP("receiver class disagrees with MemberName.clazz");
 373         __ bind(L_ok);
 374       }
 375       BLOCK_COMMENT("} check_receiver");
 376     }
 377     if (iid == vmIntrinsics::_linkToSpecial ||
 378         iid == vmIntrinsics::_linkToStatic) {
 379       DEBUG_ONLY(temp1_recv_klass = noreg);  // these guys didn't load the recv_klass
 380     }
 381 
 382     // Live registers at this point:
 383     //  member_reg - MemberName that was the trailing argument
 384     //  temp1_recv_klass - klass of stacked receiver, if needed
 385     //  rsi/r13 - interpreter linkage (if interpreted)
 386     //  rcx, rdx, rsi, rdi, r8 - compiler arguments (if compiled)
 387 

 388     Label L_incompatible_class_change_error;
 389     switch (iid) {
 390     case vmIntrinsics::_linkToSpecial:
 391       if (VerifyMethodHandles) {
 392         verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3);
 393       }
 394       __ load_heap_oop(rbx_method, member_vmtarget);
 395       __ access_load_at(T_ADDRESS, IN_HEAP, rbx_method, vmtarget_method, noreg, noreg);

 396       break;
 397 
 398     case vmIntrinsics::_linkToStatic:
 399       if (VerifyMethodHandles) {
 400         verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3);
 401       }
 402       __ load_heap_oop(rbx_method, member_vmtarget);
 403       __ access_load_at(T_ADDRESS, IN_HEAP, rbx_method, vmtarget_method, noreg, noreg);

 404       break;
 405 
 406     case vmIntrinsics::_linkToVirtual:
 407     {
 408       // same as TemplateTable::invokevirtual,
 409       // minus the CP setup and profiling:
 410 
 411       if (VerifyMethodHandles) {
 412         verify_ref_kind(_masm, JVM_REF_invokeVirtual, member_reg, temp3);
 413       }
 414 
 415       // pick out the vtable index from the MemberName, and then we can discard it:
 416       Register temp2_index = temp2;
 417       __ access_load_at(T_ADDRESS, IN_HEAP, temp2_index, member_vmindex, noreg, noreg);
 418 
 419       if (VerifyMethodHandles) {
 420         Label L_index_ok;
 421         __ cmpl(temp2_index, 0);
 422         __ jcc(Assembler::greaterEqual, L_index_ok);
 423         __ STOP("no virtual index");
 424         __ BIND(L_index_ok);
 425       }
 426 
 427       // Note:  The verifier invariants allow us to ignore MemberName.clazz and vmtarget
 428       // at this point.  And VerifyMethodHandles has already checked clazz, if needed.
 429 
 430       // get target Method* & entry point
 431       __ lookup_virtual_method(temp1_recv_klass, temp2_index, rbx_method);
 432       break;
 433     }
 434 
 435     case vmIntrinsics::_linkToInterface:
 436     {
 437       // same as TemplateTable::invokeinterface
 438       // (minus the CP setup and profiling, with different argument motion)
 439       if (VerifyMethodHandles) {
 440         verify_ref_kind(_masm, JVM_REF_invokeInterface, member_reg, temp3);
 441       }
 442 
 443       Register temp3_intf = temp3;
 444       __ load_heap_oop(temp3_intf, member_clazz);
 445       load_klass_from_Class(_masm, temp3_intf);
 446       __ verify_klass_ptr(temp3_intf);
 447 
 448       Register rbx_index = rbx_method;
 449       __ access_load_at(T_ADDRESS, IN_HEAP, rbx_index, member_vmindex, noreg, noreg);
 450       if (VerifyMethodHandles) {
 451         Label L;
 452         __ cmpl(rbx_index, 0);
 453         __ jcc(Assembler::greaterEqual, L);
 454         __ STOP("invalid vtable index for MH.invokeInterface");
 455         __ bind(L);
 456       }
 457 
 458       // given intf, index, and recv klass, dispatch to the implementation method
 459       __ lookup_interface_method(temp1_recv_klass, temp3_intf,
 460                                  // note: next two args must be the same:
 461                                  rbx_index, rbx_method,
 462                                  temp2,
 463                                  L_incompatible_class_change_error);
 464       break;
 465     }
 466 
 467     default:
 468       fatal("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid));
 469       break;


< prev index next >