< prev index next >

src/cpu/x86/vm/methodHandles_x86.cpp

Print this page




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

 168   __ verify_oop(recv);
 169   __ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())));

 170   __ verify_oop(method_temp);
 171   __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())));
 172   __ verify_oop(method_temp);
 173   // the following assumes that a Method* is normally compressed in the vmtarget field:
 174   __ movptr(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes())));
 175 
 176   if (VerifyMethodHandles && !for_compiler_entry) {
 177     // make sure recv is already on stack
 178     __ movptr(temp2, Address(method_temp, Method::const_offset()));
 179     __ load_sized_value(temp2,
 180                         Address(temp2, ConstMethod::size_of_parameters_offset()),
 181                         sizeof(u2), /*is_signed*/ false);
 182     // assert(sizeof(u2) == sizeof(Method::_size_of_parameters), "");


 183     Label L;
 184     __ cmpptr(recv, __ argument_address(temp2, -1));
 185     __ jcc(Assembler::equal, L);
 186     __ movptr(rax, __ argument_address(temp2, -1));
 187     __ STOP("receiver not on stack");
 188     __ BIND(L);
 189   }
 190 
 191   jump_from_method_handle(_masm, method_temp, temp2, for_compiler_entry);
 192   BLOCK_COMMENT("} jump_to_lambda_form");
 193 }
 194 
 195 
 196 // Code generation
 197 address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm,
 198                                                                 vmIntrinsics::ID iid) {
 199   const bool not_for_compiler_entry = false;  // this is the interpreter entry
 200   assert(is_signature_polymorphic(iid), "expected invoke iid");
 201   if (iid == vmIntrinsics::_invokeGeneric ||
 202       iid == vmIntrinsics::_compiledLambdaForm) {
 203     // Perhaps surprisingly, the symbolic references visible to Java are not directly used.
 204     // They are linked to Java-generated adapters via MethodHandleNatives.linkMethod.
 205     // They all allow an appendix argument.
 206     __ hlt();           // empty stubs make SG sick


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

 379     Label L_incompatible_class_change_error;
 380     switch (iid) {
 381     case vmIntrinsics::_linkToSpecial:
 382       if (VerifyMethodHandles) {
 383         verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3);
 384       }
 385       __ movptr(rbx_method, member_vmtarget);
 386       break;
 387 
 388     case vmIntrinsics::_linkToStatic:
 389       if (VerifyMethodHandles) {
 390         verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3);
 391       }
 392       __ movptr(rbx_method, member_vmtarget);
 393       break;
 394 
 395     case vmIntrinsics::_linkToVirtual:
 396     {
 397       // same as TemplateTable::invokevirtual,
 398       // minus the CP setup and profiling:




 148   __ jmp(Address(method, entry_offset));
 149 
 150   __ bind(L_no_such_method);
 151   __ jump(RuntimeAddress(StubRoutines::throw_AbstractMethodError_entry()));
 152 }
 153 
 154 void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
 155                                         Register recv, Register method_temp,
 156                                         Register temp2,
 157                                         bool for_compiler_entry) {
 158   BLOCK_COMMENT("jump_to_lambda_form {");
 159   // This is the initial entry point of a lazy method handle.
 160   // After type checking, it picks up the invoker from the LambdaForm.
 161   assert_different_registers(recv, method_temp, temp2);
 162   assert(recv != noreg, "required register");
 163   assert(method_temp == rbx, "required register for loading method");
 164 
 165   //NOT_PRODUCT({ FlagSetting fs(TraceMethodHandles, true); trace_method_handle(_masm, "LZMH"); });
 166 
 167   // Load the invoker, as MH -> MH.form -> LF.vmentry
 168   oopDesc::bs()->interpreter_read_barrier(_masm, recv);
 169   __ verify_oop(recv);
 170   __ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())));
 171   oopDesc::bs()->interpreter_read_barrier(_masm, method_temp);
 172   __ verify_oop(method_temp);
 173   __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())));
 174   __ verify_oop(method_temp);
 175   // the following assumes that a Method* is normally compressed in the vmtarget field:
 176   __ movptr(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes())));
 177 
 178   if (VerifyMethodHandles && !for_compiler_entry) {
 179     // make sure recv is already on stack
 180     __ movptr(temp2, Address(method_temp, Method::const_offset()));
 181     __ load_sized_value(temp2,
 182                         Address(temp2, ConstMethod::size_of_parameters_offset()),
 183                         sizeof(u2), /*is_signed*/ false);
 184     // assert(sizeof(u2) == sizeof(Method::_size_of_parameters), "");
 185     __ movptr(temp2, __ argument_address(temp2, -1));
 186     oopDesc::bs()->interpreter_read_barrier(_masm, temp2);
 187     Label L;
 188     __ cmpptr(recv, temp2);
 189     __ jcc(Assembler::equal, L);
 190     __ movptr(rax, temp2);
 191     __ STOP("receiver not on stack");
 192     __ BIND(L);
 193   }
 194 
 195   jump_from_method_handle(_masm, method_temp, temp2, for_compiler_entry);
 196   BLOCK_COMMENT("} jump_to_lambda_form");
 197 }
 198 
 199 
 200 // Code generation
 201 address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm,
 202                                                                 vmIntrinsics::ID iid) {
 203   const bool not_for_compiler_entry = false;  // this is the interpreter entry
 204   assert(is_signature_polymorphic(iid), "expected invoke iid");
 205   if (iid == vmIntrinsics::_invokeGeneric ||
 206       iid == vmIntrinsics::_compiledLambdaForm) {
 207     // Perhaps surprisingly, the symbolic references visible to Java are not directly used.
 208     // They are linked to Java-generated adapters via MethodHandleNatives.linkMethod.
 209     // They all allow an appendix argument.
 210     __ hlt();           // empty stubs make SG sick


 363         load_klass_from_Class(_masm, temp2_defc);
 364         __ verify_klass_ptr(temp2_defc);
 365         __ check_klass_subtype(temp1_recv_klass, temp2_defc, temp3, L_ok);
 366         // If we get here, the type check failed!
 367         __ STOP("receiver class disagrees with MemberName.clazz");
 368         __ bind(L_ok);
 369       }
 370       BLOCK_COMMENT("} check_receiver");
 371     }
 372     if (iid == vmIntrinsics::_linkToSpecial ||
 373         iid == vmIntrinsics::_linkToStatic) {
 374       DEBUG_ONLY(temp1_recv_klass = noreg);  // these guys didn't load the recv_klass
 375     }
 376 
 377     // Live registers at this point:
 378     //  member_reg - MemberName that was the trailing argument
 379     //  temp1_recv_klass - klass of stacked receiver, if needed
 380     //  rsi/r13 - interpreter linkage (if interpreted)
 381     //  rcx, rdx, rsi, rdi, r8 - compiler arguments (if compiled)
 382 
 383     oopDesc::bs()->interpreter_read_barrier(_masm, member_reg);
 384     Label L_incompatible_class_change_error;
 385     switch (iid) {
 386     case vmIntrinsics::_linkToSpecial:
 387       if (VerifyMethodHandles) {
 388         verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3);
 389       }
 390       __ movptr(rbx_method, member_vmtarget);
 391       break;
 392 
 393     case vmIntrinsics::_linkToStatic:
 394       if (VerifyMethodHandles) {
 395         verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3);
 396       }
 397       __ movptr(rbx_method, member_vmtarget);
 398       break;
 399 
 400     case vmIntrinsics::_linkToVirtual:
 401     {
 402       // same as TemplateTable::invokevirtual,
 403       // minus the CP setup and profiling:


< prev index next >