383 //|(1<<sun_dyn_AdapterMethodHandle::OP_SPREAD_ARGS) //BUG! |
383 //|(1<<sun_dyn_AdapterMethodHandle::OP_SPREAD_ARGS) //BUG! |
384 ); |
384 ); |
385 // FIXME: MethodHandlesTest gets a crash if we enable OP_SPREAD_ARGS. |
385 // FIXME: MethodHandlesTest gets a crash if we enable OP_SPREAD_ARGS. |
386 } |
386 } |
387 |
387 |
|
388 //------------------------------------------------------------------------------ |
|
389 // MethodHandles::generate_method_handle_stub |
|
390 // |
388 // Generate an "entry" field for a method handle. |
391 // Generate an "entry" field for a method handle. |
389 // This determines how the method handle will respond to calls. |
392 // This determines how the method handle will respond to calls. |
390 void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek) { |
393 void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek, TRAPS) { |
391 // Here is the register state during an interpreted call, |
394 // Here is the register state during an interpreted call, |
392 // as set up by generate_method_handle_interpreter_entry(): |
395 // as set up by generate_method_handle_interpreter_entry(): |
393 // - rbx: garbage temp (was MethodHandle.invoke methodOop, unused) |
396 // - rbx: garbage temp (was MethodHandle.invoke methodOop, unused) |
394 // - rcx: receiver method handle |
397 // - rcx: receiver method handle |
395 // - rax: method handle type (only used by the check_mtype entry point) |
398 // - rax: method handle type (only used by the check_mtype entry point) |
396 // - rsi/r13: sender SP (must preserve; see prepare_to_jump_from_interpreted) |
399 // - rsi/r13: sender SP (must preserve; see prepare_to_jump_from_interpreted) |
397 // - rdx: garbage temp, can blow away |
400 // - rdx: garbage temp, can blow away |
398 |
401 |
399 Register rcx_recv = rcx; |
402 const Register rcx_recv = rcx; |
400 Register rax_argslot = rax; |
403 const Register rax_argslot = rax; |
401 Register rbx_temp = rbx; |
404 const Register rbx_temp = rbx; |
402 Register rdx_temp = rdx; |
405 const Register rdx_temp = rdx; |
403 |
406 |
404 // This guy is set up by prepare_to_jump_from_interpreted (from interpreted calls) |
407 // This guy is set up by prepare_to_jump_from_interpreted (from interpreted calls) |
405 // and gen_c2i_adapter (from compiled calls): |
408 // and gen_c2i_adapter (from compiled calls): |
406 Register saved_last_sp = LP64_ONLY(r13) NOT_LP64(rsi); |
409 const Register saved_last_sp = LP64_ONLY(r13) NOT_LP64(rsi); |
|
410 |
|
411 // Argument registers for _raise_exception. |
|
412 // 32-bit: Pass first two oop/int args in registers ECX and EDX. |
|
413 const Register rarg0_code = LP64_ONLY(j_rarg0) NOT_LP64(rcx); |
|
414 const Register rarg1_actual = LP64_ONLY(j_rarg1) NOT_LP64(rdx); |
|
415 const Register rarg2_required = LP64_ONLY(j_rarg2) NOT_LP64(rdi); |
|
416 assert_different_registers(rarg0_code, rarg1_actual, rarg2_required, saved_last_sp); |
407 |
417 |
408 guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets"); |
418 guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets"); |
409 |
419 |
410 // some handy addresses |
420 // some handy addresses |
411 Address rbx_method_fie( rbx, methodOopDesc::from_interpreted_offset() ); |
421 Address rbx_method_fie( rbx, methodOopDesc::from_interpreted_offset() ); |
435 BLOCK_COMMENT(entry_name(ek)); |
445 BLOCK_COMMENT(entry_name(ek)); |
436 |
446 |
437 switch ((int) ek) { |
447 switch ((int) ek) { |
438 case _raise_exception: |
448 case _raise_exception: |
439 { |
449 { |
440 // Not a real MH entry, but rather shared code for raising an exception. |
450 // Not a real MH entry, but rather shared code for raising an |
441 // Extra local arguments are pushed on stack, as required type at TOS+8, |
451 // exception. Since we use a C2I adapter to set up the |
442 // failing object (or NULL) at TOS+4, failing bytecode type at TOS. |
452 // interpreter state, arguments are expected in compiler |
443 // Beyond those local arguments are the PC, of course. |
453 // argument registers. |
444 Register rdx_code = rdx_temp; |
454 methodHandle mh(raise_exception_method()); |
445 Register rcx_fail = rcx_recv; |
455 address c2i_entry = methodOopDesc::make_adapters(mh, CHECK); |
446 Register rax_want = rax_argslot; |
456 |
447 Register rdi_pc = rdi; |
457 const Register rdi_pc = rax; |
448 __ pop(rdx_code); // TOS+0 |
458 __ pop(rdi_pc); // caller PC |
449 __ pop(rcx_fail); // TOS+4 |
459 __ mov(rsp, saved_last_sp); // cut the stack back to where the caller started |
450 __ pop(rax_want); // TOS+8 |
|
451 __ pop(rdi_pc); // caller PC |
|
452 |
|
453 __ mov(rsp, rsi); // cut the stack back to where the caller started |
|
454 |
|
455 // Repush the arguments as if coming from the interpreter. |
|
456 __ push(rdx_code); |
|
457 __ push(rcx_fail); |
|
458 __ push(rax_want); |
|
459 |
460 |
460 Register rbx_method = rbx_temp; |
461 Register rbx_method = rbx_temp; |
461 Label no_method; |
462 Label L_no_method; |
462 // FIXME: fill in _raise_exception_method with a suitable sun.dyn method |
463 // FIXME: fill in _raise_exception_method with a suitable sun.dyn method |
463 __ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method)); |
464 __ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method)); |
464 __ testptr(rbx_method, rbx_method); |
465 __ testptr(rbx_method, rbx_method); |
465 __ jccb(Assembler::zero, no_method); |
466 __ jccb(Assembler::zero, L_no_method); |
466 int jobject_oop_offset = 0; |
467 |
|
468 const int jobject_oop_offset = 0; |
467 __ movptr(rbx_method, Address(rbx_method, jobject_oop_offset)); // dereference the jobject |
469 __ movptr(rbx_method, Address(rbx_method, jobject_oop_offset)); // dereference the jobject |
468 __ testptr(rbx_method, rbx_method); |
470 __ testptr(rbx_method, rbx_method); |
469 __ jccb(Assembler::zero, no_method); |
471 __ jccb(Assembler::zero, L_no_method); |
470 __ verify_oop(rbx_method); |
472 __ verify_oop(rbx_method); |
471 __ push(rdi_pc); // and restore caller PC |
473 |
472 __ jmp(rbx_method_fie); |
474 // 32-bit: push remaining arguments as if coming from the compiler. |
|
475 NOT_LP64(__ push(rarg2_required)); |
|
476 |
|
477 __ push(rdi_pc); // restore caller PC |
|
478 __ jump(ExternalAddress(c2i_entry)); // do C2I transition |
473 |
479 |
474 // If we get here, the Java runtime did not do its job of creating the exception. |
480 // If we get here, the Java runtime did not do its job of creating the exception. |
475 // Do something that is at least causes a valid throw from the interpreter. |
481 // Do something that is at least causes a valid throw from the interpreter. |
476 __ bind(no_method); |
482 __ bind(L_no_method); |
477 __ pop(rax_want); |
483 __ push(rarg2_required); |
478 __ pop(rcx_fail); |
484 __ push(rarg1_actual); |
479 __ push(rax_want); |
|
480 __ push(rcx_fail); |
|
481 __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry())); |
485 __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry())); |
482 } |
486 } |
483 break; |
487 break; |
484 |
488 |
485 case _invokestatic_mh: |
489 case _invokestatic_mh: |
570 __ hlt(); |
574 __ hlt(); |
571 |
575 |
572 __ bind(no_such_interface); |
576 __ bind(no_such_interface); |
573 // Throw an exception. |
577 // Throw an exception. |
574 // For historical reasons, it will be IncompatibleClassChangeError. |
578 // For historical reasons, it will be IncompatibleClassChangeError. |
575 __ pushptr(Address(rdx_intf, java_mirror_offset)); // required interface |
579 __ mov(rbx_temp, rcx_recv); // rarg2_required might be RCX |
576 __ push(rcx_recv); // bad receiver |
580 assert_different_registers(rarg2_required, rbx_temp); |
577 __ push((int)Bytecodes::_invokeinterface); // who is complaining? |
581 __ movptr(rarg2_required, Address(rdx_intf, java_mirror_offset)); // required interface |
|
582 __ mov( rarg1_actual, rbx_temp); // bad receiver |
|
583 __ movl( rarg0_code, (int) Bytecodes::_invokeinterface); // who is complaining? |
578 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); |
584 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); |
579 } |
585 } |
580 break; |
586 break; |
581 |
587 |
582 case _bound_ref_mh: |
588 case _bound_ref_mh: |
667 // Call the wrong_method_type stub, passing the failing argument type in rax. |
673 // Call the wrong_method_type stub, passing the failing argument type in rax. |
668 Register rax_mtype = rax_argslot; |
674 Register rax_mtype = rax_argslot; |
669 __ movl(rax_argslot, rcx_amh_vmargslot); // reload argslot field |
675 __ movl(rax_argslot, rcx_amh_vmargslot); // reload argslot field |
670 __ movptr(rdx_temp, vmarg); |
676 __ movptr(rdx_temp, vmarg); |
671 |
677 |
672 __ load_heap_oop(rbx_klass, rcx_amh_argument); // required class |
678 assert_different_registers(rarg2_required, rdx_temp); |
673 __ push(rbx_klass); |
679 __ load_heap_oop(rarg2_required, rcx_amh_argument); // required class |
674 __ push(rdx_temp); // bad object |
680 __ mov( rarg1_actual, rdx_temp); // bad object |
675 __ push((int)Bytecodes::_checkcast); // who is complaining? |
681 __ movl( rarg0_code, (int) Bytecodes::_checkcast); // who is complaining? |
676 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); |
682 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); |
677 |
683 |
678 __ bind(done); |
684 __ bind(done); |
679 // get the new MH: |
685 // get the new MH: |
680 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); |
686 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); |
1187 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); |
1193 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); |
1188 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); |
1194 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); |
1189 |
1195 |
1190 __ bind(bad_array_klass); |
1196 __ bind(bad_array_klass); |
1191 UNPUSH_RSI_RDI; |
1197 UNPUSH_RSI_RDI; |
1192 __ pushptr(Address(rdx_array_klass, java_mirror_offset)); // required type |
1198 assert(!vmarg.uses(rarg2_required), "must be different registers"); |
1193 __ pushptr(vmarg); // bad array |
1199 __ movptr(rarg2_required, Address(rdx_array_klass, java_mirror_offset)); // required type |
1194 __ push((int)Bytecodes::_aaload); // who is complaining? |
1200 __ movptr(rarg1_actual, vmarg); // bad array |
|
1201 __ movl( rarg0_code, (int) Bytecodes::_aaload); // who is complaining? |
1195 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); |
1202 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); |
1196 |
1203 |
1197 __ bind(bad_array_length); |
1204 __ bind(bad_array_length); |
1198 UNPUSH_RSI_RDI; |
1205 UNPUSH_RSI_RDI; |
1199 __ push(rcx_recv); // AMH requiring a certain length |
1206 assert(!vmarg.uses(rarg2_required), "must be different registers"); |
1200 __ pushptr(vmarg); // bad array |
1207 __ mov (rarg2_required, rcx_recv); // AMH requiring a certain length |
1201 __ push((int)Bytecodes::_arraylength); // who is complaining? |
1208 __ movptr(rarg1_actual, vmarg); // bad array |
|
1209 __ movl( rarg0_code, (int) Bytecodes::_arraylength); // who is complaining? |
1202 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); |
1210 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception))); |
1203 |
1211 |
1204 #undef UNPUSH_RSI_RDI |
1212 #undef UNPUSH_RSI_RDI |
1205 } |
1213 } |
1206 break; |
1214 break; |