comparison src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp @ 1145:e018e6884bd8

6631166: CMS: better heuristics when combatting fragmentation Summary: Autonomic per-worker free block cache sizing, tunable coalition policies, fixes to per-size block statistics, retuned gain and bandwidth of some feedback loop filters to allow quicker reactivity to abrupt changes in ambient demand, and other heuristics to reduce fragmentation of the CMS old gen. Also tightened some assertions, including those related to locking. Reviewed-by: jmasa
author ysr
date Wed, 23 Dec 2009 09:23:54 -0800
parents 0fbdb4381b99
children 05b775309e59
comparison
equal deleted inserted replaced
1111:44f61c24ddab 1145:e018e6884bd8
60 // possible alternative dictionary implementations to use. For 60 // possible alternative dictionary implementations to use. For
61 // now the choice is easy, since we have only one working 61 // now the choice is easy, since we have only one working
62 // implementation, namely, the simple binary tree (splaying 62 // implementation, namely, the simple binary tree (splaying
63 // temporarily disabled). 63 // temporarily disabled).
64 switch (dictionaryChoice) { 64 switch (dictionaryChoice) {
65 case FreeBlockDictionary::dictionaryBinaryTree:
66 _dictionary = new BinaryTreeDictionary(mr);
67 break;
68 case FreeBlockDictionary::dictionarySplayTree: 65 case FreeBlockDictionary::dictionarySplayTree:
69 case FreeBlockDictionary::dictionarySkipList: 66 case FreeBlockDictionary::dictionarySkipList:
70 default: 67 default:
71 warning("dictionaryChoice: selected option not understood; using" 68 warning("dictionaryChoice: selected option not understood; using"
72 " default BinaryTreeDictionary implementation instead."); 69 " default BinaryTreeDictionary implementation instead.");
70 case FreeBlockDictionary::dictionaryBinaryTree:
73 _dictionary = new BinaryTreeDictionary(mr); 71 _dictionary = new BinaryTreeDictionary(mr);
74 break; 72 break;
75 } 73 }
76 splitBirth(mr.word_size());
77 assert(_dictionary != NULL, "CMS dictionary initialization"); 74 assert(_dictionary != NULL, "CMS dictionary initialization");
78 // The indexed free lists are initially all empty and are lazily 75 // The indexed free lists are initially all empty and are lazily
79 // filled in on demand. Initialize the array elements to NULL. 76 // filled in on demand. Initialize the array elements to NULL.
80 initializeIndexedFreeListArray(); 77 initializeIndexedFreeListArray();
81 78
386 } 383 }
387 } 384 }
388 return res; 385 return res;
389 } 386 }
390 387
388 void CompactibleFreeListSpace::print_indexed_free_lists(outputStream* st)
389 const {
390 reportIndexedFreeListStatistics();
391 gclog_or_tty->print_cr("Layout of Indexed Freelists");
392 gclog_or_tty->print_cr("---------------------------");
393 FreeList::print_labels_on(st, "size");
394 for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
395 _indexedFreeList[i].print_on(gclog_or_tty);
396 for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL;
397 fc = fc->next()) {
398 gclog_or_tty->print_cr("\t[" PTR_FORMAT "," PTR_FORMAT ") %s",
399 fc, (HeapWord*)fc + i,
400 fc->cantCoalesce() ? "\t CC" : "");
401 }
402 }
403 }
404
405 void CompactibleFreeListSpace::print_promo_info_blocks(outputStream* st)
406 const {
407 _promoInfo.print_on(st);
408 }
409
410 void CompactibleFreeListSpace::print_dictionary_free_lists(outputStream* st)
411 const {
412 _dictionary->reportStatistics();
413 st->print_cr("Layout of Freelists in Tree");
414 st->print_cr("---------------------------");
415 _dictionary->print_free_lists(st);
416 }
417
418 class BlkPrintingClosure: public BlkClosure {
419 const CMSCollector* _collector;
420 const CompactibleFreeListSpace* _sp;
421 const CMSBitMap* _live_bit_map;
422 const bool _post_remark;
423 outputStream* _st;
424 public:
425 BlkPrintingClosure(const CMSCollector* collector,
426 const CompactibleFreeListSpace* sp,
427 const CMSBitMap* live_bit_map,
428 outputStream* st):
429 _collector(collector),
430 _sp(sp),
431 _live_bit_map(live_bit_map),
432 _post_remark(collector->abstract_state() > CMSCollector::FinalMarking),
433 _st(st) { }
434 size_t do_blk(HeapWord* addr);
435 };
436
437 size_t BlkPrintingClosure::do_blk(HeapWord* addr) {
438 size_t sz = _sp->block_size_no_stall(addr, _collector);
439 assert(sz != 0, "Should always be able to compute a size");
440 if (_sp->block_is_obj(addr)) {
441 const bool dead = _post_remark && !_live_bit_map->isMarked(addr);
442 _st->print_cr(PTR_FORMAT ": %s object of size " SIZE_FORMAT "%s",
443 addr,
444 dead ? "dead" : "live",
445 sz,
446 (!dead && CMSPrintObjectsInDump) ? ":" : ".");
447 if (CMSPrintObjectsInDump && !dead) {
448 oop(addr)->print_on(_st);
449 _st->print_cr("--------------------------------------");
450 }
451 } else { // free block
452 _st->print_cr(PTR_FORMAT ": free block of size " SIZE_FORMAT "%s",
453 addr, sz, CMSPrintChunksInDump ? ":" : ".");
454 if (CMSPrintChunksInDump) {
455 ((FreeChunk*)addr)->print_on(_st);
456 _st->print_cr("--------------------------------------");
457 }
458 }
459 return sz;
460 }
461
462 void CompactibleFreeListSpace::dump_at_safepoint_with_locks(CMSCollector* c,
463 outputStream* st) {
464 st->print_cr("\n=========================");
465 st->print_cr("Block layout in CMS Heap:");
466 st->print_cr("=========================");
467 BlkPrintingClosure bpcl(c, this, c->markBitMap(), st);
468 blk_iterate(&bpcl);
469
470 st->print_cr("\n=======================================");
471 st->print_cr("Order & Layout of Promotion Info Blocks");
472 st->print_cr("=======================================");
473 print_promo_info_blocks(st);
474
475 st->print_cr("\n===========================");
476 st->print_cr("Order of Indexed Free Lists");
477 st->print_cr("=========================");
478 print_indexed_free_lists(st);
479
480 st->print_cr("\n=================================");
481 st->print_cr("Order of Free Lists in Dictionary");
482 st->print_cr("=================================");
483 print_dictionary_free_lists(st);
484 }
485
486
391 void CompactibleFreeListSpace::reportFreeListStatistics() const { 487 void CompactibleFreeListSpace::reportFreeListStatistics() const {
392 assert_lock_strong(&_freelistLock); 488 assert_lock_strong(&_freelistLock);
393 assert(PrintFLSStatistics != 0, "Reporting error"); 489 assert(PrintFLSStatistics != 0, "Reporting error");
394 _dictionary->reportStatistics(); 490 _dictionary->reportStatistics();
395 if (PrintFLSStatistics > 1) { 491 if (PrintFLSStatistics > 1) {
447 assert(prevEnd == NULL || value >= unallocated_block(), "New end is below unallocated block"); 543 assert(prevEnd == NULL || value >= unallocated_block(), "New end is below unallocated block");
448 _end = value; 544 _end = value;
449 if (prevEnd != NULL) { 545 if (prevEnd != NULL) {
450 // Resize the underlying block offset table. 546 // Resize the underlying block offset table.
451 _bt.resize(pointer_delta(value, bottom())); 547 _bt.resize(pointer_delta(value, bottom()));
452 if (value <= prevEnd) { 548 if (value <= prevEnd) {
453 assert(value >= unallocated_block(), "New end is below unallocated block"); 549 assert(value >= unallocated_block(), "New end is below unallocated block");
454 } else { 550 } else {
455 // Now, take this new chunk and add it to the free blocks. 551 // Now, take this new chunk and add it to the free blocks.
456 // Note that the BOT has not yet been updated for this block. 552 // Note that the BOT has not yet been updated for this block.
457 size_t newFcSize = pointer_delta(value, prevEnd); 553 size_t newFcSize = pointer_delta(value, prevEnd);
458 // XXX This is REALLY UGLY and should be fixed up. XXX 554 // XXX This is REALLY UGLY and should be fixed up. XXX
459 if (!_adaptive_freelists && _smallLinearAllocBlock._ptr == NULL) { 555 if (!_adaptive_freelists && _smallLinearAllocBlock._ptr == NULL) {
460 // Mark the boundary of the new block in BOT 556 // Mark the boundary of the new block in BOT
461 _bt.mark_block(prevEnd, value); 557 _bt.mark_block(prevEnd, value);
462 // put it all in the linAB 558 // put it all in the linAB
463 if (ParallelGCThreads == 0) { 559 if (ParallelGCThreads == 0) {
464 _smallLinearAllocBlock._ptr = prevEnd; 560 _smallLinearAllocBlock._ptr = prevEnd;
465 _smallLinearAllocBlock._word_size = newFcSize; 561 _smallLinearAllocBlock._word_size = newFcSize;
466 repairLinearAllocBlock(&_smallLinearAllocBlock); 562 repairLinearAllocBlock(&_smallLinearAllocBlock);
467 } else { // ParallelGCThreads > 0 563 } else { // ParallelGCThreads > 0
468 MutexLockerEx x(parDictionaryAllocLock(), 564 MutexLockerEx x(parDictionaryAllocLock(),
469 Mutex::_no_safepoint_check_flag); 565 Mutex::_no_safepoint_check_flag);
470 _smallLinearAllocBlock._ptr = prevEnd; 566 _smallLinearAllocBlock._ptr = prevEnd;
471 _smallLinearAllocBlock._word_size = newFcSize; 567 _smallLinearAllocBlock._word_size = newFcSize;
472 repairLinearAllocBlock(&_smallLinearAllocBlock); 568 repairLinearAllocBlock(&_smallLinearAllocBlock);
569 }
570 // Births of chunks put into a LinAB are not recorded. Births
571 // of chunks as they are allocated out of a LinAB are.
572 } else {
573 // Add the block to the free lists, if possible coalescing it
574 // with the last free block, and update the BOT and census data.
575 addChunkToFreeListsAtEndRecordingStats(prevEnd, newFcSize);
473 } 576 }
474 // Births of chunks put into a LinAB are not recorded. Births 577 }
475 // of chunks as they are allocated out of a LinAB are.
476 } else {
477 // Add the block to the free lists, if possible coalescing it
478 // with the last free block, and update the BOT and census data.
479 addChunkToFreeListsAtEndRecordingStats(prevEnd, newFcSize);
480 }
481 }
482 } 578 }
483 } 579 }
484 580
485 class FreeListSpace_DCTOC : public Filtering_DCTOC { 581 class FreeListSpace_DCTOC : public Filtering_DCTOC {
486 CompactibleFreeListSpace* _cfls; 582 CompactibleFreeListSpace* _cfls;
730 } 826 }
731 } 827 }
732 828
733 void CompactibleFreeListSpace::object_iterate_mem(MemRegion mr, 829 void CompactibleFreeListSpace::object_iterate_mem(MemRegion mr,
734 UpwardsObjectClosure* cl) { 830 UpwardsObjectClosure* cl) {
735 assert_locked(); 831 assert_locked(freelistLock());
736 NOT_PRODUCT(verify_objects_initialized()); 832 NOT_PRODUCT(verify_objects_initialized());
737 Space::object_iterate_mem(mr, cl); 833 Space::object_iterate_mem(mr, cl);
738 } 834 }
739 835
740 // Callers of this iterator beware: The closure application should 836 // Callers of this iterator beware: The closure application should
1210 1306
1211 #ifndef PRODUCT 1307 #ifndef PRODUCT
1212 void CompactibleFreeListSpace::assert_locked() const { 1308 void CompactibleFreeListSpace::assert_locked() const {
1213 CMSLockVerifier::assert_locked(freelistLock(), parDictionaryAllocLock()); 1309 CMSLockVerifier::assert_locked(freelistLock(), parDictionaryAllocLock());
1214 } 1310 }
1311
1312 void CompactibleFreeListSpace::assert_locked(const Mutex* lock) const {
1313 CMSLockVerifier::assert_locked(lock);
1314 }
1215 #endif 1315 #endif
1216 1316
1217 FreeChunk* CompactibleFreeListSpace::allocateScratch(size_t size) { 1317 FreeChunk* CompactibleFreeListSpace::allocateScratch(size_t size) {
1218 // In the parallel case, the main thread holds the free list lock 1318 // In the parallel case, the main thread holds the free list lock
1219 // on behalf the parallel threads. 1319 // on behalf the parallel threads.
1220 assert_locked();
1221 FreeChunk* fc; 1320 FreeChunk* fc;
1222 { 1321 {
1223 // If GC is parallel, this might be called by several threads. 1322 // If GC is parallel, this might be called by several threads.
1224 // This should be rare enough that the locking overhead won't affect 1323 // This should be rare enough that the locking overhead won't affect
1225 // the sequential code. 1324 // the sequential code.
1296 // about to exhaust this linear allocation block 1395 // about to exhaust this linear allocation block
1297 if (blk->_word_size == size) { // exactly satisfied 1396 if (blk->_word_size == size) { // exactly satisfied
1298 res = blk->_ptr; 1397 res = blk->_ptr;
1299 _bt.allocated(res, blk->_word_size); 1398 _bt.allocated(res, blk->_word_size);
1300 } else if (size + MinChunkSize <= blk->_refillSize) { 1399 } else if (size + MinChunkSize <= blk->_refillSize) {
1400 size_t sz = blk->_word_size;
1301 // Update _unallocated_block if the size is such that chunk would be 1401 // Update _unallocated_block if the size is such that chunk would be
1302 // returned to the indexed free list. All other chunks in the indexed 1402 // returned to the indexed free list. All other chunks in the indexed
1303 // free lists are allocated from the dictionary so that _unallocated_block 1403 // free lists are allocated from the dictionary so that _unallocated_block
1304 // has already been adjusted for them. Do it here so that the cost 1404 // has already been adjusted for them. Do it here so that the cost
1305 // for all chunks added back to the indexed free lists. 1405 // for all chunks added back to the indexed free lists.
1306 if (blk->_word_size < SmallForDictionary) { 1406 if (sz < SmallForDictionary) {
1307 _bt.allocated(blk->_ptr, blk->_word_size); 1407 _bt.allocated(blk->_ptr, sz);
1308 } 1408 }
1309 // Return the chunk that isn't big enough, and then refill below. 1409 // Return the chunk that isn't big enough, and then refill below.
1310 addChunkToFreeLists(blk->_ptr, blk->_word_size); 1410 addChunkToFreeLists(blk->_ptr, sz);
1311 _bt.verify_single_block(blk->_ptr, (blk->_ptr + blk->_word_size)); 1411 splitBirth(sz);
1312 // Don't keep statistics on adding back chunk from a LinAB. 1412 // Don't keep statistics on adding back chunk from a LinAB.
1313 } else { 1413 } else {
1314 // A refilled block would not satisfy the request. 1414 // A refilled block would not satisfy the request.
1315 return NULL; 1415 return NULL;
1316 } 1416 }
1374 res = _indexedFreeList[size].getChunkAtHead(); 1474 res = _indexedFreeList[size].getChunkAtHead();
1375 if (res == NULL) { 1475 if (res == NULL) {
1376 res = getChunkFromIndexedFreeListHelper(size); 1476 res = getChunkFromIndexedFreeListHelper(size);
1377 } 1477 }
1378 _bt.verify_not_unallocated((HeapWord*) res, size); 1478 _bt.verify_not_unallocated((HeapWord*) res, size);
1479 assert(res == NULL || res->size() == size, "Incorrect block size");
1379 return res; 1480 return res;
1380 } 1481 }
1381 1482
1382 FreeChunk* 1483 FreeChunk*
1383 CompactibleFreeListSpace::getChunkFromIndexedFreeListHelper(size_t size) { 1484 CompactibleFreeListSpace::getChunkFromIndexedFreeListHelper(size_t size,
1485 bool replenish) {
1384 assert_locked(); 1486 assert_locked();
1385 FreeChunk* fc = NULL; 1487 FreeChunk* fc = NULL;
1386 if (size < SmallForDictionary) { 1488 if (size < SmallForDictionary) {
1387 assert(_indexedFreeList[size].head() == NULL || 1489 assert(_indexedFreeList[size].head() == NULL ||
1388 _indexedFreeList[size].surplus() <= 0, 1490 _indexedFreeList[size].surplus() <= 0,
1396 // replenishing lists. 1498 // replenishing lists.
1397 // Tried small linAB of size 256 (size in indexed list) 1499 // Tried small linAB of size 256 (size in indexed list)
1398 // and replenishing indexed lists from the small linAB. 1500 // and replenishing indexed lists from the small linAB.
1399 // 1501 //
1400 FreeChunk* newFc = NULL; 1502 FreeChunk* newFc = NULL;
1401 size_t replenish_size = CMSIndexedFreeListReplenish * size; 1503 const size_t replenish_size = CMSIndexedFreeListReplenish * size;
1402 if (replenish_size < SmallForDictionary) { 1504 if (replenish_size < SmallForDictionary) {
1403 // Do not replenish from an underpopulated size. 1505 // Do not replenish from an underpopulated size.
1404 if (_indexedFreeList[replenish_size].surplus() > 0 && 1506 if (_indexedFreeList[replenish_size].surplus() > 0 &&
1405 _indexedFreeList[replenish_size].head() != NULL) { 1507 _indexedFreeList[replenish_size].head() != NULL) {
1406 newFc = 1508 newFc = _indexedFreeList[replenish_size].getChunkAtHead();
1407 _indexedFreeList[replenish_size].getChunkAtHead(); 1509 } else if (bestFitFirst()) {
1408 } else {
1409 newFc = bestFitSmall(replenish_size); 1510 newFc = bestFitSmall(replenish_size);
1410 } 1511 }
1411 } 1512 }
1513 if (newFc == NULL && replenish_size > size) {
1514 assert(CMSIndexedFreeListReplenish > 1, "ctl pt invariant");
1515 newFc = getChunkFromIndexedFreeListHelper(replenish_size, false);
1516 }
1517 // Note: The stats update re split-death of block obtained above
1518 // will be recorded below precisely when we know we are going to
1519 // be actually splitting it into more than one pieces below.
1412 if (newFc != NULL) { 1520 if (newFc != NULL) {
1413 splitDeath(replenish_size); 1521 if (replenish || CMSReplenishIntermediate) {
1414 } else if (replenish_size > size) { 1522 // Replenish this list and return one block to caller.
1415 assert(CMSIndexedFreeListReplenish > 1, "ctl pt invariant"); 1523 size_t i;
1416 newFc = 1524 FreeChunk *curFc, *nextFc;
1417 getChunkFromIndexedFreeListHelper(replenish_size); 1525 size_t num_blk = newFc->size() / size;
1418 } 1526 assert(num_blk >= 1, "Smaller than requested?");
1419 if (newFc != NULL) { 1527 assert(newFc->size() % size == 0, "Should be integral multiple of request");
1420 assert(newFc->size() == replenish_size, "Got wrong size"); 1528 if (num_blk > 1) {
1421 size_t i; 1529 // we are sure we will be splitting the block just obtained
1422 FreeChunk *curFc, *nextFc; 1530 // into multiple pieces; record the split-death of the original
1423 // carve up and link blocks 0, ..., CMSIndexedFreeListReplenish - 2 1531 splitDeath(replenish_size);
1424 // The last chunk is not added to the lists but is returned as the 1532 }
1425 // free chunk. 1533 // carve up and link blocks 0, ..., num_blk - 2
1426 for (curFc = newFc, nextFc = (FreeChunk*)((HeapWord*)curFc + size), 1534 // The last chunk is not added to the lists but is returned as the
1427 i = 0; 1535 // free chunk.
1428 i < (CMSIndexedFreeListReplenish - 1); 1536 for (curFc = newFc, nextFc = (FreeChunk*)((HeapWord*)curFc + size),
1429 curFc = nextFc, nextFc = (FreeChunk*)((HeapWord*)nextFc + size), 1537 i = 0;
1430 i++) { 1538 i < (num_blk - 1);
1539 curFc = nextFc, nextFc = (FreeChunk*)((HeapWord*)nextFc + size),
1540 i++) {
1541 curFc->setSize(size);
1542 // Don't record this as a return in order to try and
1543 // determine the "returns" from a GC.
1544 _bt.verify_not_unallocated((HeapWord*) fc, size);
1545 _indexedFreeList[size].returnChunkAtTail(curFc, false);
1546 _bt.mark_block((HeapWord*)curFc, size);
1547 splitBirth(size);
1548 // Don't record the initial population of the indexed list
1549 // as a split birth.
1550 }
1551
1552 // check that the arithmetic was OK above
1553 assert((HeapWord*)nextFc == (HeapWord*)newFc + num_blk*size,
1554 "inconsistency in carving newFc");
1431 curFc->setSize(size); 1555 curFc->setSize(size);
1432 // Don't record this as a return in order to try and
1433 // determine the "returns" from a GC.
1434 _bt.verify_not_unallocated((HeapWord*) fc, size);
1435 _indexedFreeList[size].returnChunkAtTail(curFc, false);
1436 _bt.mark_block((HeapWord*)curFc, size); 1556 _bt.mark_block((HeapWord*)curFc, size);
1437 splitBirth(size); 1557 splitBirth(size);
1438 // Don't record the initial population of the indexed list 1558 fc = curFc;
1439 // as a split birth. 1559 } else {
1560 // Return entire block to caller
1561 fc = newFc;
1440 } 1562 }
1441
1442 // check that the arithmetic was OK above
1443 assert((HeapWord*)nextFc == (HeapWord*)newFc + replenish_size,
1444 "inconsistency in carving newFc");
1445 curFc->setSize(size);
1446 _bt.mark_block((HeapWord*)curFc, size);
1447 splitBirth(size);
1448 return curFc;
1449 } 1563 }
1450 } 1564 }
1451 } else { 1565 } else {
1452 // Get a free chunk from the free chunk dictionary to be returned to 1566 // Get a free chunk from the free chunk dictionary to be returned to
1453 // replenish the indexed free list. 1567 // replenish the indexed free list.
1454 fc = getChunkFromDictionaryExact(size); 1568 fc = getChunkFromDictionaryExact(size);
1455 } 1569 }
1456 assert(fc == NULL || fc->isFree(), "Should be returning a free chunk"); 1570 // assert(fc == NULL || fc->isFree(), "Should be returning a free chunk");
1457 return fc; 1571 return fc;
1458 } 1572 }
1459 1573
1460 FreeChunk* 1574 FreeChunk*
1461 CompactibleFreeListSpace::getChunkFromDictionary(size_t size) { 1575 CompactibleFreeListSpace::getChunkFromDictionary(size_t size) {
1510 size_t size = chunk->size(); 1624 size_t size = chunk->size();
1511 _bt.verify_single_block((HeapWord*)chunk, size); 1625 _bt.verify_single_block((HeapWord*)chunk, size);
1512 // adjust _unallocated_block downward, as necessary 1626 // adjust _unallocated_block downward, as necessary
1513 _bt.freed((HeapWord*)chunk, size); 1627 _bt.freed((HeapWord*)chunk, size);
1514 _dictionary->returnChunk(chunk); 1628 _dictionary->returnChunk(chunk);
1629 #ifndef PRODUCT
1630 if (CMSCollector::abstract_state() != CMSCollector::Sweeping) {
1631 TreeChunk::as_TreeChunk(chunk)->list()->verify_stats();
1632 }
1633 #endif // PRODUCT
1515 } 1634 }
1516 1635
1517 void 1636 void
1518 CompactibleFreeListSpace::returnChunkToFreeList(FreeChunk* fc) { 1637 CompactibleFreeListSpace::returnChunkToFreeList(FreeChunk* fc) {
1519 assert_locked(); 1638 assert_locked();
1523 if (_adaptive_freelists) { 1642 if (_adaptive_freelists) {
1524 _indexedFreeList[size].returnChunkAtTail(fc); 1643 _indexedFreeList[size].returnChunkAtTail(fc);
1525 } else { 1644 } else {
1526 _indexedFreeList[size].returnChunkAtHead(fc); 1645 _indexedFreeList[size].returnChunkAtHead(fc);
1527 } 1646 }
1647 #ifndef PRODUCT
1648 if (CMSCollector::abstract_state() != CMSCollector::Sweeping) {
1649 _indexedFreeList[size].verify_stats();
1650 }
1651 #endif // PRODUCT
1528 } 1652 }
1529 1653
1530 // Add chunk to end of last block -- if it's the largest 1654 // Add chunk to end of last block -- if it's the largest
1531 // block -- and update BOT and census data. We would 1655 // block -- and update BOT and census data. We would
1532 // of course have preferred to coalesce it with the 1656 // of course have preferred to coalesce it with the
1535 void 1659 void
1536 CompactibleFreeListSpace::addChunkToFreeListsAtEndRecordingStats( 1660 CompactibleFreeListSpace::addChunkToFreeListsAtEndRecordingStats(
1537 HeapWord* chunk, size_t size) { 1661 HeapWord* chunk, size_t size) {
1538 // check that the chunk does lie in this space! 1662 // check that the chunk does lie in this space!
1539 assert(chunk != NULL && is_in_reserved(chunk), "Not in this space!"); 1663 assert(chunk != NULL && is_in_reserved(chunk), "Not in this space!");
1540 assert_locked();
1541 // One of the parallel gc task threads may be here 1664 // One of the parallel gc task threads may be here
1542 // whilst others are allocating. 1665 // whilst others are allocating.
1543 Mutex* lock = NULL; 1666 Mutex* lock = NULL;
1544 if (ParallelGCThreads != 0) { 1667 if (ParallelGCThreads != 0) {
1545 lock = &_parDictionaryAllocLock; 1668 lock = &_parDictionaryAllocLock;
1989 assert(frag == 0.0, "Follows from totFree == 0"); 2112 assert(frag == 0.0, "Follows from totFree == 0");
1990 } 2113 }
1991 return frag; 2114 return frag;
1992 } 2115 }
1993 2116
1994 #define CoalSurplusPercent 1.05
1995 #define SplitSurplusPercent 1.10
1996
1997 void CompactibleFreeListSpace::beginSweepFLCensus( 2117 void CompactibleFreeListSpace::beginSweepFLCensus(
1998 float inter_sweep_current, 2118 float inter_sweep_current,
1999 float inter_sweep_estimate) { 2119 float inter_sweep_estimate,
2120 float intra_sweep_estimate) {
2000 assert_locked(); 2121 assert_locked();
2001 size_t i; 2122 size_t i;
2002 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { 2123 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
2003 FreeList* fl = &_indexedFreeList[i]; 2124 FreeList* fl = &_indexedFreeList[i];
2004 fl->compute_desired(inter_sweep_current, inter_sweep_estimate); 2125 if (PrintFLSStatistics > 1) {
2005 fl->set_coalDesired((ssize_t)((double)fl->desired() * CoalSurplusPercent)); 2126 gclog_or_tty->print("size[%d] : ", i);
2127 }
2128 fl->compute_desired(inter_sweep_current, inter_sweep_estimate, intra_sweep_estimate);
2129 fl->set_coalDesired((ssize_t)((double)fl->desired() * CMSSmallCoalSurplusPercent));
2006 fl->set_beforeSweep(fl->count()); 2130 fl->set_beforeSweep(fl->count());
2007 fl->set_bfrSurp(fl->surplus()); 2131 fl->set_bfrSurp(fl->surplus());
2008 } 2132 }
2009 _dictionary->beginSweepDictCensus(CoalSurplusPercent, 2133 _dictionary->beginSweepDictCensus(CMSLargeCoalSurplusPercent,
2010 inter_sweep_current, 2134 inter_sweep_current,
2011 inter_sweep_estimate); 2135 inter_sweep_estimate,
2136 intra_sweep_estimate);
2012 } 2137 }
2013 2138
2014 void CompactibleFreeListSpace::setFLSurplus() { 2139 void CompactibleFreeListSpace::setFLSurplus() {
2015 assert_locked(); 2140 assert_locked();
2016 size_t i; 2141 size_t i;
2017 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { 2142 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
2018 FreeList *fl = &_indexedFreeList[i]; 2143 FreeList *fl = &_indexedFreeList[i];
2019 fl->set_surplus(fl->count() - 2144 fl->set_surplus(fl->count() -
2020 (ssize_t)((double)fl->desired() * SplitSurplusPercent)); 2145 (ssize_t)((double)fl->desired() * CMSSmallSplitSurplusPercent));
2021 } 2146 }
2022 } 2147 }
2023 2148
2024 void CompactibleFreeListSpace::setFLHints() { 2149 void CompactibleFreeListSpace::setFLHints() {
2025 assert_locked(); 2150 assert_locked();
2046 fl->set_splitDeaths(0); 2171 fl->set_splitDeaths(0);
2047 } 2172 }
2048 } 2173 }
2049 2174
2050 void CompactibleFreeListSpace::endSweepFLCensus(size_t sweep_count) { 2175 void CompactibleFreeListSpace::endSweepFLCensus(size_t sweep_count) {
2176 if (PrintFLSStatistics > 0) {
2177 HeapWord* largestAddr = (HeapWord*) dictionary()->findLargestDict();
2178 gclog_or_tty->print_cr("CMS: Large block " PTR_FORMAT,
2179 largestAddr);
2180 }
2051 setFLSurplus(); 2181 setFLSurplus();
2052 setFLHints(); 2182 setFLHints();
2053 if (PrintGC && PrintFLSCensus > 0) { 2183 if (PrintGC && PrintFLSCensus > 0) {
2054 printFLCensus(sweep_count); 2184 printFLCensus(sweep_count);
2055 } 2185 }
2056 clearFLCensus(); 2186 clearFLCensus();
2057 assert_locked(); 2187 assert_locked();
2058 _dictionary->endSweepDictCensus(SplitSurplusPercent); 2188 _dictionary->endSweepDictCensus(CMSLargeSplitSurplusPercent);
2059 } 2189 }
2060 2190
2061 bool CompactibleFreeListSpace::coalOverPopulated(size_t size) { 2191 bool CompactibleFreeListSpace::coalOverPopulated(size_t size) {
2062 if (size < SmallForDictionary) { 2192 if (size < SmallForDictionary) {
2063 FreeList *fl = &_indexedFreeList[size]; 2193 FreeList *fl = &_indexedFreeList[size];
2310 verifyIndexedFreeList(i); 2440 verifyIndexedFreeList(i);
2311 } 2441 }
2312 } 2442 }
2313 2443
2314 void CompactibleFreeListSpace::verifyIndexedFreeList(size_t size) const { 2444 void CompactibleFreeListSpace::verifyIndexedFreeList(size_t size) const {
2315 FreeChunk* fc = _indexedFreeList[size].head(); 2445 FreeChunk* fc = _indexedFreeList[size].head();
2446 FreeChunk* tail = _indexedFreeList[size].tail();
2447 size_t num = _indexedFreeList[size].count();
2448 size_t n = 0;
2316 guarantee((size % 2 == 0) || fc == NULL, "Odd slots should be empty"); 2449 guarantee((size % 2 == 0) || fc == NULL, "Odd slots should be empty");
2317 for (; fc != NULL; fc = fc->next()) { 2450 for (; fc != NULL; fc = fc->next(), n++) {
2318 guarantee(fc->size() == size, "Size inconsistency"); 2451 guarantee(fc->size() == size, "Size inconsistency");
2319 guarantee(fc->isFree(), "!free?"); 2452 guarantee(fc->isFree(), "!free?");
2320 guarantee(fc->next() == NULL || fc->next()->prev() == fc, "Broken list"); 2453 guarantee(fc->next() == NULL || fc->next()->prev() == fc, "Broken list");
2321 } 2454 guarantee((fc->next() == NULL) == (fc == tail), "Incorrect tail");
2455 }
2456 guarantee(n == num, "Incorrect count");
2322 } 2457 }
2323 2458
2324 #ifndef PRODUCT 2459 #ifndef PRODUCT
2325 void CompactibleFreeListSpace::checkFreeListConsistency() const { 2460 void CompactibleFreeListSpace::checkFreeListConsistency() const {
2326 assert(_dictionary->minSize() <= IndexSetSize, 2461 assert(_dictionary->minSize() <= IndexSetSize,
2514 "spooling inconsistency?"); 2649 "spooling inconsistency?");
2515 _firstIndex = _nextIndex = 1; 2650 _firstIndex = _nextIndex = 1;
2516 _tracking = true; 2651 _tracking = true;
2517 } 2652 }
2518 2653
2519 void PromotionInfo::stopTrackingPromotions() { 2654 #define CMSPrintPromoBlockInfo 1
2655
2656 void PromotionInfo::stopTrackingPromotions(uint worker_id) {
2520 assert(_spoolHead == _spoolTail && _firstIndex == _nextIndex, 2657 assert(_spoolHead == _spoolTail && _firstIndex == _nextIndex,
2521 "spooling inconsistency?"); 2658 "spooling inconsistency?");
2522 _firstIndex = _nextIndex = 1; 2659 _firstIndex = _nextIndex = 1;
2523 _tracking = false; 2660 _tracking = false;
2661 if (CMSPrintPromoBlockInfo > 1) {
2662 print_statistics(worker_id);
2663 }
2664 }
2665
2666 void PromotionInfo::print_statistics(uint worker_id) const {
2667 assert(_spoolHead == _spoolTail && _firstIndex == _nextIndex,
2668 "Else will undercount");
2669 assert(CMSPrintPromoBlockInfo > 0, "Else unnecessary call");
2670 // Count the number of blocks and slots in the free pool
2671 size_t slots = 0;
2672 size_t blocks = 0;
2673 for (SpoolBlock* cur_spool = _spareSpool;
2674 cur_spool != NULL;
2675 cur_spool = cur_spool->nextSpoolBlock) {
2676 // the first entry is just a self-pointer; indices 1 through
2677 // bufferSize - 1 are occupied (thus, bufferSize - 1 slots).
2678 guarantee((void*)cur_spool->displacedHdr == (void*)&cur_spool->displacedHdr,
2679 "first entry of displacedHdr should be self-referential");
2680 slots += cur_spool->bufferSize - 1;
2681 blocks++;
2682 }
2683 if (_spoolHead != NULL) {
2684 slots += _spoolHead->bufferSize - 1;
2685 blocks++;
2686 }
2687 gclog_or_tty->print_cr(" [worker %d] promo_blocks = %d, promo_slots = %d ",
2688 worker_id, blocks, slots);
2524 } 2689 }
2525 2690
2526 // When _spoolTail is not NULL, then the slot <_spoolTail, _nextIndex> 2691 // When _spoolTail is not NULL, then the slot <_spoolTail, _nextIndex>
2527 // points to the next slot available for filling. 2692 // points to the next slot available for filling.
2528 // The set of slots holding displaced headers are then all those in the 2693 // The set of slots holding displaced headers are then all those in the
2582 // second: - (_firstIndex - 1) + (_nextIndex - 1) 2747 // second: - (_firstIndex - 1) + (_nextIndex - 1)
2583 numDisplacedHdrs += (_nextIndex - _firstIndex); 2748 numDisplacedHdrs += (_nextIndex - _firstIndex);
2584 guarantee(numDisplacedHdrs == numObjsWithDisplacedHdrs, "Displaced hdr count"); 2749 guarantee(numDisplacedHdrs == numObjsWithDisplacedHdrs, "Displaced hdr count");
2585 } 2750 }
2586 2751
2752 void PromotionInfo::print_on(outputStream* st) const {
2753 SpoolBlock* curSpool = NULL;
2754 size_t i = 0;
2755 st->print_cr("start & end indices: [" SIZE_FORMAT ", " SIZE_FORMAT ")",
2756 _firstIndex, _nextIndex);
2757 for (curSpool = _spoolHead; curSpool != _spoolTail && curSpool != NULL;
2758 curSpool = curSpool->nextSpoolBlock) {
2759 curSpool->print_on(st);
2760 st->print_cr(" active ");
2761 i++;
2762 }
2763 for (curSpool = _spoolTail; curSpool != NULL;
2764 curSpool = curSpool->nextSpoolBlock) {
2765 curSpool->print_on(st);
2766 st->print_cr(" inactive ");
2767 i++;
2768 }
2769 for (curSpool = _spareSpool; curSpool != NULL;
2770 curSpool = curSpool->nextSpoolBlock) {
2771 curSpool->print_on(st);
2772 st->print_cr(" free ");
2773 i++;
2774 }
2775 st->print_cr(SIZE_FORMAT " header spooling blocks", i);
2776 }
2777
2778 void SpoolBlock::print_on(outputStream* st) const {
2779 st->print("[" PTR_FORMAT "," PTR_FORMAT "), " SIZE_FORMAT " HeapWords -> " PTR_FORMAT,
2780 this, (HeapWord*)displacedHdr + bufferSize,
2781 bufferSize, nextSpoolBlock);
2782 }
2783
2784 ///////////////////////////////////////////////////////////////////////////
2785 // CFLS_LAB
2786 ///////////////////////////////////////////////////////////////////////////
2787
2788 #define VECTOR_257(x) \
2789 /* 1 2 3 4 5 6 7 8 9 1x 11 12 13 14 15 16 17 18 19 2x 21 22 23 24 25 26 27 28 29 3x 31 32 */ \
2790 { x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, \
2791 x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, \
2792 x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, \
2793 x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, \
2794 x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, \
2795 x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, \
2796 x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, \
2797 x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, \
2798 x }
2799
2800 // Initialize with default setting of CMSParPromoteBlocksToClaim, _not_
2801 // OldPLABSize, whose static default is different; if overridden at the
2802 // command-line, this will get reinitialized via a call to
2803 // modify_initialization() below.
2804 AdaptiveWeightedAverage CFLS_LAB::_blocks_to_claim[] =
2805 VECTOR_257(AdaptiveWeightedAverage(OldPLABWeight, (float)CMSParPromoteBlocksToClaim));
2806 size_t CFLS_LAB::_global_num_blocks[] = VECTOR_257(0);
2807 int CFLS_LAB::_global_num_workers[] = VECTOR_257(0);
2587 2808
2588 CFLS_LAB::CFLS_LAB(CompactibleFreeListSpace* cfls) : 2809 CFLS_LAB::CFLS_LAB(CompactibleFreeListSpace* cfls) :
2589 _cfls(cfls) 2810 _cfls(cfls)
2590 { 2811 {
2591 _blocks_to_claim = CMSParPromoteBlocksToClaim; 2812 assert(CompactibleFreeListSpace::IndexSetSize == 257, "Modify VECTOR_257() macro above");
2592 for (size_t i = CompactibleFreeListSpace::IndexSetStart; 2813 for (size_t i = CompactibleFreeListSpace::IndexSetStart;
2593 i < CompactibleFreeListSpace::IndexSetSize; 2814 i < CompactibleFreeListSpace::IndexSetSize;
2594 i += CompactibleFreeListSpace::IndexSetStride) { 2815 i += CompactibleFreeListSpace::IndexSetStride) {
2595 _indexedFreeList[i].set_size(i); 2816 _indexedFreeList[i].set_size(i);
2817 _num_blocks[i] = 0;
2818 }
2819 }
2820
2821 static bool _CFLS_LAB_modified = false;
2822
2823 void CFLS_LAB::modify_initialization(size_t n, unsigned wt) {
2824 assert(!_CFLS_LAB_modified, "Call only once");
2825 _CFLS_LAB_modified = true;
2826 for (size_t i = CompactibleFreeListSpace::IndexSetStart;
2827 i < CompactibleFreeListSpace::IndexSetSize;
2828 i += CompactibleFreeListSpace::IndexSetStride) {
2829 _blocks_to_claim[i].modify(n, wt, true /* force */);
2596 } 2830 }
2597 } 2831 }
2598 2832
2599 HeapWord* CFLS_LAB::alloc(size_t word_sz) { 2833 HeapWord* CFLS_LAB::alloc(size_t word_sz) {
2600 FreeChunk* res; 2834 FreeChunk* res;
2605 Mutex::_no_safepoint_check_flag); 2839 Mutex::_no_safepoint_check_flag);
2606 res = _cfls->getChunkFromDictionaryExact(word_sz); 2840 res = _cfls->getChunkFromDictionaryExact(word_sz);
2607 if (res == NULL) return NULL; 2841 if (res == NULL) return NULL;
2608 } else { 2842 } else {
2609 FreeList* fl = &_indexedFreeList[word_sz]; 2843 FreeList* fl = &_indexedFreeList[word_sz];
2610 bool filled = false; //TRAP
2611 if (fl->count() == 0) { 2844 if (fl->count() == 0) {
2612 bool filled = true; //TRAP
2613 // Attempt to refill this local free list. 2845 // Attempt to refill this local free list.
2614 _cfls->par_get_chunk_of_blocks(word_sz, _blocks_to_claim, fl); 2846 get_from_global_pool(word_sz, fl);
2615 // If it didn't work, give up. 2847 // If it didn't work, give up.
2616 if (fl->count() == 0) return NULL; 2848 if (fl->count() == 0) return NULL;
2617 } 2849 }
2618 res = fl->getChunkAtHead(); 2850 res = fl->getChunkAtHead();
2619 assert(res != NULL, "Why was count non-zero?"); 2851 assert(res != NULL, "Why was count non-zero?");
2624 // mangle a just allocated object with a distinct pattern. 2856 // mangle a just allocated object with a distinct pattern.
2625 debug_only(res->mangleAllocated(word_sz)); 2857 debug_only(res->mangleAllocated(word_sz));
2626 return (HeapWord*)res; 2858 return (HeapWord*)res;
2627 } 2859 }
2628 2860
2629 void CFLS_LAB::retire() { 2861 // Get a chunk of blocks of the right size and update related
2630 for (size_t i = CompactibleFreeListSpace::IndexSetStart; 2862 // book-keeping stats
2863 void CFLS_LAB::get_from_global_pool(size_t word_sz, FreeList* fl) {
2864 // Get the #blocks we want to claim
2865 size_t n_blks = (size_t)_blocks_to_claim[word_sz].average();
2866 assert(n_blks > 0, "Error");
2867 assert(ResizePLAB || n_blks == OldPLABSize, "Error");
2868 // In some cases, when the application has a phase change,
2869 // there may be a sudden and sharp shift in the object survival
2870 // profile, and updating the counts at the end of a scavenge
2871 // may not be quick enough, giving rise to large scavenge pauses
2872 // during these phase changes. It is beneficial to detect such
2873 // changes on-the-fly during a scavenge and avoid such a phase-change
2874 // pothole. The following code is a heuristic attempt to do that.
2875 // It is protected by a product flag until we have gained
2876 // enough experience with this heuristic and fine-tuned its behaviour.
2877 // WARNING: This might increase fragmentation if we overreact to
2878 // small spikes, so some kind of historical smoothing based on
2879 // previous experience with the greater reactivity might be useful.
2880 // Lacking sufficient experience, CMSOldPLABResizeQuicker is disabled by
2881 // default.
2882 if (ResizeOldPLAB && CMSOldPLABResizeQuicker) {
2883 size_t multiple = _num_blocks[word_sz]/(CMSOldPLABToleranceFactor*CMSOldPLABNumRefills*n_blks);
2884 n_blks += CMSOldPLABReactivityFactor*multiple*n_blks;
2885 n_blks = MIN2(n_blks, CMSOldPLABMax);
2886 }
2887 assert(n_blks > 0, "Error");
2888 _cfls->par_get_chunk_of_blocks(word_sz, n_blks, fl);
2889 // Update stats table entry for this block size
2890 _num_blocks[word_sz] += fl->count();
2891 }
2892
2893 void CFLS_LAB::compute_desired_plab_size() {
2894 for (size_t i = CompactibleFreeListSpace::IndexSetStart;
2631 i < CompactibleFreeListSpace::IndexSetSize; 2895 i < CompactibleFreeListSpace::IndexSetSize;
2632 i += CompactibleFreeListSpace::IndexSetStride) { 2896 i += CompactibleFreeListSpace::IndexSetStride) {
2633 if (_indexedFreeList[i].count() > 0) { 2897 assert((_global_num_workers[i] == 0) == (_global_num_blocks[i] == 0),
2634 MutexLockerEx x(_cfls->_indexedFreeListParLocks[i], 2898 "Counter inconsistency");
2635 Mutex::_no_safepoint_check_flag); 2899 if (_global_num_workers[i] > 0) {
2636 _cfls->_indexedFreeList[i].prepend(&_indexedFreeList[i]); 2900 // Need to smooth wrt historical average
2637 // Reset this list. 2901 if (ResizeOldPLAB) {
2638 _indexedFreeList[i] = FreeList(); 2902 _blocks_to_claim[i].sample(
2639 _indexedFreeList[i].set_size(i); 2903 MAX2((size_t)CMSOldPLABMin,
2640 } 2904 MIN2((size_t)CMSOldPLABMax,
2641 } 2905 _global_num_blocks[i]/(_global_num_workers[i]*CMSOldPLABNumRefills))));
2642 } 2906 }
2643 2907 // Reset counters for next round
2644 void 2908 _global_num_workers[i] = 0;
2645 CompactibleFreeListSpace:: 2909 _global_num_blocks[i] = 0;
2646 par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList* fl) { 2910 if (PrintOldPLAB) {
2911 gclog_or_tty->print_cr("[%d]: %d", i, (size_t)_blocks_to_claim[i].average());
2912 }
2913 }
2914 }
2915 }
2916
2917 void CFLS_LAB::retire(int tid) {
2918 // We run this single threaded with the world stopped;
2919 // so no need for locks and such.
2920 #define CFLS_LAB_PARALLEL_ACCESS 0
2921 NOT_PRODUCT(Thread* t = Thread::current();)
2922 assert(Thread::current()->is_VM_thread(), "Error");
2923 assert(CompactibleFreeListSpace::IndexSetStart == CompactibleFreeListSpace::IndexSetStride,
2924 "Will access to uninitialized slot below");
2925 #if CFLS_LAB_PARALLEL_ACCESS
2926 for (size_t i = CompactibleFreeListSpace::IndexSetSize - 1;
2927 i > 0;
2928 i -= CompactibleFreeListSpace::IndexSetStride) {
2929 #else // CFLS_LAB_PARALLEL_ACCESS
2930 for (size_t i = CompactibleFreeListSpace::IndexSetStart;
2931 i < CompactibleFreeListSpace::IndexSetSize;
2932 i += CompactibleFreeListSpace::IndexSetStride) {
2933 #endif // !CFLS_LAB_PARALLEL_ACCESS
2934 assert(_num_blocks[i] >= (size_t)_indexedFreeList[i].count(),
2935 "Can't retire more than what we obtained");
2936 if (_num_blocks[i] > 0) {
2937 size_t num_retire = _indexedFreeList[i].count();
2938 assert(_num_blocks[i] > num_retire, "Should have used at least one");
2939 {
2940 #if CFLS_LAB_PARALLEL_ACCESS
2941 MutexLockerEx x(_cfls->_indexedFreeListParLocks[i],
2942 Mutex::_no_safepoint_check_flag);
2943 #endif // CFLS_LAB_PARALLEL_ACCESS
2944 // Update globals stats for num_blocks used
2945 _global_num_blocks[i] += (_num_blocks[i] - num_retire);
2946 _global_num_workers[i]++;
2947 assert(_global_num_workers[i] <= (ssize_t)ParallelGCThreads, "Too big");
2948 if (num_retire > 0) {
2949 _cfls->_indexedFreeList[i].prepend(&_indexedFreeList[i]);
2950 // Reset this list.
2951 _indexedFreeList[i] = FreeList();
2952 _indexedFreeList[i].set_size(i);
2953 }
2954 }
2955 if (PrintOldPLAB) {
2956 gclog_or_tty->print_cr("%d[%d]: %d/%d/%d",
2957 tid, i, num_retire, _num_blocks[i], (size_t)_blocks_to_claim[i].average());
2958 }
2959 // Reset stats for next round
2960 _num_blocks[i] = 0;
2961 }
2962 }
2963 }
2964
2965 void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList* fl) {
2647 assert(fl->count() == 0, "Precondition."); 2966 assert(fl->count() == 0, "Precondition.");
2648 assert(word_sz < CompactibleFreeListSpace::IndexSetSize, 2967 assert(word_sz < CompactibleFreeListSpace::IndexSetSize,
2649 "Precondition"); 2968 "Precondition");
2650 2969
2651 // We'll try all multiples of word_sz in the indexed set (starting with 2970 // We'll try all multiples of word_sz in the indexed set, starting with
2652 // word_sz itself), then try getting a big chunk and splitting it. 2971 // word_sz itself and, if CMSSplitIndexedFreeListBlocks, try larger multiples,
2653 int k = 1; 2972 // then try getting a big chunk and splitting it.
2654 size_t cur_sz = k * word_sz; 2973 {
2655 bool found = false; 2974 bool found;
2656 while (cur_sz < CompactibleFreeListSpace::IndexSetSize && k == 1) { 2975 int k;
2657 FreeList* gfl = &_indexedFreeList[cur_sz]; 2976 size_t cur_sz;
2658 FreeList fl_for_cur_sz; // Empty. 2977 for (k = 1, cur_sz = k * word_sz, found = false;
2659 fl_for_cur_sz.set_size(cur_sz); 2978 (cur_sz < CompactibleFreeListSpace::IndexSetSize) &&
2660 { 2979 (CMSSplitIndexedFreeListBlocks || k <= 1);
2661 MutexLockerEx x(_indexedFreeListParLocks[cur_sz], 2980 k++, cur_sz = k * word_sz) {
2662 Mutex::_no_safepoint_check_flag); 2981 FreeList* gfl = &_indexedFreeList[cur_sz];
2663 if (gfl->count() != 0) { 2982 FreeList fl_for_cur_sz; // Empty.
2664 size_t nn = MAX2(n/k, (size_t)1); 2983 fl_for_cur_sz.set_size(cur_sz);
2665 gfl->getFirstNChunksFromList(nn, &fl_for_cur_sz); 2984 {
2666 found = true; 2985 MutexLockerEx x(_indexedFreeListParLocks[cur_sz],
2667 } 2986 Mutex::_no_safepoint_check_flag);
2668 } 2987 if (gfl->count() != 0) {
2669 // Now transfer fl_for_cur_sz to fl. Common case, we hope, is k = 1. 2988 // nn is the number of chunks of size cur_sz that
2670 if (found) { 2989 // we'd need to split k-ways each, in order to create
2671 if (k == 1) { 2990 // "n" chunks of size word_sz each.
2672 fl->prepend(&fl_for_cur_sz); 2991 const size_t nn = MAX2(n/k, (size_t)1);
2673 } else { 2992 gfl->getFirstNChunksFromList(nn, &fl_for_cur_sz);
2674 // Divide each block on fl_for_cur_sz up k ways. 2993 found = true;
2675 FreeChunk* fc; 2994 if (k > 1) {
2676 while ((fc = fl_for_cur_sz.getChunkAtHead()) != NULL) { 2995 // Update split death stats for the cur_sz-size blocks list:
2677 // Must do this in reverse order, so that anybody attempting to 2996 // we increment the split death count by the number of blocks
2678 // access the main chunk sees it as a single free block until we 2997 // we just took from the cur_sz-size blocks list and which
2679 // change it. 2998 // we will be splitting below.
2680 size_t fc_size = fc->size(); 2999 ssize_t deaths = _indexedFreeList[cur_sz].splitDeaths() +
2681 for (int i = k-1; i >= 0; i--) { 3000 fl_for_cur_sz.count();
2682 FreeChunk* ffc = (FreeChunk*)((HeapWord*)fc + i * word_sz); 3001 _indexedFreeList[cur_sz].set_splitDeaths(deaths);
2683 ffc->setSize(word_sz);
2684 ffc->linkNext(NULL);
2685 ffc->linkPrev(NULL); // Mark as a free block for other (parallel) GC threads.
2686 // Above must occur before BOT is updated below.
2687 // splitting from the right, fc_size == (k - i + 1) * wordsize
2688 _bt.mark_block((HeapWord*)ffc, word_sz);
2689 fc_size -= word_sz;
2690 _bt.verify_not_unallocated((HeapWord*)ffc, ffc->size());
2691 _bt.verify_single_block((HeapWord*)fc, fc_size);
2692 _bt.verify_single_block((HeapWord*)ffc, ffc->size());
2693 // Push this on "fl".
2694 fl->returnChunkAtHead(ffc);
2695 } 3002 }
2696 // TRAP
2697 assert(fl->tail()->next() == NULL, "List invariant.");
2698 } 3003 }
2699 } 3004 }
2700 return; 3005 // Now transfer fl_for_cur_sz to fl. Common case, we hope, is k = 1.
2701 } 3006 if (found) {
2702 k++; cur_sz = k * word_sz; 3007 if (k == 1) {
3008 fl->prepend(&fl_for_cur_sz);
3009 } else {
3010 // Divide each block on fl_for_cur_sz up k ways.
3011 FreeChunk* fc;
3012 while ((fc = fl_for_cur_sz.getChunkAtHead()) != NULL) {
3013 // Must do this in reverse order, so that anybody attempting to
3014 // access the main chunk sees it as a single free block until we
3015 // change it.
3016 size_t fc_size = fc->size();
3017 for (int i = k-1; i >= 0; i--) {
3018 FreeChunk* ffc = (FreeChunk*)((HeapWord*)fc + i * word_sz);
3019 ffc->setSize(word_sz);
3020 ffc->linkNext(NULL);
3021 ffc->linkPrev(NULL); // Mark as a free block for other (parallel) GC threads.
3022 // Above must occur before BOT is updated below.
3023 // splitting from the right, fc_size == (k - i + 1) * wordsize
3024 _bt.mark_block((HeapWord*)ffc, word_sz);
3025 fc_size -= word_sz;
3026 _bt.verify_not_unallocated((HeapWord*)ffc, ffc->size());
3027 _bt.verify_single_block((HeapWord*)fc, fc_size);
3028 _bt.verify_single_block((HeapWord*)ffc, ffc->size());
3029 // Push this on "fl".
3030 fl->returnChunkAtHead(ffc);
3031 }
3032 // TRAP
3033 assert(fl->tail()->next() == NULL, "List invariant.");
3034 }
3035 }
3036 // Update birth stats for this block size.
3037 size_t num = fl->count();
3038 MutexLockerEx x(_indexedFreeListParLocks[word_sz],
3039 Mutex::_no_safepoint_check_flag);
3040 ssize_t births = _indexedFreeList[word_sz].splitBirths() + num;
3041 _indexedFreeList[word_sz].set_splitBirths(births);
3042 return;
3043 }
3044 }
2703 } 3045 }
2704 // Otherwise, we'll split a block from the dictionary. 3046 // Otherwise, we'll split a block from the dictionary.
2705 FreeChunk* fc = NULL; 3047 FreeChunk* fc = NULL;
2706 FreeChunk* rem_fc = NULL; 3048 FreeChunk* rem_fc = NULL;
2707 size_t rem; 3049 size_t rem;
2721 } else { 3063 } else {
2722 n--; 3064 n--;
2723 } 3065 }
2724 } 3066 }
2725 if (fc == NULL) return; 3067 if (fc == NULL) return;
3068 assert((ssize_t)n >= 1, "Control point invariant");
2726 // Otherwise, split up that block. 3069 // Otherwise, split up that block.
2727 size_t nn = fc->size() / word_sz; 3070 const size_t nn = fc->size() / word_sz;
2728 n = MIN2(nn, n); 3071 n = MIN2(nn, n);
3072 assert((ssize_t)n >= 1, "Control point invariant");
2729 rem = fc->size() - n * word_sz; 3073 rem = fc->size() - n * word_sz;
2730 // If there is a remainder, and it's too small, allocate one fewer. 3074 // If there is a remainder, and it's too small, allocate one fewer.
2731 if (rem > 0 && rem < MinChunkSize) { 3075 if (rem > 0 && rem < MinChunkSize) {
2732 n--; rem += word_sz; 3076 n--; rem += word_sz;
2733 } 3077 }
3078 assert((ssize_t)n >= 1, "Control point invariant");
2734 // First return the remainder, if any. 3079 // First return the remainder, if any.
2735 // Note that we hold the lock until we decide if we're going to give 3080 // Note that we hold the lock until we decide if we're going to give
2736 // back the remainder to the dictionary, since a contending allocator 3081 // back the remainder to the dictionary, since a concurrent allocation
2737 // may otherwise see the heap as empty. (We're willing to take that 3082 // may otherwise see the heap as empty. (We're willing to take that
2738 // hit if the block is a small block.) 3083 // hit if the block is a small block.)
2739 if (rem > 0) { 3084 if (rem > 0) {
2740 size_t prefix_size = n * word_sz; 3085 size_t prefix_size = n * word_sz;
2741 rem_fc = (FreeChunk*)((HeapWord*)fc + prefix_size); 3086 rem_fc = (FreeChunk*)((HeapWord*)fc + prefix_size);
2742 rem_fc->setSize(rem); 3087 rem_fc->setSize(rem);
2743 rem_fc->linkNext(NULL); 3088 rem_fc->linkNext(NULL);
2744 rem_fc->linkPrev(NULL); // Mark as a free block for other (parallel) GC threads. 3089 rem_fc->linkPrev(NULL); // Mark as a free block for other (parallel) GC threads.
2745 // Above must occur before BOT is updated below. 3090 // Above must occur before BOT is updated below.
3091 assert((ssize_t)n > 0 && prefix_size > 0 && rem_fc > fc, "Error");
2746 _bt.split_block((HeapWord*)fc, fc->size(), prefix_size); 3092 _bt.split_block((HeapWord*)fc, fc->size(), prefix_size);
2747 if (rem >= IndexSetSize) { 3093 if (rem >= IndexSetSize) {
2748 returnChunkToDictionary(rem_fc); 3094 returnChunkToDictionary(rem_fc);
2749 dictionary()->dictCensusUpdate(fc->size(), 3095 dictionary()->dictCensusUpdate(rem, true /*split*/, true /*birth*/);
2750 true /*split*/,
2751 true /*birth*/);
2752 rem_fc = NULL; 3096 rem_fc = NULL;
2753 } 3097 }
2754 // Otherwise, return it to the small list below. 3098 // Otherwise, return it to the small list below.
2755 } 3099 }
2756 } 3100 }
2757 //
2758 if (rem_fc != NULL) { 3101 if (rem_fc != NULL) {
2759 MutexLockerEx x(_indexedFreeListParLocks[rem], 3102 MutexLockerEx x(_indexedFreeListParLocks[rem],
2760 Mutex::_no_safepoint_check_flag); 3103 Mutex::_no_safepoint_check_flag);
2761 _bt.verify_not_unallocated((HeapWord*)rem_fc, rem_fc->size()); 3104 _bt.verify_not_unallocated((HeapWord*)rem_fc, rem_fc->size());
2762 _indexedFreeList[rem].returnChunkAtHead(rem_fc); 3105 _indexedFreeList[rem].returnChunkAtHead(rem_fc);
2763 smallSplitBirth(rem); 3106 smallSplitBirth(rem);
2764 } 3107 }
2765 3108 assert((ssize_t)n > 0 && fc != NULL, "Consistency");
2766 // Now do the splitting up. 3109 // Now do the splitting up.
2767 // Must do this in reverse order, so that anybody attempting to 3110 // Must do this in reverse order, so that anybody attempting to
2768 // access the main chunk sees it as a single free block until we 3111 // access the main chunk sees it as a single free block until we
2769 // change it. 3112 // change it.
2770 size_t fc_size = n * word_sz; 3113 size_t fc_size = n * word_sz;
2790 fc->linkPrev(NULL); 3133 fc->linkPrev(NULL);
2791 _bt.verify_not_unallocated((HeapWord*)fc, fc->size()); 3134 _bt.verify_not_unallocated((HeapWord*)fc, fc->size());
2792 _bt.verify_single_block((HeapWord*)fc, fc->size()); 3135 _bt.verify_single_block((HeapWord*)fc, fc->size());
2793 fl->returnChunkAtHead(fc); 3136 fl->returnChunkAtHead(fc);
2794 3137
3138 assert((ssize_t)n > 0 && (ssize_t)n == fl->count(), "Incorrect number of blocks");
2795 { 3139 {
3140 // Update the stats for this block size.
2796 MutexLockerEx x(_indexedFreeListParLocks[word_sz], 3141 MutexLockerEx x(_indexedFreeListParLocks[word_sz],
2797 Mutex::_no_safepoint_check_flag); 3142 Mutex::_no_safepoint_check_flag);
2798 ssize_t new_births = _indexedFreeList[word_sz].splitBirths() + n; 3143 const ssize_t births = _indexedFreeList[word_sz].splitBirths() + n;
2799 _indexedFreeList[word_sz].set_splitBirths(new_births); 3144 _indexedFreeList[word_sz].set_splitBirths(births);
2800 ssize_t new_surplus = _indexedFreeList[word_sz].surplus() + n; 3145 // ssize_t new_surplus = _indexedFreeList[word_sz].surplus() + n;
2801 _indexedFreeList[word_sz].set_surplus(new_surplus); 3146 // _indexedFreeList[word_sz].set_surplus(new_surplus);
2802 } 3147 }
2803 3148
2804 // TRAP 3149 // TRAP
2805 assert(fl->tail()->next() == NULL, "List invariant."); 3150 assert(fl->tail()->next() == NULL, "List invariant.");
2806 } 3151 }