Mercurial > hg > graal-compiler
comparison src/share/vm/c1/c1_LIRGenerator.cpp @ 342:37f87013dfd8
6711316: Open source the Garbage-First garbage collector
Summary: First mercurial integration of the code for the Garbage-First garbage collector.
Reviewed-by: apetrusenko, iveresov, jmasa, sgoldman, tonyp, ysr
author | ysr |
---|---|
date | Thu, 05 Jun 2008 15:57:56 -0700 |
parents | a61af66fc99e |
children | f8199438385b |
comparison
equal
deleted
inserted
replaced
189:0b27f3512f9e | 342:37f87013dfd8 |
---|---|
283 | 283 |
284 //-------------------------------------------------------------- | 284 //-------------------------------------------------------------- |
285 | 285 |
286 | 286 |
287 void LIRGenerator::init() { | 287 void LIRGenerator::init() { |
288 BarrierSet* bs = Universe::heap()->barrier_set(); | 288 _bs = Universe::heap()->barrier_set(); |
289 assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind"); | |
290 CardTableModRefBS* ct = (CardTableModRefBS*)bs; | |
291 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); | |
292 | |
293 #ifdef _LP64 | |
294 _card_table_base = new LIR_Const((jlong)ct->byte_map_base); | |
295 #else | |
296 _card_table_base = new LIR_Const((jint)ct->byte_map_base); | |
297 #endif | |
298 } | 289 } |
299 | 290 |
300 | 291 |
301 void LIRGenerator::block_do_prolog(BlockBegin* block) { | 292 void LIRGenerator::block_do_prolog(BlockBegin* block) { |
302 #ifndef PRODUCT | 293 #ifndef PRODUCT |
1237 return result; | 1228 return result; |
1238 } | 1229 } |
1239 | 1230 |
1240 // Various barriers | 1231 // Various barriers |
1241 | 1232 |
1233 void LIRGenerator::pre_barrier(LIR_Opr addr_opr, bool patch, CodeEmitInfo* info) { | |
1234 // Do the pre-write barrier, if any. | |
1235 switch (_bs->kind()) { | |
1236 #ifndef SERIALGC | |
1237 case BarrierSet::G1SATBCT: | |
1238 case BarrierSet::G1SATBCTLogging: | |
1239 G1SATBCardTableModRef_pre_barrier(addr_opr, patch, info); | |
1240 break; | |
1241 #endif // SERIALGC | |
1242 case BarrierSet::CardTableModRef: | |
1243 case BarrierSet::CardTableExtension: | |
1244 // No pre barriers | |
1245 break; | |
1246 case BarrierSet::ModRef: | |
1247 case BarrierSet::Other: | |
1248 // No pre barriers | |
1249 break; | |
1250 default : | |
1251 ShouldNotReachHere(); | |
1252 | |
1253 } | |
1254 } | |
1255 | |
1242 void LIRGenerator::post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) { | 1256 void LIRGenerator::post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) { |
1243 switch (Universe::heap()->barrier_set()->kind()) { | 1257 switch (_bs->kind()) { |
1258 #ifndef SERIALGC | |
1259 case BarrierSet::G1SATBCT: | |
1260 case BarrierSet::G1SATBCTLogging: | |
1261 G1SATBCardTableModRef_post_barrier(addr, new_val); | |
1262 break; | |
1263 #endif // SERIALGC | |
1244 case BarrierSet::CardTableModRef: | 1264 case BarrierSet::CardTableModRef: |
1245 case BarrierSet::CardTableExtension: | 1265 case BarrierSet::CardTableExtension: |
1246 CardTableModRef_post_barrier(addr, new_val); | 1266 CardTableModRef_post_barrier(addr, new_val); |
1247 break; | 1267 break; |
1248 case BarrierSet::ModRef: | 1268 case BarrierSet::ModRef: |
1252 default : | 1272 default : |
1253 ShouldNotReachHere(); | 1273 ShouldNotReachHere(); |
1254 } | 1274 } |
1255 } | 1275 } |
1256 | 1276 |
1277 //////////////////////////////////////////////////////////////////////// | |
1278 #ifndef SERIALGC | |
1279 | |
1280 void LIRGenerator::G1SATBCardTableModRef_pre_barrier(LIR_Opr addr_opr, bool patch, CodeEmitInfo* info) { | |
1281 if (G1DisablePreBarrier) return; | |
1282 | |
1283 // First we test whether marking is in progress. | |
1284 BasicType flag_type; | |
1285 if (in_bytes(PtrQueue::byte_width_of_active()) == 4) { | |
1286 flag_type = T_INT; | |
1287 } else { | |
1288 guarantee(in_bytes(PtrQueue::byte_width_of_active()) == 1, | |
1289 "Assumption"); | |
1290 flag_type = T_BYTE; | |
1291 } | |
1292 LIR_Opr thrd = getThreadPointer(); | |
1293 LIR_Address* mark_active_flag_addr = | |
1294 new LIR_Address(thrd, | |
1295 in_bytes(JavaThread::satb_mark_queue_offset() + | |
1296 PtrQueue::byte_offset_of_active()), | |
1297 flag_type); | |
1298 // Read the marking-in-progress flag. | |
1299 LIR_Opr flag_val = new_register(T_INT); | |
1300 __ load(mark_active_flag_addr, flag_val); | |
1301 | |
1302 LabelObj* start_store = new LabelObj(); | |
1303 | |
1304 LIR_PatchCode pre_val_patch_code = | |
1305 patch ? lir_patch_normal : lir_patch_none; | |
1306 | |
1307 LIR_Opr pre_val = new_register(T_OBJECT); | |
1308 | |
1309 __ cmp(lir_cond_notEqual, flag_val, LIR_OprFact::intConst(0)); | |
1310 if (!addr_opr->is_address()) { | |
1311 assert(addr_opr->is_register(), "must be"); | |
1312 addr_opr = LIR_OprFact::address(new LIR_Address(addr_opr, 0, T_OBJECT)); | |
1313 } | |
1314 CodeStub* slow = new G1PreBarrierStub(addr_opr, pre_val, pre_val_patch_code, | |
1315 info); | |
1316 __ branch(lir_cond_notEqual, T_INT, slow); | |
1317 __ branch_destination(slow->continuation()); | |
1318 } | |
1319 | |
1320 void LIRGenerator::G1SATBCardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) { | |
1321 if (G1DisablePostBarrier) return; | |
1322 | |
1323 // If the "new_val" is a constant NULL, no barrier is necessary. | |
1324 if (new_val->is_constant() && | |
1325 new_val->as_constant_ptr()->as_jobject() == NULL) return; | |
1326 | |
1327 if (!new_val->is_register()) { | |
1328 LIR_Opr new_val_reg = new_pointer_register(); | |
1329 if (new_val->is_constant()) { | |
1330 __ move(new_val, new_val_reg); | |
1331 } else { | |
1332 __ leal(new_val, new_val_reg); | |
1333 } | |
1334 new_val = new_val_reg; | |
1335 } | |
1336 assert(new_val->is_register(), "must be a register at this point"); | |
1337 | |
1338 if (addr->is_address()) { | |
1339 LIR_Address* address = addr->as_address_ptr(); | |
1340 LIR_Opr ptr = new_pointer_register(); | |
1341 if (!address->index()->is_valid() && address->disp() == 0) { | |
1342 __ move(address->base(), ptr); | |
1343 } else { | |
1344 assert(address->disp() != max_jint, "lea doesn't support patched addresses!"); | |
1345 __ leal(addr, ptr); | |
1346 } | |
1347 addr = ptr; | |
1348 } | |
1349 assert(addr->is_register(), "must be a register at this point"); | |
1350 | |
1351 LIR_Opr xor_res = new_pointer_register(); | |
1352 LIR_Opr xor_shift_res = new_pointer_register(); | |
1353 | |
1354 if (TwoOperandLIRForm ) { | |
1355 __ move(addr, xor_res); | |
1356 __ logical_xor(xor_res, new_val, xor_res); | |
1357 __ move(xor_res, xor_shift_res); | |
1358 __ unsigned_shift_right(xor_shift_res, | |
1359 LIR_OprFact::intConst(HeapRegion::LogOfHRGrainBytes), | |
1360 xor_shift_res, | |
1361 LIR_OprDesc::illegalOpr()); | |
1362 } else { | |
1363 __ logical_xor(addr, new_val, xor_res); | |
1364 __ unsigned_shift_right(xor_res, | |
1365 LIR_OprFact::intConst(HeapRegion::LogOfHRGrainBytes), | |
1366 xor_shift_res, | |
1367 LIR_OprDesc::illegalOpr()); | |
1368 } | |
1369 | |
1370 if (!new_val->is_register()) { | |
1371 LIR_Opr new_val_reg = new_pointer_register(); | |
1372 __ leal(new_val, new_val_reg); | |
1373 new_val = new_val_reg; | |
1374 } | |
1375 assert(new_val->is_register(), "must be a register at this point"); | |
1376 | |
1377 __ cmp(lir_cond_notEqual, xor_shift_res, LIR_OprFact::intptrConst(NULL_WORD)); | |
1378 | |
1379 CodeStub* slow = new G1PostBarrierStub(addr, new_val); | |
1380 __ branch(lir_cond_notEqual, T_INT, slow); | |
1381 __ branch_destination(slow->continuation()); | |
1382 } | |
1383 | |
1384 #endif // SERIALGC | |
1385 //////////////////////////////////////////////////////////////////////// | |
1386 | |
1257 void LIRGenerator::CardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) { | 1387 void LIRGenerator::CardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) { |
1258 | 1388 |
1259 BarrierSet* bs = Universe::heap()->barrier_set(); | 1389 assert(sizeof(*((CardTableModRefBS*)_bs)->byte_map_base) == sizeof(jbyte), "adjust this code"); |
1260 assert(sizeof(*((CardTableModRefBS*)bs)->byte_map_base) == sizeof(jbyte), "adjust this code"); | 1390 LIR_Const* card_table_base = new LIR_Const(((CardTableModRefBS*)_bs)->byte_map_base); |
1261 LIR_Const* card_table_base = new LIR_Const(((CardTableModRefBS*)bs)->byte_map_base); | |
1262 if (addr->is_address()) { | 1391 if (addr->is_address()) { |
1263 LIR_Address* address = addr->as_address_ptr(); | 1392 LIR_Address* address = addr->as_address_ptr(); |
1264 LIR_Opr ptr = new_register(T_OBJECT); | 1393 LIR_Opr ptr = new_register(T_OBJECT); |
1265 if (!address->index()->is_valid() && address->disp() == 0) { | 1394 if (!address->index()->is_valid() && address->disp() == 0) { |
1266 __ move(address->base(), ptr); | 1395 __ move(address->base(), ptr); |
1386 | 1515 |
1387 if (is_volatile && os::is_MP()) { | 1516 if (is_volatile && os::is_MP()) { |
1388 __ membar_release(); | 1517 __ membar_release(); |
1389 } | 1518 } |
1390 | 1519 |
1520 if (is_oop) { | |
1521 // Do the pre-write barrier, if any. | |
1522 pre_barrier(LIR_OprFact::address(address), | |
1523 needs_patching, | |
1524 (info ? new CodeEmitInfo(info) : NULL)); | |
1525 } | |
1526 | |
1391 if (is_volatile) { | 1527 if (is_volatile) { |
1392 assert(!needs_patching && x->is_loaded(), | 1528 assert(!needs_patching && x->is_loaded(), |
1393 "how do we know it's volatile if it's not loaded"); | 1529 "how do we know it's volatile if it's not loaded"); |
1394 volatile_field_store(value.result(), address, info); | 1530 volatile_field_store(value.result(), address, info); |
1395 } else { | 1531 } else { |
1396 LIR_PatchCode patch_code = needs_patching ? lir_patch_normal : lir_patch_none; | 1532 LIR_PatchCode patch_code = needs_patching ? lir_patch_normal : lir_patch_none; |
1397 __ store(value.result(), address, info, patch_code); | 1533 __ store(value.result(), address, info, patch_code); |
1398 } | 1534 } |
1399 | 1535 |
1400 if (is_oop) { | 1536 if (is_oop) { |
1537 #ifdef PRECISE_CARDMARK | |
1538 // Precise cardmarks don't work | |
1539 post_barrier(LIR_OprFact::address(address), value.result()); | |
1540 #else | |
1401 post_barrier(object.result(), value.result()); | 1541 post_barrier(object.result(), value.result()); |
1542 #endif // PRECISE_CARDMARK | |
1402 } | 1543 } |
1403 | 1544 |
1404 if (is_volatile && os::is_MP()) { | 1545 if (is_volatile && os::is_MP()) { |
1405 __ membar(); | 1546 __ membar(); |
1406 } | 1547 } |