< prev index next >

src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp

Print this page




1131         oop_maps = generate_handle_exception(id, sasm);
1132       }
1133       break;
1134 
1135     case throw_index_exception_id:
1136       { StubFrame f(sasm, "index_range_check_failed", dont_gc_arguments);
1137         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_index_exception), true);
1138       }
1139       break;
1140 
1141     case throw_array_store_exception_id:
1142       { StubFrame f(sasm, "throw_array_store_exception", dont_gc_arguments);
1143         // tos + 0: link
1144         //     + 1: return address
1145         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true);
1146       }
1147       break;
1148 
1149 #if INCLUDE_ALL_GCS
1150 
1151 // Registers to be saved around calls to g1_wb_pre or g1_wb_post
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 


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);
1198         __ pop(G1_SAVE_REGS, sp);
1199         __ bind(done);
1200       }
1201       break;
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.
1245         // dirty card and log.
1246         __ strb(zr, Address(card_addr, offset));




1247 
1248         __ ldr(rscratch1, queue_index);
1249         __ cbz(rscratch1, runtime);
1250         __ sub(rscratch1, rscratch1, wordSize);
1251         __ str(rscratch1, queue_index);
1252 
1253         const Register buffer_addr = r0;

1254 
1255         __ push(RegSet::of(r0, r1), sp);
1256         __ ldr(buffer_addr, buffer);
1257         __ str(card_addr, Address(buffer_addr, rscratch1));
1258         __ pop(RegSet::of(r0, r1), sp);
1259         __ b(done);
1260 
1261         __ bind(runtime);
1262         __ push(G1_SAVE_REGS, sp);
1263         __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), card_addr, thread);
1264         __ pop(G1_SAVE_REGS, sp);
1265         __ bind(done);
1266 
1267       }
1268       break;
1269 #endif
1270 
1271     case predicate_failed_trap_id:
1272       {
1273         StubFrame f(sasm, "predicate_failed_trap", dont_gc_arguments);
1274 
1275         OopMap* map = save_live_registers(sasm);
1276 
1277         int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, predicate_failed_trap));
1278         oop_maps = new OopMapSet();
1279         oop_maps->add_gc_map(call_offset, map);
1280         restore_live_registers(sasm);
1281         __ leave();
1282         DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
1283         assert(deopt_blob != NULL, "deoptimization blob must have been created");
1284 


1131         oop_maps = generate_handle_exception(id, sasm);
1132       }
1133       break;
1134 
1135     case throw_index_exception_id:
1136       { StubFrame f(sasm, "index_range_check_failed", dont_gc_arguments);
1137         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_index_exception), true);
1138       }
1139       break;
1140 
1141     case throw_array_store_exception_id:
1142       { StubFrame f(sasm, "throw_array_store_exception", dont_gc_arguments);
1143         // tos + 0: link
1144         //     + 1: return address
1145         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true);
1146       }
1147       break;
1148 
1149 #if INCLUDE_ALL_GCS
1150 



1151     case g1_pre_barrier_slow_id:
1152       {
1153         StubFrame f(sasm, "g1_pre_barrier", dont_gc_arguments);
1154         // arg0 : previous value of memory
1155 
1156         BarrierSet* bs = Universe::heap()->barrier_set();
1157         if (bs->kind() != BarrierSet::G1SATBCTLogging) {
1158           __ mov(r0, (int)id);
1159           __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), r0);
1160           __ should_not_reach_here();
1161           break;
1162         }
1163 
1164         const Register pre_val = r0;
1165         const Register thread = rthread;
1166         const Register tmp = rscratch1;
1167 
1168         Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
1169                                              SATBMarkQueue::byte_offset_of_active()));
1170 


