1178 }
1179
1180 void restore_arg_regs() {
1181 const Register saved_rdi = r9;
1182 const Register saved_rsi = r10;
1183 #ifdef _WIN64
1184 __ movptr(rdi, saved_rdi);
1185 __ movptr(rsi, saved_rsi);
1186 #endif
1187 }
1188
1189 // Generate code for an array write pre barrier
1190 //
1191 // addr - starting address
1192 // count - element count
1193 // tmp - scratch register
1194 //
1195 // Destroy no registers!
1196 //
1197 void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
1198 BarrierSet* bs = Universe::heap()->barrier_set();
1199 switch (bs->kind()) {
1200 case BarrierSet::G1SATBCTLogging:
1201 // With G1, don't generate the call if we statically know that the target in uninitialized
1202 if (!dest_uninitialized) {
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 }
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();
1243 switch (bs->kind()) {
1244 case BarrierSet::G1SATBCTLogging:
1245 {
1246 __ pusha(); // push registers (overkill)
1247 if (c_rarg0 == count) { // On win64 c_rarg0 == rcx
1248 assert_different_registers(c_rarg1, start);
1249 __ mov(c_rarg1, count);
1250 __ mov(c_rarg0, start);
1251 } else {
1252 assert_different_registers(c_rarg0, count);
1253 __ mov(c_rarg0, start);
1254 __ mov(c_rarg1, count);
1255 }
1256 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), 2);
1257 __ popa();
1258 }
1259 break;
1260 case BarrierSet::CardTableForRS:
1261 case BarrierSet::CardTableExtension:
1262 {
|
1178 }
1179
1180 void restore_arg_regs() {
1181 const Register saved_rdi = r9;
1182 const Register saved_rsi = r10;
1183 #ifdef _WIN64
1184 __ movptr(rdi, saved_rdi);
1185 __ movptr(rsi, saved_rsi);
1186 #endif
1187 }
1188
1189 // Generate code for an array write pre barrier
1190 //
1191 // addr - starting address
1192 // count - element count
1193 // tmp - scratch register
1194 //
1195 // Destroy no registers!
1196 //
1197 void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
1198 BarrierSet* bs = GC::gc()->heap()->barrier_set();
1199 switch (bs->kind()) {
1200 case BarrierSet::G1SATBCTLogging:
1201 // With G1, don't generate the call if we statically know that the target in uninitialized
1202 if (!dest_uninitialized) {
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 }
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 = GC::gc()->heap()->barrier_set();
1243 switch (bs->kind()) {
1244 case BarrierSet::G1SATBCTLogging:
1245 {
1246 __ pusha(); // push registers (overkill)
1247 if (c_rarg0 == count) { // On win64 c_rarg0 == rcx
1248 assert_different_registers(c_rarg1, start);
1249 __ mov(c_rarg1, count);
1250 __ mov(c_rarg0, start);
1251 } else {
1252 assert_different_registers(c_rarg0, count);
1253 __ mov(c_rarg0, start);
1254 __ mov(c_rarg1, count);
1255 }
1256 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), 2);
1257 __ popa();
1258 }
1259 break;
1260 case BarrierSet::CardTableForRS:
1261 case BarrierSet::CardTableExtension:
1262 {
|