comparison src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp @ 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 a8127dc669ba
comparison
equal deleted inserted replaced
1111:44f61c24ddab 1145:e018e6884bd8
23 */ 23 */
24 24
25 // Classes in support of keeping track of promotions into a non-Contiguous 25 // Classes in support of keeping track of promotions into a non-Contiguous
26 // space, in this case a CompactibleFreeListSpace. 26 // space, in this case a CompactibleFreeListSpace.
27 27
28 #define CFLS_LAB_REFILL_STATS 0
29
30 // Forward declarations 28 // Forward declarations
31 class CompactibleFreeListSpace; 29 class CompactibleFreeListSpace;
32 class BlkClosure; 30 class BlkClosure;
33 class BlkClosureCareful; 31 class BlkClosureCareful;
34 class UpwardsObjectClosure; 32 class UpwardsObjectClosure;
87 void init() { 85 void init() {
88 bufferSize = computeBufferSize(); 86 bufferSize = computeBufferSize();
89 displacedHdr = (markOop*)&displacedHdr; 87 displacedHdr = (markOop*)&displacedHdr;
90 nextSpoolBlock = NULL; 88 nextSpoolBlock = NULL;
91 } 89 }
90
91 void print_on(outputStream* st) const;
92 void print() const { print_on(gclog_or_tty); }
92 }; 93 };
93 94
94 class PromotionInfo VALUE_OBJ_CLASS_SPEC { 95 class PromotionInfo VALUE_OBJ_CLASS_SPEC {
95 bool _tracking; // set if tracking 96 bool _tracking; // set if tracking
96 CompactibleFreeListSpace* _space; // the space to which this belongs 97 CompactibleFreeListSpace* _space; // the space to which this belongs
119 bool noPromotions() const { 120 bool noPromotions() const {
120 assert(_promoHead != NULL || _promoTail == NULL, "list inconsistency"); 121 assert(_promoHead != NULL || _promoTail == NULL, "list inconsistency");
121 return _promoHead == NULL; 122 return _promoHead == NULL;
122 } 123 }
123 void startTrackingPromotions(); 124 void startTrackingPromotions();
124 void stopTrackingPromotions(); 125 void stopTrackingPromotions(uint worker_id = 0);
125 bool tracking() const { return _tracking; } 126 bool tracking() const { return _tracking; }
126 void track(PromotedObject* trackOop); // keep track of a promoted oop 127 void track(PromotedObject* trackOop); // keep track of a promoted oop
127 // The following variant must be used when trackOop is not fully 128 // The following variant must be used when trackOop is not fully
128 // initialized and has a NULL klass: 129 // initialized and has a NULL klass:
129 void track(PromotedObject* trackOop, klassOop klassOfOop); // keep track of a promoted oop 130 void track(PromotedObject* trackOop, klassOop klassOfOop); // keep track of a promoted oop
159 _spareSpool = NULL; 160 _spareSpool = NULL;
160 _firstIndex = 0; 161 _firstIndex = 0;
161 _nextIndex = 0; 162 _nextIndex = 0;
162 163
163 } 164 }
165
166 void print_on(outputStream* st) const;
167 void print_statistics(uint worker_id) const;
164 }; 168 };
165 169
166 class LinearAllocBlock VALUE_OBJ_CLASS_SPEC { 170 class LinearAllocBlock VALUE_OBJ_CLASS_SPEC {
167 public: 171 public:
168 LinearAllocBlock() : _ptr(0), _word_size(0), _refillSize(0), 172 LinearAllocBlock() : _ptr(0), _word_size(0), _refillSize(0),
241 // a lock protecting the free lists and free blocks; 245 // a lock protecting the free lists and free blocks;
242 // mutable because of ubiquity of locking even for otherwise const methods 246 // mutable because of ubiquity of locking even for otherwise const methods
243 mutable Mutex _freelistLock; 247 mutable Mutex _freelistLock;
244 // locking verifier convenience function 248 // locking verifier convenience function
245 void assert_locked() const PRODUCT_RETURN; 249 void assert_locked() const PRODUCT_RETURN;
250 void assert_locked(const Mutex* lock) const PRODUCT_RETURN;
246 251
247 // Linear allocation blocks 252 // Linear allocation blocks
248 LinearAllocBlock _smallLinearAllocBlock; 253 LinearAllocBlock _smallLinearAllocBlock;
249 254
250 FreeBlockDictionary::DictionaryChoice _dictionaryChoice; 255 FreeBlockDictionary::DictionaryChoice _dictionaryChoice;
278 mutable Mutex _parDictionaryAllocLock; 283 mutable Mutex _parDictionaryAllocLock;
279 Mutex* parDictionaryAllocLock() const { return &_parDictionaryAllocLock; } 284 Mutex* parDictionaryAllocLock() const { return &_parDictionaryAllocLock; }
280 285
281 // Locks protecting the exact lists during par promotion allocation. 286 // Locks protecting the exact lists during par promotion allocation.
282 Mutex* _indexedFreeListParLocks[IndexSetSize]; 287 Mutex* _indexedFreeListParLocks[IndexSetSize];
283
284 #if CFLS_LAB_REFILL_STATS
285 // Some statistics.
286 jint _par_get_chunk_from_small;
287 jint _par_get_chunk_from_large;
288 #endif
289
290 288
291 // Attempt to obtain up to "n" blocks of the size "word_sz" (which is 289 // Attempt to obtain up to "n" blocks of the size "word_sz" (which is
292 // required to be smaller than "IndexSetSize".) If successful, 290 // required to be smaller than "IndexSetSize".) If successful,
293 // adds them to "fl", which is required to be an empty free list. 291 // adds them to "fl", which is required to be an empty free list.
294 // If the count of "fl" is negative, it's absolute value indicates a 292 // If the count of "fl" is negative, it's absolute value indicates a
318 inline HeapWord* getChunkFromSmallLinearAllocBlockRemainder(size_t size); 316 inline HeapWord* getChunkFromSmallLinearAllocBlockRemainder(size_t size);
319 317
320 // Helper function for getChunkFromIndexedFreeList. 318 // Helper function for getChunkFromIndexedFreeList.
321 // Replenish the indexed free list for this "size". Do not take from an 319 // Replenish the indexed free list for this "size". Do not take from an
322 // underpopulated size. 320 // underpopulated size.
323 FreeChunk* getChunkFromIndexedFreeListHelper(size_t size); 321 FreeChunk* getChunkFromIndexedFreeListHelper(size_t size, bool replenish = true);
324 322
325 // Get a chunk from the indexed free list. If the indexed free list 323 // Get a chunk from the indexed free list. If the indexed free list
326 // does not have a free chunk, try to replenish the indexed free list 324 // does not have a free chunk, try to replenish the indexed free list
327 // then get the free chunk from the replenished indexed free list. 325 // then get the free chunk from the replenished indexed free list.
328 inline FreeChunk* getChunkFromIndexedFreeList(size_t size); 326 inline FreeChunk* getChunkFromIndexedFreeList(size_t size);
428 SequentialSubTasksDone* conc_par_seq_tasks() {return &_conc_par_seq_tasks; } 426 SequentialSubTasksDone* conc_par_seq_tasks() {return &_conc_par_seq_tasks; }
429 void initialize_sequential_subtasks_for_rescan(int n_threads); 427 void initialize_sequential_subtasks_for_rescan(int n_threads);
430 void initialize_sequential_subtasks_for_marking(int n_threads, 428 void initialize_sequential_subtasks_for_marking(int n_threads,
431 HeapWord* low = NULL); 429 HeapWord* low = NULL);
432 430
433 #if CFLS_LAB_REFILL_STATS
434 void print_par_alloc_stats();
435 #endif
436
437 // Space enquiries 431 // Space enquiries
438 size_t used() const; 432 size_t used() const;
439 size_t free() const; 433 size_t free() const;
440 size_t max_alloc_in_words() const; 434 size_t max_alloc_in_words() const;
441 // XXX: should have a less conservative used_region() than that of 435 // XXX: should have a less conservative used_region() than that of
615 // verify that the given chunk is in the free lists. 609 // verify that the given chunk is in the free lists.
616 bool verifyChunkInFreeLists(FreeChunk* fc) const; 610 bool verifyChunkInFreeLists(FreeChunk* fc) const;
617 // Do some basic checks on the the free lists. 611 // Do some basic checks on the the free lists.
618 void checkFreeListConsistency() const PRODUCT_RETURN; 612 void checkFreeListConsistency() const PRODUCT_RETURN;
619 613
614 // Printing support
615 void dump_at_safepoint_with_locks(CMSCollector* c, outputStream* st);
616 void print_indexed_free_lists(outputStream* st) const;
617 void print_dictionary_free_lists(outputStream* st) const;
618 void print_promo_info_blocks(outputStream* st) const;
619
620 NOT_PRODUCT ( 620 NOT_PRODUCT (
621 void initializeIndexedFreeListArrayReturnedBytes(); 621 void initializeIndexedFreeListArrayReturnedBytes();
622 size_t sumIndexedFreeListArrayReturnedBytes(); 622 size_t sumIndexedFreeListArrayReturnedBytes();
623 // Return the total number of chunks in the indexed free lists. 623 // Return the total number of chunks in the indexed free lists.
624 size_t totalCountInIndexedFreeLists() const; 624 size_t totalCountInIndexedFreeLists() const;
636 // Print the statistics for the free lists. 636 // Print the statistics for the free lists.
637 void printFLCensus(size_t sweep_count) const; 637 void printFLCensus(size_t sweep_count) const;
638 638
639 // Statistics functions 639 // Statistics functions
640 // Initialize census for lists before the sweep. 640 // Initialize census for lists before the sweep.
641 void beginSweepFLCensus(float sweep_current, 641 void beginSweepFLCensus(float inter_sweep_current,
642 float sweep_estimate); 642 float inter_sweep_estimate,
643 float intra_sweep_estimate);
643 // Set the surplus for each of the free lists. 644 // Set the surplus for each of the free lists.
644 void setFLSurplus(); 645 void setFLSurplus();
645 // Set the hint for each of the free lists. 646 // Set the hint for each of the free lists.
646 void setFLHints(); 647 void setFLHints();
647 // Clear the census for each of the free lists. 648 // Clear the census for each of the free lists.
728 729
729 // Our local free lists. 730 // Our local free lists.
730 FreeList _indexedFreeList[CompactibleFreeListSpace::IndexSetSize]; 731 FreeList _indexedFreeList[CompactibleFreeListSpace::IndexSetSize];
731 732
732 // Initialized from a command-line arg. 733 // Initialized from a command-line arg.
733 size_t _blocks_to_claim; 734
734 735 // Allocation statistics in support of dynamic adjustment of
735 #if CFLS_LAB_REFILL_STATS 736 // #blocks to claim per get_from_global_pool() call below.
736 // Some statistics. 737 static AdaptiveWeightedAverage
737 int _refills; 738 _blocks_to_claim [CompactibleFreeListSpace::IndexSetSize];
738 int _blocksTaken; 739 static size_t _global_num_blocks [CompactibleFreeListSpace::IndexSetSize];
739 static int _tot_refills; 740 static int _global_num_workers[CompactibleFreeListSpace::IndexSetSize];
740 static int _tot_blocksTaken; 741 size_t _num_blocks [CompactibleFreeListSpace::IndexSetSize];
741 static int _next_threshold; 742
742 #endif 743 // Internal work method
744 void get_from_global_pool(size_t word_sz, FreeList* fl);
743 745
744 public: 746 public:
745 CFLS_LAB(CompactibleFreeListSpace* cfls); 747 CFLS_LAB(CompactibleFreeListSpace* cfls);
746 748
747 // Allocate and return a block of the given size, or else return NULL. 749 // Allocate and return a block of the given size, or else return NULL.
748 HeapWord* alloc(size_t word_sz); 750 HeapWord* alloc(size_t word_sz);
749 751
750 // Return any unused portions of the buffer to the global pool. 752 // Return any unused portions of the buffer to the global pool.
751 void retire(); 753 void retire(int tid);
754
755 // Dynamic OldPLABSize sizing
756 static void compute_desired_plab_size();
757 // When the settings are modified from default static initialization
758 static void modify_initialization(size_t n, unsigned wt);
752 }; 759 };
753 760
754 size_t PromotionInfo::refillSize() const { 761 size_t PromotionInfo::refillSize() const {
755 const size_t CMSSpoolBlockSize = 256; 762 const size_t CMSSpoolBlockSize = 256;
756 const size_t sz = heap_word_size(sizeof(SpoolBlock) + sizeof(markOop) 763 const size_t sz = heap_word_size(sizeof(SpoolBlock) + sizeof(markOop)