src/cpu/x86/vm/stubGenerator_x86_64.cpp

changeset 2606
0ac769a57c64
parent 2595
d89a22843c62
child 2689
b1c22848507b
     1.1 --- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Tue Mar 01 10:27:15 2011 -0800
     1.2 +++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Tue Mar 01 14:56:48 2011 -0800
     1.3 @@ -1159,34 +1159,35 @@
     1.4    // Generate code for an array write pre barrier
     1.5    //
     1.6    //     addr    -  starting address
     1.7 -  //     count    -  element count
     1.8 +  //     count   -  element count
     1.9 +  //     tmp     - scratch register
    1.10    //
    1.11    //     Destroy no registers!
    1.12    //
    1.13 -  void  gen_write_ref_array_pre_barrier(Register addr, Register count) {
    1.14 +  void  gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
    1.15      BarrierSet* bs = Universe::heap()->barrier_set();
    1.16      switch (bs->kind()) {
    1.17        case BarrierSet::G1SATBCT:
    1.18        case BarrierSet::G1SATBCTLogging:
    1.19 -        {
    1.20 -          __ pusha();                      // push registers
    1.21 -          if (count == c_rarg0) {
    1.22 -            if (addr == c_rarg1) {
    1.23 -              // exactly backwards!!
    1.24 -              __ xchgptr(c_rarg1, c_rarg0);
    1.25 -            } else {
    1.26 -              __ movptr(c_rarg1, count);
    1.27 -              __ movptr(c_rarg0, addr);
    1.28 -            }
    1.29 -
    1.30 -          } else {
    1.31 -            __ movptr(c_rarg0, addr);
    1.32 -            __ movptr(c_rarg1, count);
    1.33 -          }
    1.34 -          __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 2);
    1.35 -          __ popa();
    1.36 +        // With G1, don't generate the call if we statically know that the target in uninitialized
    1.37 +        if (!dest_uninitialized) {
    1.38 +           __ pusha();                      // push registers
    1.39 +           if (count == c_rarg0) {
    1.40 +             if (addr == c_rarg1) {
    1.41 +               // exactly backwards!!
    1.42 +               __ xchgptr(c_rarg1, c_rarg0);
    1.43 +             } else {
    1.44 +               __ movptr(c_rarg1, count);
    1.45 +               __ movptr(c_rarg0, addr);
    1.46 +             }
    1.47 +           } else {
    1.48 +             __ movptr(c_rarg0, addr);
    1.49 +             __ movptr(c_rarg1, count);
    1.50 +           }
    1.51 +           __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 2);
    1.52 +           __ popa();
    1.53          }
    1.54 -        break;
    1.55 +         break;
    1.56        case BarrierSet::CardTableModRef:
    1.57        case BarrierSet::CardTableExtension:
    1.58        case BarrierSet::ModRef:
    1.59 @@ -1769,7 +1770,8 @@
    1.60    //   disjoint_int_copy_entry is set to the no-overlap entry point
    1.61    //   used by generate_conjoint_int_oop_copy().
    1.62    //
    1.63 -  address generate_disjoint_int_oop_copy(bool aligned, bool is_oop, address* entry, const char *name) {
    1.64 +  address generate_disjoint_int_oop_copy(bool aligned, bool is_oop, address* entry,
    1.65 +                                         const char *name, bool dest_uninitialized = false) {
    1.66      __ align(CodeEntryAlignment);
    1.67      StubCodeMark mark(this, "StubRoutines", name);
    1.68      address start = __ pc();
    1.69 @@ -1799,7 +1801,7 @@
    1.70                        // r9 and r10 may be used to save non-volatile registers
    1.71      if (is_oop) {
    1.72        __ movq(saved_to, to);
    1.73 -      gen_write_ref_array_pre_barrier(to, count);
    1.74 +      gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
    1.75      }
    1.76  
    1.77      // 'from', 'to' and 'count' are now valid
    1.78 @@ -1860,7 +1862,8 @@
    1.79    // cache line boundaries will still be loaded and stored atomicly.
    1.80    //
    1.81    address generate_conjoint_int_oop_copy(bool aligned, bool is_oop, address nooverlap_target,
    1.82 -                                         address *entry, const char *name) {
    1.83 +                                         address *entry, const char *name,
    1.84 +                                         bool dest_uninitialized = false) {
    1.85      __ align(CodeEntryAlignment);
    1.86      StubCodeMark mark(this, "StubRoutines", name);
    1.87      address start = __ pc();
    1.88 @@ -1887,7 +1890,7 @@
    1.89  
    1.90      if (is_oop) {
    1.91        // no registers are destroyed by this call
    1.92 -      gen_write_ref_array_pre_barrier(to, count);
    1.93 +      gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
    1.94      }
    1.95  
    1.96      assert_clean_int(count, rax); // Make sure 'count' is clean int.
    1.97 @@ -1953,7 +1956,8 @@
    1.98    //   disjoint_oop_copy_entry or disjoint_long_copy_entry is set to the
    1.99    //   no-overlap entry point used by generate_conjoint_long_oop_copy().
   1.100    //
   1.101 -  address generate_disjoint_long_oop_copy(bool aligned, bool is_oop, address *entry, const char *name) {
   1.102 +  address generate_disjoint_long_oop_copy(bool aligned, bool is_oop, address *entry,
   1.103 +                                          const char *name, bool dest_uninitialized = false) {
   1.104      __ align(CodeEntryAlignment);
   1.105      StubCodeMark mark(this, "StubRoutines", name);
   1.106      address start = __ pc();
   1.107 @@ -1983,7 +1987,7 @@
   1.108      // 'from', 'to' and 'qword_count' are now valid
   1.109      if (is_oop) {
   1.110        // no registers are destroyed by this call
   1.111 -      gen_write_ref_array_pre_barrier(to, qword_count);
   1.112 +      gen_write_ref_array_pre_barrier(to, qword_count, dest_uninitialized);
   1.113      }
   1.114  
   1.115      // Copy from low to high addresses.  Use 'to' as scratch.
   1.116 @@ -2038,8 +2042,9 @@
   1.117    //   c_rarg1   - destination array address
   1.118    //   c_rarg2   - element count, treated as ssize_t, can be zero
   1.119    //
   1.120 -  address generate_conjoint_long_oop_copy(bool aligned, bool is_oop, address nooverlap_target,
   1.121 -                                          address *entry, const char *name) {
   1.122 +  address generate_conjoint_long_oop_copy(bool aligned, bool is_oop,
   1.123 +                                          address nooverlap_target, address *entry,
   1.124 +                                          const char *name, bool dest_uninitialized = false) {
   1.125      __ align(CodeEntryAlignment);
   1.126      StubCodeMark mark(this, "StubRoutines", name);
   1.127      address start = __ pc();
   1.128 @@ -2067,7 +2072,7 @@
   1.129        // Save to and count for store barrier
   1.130        __ movptr(saved_count, qword_count);
   1.131        // No registers are destroyed by this call
   1.132 -      gen_write_ref_array_pre_barrier(to, saved_count);
   1.133 +      gen_write_ref_array_pre_barrier(to, saved_count, dest_uninitialized);
   1.134      }
   1.135  
   1.136      __ jmp(L_copy_32_bytes);
   1.137 @@ -2146,7 +2151,8 @@
   1.138    //    rax ==  0  -  success
   1.139    //    rax == -1^K - failure, where K is partial transfer count
   1.140    //
   1.141 -  address generate_checkcast_copy(const char *name, address *entry) {
   1.142 +  address generate_checkcast_copy(const char *name, address *entry,
   1.143 +                                  bool dest_uninitialized = false) {
   1.144  
   1.145      Label L_load_element, L_store_element, L_do_card_marks, L_done;
   1.146  
   1.147 @@ -2240,7 +2246,7 @@
   1.148      Address from_element_addr(end_from, count, TIMES_OOP, 0);
   1.149      Address   to_element_addr(end_to,   count, TIMES_OOP, 0);
   1.150  
   1.151 -    gen_write_ref_array_pre_barrier(to, count);
   1.152 +    gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
   1.153  
   1.154      // Copy from low to high addresses, indexed from the end of each array.
   1.155      __ lea(end_from, end_from_addr);
   1.156 @@ -2750,14 +2756,29 @@
   1.157                                                                                "oop_disjoint_arraycopy");
   1.158        StubRoutines::_oop_arraycopy           = generate_conjoint_int_oop_copy(false, true, entry,
   1.159                                                                                &entry_oop_arraycopy, "oop_arraycopy");
   1.160 +      StubRoutines::_oop_disjoint_arraycopy_uninit  = generate_disjoint_int_oop_copy(false, true, &entry,
   1.161 +                                                                                     "oop_disjoint_arraycopy_uninit",
   1.162 +                                                                                     /*dest_uninitialized*/true);
   1.163 +      StubRoutines::_oop_arraycopy_uninit           = generate_conjoint_int_oop_copy(false, true, entry,
   1.164 +                                                                                     NULL, "oop_arraycopy_uninit",
   1.165 +                                                                                     /*dest_uninitialized*/true);
   1.166      } else {
   1.167        StubRoutines::_oop_disjoint_arraycopy  = generate_disjoint_long_oop_copy(false, true, &entry,
   1.168                                                                                 "oop_disjoint_arraycopy");
   1.169        StubRoutines::_oop_arraycopy           = generate_conjoint_long_oop_copy(false, true, entry,
   1.170                                                                                 &entry_oop_arraycopy, "oop_arraycopy");
   1.171 +      StubRoutines::_oop_disjoint_arraycopy_uninit  = generate_disjoint_long_oop_copy(false, true, &entry,
   1.172 +                                                                                      "oop_disjoint_arraycopy_uninit",
   1.173 +                                                                                      /*dest_uninitialized*/true);
   1.174 +      StubRoutines::_oop_arraycopy_uninit           = generate_conjoint_long_oop_copy(false, true, entry,
   1.175 +                                                                                      NULL, "oop_arraycopy_uninit",
   1.176 +                                                                                      /*dest_uninitialized*/true);
   1.177      }
   1.178  
   1.179 -    StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy);
   1.180 +    StubRoutines::_checkcast_arraycopy        = generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy);
   1.181 +    StubRoutines::_checkcast_arraycopy_uninit = generate_checkcast_copy("checkcast_arraycopy_uninit", NULL,
   1.182 +                                                                        /*dest_uninitialized*/true);
   1.183 +
   1.184      StubRoutines::_unsafe_arraycopy    = generate_unsafe_copy("unsafe_arraycopy",
   1.185                                                                entry_jbyte_arraycopy,
   1.186                                                                entry_jshort_arraycopy,
   1.187 @@ -2794,6 +2815,9 @@
   1.188  
   1.189      StubRoutines::_arrayof_oop_disjoint_arraycopy    = StubRoutines::_oop_disjoint_arraycopy;
   1.190      StubRoutines::_arrayof_oop_arraycopy             = StubRoutines::_oop_arraycopy;
   1.191 +
   1.192 +    StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit    = StubRoutines::_oop_disjoint_arraycopy_uninit;
   1.193 +    StubRoutines::_arrayof_oop_arraycopy_uninit             = StubRoutines::_oop_arraycopy_uninit;
   1.194    }
   1.195  
   1.196    void generate_math_stubs() {

mercurial