Print this page


Split Close
Expand all
Collapse all
          --- old/src/cpu/x86/vm/stubGenerator_x86_32.cpp
          +++ new/src/cpu/x86/vm/stubGenerator_x86_32.cpp
↓ open down ↓ 915 lines elided ↑ open up ↑
 916  916      __ movq(Address(from, to_from, Address::times_1), mmx0);
 917  917      __ addptr(from, 8);
 918  918      __ decrement(qword_count);
 919  919      __ jcc(Assembler::greater, L_copy_8_bytes);
 920  920    __ BIND(L_exit);
 921  921      __ emms();
 922  922    }
 923  923  
 924  924    address generate_disjoint_copy(BasicType t, bool aligned,
 925  925                                   Address::ScaleFactor sf,
 926      -                                 address* entry, const char *name) {
      926 +                                 address* entry, const char *name,
      927 +                                 bool need_pre_barrier = true) {
 927  928      __ align(CodeEntryAlignment);
 928  929      StubCodeMark mark(this, "StubRoutines", name);
 929  930      address start = __ pc();
 930  931  
 931  932      Label L_0_count, L_exit, L_skip_align1, L_skip_align2, L_copy_byte;
 932  933      Label L_copy_2_bytes, L_copy_4_bytes, L_copy_64_bytes;
 933  934  
 934  935      int shift = Address::times_ptr - sf;
 935  936  
 936  937      const Register from     = rsi;  // source array address
↓ open down ↓ 10 lines elided ↑ open up ↑
 947  948      __ movl(count, Address(rsp, 12+ 12));
 948  949  
 949  950      if (entry != NULL) {
 950  951        *entry = __ pc(); // Entry point from conjoint arraycopy stub.
 951  952        BLOCK_COMMENT("Entry:");
 952  953      }
 953  954  
 954  955      if (t == T_OBJECT) {
 955  956        __ testl(count, count);
 956  957        __ jcc(Assembler::zero, L_0_count);
 957      -      gen_write_ref_array_pre_barrier(to, count);
      958 +      if (need_pre_barrier) {
      959 +        gen_write_ref_array_pre_barrier(to, count);
      960 +      }
 958  961        __ mov(saved_to, to);          // save 'to'
 959  962      }
 960  963  
 961  964      __ subptr(to, from); // to --> to_from
 962  965      __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
 963  966      __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp
 964  967      if (!UseUnalignedLoadStores && !aligned && (t == T_BYTE || t == T_SHORT)) {
 965  968        // align source address at 4 bytes address boundary
 966  969        if (t == T_BYTE) {
 967  970          // One byte misalignment happens only for byte arrays
↓ open down ↓ 113 lines elided ↑ open up ↑
1081 1084      __ pop(rdi);
1082 1085      __ pop(rsi);
1083 1086      __ leave(); // required for proper stackwalking of RuntimeStub frame
1084 1087      __ ret(0);
1085 1088      return start;
1086 1089    }
1087 1090  
1088 1091    address generate_conjoint_copy(BasicType t, bool aligned,
1089 1092                                   Address::ScaleFactor sf,
1090 1093                                   address nooverlap_target,
1091      -                                 address* entry, const char *name) {
     1094 +                                 address* entry, const char *name,
     1095 +                                 bool need_pre_barrier = true) {
1092 1096      __ align(CodeEntryAlignment);
1093 1097      StubCodeMark mark(this, "StubRoutines", name);
1094 1098      address start = __ pc();
1095 1099  
1096 1100      Label L_0_count, L_exit, L_skip_align1, L_skip_align2, L_copy_byte;
1097 1101      Label L_copy_2_bytes, L_copy_4_bytes, L_copy_8_bytes, L_copy_8_bytes_loop;
1098 1102  
1099 1103      int shift = Address::times_ptr - sf;
1100 1104  
1101 1105      const Register src   = rax;  // source array address
↓ open down ↓ 23 lines elided ↑ open up ↑
1125 1129      RuntimeAddress nooverlap(nooverlap_target);
1126 1130      __ cmpptr(dst, src);
1127 1131      __ lea(end, Address(src, count, sf, 0)); // src + count * elem_size
1128 1132      __ jump_cc(Assembler::belowEqual, nooverlap);
1129 1133      __ cmpptr(dst, end);
1130 1134      __ jump_cc(Assembler::aboveEqual, nooverlap);
1131 1135  
1132 1136      if (t == T_OBJECT) {
1133 1137        __ testl(count, count);
1134 1138        __ jcc(Assembler::zero, L_0_count);
1135      -       gen_write_ref_array_pre_barrier(dst, count);
     1139 +      if (need_pre_barrier) {
     1140 +        gen_write_ref_array_pre_barrier(dst, count);
     1141 +      }
1136 1142      }
1137 1143  
1138 1144      // copy from high to low
1139 1145      __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
1140 1146      __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp
1141 1147      if (t == T_BYTE || t == T_SHORT) {
1142 1148        // Align the end of destination array at 4 bytes address boundary
1143 1149        __ lea(end, Address(dst, count, sf, 0));
1144 1150        if (t == T_BYTE) {
1145 1151          // One byte misalignment happens only for byte arrays
↓ open down ↓ 266 lines elided ↑ open up ↑
1412 1418    //    4(rsp)   - source array address
1413 1419    //    8(rsp)   - destination array address
1414 1420    //   12(rsp)   - element count, can be zero
1415 1421    //   16(rsp)   - size_t ckoff (super_check_offset)
1416 1422    //   20(rsp)   - oop ckval (super_klass)
1417 1423    //
1418 1424    //  Output:
1419 1425    //    rax, ==  0  -  success
1420 1426    //    rax, == -1^K - failure, where K is partial transfer count
1421 1427    //
1422      -  address generate_checkcast_copy(const char *name, address* entry) {
     1428 +  address generate_checkcast_copy(const char *name, address* entry, bool need_pre_barrier = true) {
1423 1429      __ align(CodeEntryAlignment);
1424 1430      StubCodeMark mark(this, "StubRoutines", name);
1425 1431      address start = __ pc();
1426 1432  
1427 1433      Label L_load_element, L_store_element, L_do_card_marks, L_done;
1428 1434  
1429 1435      // register use:
1430 1436      //  rax, rdx, rcx -- loop control (end_from, end_to, count)
1431 1437      //  rdi, rsi      -- element access (oop, klass)
1432 1438      //  rbx,           -- temp
↓ open down ↓ 40 lines elided ↑ open up ↑
1473 1479      Register end_from = from;           // re-use
1474 1480      Register end_to   = to;             // re-use
1475 1481      Register count    = length;         // re-use
1476 1482  
1477 1483      // Loop-variant addresses.  They assume post-incremented count < 0.
1478 1484      Address from_element_addr(end_from, count, Address::times_ptr, 0);
1479 1485      Address   to_element_addr(end_to,   count, Address::times_ptr, 0);
1480 1486      Address elem_klass_addr(elem, oopDesc::klass_offset_in_bytes());
1481 1487  
1482 1488      // Copy from low to high addresses, indexed from the end of each array.
1483      -    gen_write_ref_array_pre_barrier(to, count);
     1489 +    if (need_pre_barrier) {
     1490 +      gen_write_ref_array_pre_barrier(to, count);
     1491 +    }
1484 1492      __ lea(end_from, end_from_addr);
1485 1493      __ lea(end_to,   end_to_addr);
1486 1494      assert(length == count, "");        // else fix next line:
1487 1495      __ negptr(count);                   // negate and test the length
1488 1496      __ jccb(Assembler::notZero, L_load_element);
1489 1497  
1490 1498      // Empty array:  Nothing to do.
1491 1499      __ xorptr(rax, rax);                  // return 0 on (trivial) success
1492 1500      __ jmp(L_done);
1493 1501  
↓ open down ↓ 542 lines elided ↑ open up ↑
2036 2044          generate_conjoint_copy(T_INT, true, Address::times_4,  entry,
2037 2045                                 &entry_jint_arraycopy, "jint_arraycopy");
2038 2046  
2039 2047      StubRoutines::_oop_disjoint_arraycopy =
2040 2048          generate_disjoint_copy(T_OBJECT, true, Address::times_ptr, &entry,
2041 2049                                 "oop_disjoint_arraycopy");
2042 2050      StubRoutines::_oop_arraycopy =
2043 2051          generate_conjoint_copy(T_OBJECT, true, Address::times_ptr,  entry,
2044 2052                                 &entry_oop_arraycopy, "oop_arraycopy");
2045 2053  
     2054 +    StubRoutines::_oop_disjoint_arraycopy_no_pre =
     2055 +        generate_disjoint_copy(T_OBJECT, true, Address::times_ptr, &entry,
     2056 +                               "oop_disjoint_arraycopy_no_pre", false);
     2057 +    StubRoutines::_oop_arraycopy_no_pre =
     2058 +        generate_conjoint_copy(T_OBJECT, true, Address::times_ptr,  entry,
     2059 +                               NULL, "oop_arraycopy_no_pre", false);
     2060 +
2046 2061      StubRoutines::_jlong_disjoint_arraycopy =
2047 2062          generate_disjoint_long_copy(&entry, "jlong_disjoint_arraycopy");
2048 2063      StubRoutines::_jlong_arraycopy =
2049 2064          generate_conjoint_long_copy(entry, &entry_jlong_arraycopy,
2050 2065                                      "jlong_arraycopy");
2051 2066  
2052 2067      StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill");
2053 2068      StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill");
2054 2069      StubRoutines::_jint_fill = generate_fill(T_INT, false, "jint_fill");
2055 2070      StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill");
2056 2071      StubRoutines::_arrayof_jshort_fill = generate_fill(T_SHORT, true, "arrayof_jshort_fill");
2057 2072      StubRoutines::_arrayof_jint_fill = generate_fill(T_INT, true, "arrayof_jint_fill");
2058 2073  
2059      -    StubRoutines::_arrayof_jint_disjoint_arraycopy  =
2060      -        StubRoutines::_jint_disjoint_arraycopy;
2061      -    StubRoutines::_arrayof_oop_disjoint_arraycopy   =
2062      -        StubRoutines::_oop_disjoint_arraycopy;
2063      -    StubRoutines::_arrayof_jlong_disjoint_arraycopy =
2064      -        StubRoutines::_jlong_disjoint_arraycopy;
2065      -
2066      -    StubRoutines::_arrayof_jint_arraycopy  = StubRoutines::_jint_arraycopy;
2067      -    StubRoutines::_arrayof_oop_arraycopy   = StubRoutines::_oop_arraycopy;
2068      -    StubRoutines::_arrayof_jlong_arraycopy = StubRoutines::_jlong_arraycopy;
     2074 +    StubRoutines::_arrayof_jint_disjoint_arraycopy       = StubRoutines::_jint_disjoint_arraycopy;
     2075 +    StubRoutines::_arrayof_oop_disjoint_arraycopy        = StubRoutines::_oop_disjoint_arraycopy;
     2076 +    StubRoutines::_arrayof_oop_disjoint_arraycopy_no_pre = StubRoutines::_oop_disjoint_arraycopy_no_pre;
     2077 +    StubRoutines::_arrayof_jlong_disjoint_arraycopy      = StubRoutines::_jlong_disjoint_arraycopy;
     2078 +
     2079 +    StubRoutines::_arrayof_jint_arraycopy       = StubRoutines::_jint_arraycopy;
     2080 +    StubRoutines::_arrayof_oop_arraycopy        = StubRoutines::_oop_arraycopy;
     2081 +    StubRoutines::_arrayof_oop_arraycopy_no_pre = StubRoutines::_oop_arraycopy_no_pre;
     2082 +    StubRoutines::_arrayof_jlong_arraycopy      = StubRoutines::_jlong_arraycopy;
2069 2083  
2070 2084      StubRoutines::_checkcast_arraycopy =
2071      -        generate_checkcast_copy("checkcast_arraycopy",
2072      -                                  &entry_checkcast_arraycopy);
     2085 +        generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy);
     2086 +    StubRoutines::_checkcast_arraycopy_no_pre =
     2087 +        generate_checkcast_copy("checkcast_arraycopy_no_pre", NULL, false);
2073 2088  
2074 2089      StubRoutines::_unsafe_arraycopy =
2075 2090          generate_unsafe_copy("unsafe_arraycopy",
2076 2091                                 entry_jbyte_arraycopy,
2077 2092                                 entry_jshort_arraycopy,
2078 2093                                 entry_jint_arraycopy,
2079 2094                                 entry_jlong_arraycopy);
2080 2095  
2081 2096      StubRoutines::_generic_arraycopy =
2082 2097          generate_generic_copy("generic_arraycopy",
↓ open down ↓ 263 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX