src/cpu/x86/vm/stubGenerator_x86_32.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File g1-bulk-zeroing-reduction Sdiff src/cpu/x86/vm

src/cpu/x86/vm/stubGenerator_x86_32.cpp

Print this page




 906   __ BIND(L_copy_64_bytes);
 907     __ subl(qword_count, 8);
 908     __ jcc(Assembler::greaterEqual, L_copy_64_bytes_loop);
 909     __ addl(qword_count, 8);
 910     __ jccb(Assembler::zero, L_exit);
 911     //
 912     // length is too short, just copy qwords
 913     //
 914   __ BIND(L_copy_8_bytes);
 915     __ movq(mmx0, Address(from, 0));
 916     __ movq(Address(from, to_from, Address::times_1), mmx0);
 917     __ addptr(from, 8);
 918     __ decrement(qword_count);
 919     __ jcc(Assembler::greater, L_copy_8_bytes);
 920   __ BIND(L_exit);
 921     __ emms();
 922   }
 923 
 924   address generate_disjoint_copy(BasicType t, bool aligned,
 925                                  Address::ScaleFactor sf,
 926                                  address* entry, const char *name) {

 927     __ align(CodeEntryAlignment);
 928     StubCodeMark mark(this, "StubRoutines", name);
 929     address start = __ pc();
 930 
 931     Label L_0_count, L_exit, L_skip_align1, L_skip_align2, L_copy_byte;
 932     Label L_copy_2_bytes, L_copy_4_bytes, L_copy_64_bytes;
 933 
 934     int shift = Address::times_ptr - sf;
 935 
 936     const Register from     = rsi;  // source array address
 937     const Register to       = rdi;  // destination array address
 938     const Register count    = rcx;  // elements count
 939     const Register to_from  = to;   // (to - from)
 940     const Register saved_to = rdx;  // saved destination array address
 941 
 942     __ enter(); // required for proper stackwalking of RuntimeStub frame
 943     __ push(rsi);
 944     __ push(rdi);
 945     __ movptr(from , Address(rsp, 12+ 4));
 946     __ movptr(to   , Address(rsp, 12+ 8));
 947     __ movl(count, Address(rsp, 12+ 12));
 948 
 949     if (entry != NULL) {
 950       *entry = __ pc(); // Entry point from conjoint arraycopy stub.
 951       BLOCK_COMMENT("Entry:");
 952     }
 953 
 954     if (t == T_OBJECT) {
 955       __ testl(count, count);
 956       __ jcc(Assembler::zero, L_0_count);

 957       gen_write_ref_array_pre_barrier(to, count);

 958       __ mov(saved_to, to);          // save 'to'
 959     }
 960 
 961     __ subptr(to, from); // to --> to_from
 962     __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
 963     __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp
 964     if (!UseUnalignedLoadStores && !aligned && (t == T_BYTE || t == T_SHORT)) {
 965       // align source address at 4 bytes address boundary
 966       if (t == T_BYTE) {
 967         // One byte misalignment happens only for byte arrays
 968         __ testl(from, 1);
 969         __ jccb(Assembler::zero, L_skip_align1);
 970         __ movb(rax, Address(from, 0));
 971         __ movb(Address(from, to_from, Address::times_1, 0), rax);
 972         __ increment(from);
 973         __ decrement(count);
 974       __ BIND(L_skip_align1);
 975       }
 976       // Two bytes misalignment happens only for byte and short (char) arrays
 977       __ testl(from, 2);


1071 
1072     __ enter(); // required for proper stackwalking of RuntimeStub frame
1073     __ push(rsi);
1074     __ push(rdi);
1075     __ movptr(to   , Address(rsp, 12+ 4));
1076     __ movl(value, Address(rsp, 12+ 8));
1077     __ movl(count, Address(rsp, 12+ 12));
1078 
1079     __ generate_fill(t, aligned, to, value, count, rax, xmm0);
1080 
1081     __ pop(rdi);
1082     __ pop(rsi);
1083     __ leave(); // required for proper stackwalking of RuntimeStub frame
1084     __ ret(0);
1085     return start;
1086   }
1087 
1088   address generate_conjoint_copy(BasicType t, bool aligned,
1089                                  Address::ScaleFactor sf,
1090                                  address nooverlap_target,
1091                                  address* entry, const char *name) {

1092     __ align(CodeEntryAlignment);
1093     StubCodeMark mark(this, "StubRoutines", name);
1094     address start = __ pc();
1095 
1096     Label L_0_count, L_exit, L_skip_align1, L_skip_align2, L_copy_byte;
1097     Label L_copy_2_bytes, L_copy_4_bytes, L_copy_8_bytes, L_copy_8_bytes_loop;
1098 
1099     int shift = Address::times_ptr - sf;
1100 
1101     const Register src   = rax;  // source array address
1102     const Register dst   = rdx;  // destination array address
1103     const Register from  = rsi;  // source array address
1104     const Register to    = rdi;  // destination array address
1105     const Register count = rcx;  // elements count
1106     const Register end   = rax;  // array end address
1107 
1108     __ enter(); // required for proper stackwalking of RuntimeStub frame
1109     __ push(rsi);
1110     __ push(rdi);
1111     __ movptr(src  , Address(rsp, 12+ 4));   // from


1115     if (entry != NULL) {
1116       *entry = __ pc(); // Entry point from generic arraycopy stub.
1117       BLOCK_COMMENT("Entry:");
1118     }
1119 
1120     // nooverlap_target expects arguments in rsi and rdi.
1121     __ mov(from, src);
1122     __ mov(to  , dst);
1123 
1124     // arrays overlap test: dispatch to disjoint stub if necessary.
1125     RuntimeAddress nooverlap(nooverlap_target);
1126     __ cmpptr(dst, src);
1127     __ lea(end, Address(src, count, sf, 0)); // src + count * elem_size
1128     __ jump_cc(Assembler::belowEqual, nooverlap);
1129     __ cmpptr(dst, end);
1130     __ jump_cc(Assembler::aboveEqual, nooverlap);
1131 
1132     if (t == T_OBJECT) {
1133       __ testl(count, count);
1134       __ jcc(Assembler::zero, L_0_count);

1135        gen_write_ref_array_pre_barrier(dst, count);
1136     }

1137 
1138     // copy from high to low
1139     __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
1140     __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp
1141     if (t == T_BYTE || t == T_SHORT) {
1142       // Align the end of destination array at 4 bytes address boundary
1143       __ lea(end, Address(dst, count, sf, 0));
1144       if (t == T_BYTE) {
1145         // One byte misalignment happens only for byte arrays
1146         __ testl(end, 1);
1147         __ jccb(Assembler::zero, L_skip_align1);
1148         __ decrement(count);
1149         __ movb(rdx, Address(from, count, sf, 0));
1150         __ movb(Address(to, count, sf, 0), rdx);
1151       __ BIND(L_skip_align1);
1152       }
1153       // Two bytes misalignment happens only for byte and short (char) arrays
1154       __ testl(end, 2);
1155       __ jccb(Assembler::zero, L_skip_align2);
1156       __ subptr(count, 1<<(shift-1));


1402     if (L_success == NULL) { BLOCK_COMMENT("L_success:"); }
1403     if (L_failure == NULL) { BLOCK_COMMENT("L_failure:"); }
1404 
1405 #undef LOCAL_JCC
1406   }
1407 
1408   //
1409   //  Generate checkcasting array copy stub
1410   //
1411   //  Input:
1412   //    4(rsp)   - source array address
1413   //    8(rsp)   - destination array address
1414   //   12(rsp)   - element count, can be zero
1415   //   16(rsp)   - size_t ckoff (super_check_offset)
1416   //   20(rsp)   - oop ckval (super_klass)
1417   //
1418   //  Output:
1419   //    rax, ==  0  -  success
1420   //    rax, == -1^K - failure, where K is partial transfer count
1421   //
1422   address generate_checkcast_copy(const char *name, address* entry) {
1423     __ align(CodeEntryAlignment);
1424     StubCodeMark mark(this, "StubRoutines", name);
1425     address start = __ pc();
1426 
1427     Label L_load_element, L_store_element, L_do_card_marks, L_done;
1428 
1429     // register use:
1430     //  rax, rdx, rcx -- loop control (end_from, end_to, count)
1431     //  rdi, rsi      -- element access (oop, klass)
1432     //  rbx,           -- temp
1433     const Register from       = rax;    // source array address
1434     const Register to         = rdx;    // destination array address
1435     const Register length     = rcx;    // elements count
1436     const Register elem       = rdi;    // each oop copied
1437     const Register elem_klass = rsi;    // each elem._klass (sub_klass)
1438     const Register temp       = rbx;    // lone remaining temp
1439 
1440     __ enter(); // required for proper stackwalking of RuntimeStub frame
1441 
1442     __ push(rsi);


1463     // Assembler stub will be used for this call to arraycopy
1464     // if the two arrays are subtypes of Object[] but the
1465     // destination array type is not equal to or a supertype
1466     // of the source type.  Each element must be separately
1467     // checked.
1468 
1469     // Loop-invariant addresses.  They are exclusive end pointers.
1470     Address end_from_addr(from, length, Address::times_ptr, 0);
1471     Address   end_to_addr(to,   length, Address::times_ptr, 0);
1472 
1473     Register end_from = from;           // re-use
1474     Register end_to   = to;             // re-use
1475     Register count    = length;         // re-use
1476 
1477     // Loop-variant addresses.  They assume post-incremented count < 0.
1478     Address from_element_addr(end_from, count, Address::times_ptr, 0);
1479     Address   to_element_addr(end_to,   count, Address::times_ptr, 0);
1480     Address elem_klass_addr(elem, oopDesc::klass_offset_in_bytes());
1481 
1482     // Copy from low to high addresses, indexed from the end of each array.

1483     gen_write_ref_array_pre_barrier(to, count);

1484     __ lea(end_from, end_from_addr);
1485     __ lea(end_to,   end_to_addr);
1486     assert(length == count, "");        // else fix next line:
1487     __ negptr(count);                   // negate and test the length
1488     __ jccb(Assembler::notZero, L_load_element);
1489 
1490     // Empty array:  Nothing to do.
1491     __ xorptr(rax, rax);                  // return 0 on (trivial) success
1492     __ jmp(L_done);
1493 
1494     // ======== begin loop ========
1495     // (Loop is rotated; its entry is L_load_element.)
1496     // Loop control:
1497     //   for (count = -count; count != 0; count++)
1498     // Base pointers src, dst are biased by 8*count,to last element.
1499     __ align(OptoLoopAlignment);
1500 
1501     __ BIND(L_store_element);
1502     __ movptr(to_element_addr, elem);     // store the oop
1503     __ increment(count);                // increment the count toward zero


2026                                "jshort_disjoint_arraycopy");
2027     StubRoutines::_jshort_arraycopy =
2028         generate_conjoint_copy(T_SHORT, false, Address::times_2,  entry,
2029                                &entry_jshort_arraycopy, "jshort_arraycopy");
2030 
2031     // Next arrays are always aligned on 4 bytes at least.
2032     StubRoutines::_jint_disjoint_arraycopy =
2033         generate_disjoint_copy(T_INT, true, Address::times_4, &entry,
2034                                "jint_disjoint_arraycopy");
2035     StubRoutines::_jint_arraycopy =
2036         generate_conjoint_copy(T_INT, true, Address::times_4,  entry,
2037                                &entry_jint_arraycopy, "jint_arraycopy");
2038 
2039     StubRoutines::_oop_disjoint_arraycopy =
2040         generate_disjoint_copy(T_OBJECT, true, Address::times_ptr, &entry,
2041                                "oop_disjoint_arraycopy");
2042     StubRoutines::_oop_arraycopy =
2043         generate_conjoint_copy(T_OBJECT, true, Address::times_ptr,  entry,
2044                                &entry_oop_arraycopy, "oop_arraycopy");
2045 







2046     StubRoutines::_jlong_disjoint_arraycopy =
2047         generate_disjoint_long_copy(&entry, "jlong_disjoint_arraycopy");
2048     StubRoutines::_jlong_arraycopy =
2049         generate_conjoint_long_copy(entry, &entry_jlong_arraycopy,
2050                                     "jlong_arraycopy");
2051 
2052     StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill");
2053     StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill");
2054     StubRoutines::_jint_fill = generate_fill(T_INT, false, "jint_fill");
2055     StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill");
2056     StubRoutines::_arrayof_jshort_fill = generate_fill(T_SHORT, true, "arrayof_jshort_fill");
2057     StubRoutines::_arrayof_jint_fill = generate_fill(T_INT, true, "arrayof_jint_fill");
2058 
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;
2069 
2070     StubRoutines::_checkcast_arraycopy =
2071         generate_checkcast_copy("checkcast_arraycopy",
2072                                   &entry_checkcast_arraycopy);

2073 
2074     StubRoutines::_unsafe_arraycopy =
2075         generate_unsafe_copy("unsafe_arraycopy",
2076                                entry_jbyte_arraycopy,
2077                                entry_jshort_arraycopy,
2078                                entry_jint_arraycopy,
2079                                entry_jlong_arraycopy);
2080 
2081     StubRoutines::_generic_arraycopy =
2082         generate_generic_copy("generic_arraycopy",
2083                                entry_jbyte_arraycopy,
2084                                entry_jshort_arraycopy,
2085                                entry_jint_arraycopy,
2086                                entry_oop_arraycopy,
2087                                entry_jlong_arraycopy,
2088                                entry_checkcast_arraycopy);
2089   }
2090 
2091   void generate_math_stubs() {
2092     {




 906   __ BIND(L_copy_64_bytes);
 907     __ subl(qword_count, 8);
 908     __ jcc(Assembler::greaterEqual, L_copy_64_bytes_loop);
 909     __ addl(qword_count, 8);
 910     __ jccb(Assembler::zero, L_exit);
 911     //
 912     // length is too short, just copy qwords
 913     //
 914   __ BIND(L_copy_8_bytes);
 915     __ movq(mmx0, Address(from, 0));
 916     __ movq(Address(from, to_from, Address::times_1), mmx0);
 917     __ addptr(from, 8);
 918     __ decrement(qword_count);
 919     __ jcc(Assembler::greater, L_copy_8_bytes);
 920   __ BIND(L_exit);
 921     __ emms();
 922   }
 923 
 924   address generate_disjoint_copy(BasicType t, bool aligned,
 925                                  Address::ScaleFactor sf,
 926                                  address* entry, const char *name,
 927                                  bool need_pre_barrier = true) {
 928     __ align(CodeEntryAlignment);
 929     StubCodeMark mark(this, "StubRoutines", name);
 930     address start = __ pc();
 931 
 932     Label L_0_count, L_exit, L_skip_align1, L_skip_align2, L_copy_byte;
 933     Label L_copy_2_bytes, L_copy_4_bytes, L_copy_64_bytes;
 934 
 935     int shift = Address::times_ptr - sf;
 936 
 937     const Register from     = rsi;  // source array address
 938     const Register to       = rdi;  // destination array address
 939     const Register count    = rcx;  // elements count
 940     const Register to_from  = to;   // (to - from)
 941     const Register saved_to = rdx;  // saved destination array address
 942 
 943     __ enter(); // required for proper stackwalking of RuntimeStub frame
 944     __ push(rsi);
 945     __ push(rdi);
 946     __ movptr(from , Address(rsp, 12+ 4));
 947     __ movptr(to   , Address(rsp, 12+ 8));
 948     __ movl(count, Address(rsp, 12+ 12));
 949 
 950     if (entry != NULL) {
 951       *entry = __ pc(); // Entry point from conjoint arraycopy stub.
 952       BLOCK_COMMENT("Entry:");
 953     }
 954 
 955     if (t == T_OBJECT) {
 956       __ testl(count, count);
 957       __ jcc(Assembler::zero, L_0_count);
 958       if (need_pre_barrier) {
 959         gen_write_ref_array_pre_barrier(to, count);
 960       }
 961       __ mov(saved_to, to);          // save 'to'
 962     }
 963 
 964     __ subptr(to, from); // to --> to_from
 965     __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
 966     __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp
 967     if (!UseUnalignedLoadStores && !aligned && (t == T_BYTE || t == T_SHORT)) {
 968       // align source address at 4 bytes address boundary
 969       if (t == T_BYTE) {
 970         // One byte misalignment happens only for byte arrays
 971         __ testl(from, 1);
 972         __ jccb(Assembler::zero, L_skip_align1);
 973         __ movb(rax, Address(from, 0));
 974         __ movb(Address(from, to_from, Address::times_1, 0), rax);
 975         __ increment(from);
 976         __ decrement(count);
 977       __ BIND(L_skip_align1);
 978       }
 979       // Two bytes misalignment happens only for byte and short (char) arrays
 980       __ testl(from, 2);


1074 
1075     __ enter(); // required for proper stackwalking of RuntimeStub frame
1076     __ push(rsi);
1077     __ push(rdi);
1078     __ movptr(to   , Address(rsp, 12+ 4));
1079     __ movl(value, Address(rsp, 12+ 8));
1080     __ movl(count, Address(rsp, 12+ 12));
1081 
1082     __ generate_fill(t, aligned, to, value, count, rax, xmm0);
1083 
1084     __ pop(rdi);
1085     __ pop(rsi);
1086     __ leave(); // required for proper stackwalking of RuntimeStub frame
1087     __ ret(0);
1088     return start;
1089   }
1090 
1091   address generate_conjoint_copy(BasicType t, bool aligned,
1092                                  Address::ScaleFactor sf,
1093                                  address nooverlap_target,
1094                                  address* entry, const char *name,
1095                                  bool need_pre_barrier = true) {
1096     __ align(CodeEntryAlignment);
1097     StubCodeMark mark(this, "StubRoutines", name);
1098     address start = __ pc();
1099 
1100     Label L_0_count, L_exit, L_skip_align1, L_skip_align2, L_copy_byte;
1101     Label L_copy_2_bytes, L_copy_4_bytes, L_copy_8_bytes, L_copy_8_bytes_loop;
1102 
1103     int shift = Address::times_ptr - sf;
1104 
1105     const Register src   = rax;  // source array address
1106     const Register dst   = rdx;  // destination array address
1107     const Register from  = rsi;  // source array address
1108     const Register to    = rdi;  // destination array address
1109     const Register count = rcx;  // elements count
1110     const Register end   = rax;  // array end address
1111 
1112     __ enter(); // required for proper stackwalking of RuntimeStub frame
1113     __ push(rsi);
1114     __ push(rdi);
1115     __ movptr(src  , Address(rsp, 12+ 4));   // from


1119     if (entry != NULL) {
1120       *entry = __ pc(); // Entry point from generic arraycopy stub.
1121       BLOCK_COMMENT("Entry:");
1122     }
1123 
1124     // nooverlap_target expects arguments in rsi and rdi.
1125     __ mov(from, src);
1126     __ mov(to  , dst);
1127 
1128     // arrays overlap test: dispatch to disjoint stub if necessary.
1129     RuntimeAddress nooverlap(nooverlap_target);
1130     __ cmpptr(dst, src);
1131     __ lea(end, Address(src, count, sf, 0)); // src + count * elem_size
1132     __ jump_cc(Assembler::belowEqual, nooverlap);
1133     __ cmpptr(dst, end);
1134     __ jump_cc(Assembler::aboveEqual, nooverlap);
1135 
1136     if (t == T_OBJECT) {
1137       __ testl(count, count);
1138       __ jcc(Assembler::zero, L_0_count);
1139       if (need_pre_barrier) {
1140         gen_write_ref_array_pre_barrier(dst, count);
1141       }
1142     }
1143 
1144     // copy from high to low
1145     __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
1146     __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp
1147     if (t == T_BYTE || t == T_SHORT) {
1148       // Align the end of destination array at 4 bytes address boundary
1149       __ lea(end, Address(dst, count, sf, 0));
1150       if (t == T_BYTE) {
1151         // One byte misalignment happens only for byte arrays
1152         __ testl(end, 1);
1153         __ jccb(Assembler::zero, L_skip_align1);
1154         __ decrement(count);
1155         __ movb(rdx, Address(from, count, sf, 0));
1156         __ movb(Address(to, count, sf, 0), rdx);
1157       __ BIND(L_skip_align1);
1158       }
1159       // Two bytes misalignment happens only for byte and short (char) arrays
1160       __ testl(end, 2);
1161       __ jccb(Assembler::zero, L_skip_align2);
1162       __ subptr(count, 1<<(shift-1));


1408     if (L_success == NULL) { BLOCK_COMMENT("L_success:"); }
1409     if (L_failure == NULL) { BLOCK_COMMENT("L_failure:"); }
1410 
1411 #undef LOCAL_JCC
1412   }
1413 
1414   //
1415   //  Generate checkcasting array copy stub
1416   //
1417   //  Input:
1418   //    4(rsp)   - source array address
1419   //    8(rsp)   - destination array address
1420   //   12(rsp)   - element count, can be zero
1421   //   16(rsp)   - size_t ckoff (super_check_offset)
1422   //   20(rsp)   - oop ckval (super_klass)
1423   //
1424   //  Output:
1425   //    rax, ==  0  -  success
1426   //    rax, == -1^K - failure, where K is partial transfer count
1427   //
1428   address generate_checkcast_copy(const char *name, address* entry, bool need_pre_barrier = true) {
1429     __ align(CodeEntryAlignment);
1430     StubCodeMark mark(this, "StubRoutines", name);
1431     address start = __ pc();
1432 
1433     Label L_load_element, L_store_element, L_do_card_marks, L_done;
1434 
1435     // register use:
1436     //  rax, rdx, rcx -- loop control (end_from, end_to, count)
1437     //  rdi, rsi      -- element access (oop, klass)
1438     //  rbx,           -- temp
1439     const Register from       = rax;    // source array address
1440     const Register to         = rdx;    // destination array address
1441     const Register length     = rcx;    // elements count
1442     const Register elem       = rdi;    // each oop copied
1443     const Register elem_klass = rsi;    // each elem._klass (sub_klass)
1444     const Register temp       = rbx;    // lone remaining temp
1445 
1446     __ enter(); // required for proper stackwalking of RuntimeStub frame
1447 
1448     __ push(rsi);


1469     // Assembler stub will be used for this call to arraycopy
1470     // if the two arrays are subtypes of Object[] but the
1471     // destination array type is not equal to or a supertype
1472     // of the source type.  Each element must be separately
1473     // checked.
1474 
1475     // Loop-invariant addresses.  They are exclusive end pointers.
1476     Address end_from_addr(from, length, Address::times_ptr, 0);
1477     Address   end_to_addr(to,   length, Address::times_ptr, 0);
1478 
1479     Register end_from = from;           // re-use
1480     Register end_to   = to;             // re-use
1481     Register count    = length;         // re-use
1482 
1483     // Loop-variant addresses.  They assume post-incremented count < 0.
1484     Address from_element_addr(end_from, count, Address::times_ptr, 0);
1485     Address   to_element_addr(end_to,   count, Address::times_ptr, 0);
1486     Address elem_klass_addr(elem, oopDesc::klass_offset_in_bytes());
1487 
1488     // Copy from low to high addresses, indexed from the end of each array.
1489     if (need_pre_barrier) {
1490       gen_write_ref_array_pre_barrier(to, count);
1491     }
1492     __ lea(end_from, end_from_addr);
1493     __ lea(end_to,   end_to_addr);
1494     assert(length == count, "");        // else fix next line:
1495     __ negptr(count);                   // negate and test the length
1496     __ jccb(Assembler::notZero, L_load_element);
1497 
1498     // Empty array:  Nothing to do.
1499     __ xorptr(rax, rax);                  // return 0 on (trivial) success
1500     __ jmp(L_done);
1501 
1502     // ======== begin loop ========
1503     // (Loop is rotated; its entry is L_load_element.)
1504     // Loop control:
1505     //   for (count = -count; count != 0; count++)
1506     // Base pointers src, dst are biased by 8*count,to last element.
1507     __ align(OptoLoopAlignment);
1508 
1509     __ BIND(L_store_element);
1510     __ movptr(to_element_addr, elem);     // store the oop
1511     __ increment(count);                // increment the count toward zero


2034                                "jshort_disjoint_arraycopy");
2035     StubRoutines::_jshort_arraycopy =
2036         generate_conjoint_copy(T_SHORT, false, Address::times_2,  entry,
2037                                &entry_jshort_arraycopy, "jshort_arraycopy");
2038 
2039     // Next arrays are always aligned on 4 bytes at least.
2040     StubRoutines::_jint_disjoint_arraycopy =
2041         generate_disjoint_copy(T_INT, true, Address::times_4, &entry,
2042                                "jint_disjoint_arraycopy");
2043     StubRoutines::_jint_arraycopy =
2044         generate_conjoint_copy(T_INT, true, Address::times_4,  entry,
2045                                &entry_jint_arraycopy, "jint_arraycopy");
2046 
2047     StubRoutines::_oop_disjoint_arraycopy =
2048         generate_disjoint_copy(T_OBJECT, true, Address::times_ptr, &entry,
2049                                "oop_disjoint_arraycopy");
2050     StubRoutines::_oop_arraycopy =
2051         generate_conjoint_copy(T_OBJECT, true, Address::times_ptr,  entry,
2052                                &entry_oop_arraycopy, "oop_arraycopy");
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 
2061     StubRoutines::_jlong_disjoint_arraycopy =
2062         generate_disjoint_long_copy(&entry, "jlong_disjoint_arraycopy");
2063     StubRoutines::_jlong_arraycopy =
2064         generate_conjoint_long_copy(entry, &entry_jlong_arraycopy,
2065                                     "jlong_arraycopy");
2066 
2067     StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill");
2068     StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill");
2069     StubRoutines::_jint_fill = generate_fill(T_INT, false, "jint_fill");
2070     StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill");
2071     StubRoutines::_arrayof_jshort_fill = generate_fill(T_SHORT, true, "arrayof_jshort_fill");
2072     StubRoutines::_arrayof_jint_fill = generate_fill(T_INT, true, "arrayof_jint_fill");
2073 
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;
2083 
2084     StubRoutines::_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);
2088 
2089     StubRoutines::_unsafe_arraycopy =
2090         generate_unsafe_copy("unsafe_arraycopy",
2091                                entry_jbyte_arraycopy,
2092                                entry_jshort_arraycopy,
2093                                entry_jint_arraycopy,
2094                                entry_jlong_arraycopy);
2095 
2096     StubRoutines::_generic_arraycopy =
2097         generate_generic_copy("generic_arraycopy",
2098                                entry_jbyte_arraycopy,
2099                                entry_jshort_arraycopy,
2100                                entry_jint_arraycopy,
2101                                entry_oop_arraycopy,
2102                                entry_jlong_arraycopy,
2103                                entry_checkcast_arraycopy);
2104   }
2105 
2106   void generate_math_stubs() {
2107     {


src/cpu/x86/vm/stubGenerator_x86_32.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File