1172                                              SATBMarkQueue::byte_offset_of_index()));
1173         Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
1174                                         SATBMarkQueue::byte_offset_of_buf()));
1175 
1176         Label done;
1177         Label runtime;
1178 
1179         // Can we store original value in the thread's buffer?
1180         __ ldr(tmp, queue_index);
1181         __ cbz(tmp, runtime);
1182 
1183         __ sub(tmp, tmp, wordSize);
1184         __ str(tmp, queue_index);
1185         __ ldr(rscratch2, buffer);
1186         __ add(tmp, tmp, rscratch2);
1187         f.load_argument(0, rscratch2);
1188         __ str(rscratch2, Address(tmp, 0));
1189         __ b(done);
1190 
1191         __ bind(runtime);
1192         __ push_call_clobbered_registers();
1193         f.load_argument(0, pre_val);
1194         __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), pre_val, thread);
1195         __ pop_call_clobbered_registers();
1196         __ bind(done);
1197       }
1198       break;
1199     case g1_post_barrier_slow_id:
1200       {
1201         StubFrame f(sasm, "g1_post_barrier", dont_gc_arguments);
1202 
1203         // arg0: store_address
1204         Address store_addr(rfp, 2*BytesPerWord);
1205 
1206         BarrierSet* bs = Universe::heap()->barrier_set();
1207         CardTableModRefBS* ct = (CardTableModRefBS*)bs;
1208         assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
1209 
1210         Label done;
1211         Label runtime;
1212 
1213         // At this point we know new_value is non-NULL and the new_value crosses regions.
1214         // Must check to see if card is already dirty
1215 
1216         const Register thread = rthread;
1217 
1218         Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
1219                                              DirtyCardQueue::byte_offset_of_index()));
1220         Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
1221                                         DirtyCardQueue::byte_offset_of_buf()));
1222 
1223         const Register card_offset = rscratch2;
1224         // LR is free here, so we can use it to hold the byte_map_base.
1225         const Register byte_map_base = lr;
1226 
1227         assert_different_registers(card_offset, byte_map_base, rscratch1);
1228 
1229         f.load_argument(0, card_offset);
1230         __ lsr(card_offset, card_offset, CardTableModRefBS::card_shift);
1231         __ load_byte_map_base(byte_map_base);
1232         __ ldrb(rscratch1, Address(byte_map_base, card_offset));
1233         __ cmpw(rscratch1, (int)G1SATBCardTableModRefBS::g1_young_card_val());
1234         __ br(Assembler::EQ, done);
1235 
1236         assert((int)CardTableModRefBS::dirty_card_val() == 0, "must be 0");
1237 
1238         __ membar(Assembler::StoreLoad);
1239         __ ldrb(rscratch1, Address(byte_map_base, card_offset));
1240         __ cbzw(rscratch1, done);
1241 
1242         // storing region crossing non-NULL, card is clean.
1243         // dirty card and log.
1244         __ strb(zr, Address(byte_map_base, card_offset));
1245 
1246         // Convert card offset into an address in card_addr
1247         Register card_addr = card_offset;
1248         __ add(card_addr, byte_map_base, card_addr);
1249 
1250         __ ldr(rscratch1, queue_index);
1251         __ cbz(rscratch1, runtime);
1252         __ sub(rscratch1, rscratch1, wordSize);
1253         __ str(rscratch1, queue_index);
1254 
1255         // Reuse LR to hold buffer_addr
1256         const Register buffer_addr = lr;
1257 

1258         __ ldr(buffer_addr, buffer);
1259         __ str(card_addr, Address(buffer_addr, rscratch1));

1260         __ b(done);
1261 
1262         __ bind(runtime);
1263         __ push_call_clobbered_registers();
1264         __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), card_addr, thread);
1265         __ pop_call_clobbered_registers();
1266         __ bind(done);
1267 
1268       }
1269       break;
1270 #endif
1271 
1272     case predicate_failed_trap_id:
1273       {
1274         StubFrame f(sasm, "predicate_failed_trap", dont_gc_arguments);
1275 
1276         OopMap* map = save_live_registers(sasm);
1277 
1278         int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, predicate_failed_trap));
1279         oop_maps = new OopMapSet();
1280         oop_maps->add_gc_map(call_offset, map);
1281         restore_live_registers(sasm);
1282         __ leave();
1283         DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
1284         assert(deopt_blob != NULL, "deoptimization blob must have been created");
1285 
< prev index next >