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