1 /*
2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
1190 void restore_arg_regs() {
1191 const Register saved_rdi = r9;
1192 const Register saved_rsi = r10;
1193 #ifdef _WIN64
1194 __ movptr(rdi, saved_rdi);
1195 __ movptr(rsi, saved_rsi);
1196 #endif
1197 }
1198
1199 // Generate code for an array write pre barrier
1200 //
1201 // addr - starting address
1202 // count - element count
1203 // tmp - scratch register
1204 //
1205 // Destroy no registers!
1206 //
1207 void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
1208 BarrierSet* bs = Universe::heap()->barrier_set();
1209 switch (bs->kind()) {
1210 case BarrierSet::G1SATBCT:
1211 case BarrierSet::G1SATBCTLogging:
1212 // With G1, don't generate the call if we statically know that the target in uninitialized
1213 if (!dest_uninitialized) {
1214 __ pusha(); // push registers
1215 if (count == c_rarg0) {
1216 if (addr == c_rarg1) {
1217 // exactly backwards!!
1218 __ xchgptr(c_rarg1, c_rarg0);
1219 } else {
1220 __ movptr(c_rarg1, count);
1221 __ movptr(c_rarg0, addr);
1222 }
1223 } else {
1224 __ movptr(c_rarg0, addr);
1225 __ movptr(c_rarg1, count);
1226 }
1227 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 2);
1228 __ popa();
1229 }
1230 break;
1235 default:
1236 ShouldNotReachHere();
1237
1238 }
1239 }
1240
1241 //
1242 // Generate code for an array write post barrier
1243 //
1244 // Input:
1245 // start - register containing starting address of destination array
1246 // count - elements count
1247 // scratch - scratch register
1248 //
1249 // The input registers are overwritten.
1250 //
1251 void gen_write_ref_array_post_barrier(Register start, Register count, Register scratch) {
1252 assert_different_registers(start, count, scratch);
1253 BarrierSet* bs = Universe::heap()->barrier_set();
1254 switch (bs->kind()) {
1255 case BarrierSet::G1SATBCT:
1256 case BarrierSet::G1SATBCTLogging:
1257 {
1258 __ pusha(); // push registers (overkill)
1259 if (c_rarg0 == count) { // On win64 c_rarg0 == rcx
1260 assert_different_registers(c_rarg1, start);
1261 __ mov(c_rarg1, count);
1262 __ mov(c_rarg0, start);
1263 } else {
1264 assert_different_registers(c_rarg0, count);
1265 __ mov(c_rarg0, start);
1266 __ mov(c_rarg1, count);
1267 }
1268 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), 2);
1269 __ popa();
1270 }
1271 break;
1272 case BarrierSet::CardTableModRef:
1273 case BarrierSet::CardTableExtension:
1274 {
1275 CardTableModRefBS* ct = (CardTableModRefBS*)bs;
|
1 /*
2 * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
1190 void restore_arg_regs() {
1191 const Register saved_rdi = r9;
1192 const Register saved_rsi = r10;
1193 #ifdef _WIN64
1194 __ movptr(rdi, saved_rdi);
1195 __ movptr(rsi, saved_rsi);
1196 #endif
1197 }
1198
1199 // Generate code for an array write pre barrier
1200 //
1201 // addr - starting address
1202 // count - element count
1203 // tmp - scratch register
1204 //
1205 // Destroy no registers!
1206 //
1207 void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
1208 BarrierSet* bs = Universe::heap()->barrier_set();
1209 switch (bs->kind()) {
1210 case BarrierSet::G1SATBCTLogging:
1211 // With G1, don't generate the call if we statically know that the target in uninitialized
1212 if (!dest_uninitialized) {
1213 __ pusha(); // push registers
1214 if (count == c_rarg0) {
1215 if (addr == c_rarg1) {
1216 // exactly backwards!!
1217 __ xchgptr(c_rarg1, c_rarg0);
1218 } else {
1219 __ movptr(c_rarg1, count);
1220 __ movptr(c_rarg0, addr);
1221 }
1222 } else {
1223 __ movptr(c_rarg0, addr);
1224 __ movptr(c_rarg1, count);
1225 }
1226 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 2);
1227 __ popa();
1228 }
1229 break;
1234 default:
1235 ShouldNotReachHere();
1236
1237 }
1238 }
1239
1240 //
1241 // Generate code for an array write post barrier
1242 //
1243 // Input:
1244 // start - register containing starting address of destination array
1245 // count - elements count
1246 // scratch - scratch register
1247 //
1248 // The input registers are overwritten.
1249 //
1250 void gen_write_ref_array_post_barrier(Register start, Register count, Register scratch) {
1251 assert_different_registers(start, count, scratch);
1252 BarrierSet* bs = Universe::heap()->barrier_set();
1253 switch (bs->kind()) {
1254 case BarrierSet::G1SATBCTLogging:
1255 {
1256 __ pusha(); // push registers (overkill)
1257 if (c_rarg0 == count) { // On win64 c_rarg0 == rcx
1258 assert_different_registers(c_rarg1, start);
1259 __ mov(c_rarg1, count);
1260 __ mov(c_rarg0, start);
1261 } else {
1262 assert_different_registers(c_rarg0, count);
1263 __ mov(c_rarg0, start);
1264 __ mov(c_rarg1, count);
1265 }
1266 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), 2);
1267 __ popa();
1268 }
1269 break;
1270 case BarrierSet::CardTableModRef:
1271 case BarrierSet::CardTableExtension:
1272 {
1273 CardTableModRefBS* ct = (CardTableModRefBS*)bs;
|