src/cpu/x86/vm/methodHandles_x86.cpp

changeset 3501
392a3f07d567
parent 3451
5dbed2f542ff
child 3566
45a1bf98f1bb
     1.1 --- a/src/cpu/x86/vm/methodHandles_x86.cpp	Wed Feb 01 16:57:08 2012 -0800
     1.2 +++ b/src/cpu/x86/vm/methodHandles_x86.cpp	Thu Feb 02 09:14:38 2012 -0800
     1.3 @@ -2364,23 +2364,19 @@
     1.4  
     1.5        // grab another temp
     1.6        Register rsi_temp = rsi;
     1.7 -      { if (rsi_temp == saved_last_sp)  __ push(saved_last_sp); }
     1.8 -      // (preceding push must be done after argslot address is taken!)
     1.9 -#define UNPUSH_RSI \
    1.10 -      { if (rsi_temp == saved_last_sp)  __ pop(saved_last_sp); }
    1.11  
    1.12        // arx_argslot points both to the array and to the first output arg
    1.13        vmarg = Address(rax_argslot, 0);
    1.14  
    1.15        // Get the array value.
    1.16 -      Register  rsi_array       = rsi_temp;
    1.17 +      Register  rdi_array       = rdi_temp;
    1.18        Register  rdx_array_klass = rdx_temp;
    1.19        BasicType elem_type = ek_adapter_opt_spread_type(ek);
    1.20        int       elem_slots = type2size[elem_type];  // 1 or 2
    1.21        int       array_slots = 1;  // array is always a T_OBJECT
    1.22        int       length_offset   = arrayOopDesc::length_offset_in_bytes();
    1.23        int       elem0_offset    = arrayOopDesc::base_offset_in_bytes(elem_type);
    1.24 -      __ movptr(rsi_array, vmarg);
    1.25 +      __ movptr(rdi_array, vmarg);
    1.26  
    1.27        Label L_array_is_empty, L_insert_arg_space, L_copy_args, L_args_done;
    1.28        if (length_can_be_zero) {
    1.29 @@ -2391,12 +2387,30 @@
    1.30            __ testl(rbx_temp, rbx_temp);
    1.31            __ jcc(Assembler::notZero, L_skip);
    1.32          }
    1.33 -        __ testptr(rsi_array, rsi_array);
    1.34 -        __ jcc(Assembler::zero, L_array_is_empty);
    1.35 +        __ testptr(rdi_array, rdi_array);
    1.36 +        __ jcc(Assembler::notZero, L_skip);
    1.37 +
    1.38 +        // If 'rsi' contains the 'saved_last_sp' (this is only the
    1.39 +        // case in a 32-bit version of the VM) we have to save 'rsi'
    1.40 +        // on the stack because later on (at 'L_array_is_empty') 'rsi'
    1.41 +        // will be overwritten.
    1.42 +        { if (rsi_temp == saved_last_sp)  __ push(saved_last_sp); }
    1.43 +        // Also prepare a handy macro which restores 'rsi' if required.
    1.44 +#define UNPUSH_RSI                                                      \
    1.45 +        { if (rsi_temp == saved_last_sp)  __ pop(saved_last_sp); }
    1.46 +
    1.47 +        __ jmp(L_array_is_empty);
    1.48          __ bind(L_skip);
    1.49        }
    1.50 -      __ null_check(rsi_array, oopDesc::klass_offset_in_bytes());
    1.51 -      __ load_klass(rdx_array_klass, rsi_array);
    1.52 +      __ null_check(rdi_array, oopDesc::klass_offset_in_bytes());
    1.53 +      __ load_klass(rdx_array_klass, rdi_array);
    1.54 +
    1.55 +      // Save 'rsi' if required (see comment above).  Do this only
    1.56 +      // after the null check such that the exception handler which is
    1.57 +      // called in the case of a null pointer exception will not be
    1.58 +      // confused by the extra value on the stack (it expects the
    1.59 +      // return pointer on top of the stack)
    1.60 +      { if (rsi_temp == saved_last_sp)  __ push(saved_last_sp); }
    1.61  
    1.62        // Check the array type.
    1.63        Register rbx_klass = rbx_temp;
    1.64 @@ -2404,18 +2418,18 @@
    1.65        load_klass_from_Class(_masm, rbx_klass);
    1.66  
    1.67        Label ok_array_klass, bad_array_klass, bad_array_length;
    1.68 -      __ check_klass_subtype(rdx_array_klass, rbx_klass, rdi_temp, ok_array_klass);
    1.69 +      __ check_klass_subtype(rdx_array_klass, rbx_klass, rsi_temp, ok_array_klass);
    1.70        // If we get here, the type check failed!
    1.71        __ jmp(bad_array_klass);
    1.72        __ BIND(ok_array_klass);
    1.73  
    1.74        // Check length.
    1.75        if (length_constant >= 0) {
    1.76 -        __ cmpl(Address(rsi_array, length_offset), length_constant);
    1.77 +        __ cmpl(Address(rdi_array, length_offset), length_constant);
    1.78        } else {
    1.79          Register rbx_vminfo = rbx_temp;
    1.80          load_conversion_vminfo(_masm, rbx_vminfo, rcx_amh_conversion);
    1.81 -        __ cmpl(rbx_vminfo, Address(rsi_array, length_offset));
    1.82 +        __ cmpl(rbx_vminfo, Address(rdi_array, length_offset));
    1.83        }
    1.84        __ jcc(Assembler::notEqual, bad_array_length);
    1.85  
    1.86 @@ -2427,9 +2441,9 @@
    1.87          __ lea(rdx_argslot_limit, Address(rax_argslot, Interpreter::stackElementSize));
    1.88          // 'stack_move' is negative number of words to insert
    1.89          // This number already accounts for elem_slots.
    1.90 -        Register rdi_stack_move = rdi_temp;
    1.91 -        load_stack_move(_masm, rdi_stack_move, rcx_recv, true);
    1.92 -        __ cmpptr(rdi_stack_move, 0);
    1.93 +        Register rsi_stack_move = rsi_temp;
    1.94 +        load_stack_move(_masm, rsi_stack_move, rcx_recv, true);
    1.95 +        __ cmpptr(rsi_stack_move, 0);
    1.96          assert(stack_move_unit() < 0, "else change this comparison");
    1.97          __ jcc(Assembler::less, L_insert_arg_space);
    1.98          __ jcc(Assembler::equal, L_copy_args);
    1.99 @@ -2440,12 +2454,12 @@
   1.100          __ jmp(L_args_done);  // no spreading to do
   1.101          __ BIND(L_insert_arg_space);
   1.102          // come here in the usual case, stack_move < 0 (2 or more spread arguments)
   1.103 -        Register rsi_temp = rsi_array;  // spill this
   1.104 -        insert_arg_slots(_masm, rdi_stack_move,
   1.105 -                         rax_argslot, rbx_temp, rsi_temp);
   1.106 +        Register rdi_temp = rdi_array;  // spill this
   1.107 +        insert_arg_slots(_masm, rsi_stack_move,
   1.108 +                         rax_argslot, rbx_temp, rdi_temp);
   1.109          // reload the array since rsi was killed
   1.110          // reload from rdx_argslot_limit since rax_argslot is now decremented
   1.111 -        __ movptr(rsi_array, Address(rdx_argslot_limit, -Interpreter::stackElementSize));
   1.112 +        __ movptr(rdi_array, Address(rdx_argslot_limit, -Interpreter::stackElementSize));
   1.113        } else if (length_constant >= 1) {
   1.114          int new_slots = (length_constant * elem_slots) - array_slots;
   1.115          insert_arg_slots(_masm, new_slots * stack_move_unit(),
   1.116 @@ -2468,16 +2482,16 @@
   1.117        if (length_constant == -1) {
   1.118          // [rax_argslot, rdx_argslot_limit) is the area we are inserting into.
   1.119          // Array element [0] goes at rdx_argslot_limit[-wordSize].
   1.120 -        Register rsi_source = rsi_array;
   1.121 -        __ lea(rsi_source, Address(rsi_array, elem0_offset));
   1.122 +        Register rdi_source = rdi_array;
   1.123 +        __ lea(rdi_source, Address(rdi_array, elem0_offset));
   1.124          Register rdx_fill_ptr = rdx_argslot_limit;
   1.125          Label loop;
   1.126          __ BIND(loop);
   1.127          __ addptr(rdx_fill_ptr, -Interpreter::stackElementSize * elem_slots);
   1.128          move_typed_arg(_masm, elem_type, true,
   1.129 -                       Address(rdx_fill_ptr, 0), Address(rsi_source, 0),
   1.130 -                       rbx_temp, rdi_temp);
   1.131 -        __ addptr(rsi_source, type2aelembytes(elem_type));
   1.132 +                       Address(rdx_fill_ptr, 0), Address(rdi_source, 0),
   1.133 +                       rbx_temp, rsi_temp);
   1.134 +        __ addptr(rdi_source, type2aelembytes(elem_type));
   1.135          __ cmpptr(rdx_fill_ptr, rax_argslot);
   1.136          __ jcc(Assembler::above, loop);
   1.137        } else if (length_constant == 0) {
   1.138 @@ -2488,8 +2502,8 @@
   1.139          for (int index = 0; index < length_constant; index++) {
   1.140            slot_offset -= Interpreter::stackElementSize * elem_slots;  // fill backward
   1.141            move_typed_arg(_masm, elem_type, true,
   1.142 -                         Address(rax_argslot, slot_offset), Address(rsi_array, elem_offset),
   1.143 -                         rbx_temp, rdi_temp);
   1.144 +                         Address(rax_argslot, slot_offset), Address(rdi_array, elem_offset),
   1.145 +                         rbx_temp, rsi_temp);
   1.146            elem_offset += type2aelembytes(elem_type);
   1.147          }
   1.148        }

mercurial