1203 __ pusha(); // push registers
1204 if (count == c_rarg0) {
1205 if (addr == c_rarg1) {
1206 // exactly backwards!!
1207 __ xchgptr(c_rarg1, c_rarg0);
1208 } else {
1209 __ movptr(c_rarg1, count);
1210 __ movptr(c_rarg0, addr);
1211 }
1212 } else {
1213 __ movptr(c_rarg0, addr);
1214 __ movptr(c_rarg1, count);
1215 }
1216 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 2);
1217 __ popa();
1218 }
1219 break;
1220 case BarrierSet::CardTableForRS:
1221 case BarrierSet::CardTableExtension:
1222 case BarrierSet::ModRef:
1223 break;
1224 default:
1225 ShouldNotReachHere();
1226
1227 }
1228 }
1229
1230 //
1231 // Generate code for an array write post barrier
1232 //
1233 // Input:
1234 // start - register containing starting address of destination array
1235 // count - elements count
1236 // scratch - scratch register
1237 //
1238 // The input registers are overwritten.
1239 //
1240 void gen_write_ref_array_post_barrier(Register start, Register count, Register scratch) {
1241 assert_different_registers(start, count, scratch);
1242 BarrierSet* bs = Universe::heap()->barrier_set();
1263 CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(bs);
1264 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
1265
1266 Label L_loop;
1267 const Register end = count;
1268
1269 __ leaq(end, Address(start, count, TIMES_OOP, 0)); // end == start+count*oop_size
1270 __ subptr(end, BytesPerHeapOop); // end - 1 to make inclusive
1271 __ shrptr(start, CardTableModRefBS::card_shift);
1272 __ shrptr(end, CardTableModRefBS::card_shift);
1273 __ subptr(end, start); // end --> cards count
1274
1275 int64_t disp = (int64_t) ct->byte_map_base;
1276 __ mov64(scratch, disp);
1277 __ addptr(start, scratch);
1278 __ BIND(L_loop);
1279 __ movb(Address(start, count, Address::times_1), 0);
1280 __ decrement(count);
1281 __ jcc(Assembler::greaterEqual, L_loop);
1282 }
1283 break;
1284 default:
1285 ShouldNotReachHere();
1286
1287 }
1288 }
1289
1290
1291 // Copy big chunks forward
1292 //
1293 // Inputs:
1294 // end_from - source arrays end address
1295 // end_to - destination array end address
1296 // qword_count - 64-bits element count, negative
1297 // to - scratch
1298 // L_copy_bytes - entry label
1299 // L_copy_8_bytes - exit label
1300 //
1301 void copy_bytes_forward(Register end_from, Register end_to,
1302 Register qword_count, Register to,
|
1203 __ pusha(); // push registers
1204 if (count == c_rarg0) {
1205 if (addr == c_rarg1) {
1206 // exactly backwards!!
1207 __ xchgptr(c_rarg1, c_rarg0);
1208 } else {
1209 __ movptr(c_rarg1, count);
1210 __ movptr(c_rarg0, addr);
1211 }
1212 } else {
1213 __ movptr(c_rarg0, addr);
1214 __ movptr(c_rarg1, count);
1215 }
1216 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 2);
1217 __ popa();
1218 }
1219 break;
1220 case BarrierSet::CardTableForRS:
1221 case BarrierSet::CardTableExtension:
1222 case BarrierSet::ModRef:
1223 case BarrierSet::Epsilon:
1224 break;
1225 default:
1226 ShouldNotReachHere();
1227
1228 }
1229 }
1230
1231 //
1232 // Generate code for an array write post barrier
1233 //
1234 // Input:
1235 // start - register containing starting address of destination array
1236 // count - elements count
1237 // scratch - scratch register
1238 //
1239 // The input registers are overwritten.
1240 //
1241 void gen_write_ref_array_post_barrier(Register start, Register count, Register scratch) {
1242 assert_different_registers(start, count, scratch);
1243 BarrierSet* bs = Universe::heap()->barrier_set();
1264 CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(bs);
1265 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
1266
1267 Label L_loop;
1268 const Register end = count;
1269
1270 __ leaq(end, Address(start, count, TIMES_OOP, 0)); // end == start+count*oop_size
1271 __ subptr(end, BytesPerHeapOop); // end - 1 to make inclusive
1272 __ shrptr(start, CardTableModRefBS::card_shift);
1273 __ shrptr(end, CardTableModRefBS::card_shift);
1274 __ subptr(end, start); // end --> cards count
1275
1276 int64_t disp = (int64_t) ct->byte_map_base;
1277 __ mov64(scratch, disp);
1278 __ addptr(start, scratch);
1279 __ BIND(L_loop);
1280 __ movb(Address(start, count, Address::times_1), 0);
1281 __ decrement(count);
1282 __ jcc(Assembler::greaterEqual, L_loop);
1283 }
1284 break;
1285 case BarrierSet::Epsilon:
1286 // TODO: why are we here at all?
1287 break;
1288 default:
1289 ShouldNotReachHere();
1290
1291 }
1292 }
1293
1294
1295 // Copy big chunks forward
1296 //
1297 // Inputs:
1298 // end_from - source arrays end address
1299 // end_to - destination array end address
1300 // qword_count - 64-bits element count, negative
1301 // to - scratch
1302 // L_copy_bytes - entry label
1303 // L_copy_8_bytes - exit label
1304 //
1305 void copy_bytes_forward(Register end_from, Register end_to,
1306 Register qword_count, Register to,
|