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 |