158 Register recv, Register method_temp,
159 Register temp2,
160 bool for_compiler_entry) {
161 BLOCK_COMMENT("jump_to_lambda_form {");
162 // This is the initial entry point of a lazy method handle.
163 // After type checking, it picks up the invoker from the LambdaForm.
164 assert_different_registers(recv, method_temp, temp2);
165 assert(recv != noreg, "required register");
166 assert(method_temp == rbx, "required register for loading method");
167
168 //NOT_PRODUCT({ FlagSetting fs(TraceMethodHandles, true); trace_method_handle(_masm, "LZMH"); });
169
170 // Load the invoker, as MH -> MH.form -> LF.vmentry
171 __ verify_oop(recv);
172 __ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())), temp2);
173 __ verify_oop(method_temp);
174 __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())), temp2);
175 __ verify_oop(method_temp);
176 __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes())), temp2);
177 __ verify_oop(method_temp);
178 __ movptr(method_temp, Address(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes())));
179
180 if (VerifyMethodHandles && !for_compiler_entry) {
181 // make sure recv is already on stack
182 __ movptr(temp2, Address(method_temp, Method::const_offset()));
183 __ load_sized_value(temp2,
184 Address(temp2, ConstMethod::size_of_parameters_offset()),
185 sizeof(u2), /*is_signed*/ false);
186 // assert(sizeof(u2) == sizeof(Method::_size_of_parameters), "");
187 Label L;
188 __ cmpoop(recv, __ argument_address(temp2, -1));
189 __ jcc(Assembler::equal, L);
190 __ movptr(rax, __ argument_address(temp2, -1));
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
373 BLOCK_COMMENT("} check_receiver");
374 }
375 if (iid == vmIntrinsics::_linkToSpecial ||
376 iid == vmIntrinsics::_linkToStatic) {
377 DEBUG_ONLY(temp1_recv_klass = noreg); // these guys didn't load the recv_klass
378 }
379
380 // Live registers at this point:
381 // member_reg - MemberName that was the trailing argument
382 // temp1_recv_klass - klass of stacked receiver, if needed
383 // rsi/r13 - interpreter linkage (if interpreted)
384 // rcx, rdx, rsi, rdi, r8 - compiler arguments (if compiled)
385
386 Label L_incompatible_class_change_error;
387 switch (iid) {
388 case vmIntrinsics::_linkToSpecial:
389 if (VerifyMethodHandles) {
390 verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3);
391 }
392 __ load_heap_oop(rbx_method, member_vmtarget);
393 __ movptr(rbx_method, vmtarget_method);
394 break;
395
396 case vmIntrinsics::_linkToStatic:
397 if (VerifyMethodHandles) {
398 verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3);
399 }
400 __ load_heap_oop(rbx_method, member_vmtarget);
401 __ movptr(rbx_method, vmtarget_method);
402 break;
403
404 case vmIntrinsics::_linkToVirtual:
405 {
406 // same as TemplateTable::invokevirtual,
407 // minus the CP setup and profiling:
408
409 if (VerifyMethodHandles) {
410 verify_ref_kind(_masm, JVM_REF_invokeVirtual, member_reg, temp3);
411 }
412
413 // pick out the vtable index from the MemberName, and then we can discard it:
414 Register temp2_index = temp2;
415 __ movptr(temp2_index, member_vmindex);
416
417 if (VerifyMethodHandles) {
418 Label L_index_ok;
419 __ cmpl(temp2_index, 0);
420 __ jcc(Assembler::greaterEqual, L_index_ok);
421 __ STOP("no virtual index");
422 __ BIND(L_index_ok);
423 }
424
425 // Note: The verifier invariants allow us to ignore MemberName.clazz and vmtarget
426 // at this point. And VerifyMethodHandles has already checked clazz, if needed.
427
428 // get target Method* & entry point
429 __ lookup_virtual_method(temp1_recv_klass, temp2_index, rbx_method);
430 break;
431 }
432
433 case vmIntrinsics::_linkToInterface:
434 {
435 // same as TemplateTable::invokeinterface
436 // (minus the CP setup and profiling, with different argument motion)
437 if (VerifyMethodHandles) {
438 verify_ref_kind(_masm, JVM_REF_invokeInterface, member_reg, temp3);
439 }
440
441 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
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 __ movptr(rbx_index, member_vmindex);
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;
|
158 Register recv, Register method_temp,
159 Register temp2,
160 bool for_compiler_entry) {
161 BLOCK_COMMENT("jump_to_lambda_form {");
162 // This is the initial entry point of a lazy method handle.
163 // After type checking, it picks up the invoker from the LambdaForm.
164 assert_different_registers(recv, method_temp, temp2);
165 assert(recv != noreg, "required register");
166 assert(method_temp == rbx, "required register for loading method");
167
168 //NOT_PRODUCT({ FlagSetting fs(TraceMethodHandles, true); trace_method_handle(_masm, "LZMH"); });
169
170 // Load the invoker, as MH -> MH.form -> LF.vmentry
171 __ verify_oop(recv);
172 __ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())), temp2);
173 __ verify_oop(method_temp);
174 __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())), temp2);
175 __ verify_oop(method_temp);
176 __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes())), temp2);
177 __ verify_oop(method_temp);
178 __ access_load_at(T_ADDRESS, IN_HEAP, method_temp,
179 Address(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes())),
180 noreg, noreg);
181
182 if (VerifyMethodHandles && !for_compiler_entry) {
183 // make sure recv is already on stack
184 __ movptr(temp2, Address(method_temp, Method::const_offset()));
185 __ load_sized_value(temp2,
186 Address(temp2, ConstMethod::size_of_parameters_offset()),
187 sizeof(u2), /*is_signed*/ false);
188 // assert(sizeof(u2) == sizeof(Method::_size_of_parameters), "");
189 Label L;
190 __ cmpoop(recv, __ argument_address(temp2, -1));
191 __ jcc(Assembler::equal, L);
192 __ movptr(rax, __ argument_address(temp2, -1));
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 }
200
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 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
444
445 Register temp3_intf = temp3;
446 __ load_heap_oop(temp3_intf, member_clazz);
447 load_klass_from_Class(_masm, temp3_intf);
448 __ verify_klass_ptr(temp3_intf);
449
450 Register rbx_index = rbx_method;
451 __ access_load_at(T_ADDRESS, IN_HEAP, rbx_index, member_vmindex, noreg, noreg);
452 if (VerifyMethodHandles) {
453 Label L;
454 __ cmpl(rbx_index, 0);
455 __ jcc(Assembler::greaterEqual, L);
456 __ STOP("invalid vtable index for MH.invokeInterface");
457 __ bind(L);
458 }
459
460 // given intf, index, and recv klass, dispatch to the implementation method
461 __ lookup_interface_method(temp1_recv_klass, temp3_intf,
462 // note: next two args must be the same:
463 rbx_index, rbx_method,
464 temp2,
465 L_incompatible_class_change_error);
466 break;
467 }
468
469 default:
470 fatal("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid));
471 break;
|