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;
|