41 #include "runtime/java.hpp" 42 #include "runtime/vmThread.hpp" 43 #include "utilities/copy.hpp" 44 45 ///////////////////////////////////////////////////////////////////////// 46 //// CompactibleFreeListSpace 47 ///////////////////////////////////////////////////////////////////////// 48 49 // highest ranked free list lock rank 50 int CompactibleFreeListSpace::_lockRank = Mutex::leaf + 3; 51 52 // Defaults are 0 so things will break badly if incorrectly initialized. 53 size_t CompactibleFreeListSpace::IndexSetStart = 0; 54 size_t CompactibleFreeListSpace::IndexSetStride = 0; 55 56 size_t MinChunkSize = 0; 57 58 void CompactibleFreeListSpace::set_cms_values() { 59 // Set CMS global values 60 assert(MinChunkSize == 0, "already set"); 61 #define numQuanta(x,y) ((x+y-1)/y) 62 MinChunkSize = numQuanta(sizeof(FreeChunk), MinObjAlignmentInBytes) * MinObjAlignment; 63 64 assert(IndexSetStart == 0 && IndexSetStride == 0, "already set"); 65 IndexSetStart = MinChunkSize; 66 IndexSetStride = MinObjAlignment; 67 } 68 69 // Constructor 70 CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs, 71 MemRegion mr, bool use_adaptive_freelists, 72 FreeBlockDictionary<FreeChunk>::DictionaryChoice dictionaryChoice) : 73 _dictionaryChoice(dictionaryChoice), 74 _adaptive_freelists(use_adaptive_freelists), 75 _bt(bs, mr), 76 // free list locks are in the range of values taken by _lockRank 77 // This range currently is [_leaf+2, _leaf+3] 78 // Note: this requires that CFLspace c'tors 79 // are called serially in the order in which the locks are 80 // are acquired in the program text. This is true today. 81 _freelistLock(_lockRank--, "CompactibleFreeListSpace._lock", true), 82 _parDictionaryAllocLock(Mutex::leaf - 1, // == rank(ExpandHeap_lock) - 1 2517 size_t num = _indexedFreeList[size].count(); 2518 size_t n = 0; 2519 guarantee(((size >= IndexSetStart) && (size % IndexSetStride == 0)) || fc == NULL, 2520 "Slot should have been empty"); 2521 for (; fc != NULL; fc = fc->next(), n++) { 2522 guarantee(fc->size() == size, "Size inconsistency"); 2523 guarantee(fc->is_free(), "!free?"); 2524 guarantee(fc->next() == NULL || fc->next()->prev() == fc, "Broken list"); 2525 guarantee((fc->next() == NULL) == (fc == tail), "Incorrect tail"); 2526 } 2527 guarantee(n == num, "Incorrect count"); 2528 } 2529 2530 #ifndef PRODUCT 2531 void CompactibleFreeListSpace::check_free_list_consistency() const { 2532 assert(_dictionary->min_size() <= IndexSetSize, 2533 "Some sizes can't be allocated without recourse to" 2534 " linear allocation buffers"); 2535 assert(BinaryTreeDictionary<FreeChunk>::min_tree_chunk_size*HeapWordSize == sizeof(TreeChunk<FreeChunk>), 2536 "else MIN_TREE_CHUNK_SIZE is wrong"); 2537 assert((IndexSetStride == 2 && IndexSetStart == 4) || // 32-bit 2538 (IndexSetStride == 1 && IndexSetStart == 3), "just checking"); // 64-bit 2539 assert((IndexSetStride != 2) || (IndexSetStart % 2 == 0), 2540 "Some for-loops may be incorrectly initialized"); 2541 assert((IndexSetStride != 2) || (IndexSetSize % 2 == 1), 2542 "For-loops that iterate over IndexSet with stride 2 may be wrong"); 2543 } 2544 #endif 2545 2546 void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const { 2547 assert_lock_strong(&_freelistLock); 2548 FreeList<FreeChunk> total; 2549 gclog_or_tty->print("end sweep# " SIZE_FORMAT "\n", sweep_count); 2550 FreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size"); 2551 size_t total_free = 0; 2552 for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { 2553 const FreeList<FreeChunk> *fl = &_indexedFreeList[i]; 2554 total_free += fl->count() * fl->size(); 2555 if (i % (40*IndexSetStride) == 0) { 2556 FreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size"); 2557 } 2558 fl->print_on(gclog_or_tty); 2559 total.set_bfr_surp( total.bfr_surp() + fl->bfr_surp() ); 2560 total.set_surplus( total.surplus() + fl->surplus() ); 2561 total.set_desired( total.desired() + fl->desired() ); 2562 total.set_prev_sweep( total.prev_sweep() + fl->prev_sweep() ); | 41 #include "runtime/java.hpp" 42 #include "runtime/vmThread.hpp" 43 #include "utilities/copy.hpp" 44 45 ///////////////////////////////////////////////////////////////////////// 46 //// CompactibleFreeListSpace 47 ///////////////////////////////////////////////////////////////////////// 48 49 // highest ranked free list lock rank 50 int CompactibleFreeListSpace::_lockRank = Mutex::leaf + 3; 51 52 // Defaults are 0 so things will break badly if incorrectly initialized. 53 size_t CompactibleFreeListSpace::IndexSetStart = 0; 54 size_t CompactibleFreeListSpace::IndexSetStride = 0; 55 56 size_t MinChunkSize = 0; 57 58 void CompactibleFreeListSpace::set_cms_values() { 59 // Set CMS global values 60 assert(MinChunkSize == 0, "already set"); 61 62 // MinChunkSize should be a multiple of MinObjAlignment and be large enough 63 // for chunks to contain a FreeChunk. 64 size_t min_chunk_size_in_bytes = align_size_up(sizeof(FreeChunk), MinObjAlignmentInBytes); 65 MinChunkSize = min_chunk_size_in_bytes / BytesPerWord; 66 67 assert(IndexSetStart == 0 && IndexSetStride == 0, "already set"); 68 IndexSetStart = MinChunkSize; 69 IndexSetStride = MinObjAlignment; 70 } 71 72 // Constructor 73 CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs, 74 MemRegion mr, bool use_adaptive_freelists, 75 FreeBlockDictionary<FreeChunk>::DictionaryChoice dictionaryChoice) : 76 _dictionaryChoice(dictionaryChoice), 77 _adaptive_freelists(use_adaptive_freelists), 78 _bt(bs, mr), 79 // free list locks are in the range of values taken by _lockRank 80 // This range currently is [_leaf+2, _leaf+3] 81 // Note: this requires that CFLspace c'tors 82 // are called serially in the order in which the locks are 83 // are acquired in the program text. This is true today. 84 _freelistLock(_lockRank--, "CompactibleFreeListSpace._lock", true), 85 _parDictionaryAllocLock(Mutex::leaf - 1, // == rank(ExpandHeap_lock) - 1 2520 size_t num = _indexedFreeList[size].count(); 2521 size_t n = 0; 2522 guarantee(((size >= IndexSetStart) && (size % IndexSetStride == 0)) || fc == NULL, 2523 "Slot should have been empty"); 2524 for (; fc != NULL; fc = fc->next(), n++) { 2525 guarantee(fc->size() == size, "Size inconsistency"); 2526 guarantee(fc->is_free(), "!free?"); 2527 guarantee(fc->next() == NULL || fc->next()->prev() == fc, "Broken list"); 2528 guarantee((fc->next() == NULL) == (fc == tail), "Incorrect tail"); 2529 } 2530 guarantee(n == num, "Incorrect count"); 2531 } 2532 2533 #ifndef PRODUCT 2534 void CompactibleFreeListSpace::check_free_list_consistency() const { 2535 assert(_dictionary->min_size() <= IndexSetSize, 2536 "Some sizes can't be allocated without recourse to" 2537 " linear allocation buffers"); 2538 assert(BinaryTreeDictionary<FreeChunk>::min_tree_chunk_size*HeapWordSize == sizeof(TreeChunk<FreeChunk>), 2539 "else MIN_TREE_CHUNK_SIZE is wrong"); 2540 assert(IndexSetStart != 0, "IndexSetStart not initialized"); 2541 assert(IndexSetStride != 0, "IndexSetStride not initialized"); 2542 } 2543 #endif 2544 2545 void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const { 2546 assert_lock_strong(&_freelistLock); 2547 FreeList<FreeChunk> total; 2548 gclog_or_tty->print("end sweep# " SIZE_FORMAT "\n", sweep_count); 2549 FreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size"); 2550 size_t total_free = 0; 2551 for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { 2552 const FreeList<FreeChunk> *fl = &_indexedFreeList[i]; 2553 total_free += fl->count() * fl->size(); 2554 if (i % (40*IndexSetStride) == 0) { 2555 FreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size"); 2556 } 2557 fl->print_on(gclog_or_tty); 2558 total.set_bfr_surp( total.bfr_surp() + fl->bfr_surp() ); 2559 total.set_surplus( total.surplus() + fl->surplus() ); 2560 total.set_desired( total.desired() + fl->desired() ); 2561 total.set_prev_sweep( total.prev_sweep() + fl->prev_sweep() ); |