393 //------------------------------------------------------------------------------ |
393 //------------------------------------------------------------------------------ |
394 // MethodHandles::generate_method_handle_stub |
394 // MethodHandles::generate_method_handle_stub |
395 // |
395 // |
396 // Generate an "entry" field for a method handle. |
396 // Generate an "entry" field for a method handle. |
397 // This determines how the method handle will respond to calls. |
397 // This determines how the method handle will respond to calls. |
398 void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek) { |
398 void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek, TRAPS) { |
399 // Here is the register state during an interpreted call, |
399 // Here is the register state during an interpreted call, |
400 // as set up by generate_method_handle_interpreter_entry(): |
400 // as set up by generate_method_handle_interpreter_entry(): |
401 // - G5: garbage temp (was MethodHandle.invoke methodOop, unused) |
401 // - G5: garbage temp (was MethodHandle.invoke methodOop, unused) |
402 // - G3: receiver method handle |
402 // - G3: receiver method handle |
403 // - O5_savedSP: sender SP (must preserve) |
403 // - O5_savedSP: sender SP (must preserve) |
404 |
404 |
405 Register O0_argslot = O0; |
405 const Register O0_argslot = O0; |
406 Register O1_scratch = O1; |
406 const Register O1_scratch = O1; |
407 Register O2_scratch = O2; |
407 const Register O2_scratch = O2; |
408 Register O3_scratch = O3; |
408 const Register O3_scratch = O3; |
409 Register G5_index = G5; |
409 const Register G5_index = G5; |
|
410 |
|
411 // Argument registers for _raise_exception. |
|
412 const Register O0_code = O0; |
|
413 const Register O1_actual = O1; |
|
414 const Register O2_required = O2; |
410 |
415 |
411 guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets"); |
416 guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets"); |
412 |
417 |
413 // Some handy addresses: |
418 // Some handy addresses: |
414 Address G5_method_fie( G5_method, in_bytes(methodOopDesc::from_interpreted_offset())); |
419 Address G5_method_fie( G5_method, in_bytes(methodOopDesc::from_interpreted_offset())); |
437 |
442 |
438 switch ((int) ek) { |
443 switch ((int) ek) { |
439 case _raise_exception: |
444 case _raise_exception: |
440 { |
445 { |
441 // Not a real MH entry, but rather shared code for raising an |
446 // Not a real MH entry, but rather shared code for raising an |
442 // exception. Extra local arguments are passed in scratch |
447 // exception. Since we use a C2I adapter to set up the |
443 // registers, as required type in O3, failing object (or NULL) |
448 // interpreter state, arguments are expected in compiler |
444 // in O2, failing bytecode type in O1. |
449 // argument registers. |
|
450 methodHandle mh(raise_exception_method()); |
|
451 address c2i_entry = methodOopDesc::make_adapters(mh, CATCH); |
445 |
452 |
446 __ mov(O5_savedSP, SP); // Cut the stack back to where the caller started. |
453 __ mov(O5_savedSP, SP); // Cut the stack back to where the caller started. |
447 |
454 |
448 // Push arguments as if coming from the interpreter. |
455 Label L_no_method; |
449 Register O0_scratch = O0_argslot; |
|
450 int stackElementSize = Interpreter::stackElementSize; |
|
451 |
|
452 // Make space on the stack for the arguments and set Gargs |
|
453 // correctly. |
|
454 __ sub(SP, 4*stackElementSize, SP); // Keep stack aligned. |
|
455 __ add(SP, (frame::varargs_offset)*wordSize - 1*Interpreter::stackElementSize + STACK_BIAS + BytesPerWord, Gargs); |
|
456 |
|
457 // void raiseException(int code, Object actual, Object required) |
|
458 __ st( O1_scratch, Address(Gargs, 2*stackElementSize)); // code |
|
459 __ st_ptr(O2_scratch, Address(Gargs, 1*stackElementSize)); // actual |
|
460 __ st_ptr(O3_scratch, Address(Gargs, 0*stackElementSize)); // required |
|
461 |
|
462 Label no_method; |
|
463 // FIXME: fill in _raise_exception_method with a suitable sun.dyn method |
456 // FIXME: fill in _raise_exception_method with a suitable sun.dyn method |
464 __ set(AddressLiteral((address) &_raise_exception_method), G5_method); |
457 __ set(AddressLiteral((address) &_raise_exception_method), G5_method); |
465 __ ld_ptr(Address(G5_method, 0), G5_method); |
458 __ ld_ptr(Address(G5_method, 0), G5_method); |
466 __ tst(G5_method); |
459 __ tst(G5_method); |
467 __ brx(Assembler::zero, false, Assembler::pn, no_method); |
460 __ brx(Assembler::zero, false, Assembler::pn, L_no_method); |
468 __ delayed()->nop(); |
461 __ delayed()->nop(); |
469 |
462 |
470 int jobject_oop_offset = 0; |
463 const int jobject_oop_offset = 0; |
471 __ ld_ptr(Address(G5_method, jobject_oop_offset), G5_method); |
464 __ ld_ptr(Address(G5_method, jobject_oop_offset), G5_method); |
472 __ tst(G5_method); |
465 __ tst(G5_method); |
473 __ brx(Assembler::zero, false, Assembler::pn, no_method); |
466 __ brx(Assembler::zero, false, Assembler::pn, L_no_method); |
474 __ delayed()->nop(); |
467 __ delayed()->nop(); |
475 |
468 |
476 __ verify_oop(G5_method); |
469 __ verify_oop(G5_method); |
477 __ jump_indirect_to(G5_method_fie, O1_scratch); |
470 __ jump_to(AddressLiteral(c2i_entry), O3_scratch); |
478 __ delayed()->nop(); |
471 __ delayed()->nop(); |
479 |
472 |
480 // If we get here, the Java runtime did not do its job of creating the exception. |
473 // If we get here, the Java runtime did not do its job of creating the exception. |
481 // Do something that is at least causes a valid throw from the interpreter. |
474 // Do something that is at least causes a valid throw from the interpreter. |
482 __ bind(no_method); |
475 __ bind(L_no_method); |
483 __ unimplemented("_raise_exception no method"); |
476 __ unimplemented("call throw_WrongMethodType_entry"); |
484 } |
477 } |
485 break; |
478 break; |
486 |
479 |
487 case _invokestatic_mh: |
480 case _invokestatic_mh: |
488 case _invokespecial_mh: |
481 case _invokespecial_mh: |
568 |
561 |
569 __ bind(no_such_interface); |
562 __ bind(no_such_interface); |
570 // Throw an exception. |
563 // Throw an exception. |
571 // For historical reasons, it will be IncompatibleClassChangeError. |
564 // For historical reasons, it will be IncompatibleClassChangeError. |
572 __ unimplemented("not tested yet"); |
565 __ unimplemented("not tested yet"); |
573 __ ld_ptr(Address(O1_intf, java_mirror_offset), O3_scratch); // required interface |
566 __ ld_ptr(Address(O1_intf, java_mirror_offset), O2_required); // required interface |
574 __ mov(O0_klass, O2_scratch); // bad receiver |
567 __ mov( O0_klass, O1_actual); // bad receiver |
575 __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O0_argslot); |
568 __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O3_scratch); |
576 __ delayed()->mov(Bytecodes::_invokeinterface, O1_scratch); // who is complaining? |
569 __ delayed()->mov(Bytecodes::_invokeinterface, O0_code); // who is complaining? |
577 } |
570 } |
578 break; |
571 break; |
579 |
572 |
580 case _bound_ref_mh: |
573 case _bound_ref_mh: |
581 case _bound_int_mh: |
574 case _bound_int_mh: |
661 // - O1_scratch : argument klass to test |
654 // - O1_scratch : argument klass to test |
662 // - G3_method_handle: adapter method handle |
655 // - G3_method_handle: adapter method handle |
663 __ check_klass_subtype(O1_scratch, G5_klass, O0_argslot, O2_scratch, done); |
656 __ check_klass_subtype(O1_scratch, G5_klass, O0_argslot, O2_scratch, done); |
664 |
657 |
665 // If we get here, the type check failed! |
658 // If we get here, the type check failed! |
666 __ ldsw(G3_amh_vmargslot, O0_argslot); // reload argslot field |
659 __ load_heap_oop(G3_amh_argument, O2_required); // required class |
667 __ load_heap_oop(G3_amh_argument, O3_scratch); // required class |
660 __ ld_ptr( vmarg, O1_actual); // bad object |
668 __ ld_ptr(vmarg, O2_scratch); // bad object |
661 __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O3_scratch); |
669 __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O0_argslot); |
662 __ delayed()->mov(Bytecodes::_checkcast, O0_code); // who is complaining? |
670 __ delayed()->mov(Bytecodes::_checkcast, O1_scratch); // who is complaining? |
|
671 |
663 |
672 __ bind(done); |
664 __ bind(done); |
673 // Get the new MH: |
665 // Get the new MH: |
674 __ load_heap_oop(G3_mh_vmtarget, G3_method_handle); |
666 __ load_heap_oop(G3_mh_vmtarget, G3_method_handle); |
675 __ jump_to_method_handle_entry(G3_method_handle, O1_scratch); |
667 __ jump_to_method_handle_entry(G3_method_handle, O1_scratch); |