Mercurial > hg > graal-jvmci-8
comparison src/cpu/x86/vm/stubGenerator_x86_32.cpp @ 2313:d89a22843c62
7020521: arraycopy stubs place prebarriers incorrectly
Summary: Rearranged the pre-barrier placement in arraycopy stubs so that they are properly called in case of chained calls. Also refactored the code a little bit so that it looks uniform across the platforms and is more readable.
Reviewed-by: never, kvn
author | iveresov |
---|---|
date | Tue, 22 Feb 2011 15:25:02 -0800 |
parents | 638119ce7cfd |
children | 1b4e6a5d98e0 |
comparison
equal
deleted
inserted
replaced
2262:6bbaedb03534 | 2313:d89a22843c62 |
---|---|
943 __ push(rsi); | 943 __ push(rsi); |
944 __ push(rdi); | 944 __ push(rdi); |
945 __ movptr(from , Address(rsp, 12+ 4)); | 945 __ movptr(from , Address(rsp, 12+ 4)); |
946 __ movptr(to , Address(rsp, 12+ 8)); | 946 __ movptr(to , Address(rsp, 12+ 8)); |
947 __ movl(count, Address(rsp, 12+ 12)); | 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 | |
948 if (t == T_OBJECT) { | 954 if (t == T_OBJECT) { |
949 __ testl(count, count); | 955 __ testl(count, count); |
950 __ jcc(Assembler::zero, L_0_count); | 956 __ jcc(Assembler::zero, L_0_count); |
951 gen_write_ref_array_pre_barrier(to, count); | 957 gen_write_ref_array_pre_barrier(to, count); |
952 __ mov(saved_to, to); // save 'to' | 958 __ mov(saved_to, to); // save 'to' |
953 } | 959 } |
954 | |
955 *entry = __ pc(); // Entry point from conjoint arraycopy stub. | |
956 BLOCK_COMMENT("Entry:"); | |
957 | 960 |
958 __ subptr(to, from); // to --> to_from | 961 __ subptr(to, from); // to --> to_from |
959 __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element | 962 __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element |
960 __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp | 963 __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp |
961 if (!UseUnalignedLoadStores && !aligned && (t == T_BYTE || t == T_SHORT)) { | 964 if (!UseUnalignedLoadStores && !aligned && (t == T_BYTE || t == T_SHORT)) { |
1106 __ push(rsi); | 1109 __ push(rsi); |
1107 __ push(rdi); | 1110 __ push(rdi); |
1108 __ movptr(src , Address(rsp, 12+ 4)); // from | 1111 __ movptr(src , Address(rsp, 12+ 4)); // from |
1109 __ movptr(dst , Address(rsp, 12+ 8)); // to | 1112 __ movptr(dst , Address(rsp, 12+ 8)); // to |
1110 __ movl2ptr(count, Address(rsp, 12+12)); // count | 1113 __ movl2ptr(count, Address(rsp, 12+12)); // count |
1111 if (t == T_OBJECT) { | |
1112 gen_write_ref_array_pre_barrier(dst, count); | |
1113 } | |
1114 | 1114 |
1115 if (entry != NULL) { | 1115 if (entry != NULL) { |
1116 *entry = __ pc(); // Entry point from generic arraycopy stub. | 1116 *entry = __ pc(); // Entry point from generic arraycopy stub. |
1117 BLOCK_COMMENT("Entry:"); | 1117 BLOCK_COMMENT("Entry:"); |
1118 } | 1118 } |
1119 | 1119 |
1120 if (t == T_OBJECT) { | 1120 // nooverlap_target expects arguments in rsi and rdi. |
1121 __ testl(count, count); | |
1122 __ jcc(Assembler::zero, L_0_count); | |
1123 } | |
1124 __ mov(from, src); | 1121 __ mov(from, src); |
1125 __ mov(to , dst); | 1122 __ mov(to , dst); |
1126 | 1123 |
1127 // arrays overlap test | 1124 // arrays overlap test: dispatch to disjoint stub if necessary. |
1128 RuntimeAddress nooverlap(nooverlap_target); | 1125 RuntimeAddress nooverlap(nooverlap_target); |
1129 __ cmpptr(dst, src); | 1126 __ cmpptr(dst, src); |
1130 __ lea(end, Address(src, count, sf, 0)); // src + count * elem_size | 1127 __ lea(end, Address(src, count, sf, 0)); // src + count * elem_size |
1131 __ jump_cc(Assembler::belowEqual, nooverlap); | 1128 __ jump_cc(Assembler::belowEqual, nooverlap); |
1132 __ cmpptr(dst, end); | 1129 __ cmpptr(dst, end); |
1133 __ jump_cc(Assembler::aboveEqual, nooverlap); | 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 } | |
1134 | 1137 |
1135 // copy from high to low | 1138 // copy from high to low |
1136 __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element | 1139 __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element |
1137 __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp | 1140 __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp |
1138 if (t == T_BYTE || t == T_SHORT) { | 1141 if (t == T_BYTE || t == T_SHORT) { |
1449 // Load up: | 1452 // Load up: |
1450 __ movptr(from, from_arg); | 1453 __ movptr(from, from_arg); |
1451 __ movptr(to, to_arg); | 1454 __ movptr(to, to_arg); |
1452 __ movl2ptr(length, length_arg); | 1455 __ movl2ptr(length, length_arg); |
1453 | 1456 |
1454 *entry = __ pc(); // Entry point from generic arraycopy stub. | 1457 if (entry != NULL) { |
1455 BLOCK_COMMENT("Entry:"); | 1458 *entry = __ pc(); // Entry point from generic arraycopy stub. |
1459 BLOCK_COMMENT("Entry:"); | |
1460 } | |
1456 | 1461 |
1457 //--------------------------------------------------------------- | 1462 //--------------------------------------------------------------- |
1458 // Assembler stub will be used for this call to arraycopy | 1463 // Assembler stub will be used for this call to arraycopy |
1459 // if the two arrays are subtypes of Object[] but the | 1464 // if the two arrays are subtypes of Object[] but the |
1460 // destination array type is not equal to or a supertype | 1465 // destination array type is not equal to or a supertype |