Print this page


Split Close
Expand all
Collapse all
          --- old/src/cpu/sparc/vm/methodHandles_sparc.cpp
          +++ new/src/cpu/sparc/vm/methodHandles_sparc.cpp
↓ open down ↓ 62 lines elided ↑ open up ↑
  63   63    // Fill in the real end_address:
  64   64    __ align(wordSize);
  65   65    me->set_end_address(__ pc());
  66   66  
  67   67    return me;
  68   68  }
  69   69  
  70   70  
  71   71  // Code generation
  72   72  address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm) {
  73      -  // I5_savedSP: sender SP (must preserve)
       73 +  // I5_savedSP/O5_savedSP: sender SP (must preserve)
  74   74    // G4 (Gargs): incoming argument list (must preserve)
  75      -  // G5_method:  invoke methodOop; becomes method type.
       75 +  // G5_method:  invoke methodOop
  76   76    // G3_method_handle: receiver method handle (must load from sp[MethodTypeForm.vmslots])
  77      -  // O0, O1: garbage temps, blown away
  78      -  Register O0_argslot = O0;
       77 +  // O0, O1, O2, O3, O4: garbage temps, blown away
       78 +  Register O0_mtype   = O0;
  79   79    Register O1_scratch = O1;
  80   80    Register O2_scratch = O2;
  81   81    Register O3_scratch = O3;
       82 +  Register O4_argslot = O4;
  82   83    Register O4_argbase = O4;
  83      -  Register O5_mtype   = O5;
  84   84  
  85   85    // emit WrongMethodType path first, to enable back-branch from main path
  86   86    Label wrong_method_type;
  87   87    __ bind(wrong_method_type);
  88   88    Label invoke_generic_slow_path;
  89   89    assert(methodOopDesc::intrinsic_id_size_in_bytes() == sizeof(u1), "");;
  90   90    __ ldub(Address(G5_method, methodOopDesc::intrinsic_id_offset_in_bytes()), O1_scratch);
  91   91    __ cmp(O1_scratch, (int) vmIntrinsics::_invokeExact);
  92   92    __ brx(Assembler::notEqual, false, Assembler::pt, invoke_generic_slow_path);
  93   93    __ delayed()->nop();
  94      -  __ mov(O5_mtype, G5_method_type);  // required by throw_WrongMethodType
       94 +  __ mov(O0_mtype, G5_method_type);  // required by throw_WrongMethodType
  95   95    // mov(G3_method_handle, G3_method_handle);  // already in this register
  96   96    __ jump_to(AddressLiteral(Interpreter::throw_WrongMethodType_entry()), O1_scratch);
  97   97    __ delayed()->nop();
  98   98  
  99   99    // here's where control starts out:
 100  100    __ align(CodeEntryAlignment);
 101  101    address entry_point = __ pc();
 102  102  
 103  103    // fetch the MethodType from the method handle
 104  104    {
 105  105      Register tem = G5_method;
 106  106      for (jint* pchase = methodOopDesc::method_type_offsets_chain(); (*pchase) != -1; pchase++) {
 107      -      __ ld_ptr(Address(tem, *pchase), O5_mtype);
 108      -      tem = O5_mtype;          // in case there is another indirection
      107 +      __ ld_ptr(Address(tem, *pchase), O0_mtype);
      108 +      tem = O0_mtype;          // in case there is another indirection
 109  109      }
 110  110    }
 111  111  
 112  112    // given the MethodType, find out where the MH argument is buried
 113      -  __ load_heap_oop(Address(O5_mtype,   __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, O1_scratch)),        O0_argslot);
 114      -  __ ldsw(  Address(O0_argslot, __ delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, O1_scratch)), O0_argslot);
 115      -  __ add(Gargs, __ argument_offset(O0_argslot, 1), O4_argbase);
      113 +  __ load_heap_oop(Address(O0_mtype,   __ delayed_value(java_dyn_MethodType::form_offset_in_bytes,        O1_scratch)), O4_argslot);
      114 +  __ ldsw(         Address(O4_argslot, __ delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, O1_scratch)), O4_argslot);
      115 +  __ add(Gargs, __ argument_offset(O4_argslot, 1), O4_argbase);
 116  116    // Note: argument_address uses its input as a scratch register!
 117  117    __ ld_ptr(Address(O4_argbase, -Interpreter::stackElementSize), G3_method_handle);
 118  118  
 119  119    trace_method_handle(_masm, "invokeExact");
 120  120  
 121      -  __ check_method_handle_type(O5_mtype, G3_method_handle, O1_scratch, wrong_method_type);
      121 +  __ check_method_handle_type(O0_mtype, G3_method_handle, O1_scratch, wrong_method_type);
 122  122    __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
 123  123  
 124  124    // for invokeGeneric (only), apply argument and result conversions on the fly
 125  125    __ bind(invoke_generic_slow_path);
 126  126  #ifdef ASSERT
 127  127    { Label L;
 128  128      __ ldub(Address(G5_method, methodOopDesc::intrinsic_id_offset_in_bytes()), O1_scratch);
 129  129      __ cmp(O1_scratch, (int) vmIntrinsics::_invokeGeneric);
 130  130      __ brx(Assembler::equal, false, Assembler::pt, L);
 131  131      __ delayed()->nop();
 132  132      __ stop("bad methodOop::intrinsic_id");
 133  133      __ bind(L);
 134  134    }
 135  135  #endif //ASSERT
 136  136  
 137  137    // make room on the stack for another pointer:
 138      -  insert_arg_slots(_masm, 2 * stack_move_unit(), _INSERT_REF_MASK,
 139      -                   O4_argbase, O1_scratch, O2_scratch, O3_scratch);
      138 +  insert_arg_slots(_masm, 2 * stack_move_unit(), _INSERT_REF_MASK, O4_argbase, O1_scratch, O2_scratch, O3_scratch);
 140  139    // load up an adapter from the calling type (Java weaves this)
 141  140    Register O2_form    = O2_scratch;
 142  141    Register O3_adapter = O3_scratch;
 143      -  __ load_heap_oop(Address(O5_mtype, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, O1_scratch)), O2_form);
      142 +  __ load_heap_oop(Address(O0_mtype, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes,               O1_scratch)), O2_form);
 144  143    // load_heap_oop(Address(O2_form,  __ delayed_value(java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes, O1_scratch)), O3_adapter);
 145  144    // deal with old JDK versions:
 146      -  __ add(   Address(O2_form,  __ delayed_value(java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes, O1_scratch)), O3_adapter);
      145 +  __ add(          Address(O2_form,  __ delayed_value(java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes, O1_scratch)), O3_adapter);
 147  146    __ cmp(O3_adapter, O2_form);
 148  147    Label sorry_no_invoke_generic;
 149  148    __ brx(Assembler::lessUnsigned, false, Assembler::pn, sorry_no_invoke_generic);
 150  149    __ delayed()->nop();
 151  150  
 152  151    __ load_heap_oop(Address(O3_adapter, 0), O3_adapter);
 153  152    __ tst(O3_adapter);
 154  153    __ brx(Assembler::zero, false, Assembler::pn, sorry_no_invoke_generic);
 155  154    __ delayed()->nop();
 156  155    __ st_ptr(O3_adapter, Address(O4_argbase, 1 * Interpreter::stackElementSize));
 157  156    // As a trusted first argument, pass the type being called, so the adapter knows
 158  157    // the actual types of the arguments and return values.
 159  158    // (Generic invokers are shared among form-families of method-type.)
 160      -  __ st_ptr(O5_mtype,   Address(O4_argbase, 0 * Interpreter::stackElementSize));
      159 +  __ st_ptr(O0_mtype,   Address(O4_argbase, 0 * Interpreter::stackElementSize));
 161  160    // FIXME: assert that O3_adapter is of the right method-type.
 162  161    __ mov(O3_adapter, G3_method_handle);
 163  162    trace_method_handle(_masm, "invokeGeneric");
 164  163    __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
 165  164  
 166  165    __ bind(sorry_no_invoke_generic); // no invokeGeneric implementation available!
 167      -  __ mov(O5_mtype, G5_method_type);  // required by throw_WrongMethodType
      166 +  __ mov(O0_mtype, G5_method_type);  // required by throw_WrongMethodType
 168  167    // mov(G3_method_handle, G3_method_handle);  // already in this register
 169  168    __ jump_to(AddressLiteral(Interpreter::throw_WrongMethodType_entry()), O1_scratch);
 170  169    __ delayed()->nop();
 171  170  
 172  171    return entry_point;
 173  172  }
 174  173  
 175  174  
 176  175  #ifdef ASSERT
 177  176  static void verify_argslot(MacroAssembler* _masm, Register argslot_reg, Register temp_reg, const char* error_message) {
↓ open down ↓ 854 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX