src/cpu/sparc/vm/methodHandles_sparc.cpp

changeset 2411
8d0b933dda2d
parent 2351
b856cd7f4e60
child 2436
d810e9a3fc33
     1.1 --- a/src/cpu/sparc/vm/methodHandles_sparc.cpp	Tue Dec 21 22:57:17 2010 -0800
     1.2 +++ b/src/cpu/sparc/vm/methodHandles_sparc.cpp	Wed Dec 22 02:02:53 2010 -0800
     1.3 @@ -395,18 +395,23 @@
     1.4  //
     1.5  // Generate an "entry" field for a method handle.
     1.6  // This determines how the method handle will respond to calls.
     1.7 -void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek) {
     1.8 +void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek, TRAPS) {
     1.9    // Here is the register state during an interpreted call,
    1.10    // as set up by generate_method_handle_interpreter_entry():
    1.11    // - G5: garbage temp (was MethodHandle.invoke methodOop, unused)
    1.12    // - G3: receiver method handle
    1.13    // - O5_savedSP: sender SP (must preserve)
    1.14  
    1.15 -  Register O0_argslot = O0;
    1.16 -  Register O1_scratch = O1;
    1.17 -  Register O2_scratch = O2;
    1.18 -  Register O3_scratch = O3;
    1.19 -  Register G5_index   = G5;
    1.20 +  const Register O0_argslot = O0;
    1.21 +  const Register O1_scratch = O1;
    1.22 +  const Register O2_scratch = O2;
    1.23 +  const Register O3_scratch = O3;
    1.24 +  const Register G5_index   = G5;
    1.25 +
    1.26 +  // Argument registers for _raise_exception.
    1.27 +  const Register O0_code     = O0;
    1.28 +  const Register O1_actual   = O1;
    1.29 +  const Register O2_required = O2;
    1.30  
    1.31    guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets");
    1.32  
    1.33 @@ -439,48 +444,36 @@
    1.34    case _raise_exception:
    1.35      {
    1.36        // Not a real MH entry, but rather shared code for raising an
    1.37 -      // exception.  Extra local arguments are passed in scratch
    1.38 -      // registers, as required type in O3, failing object (or NULL)
    1.39 -      // in O2, failing bytecode type in O1.
    1.40 +      // exception.  Since we use a C2I adapter to set up the
    1.41 +      // interpreter state, arguments are expected in compiler
    1.42 +      // argument registers.
    1.43 +      methodHandle mh(raise_exception_method());
    1.44 +      address c2i_entry = methodOopDesc::make_adapters(mh, CATCH);
    1.45  
    1.46        __ mov(O5_savedSP, SP);  // Cut the stack back to where the caller started.
    1.47  
    1.48 -      // Push arguments as if coming from the interpreter.
    1.49 -      Register O0_scratch = O0_argslot;
    1.50 -      int stackElementSize = Interpreter::stackElementSize;
    1.51 -
    1.52 -      // Make space on the stack for the arguments and set Gargs
    1.53 -      // correctly.
    1.54 -      __ sub(SP, 4*stackElementSize, SP);  // Keep stack aligned.
    1.55 -      __ add(SP, (frame::varargs_offset)*wordSize - 1*Interpreter::stackElementSize + STACK_BIAS + BytesPerWord, Gargs);
    1.56 -
    1.57 -      // void raiseException(int code, Object actual, Object required)
    1.58 -      __ st(    O1_scratch, Address(Gargs, 2*stackElementSize));  // code
    1.59 -      __ st_ptr(O2_scratch, Address(Gargs, 1*stackElementSize));  // actual
    1.60 -      __ st_ptr(O3_scratch, Address(Gargs, 0*stackElementSize));  // required
    1.61 -
    1.62 -      Label no_method;
    1.63 +      Label L_no_method;
    1.64        // FIXME: fill in _raise_exception_method with a suitable sun.dyn method
    1.65        __ set(AddressLiteral((address) &_raise_exception_method), G5_method);
    1.66        __ ld_ptr(Address(G5_method, 0), G5_method);
    1.67        __ tst(G5_method);
    1.68 -      __ brx(Assembler::zero, false, Assembler::pn, no_method);
    1.69 +      __ brx(Assembler::zero, false, Assembler::pn, L_no_method);
    1.70        __ delayed()->nop();
    1.71  
    1.72 -      int jobject_oop_offset = 0;
    1.73 +      const int jobject_oop_offset = 0;
    1.74        __ ld_ptr(Address(G5_method, jobject_oop_offset), G5_method);
    1.75        __ tst(G5_method);
    1.76 -      __ brx(Assembler::zero, false, Assembler::pn, no_method);
    1.77 +      __ brx(Assembler::zero, false, Assembler::pn, L_no_method);
    1.78        __ delayed()->nop();
    1.79  
    1.80        __ verify_oop(G5_method);
    1.81 -      __ jump_indirect_to(G5_method_fie, O1_scratch);
    1.82 +      __ jump_to(AddressLiteral(c2i_entry), O3_scratch);
    1.83        __ delayed()->nop();
    1.84  
    1.85        // If we get here, the Java runtime did not do its job of creating the exception.
    1.86        // Do something that is at least causes a valid throw from the interpreter.
    1.87 -      __ bind(no_method);
    1.88 -      __ unimplemented("_raise_exception no method");
    1.89 +      __ bind(L_no_method);
    1.90 +      __ unimplemented("call throw_WrongMethodType_entry");
    1.91      }
    1.92      break;
    1.93  
    1.94 @@ -570,10 +563,10 @@
    1.95        // Throw an exception.
    1.96        // For historical reasons, it will be IncompatibleClassChangeError.
    1.97        __ unimplemented("not tested yet");
    1.98 -      __ ld_ptr(Address(O1_intf, java_mirror_offset), O3_scratch);  // required interface
    1.99 -      __ mov(O0_klass, O2_scratch);  // bad receiver
   1.100 -      __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O0_argslot);
   1.101 -      __ delayed()->mov(Bytecodes::_invokeinterface, O1_scratch);  // who is complaining?
   1.102 +      __ ld_ptr(Address(O1_intf, java_mirror_offset), O2_required);  // required interface
   1.103 +      __ mov(   O0_klass,                             O1_actual);    // bad receiver
   1.104 +      __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O3_scratch);
   1.105 +      __ delayed()->mov(Bytecodes::_invokeinterface,  O0_code);      // who is complaining?
   1.106      }
   1.107      break;
   1.108  
   1.109 @@ -663,11 +656,10 @@
   1.110        __ check_klass_subtype(O1_scratch, G5_klass, O0_argslot, O2_scratch, done);
   1.111  
   1.112        // If we get here, the type check failed!
   1.113 -      __ ldsw(G3_amh_vmargslot, O0_argslot);  // reload argslot field
   1.114 -      __ load_heap_oop(G3_amh_argument, O3_scratch);  // required class
   1.115 -      __ ld_ptr(vmarg, O2_scratch);  // bad object
   1.116 -      __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O0_argslot);
   1.117 -      __ delayed()->mov(Bytecodes::_checkcast, O1_scratch);  // who is complaining?
   1.118 +      __ load_heap_oop(G3_amh_argument,        O2_required);  // required class
   1.119 +      __ ld_ptr(       vmarg,                  O1_actual);    // bad object
   1.120 +      __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O3_scratch);
   1.121 +      __ delayed()->mov(Bytecodes::_checkcast, O0_code);      // who is complaining?
   1.122  
   1.123        __ bind(done);
   1.124        // Get the new MH:

mercurial