1152 #define G1_SAVE_REGS (RegSet::range(r0, r18) - RegSet::of(rscratch1, rscratch2))
1153
1154 case g1_pre_barrier_slow_id:
1155 {
1156 StubFrame f(sasm, "g1_pre_barrier", dont_gc_arguments);
1157 // arg0 : previous value of memory
1158
1159 BarrierSet* bs = Universe::heap()->barrier_set();
1160 if (bs->kind() != BarrierSet::G1SATBCTLogging) {
1161 __ mov(r0, (int)id);
1162 __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), r0);
1163 __ should_not_reach_here();
1164 break;
1165 }
1166
1167 const Register pre_val = r0;
1168 const Register thread = rthread;
1169 const Register tmp = rscratch1;
1170
1171 Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
1172 PtrQueue::byte_offset_of_active()));
1173
1174 Address queue_index(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
1175 PtrQueue::byte_offset_of_index()));
1176 Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
1177 PtrQueue::byte_offset_of_buf()));
1178
1179 Label done;
1180 Label runtime;
1181
1182 // Can we store original value in the thread's buffer?
1183 __ ldr(tmp, queue_index);
1184 __ cbz(tmp, runtime);
1185
1186 __ sub(tmp, tmp, wordSize);
1187 __ str(tmp, queue_index);
1188 __ ldr(rscratch2, buffer);
1189 __ add(tmp, tmp, rscratch2);
1190 f.load_argument(0, rscratch2);
1191 __ str(rscratch2, Address(tmp, 0));
1192 __ b(done);
1193
1194 __ bind(runtime);
1195 __ push(G1_SAVE_REGS, sp);
1196 f.load_argument(0, pre_val);
1197 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), pre_val, thread);
1202 case g1_post_barrier_slow_id:
1203 {
1204 StubFrame f(sasm, "g1_post_barrier", dont_gc_arguments);
1205
1206 // arg0: store_address
1207 Address store_addr(rfp, 2*BytesPerWord);
1208
1209 BarrierSet* bs = Universe::heap()->barrier_set();
1210 CardTableModRefBS* ct = (CardTableModRefBS*)bs;
1211 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
1212
1213 Label done;
1214 Label runtime;
1215
1216 // At this point we know new_value is non-NULL and the new_value crosses regions.
1217 // Must check to see if card is already dirty
1218
1219 const Register thread = rthread;
1220
1221 Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
1222 PtrQueue::byte_offset_of_index()));
1223 Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
1224 PtrQueue::byte_offset_of_buf()));
1225
1226 const Register card_addr = rscratch2;
1227 ExternalAddress cardtable((address) ct->byte_map_base);
1228
1229 f.load_argument(0, card_addr);
1230 __ lsr(card_addr, card_addr, CardTableModRefBS::card_shift);
1231 unsigned long offset;
1232 __ adrp(rscratch1, cardtable, offset);
1233 __ add(card_addr, card_addr, rscratch1);
1234 __ ldrb(rscratch1, Address(card_addr, offset));
1235 __ cmpw(rscratch1, (int)G1SATBCardTableModRefBS::g1_young_card_val());
1236 __ br(Assembler::EQ, done);
1237
1238 assert((int)CardTableModRefBS::dirty_card_val() == 0, "must be 0");
1239
1240 __ membar(Assembler::StoreLoad);
1241 __ ldrb(rscratch1, Address(card_addr, offset));
1242 __ cbzw(rscratch1, done);
1243
1244 // storing region crossing non-NULL, card is clean.
|
1152 #define G1_SAVE_REGS (RegSet::range(r0, r18) - RegSet::of(rscratch1, rscratch2))
1153
1154 case g1_pre_barrier_slow_id:
1155 {
1156 StubFrame f(sasm, "g1_pre_barrier", dont_gc_arguments);
1157 // arg0 : previous value of memory
1158
1159 BarrierSet* bs = Universe::heap()->barrier_set();
1160 if (bs->kind() != BarrierSet::G1SATBCTLogging) {
1161 __ mov(r0, (int)id);
1162 __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), r0);
1163 __ should_not_reach_here();
1164 break;
1165 }
1166
1167 const Register pre_val = r0;
1168 const Register thread = rthread;
1169 const Register tmp = rscratch1;
1170
1171 Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
1172 SATBMarkQueue::byte_offset_of_active()));
1173
1174 Address queue_index(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
1175 SATBMarkQueue::byte_offset_of_index()));
1176 Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
1177 SATBMarkQueue::byte_offset_of_buf()));
1178
1179 Label done;
1180 Label runtime;
1181
1182 // Can we store original value in the thread's buffer?
1183 __ ldr(tmp, queue_index);
1184 __ cbz(tmp, runtime);
1185
1186 __ sub(tmp, tmp, wordSize);
1187 __ str(tmp, queue_index);
1188 __ ldr(rscratch2, buffer);
1189 __ add(tmp, tmp, rscratch2);
1190 f.load_argument(0, rscratch2);
1191 __ str(rscratch2, Address(tmp, 0));
1192 __ b(done);
1193
1194 __ bind(runtime);
1195 __ push(G1_SAVE_REGS, sp);
1196 f.load_argument(0, pre_val);
1197 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), pre_val, thread);
1202 case g1_post_barrier_slow_id:
1203 {
1204 StubFrame f(sasm, "g1_post_barrier", dont_gc_arguments);
1205
1206 // arg0: store_address
1207 Address store_addr(rfp, 2*BytesPerWord);
1208
1209 BarrierSet* bs = Universe::heap()->barrier_set();
1210 CardTableModRefBS* ct = (CardTableModRefBS*)bs;
1211 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
1212
1213 Label done;
1214 Label runtime;
1215
1216 // At this point we know new_value is non-NULL and the new_value crosses regions.
1217 // Must check to see if card is already dirty
1218
1219 const Register thread = rthread;
1220
1221 Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
1222 DirtyCardQueue::byte_offset_of_index()));
1223 Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
1224 DirtyCardQueue::byte_offset_of_buf()));
1225
1226 const Register card_addr = rscratch2;
1227 ExternalAddress cardtable((address) ct->byte_map_base);
1228
1229 f.load_argument(0, card_addr);
1230 __ lsr(card_addr, card_addr, CardTableModRefBS::card_shift);
1231 unsigned long offset;
1232 __ adrp(rscratch1, cardtable, offset);
1233 __ add(card_addr, card_addr, rscratch1);
1234 __ ldrb(rscratch1, Address(card_addr, offset));
1235 __ cmpw(rscratch1, (int)G1SATBCardTableModRefBS::g1_young_card_val());
1236 __ br(Assembler::EQ, done);
1237
1238 assert((int)CardTableModRefBS::dirty_card_val() == 0, "must be 0");
1239
1240 __ membar(Assembler::StoreLoad);
1241 __ ldrb(rscratch1, Address(card_addr, offset));
1242 __ cbzw(rscratch1, done);
1243
1244 // storing region crossing non-NULL, card is clean.
|