1.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Mon Oct 20 15:14:56 2014 -0400 1.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Thu Nov 21 09:57:00 2013 -0800 1.3 @@ -2760,10 +2760,12 @@ 1.4 } 1.5 } 1.6 1.7 -void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, AdaptiveFreeList<FreeChunk>* fl) { 1.8 - assert(fl->count() == 0, "Precondition."); 1.9 - assert(word_sz < CompactibleFreeListSpace::IndexSetSize, 1.10 - "Precondition"); 1.11 +// Used by par_get_chunk_of_blocks() for the chunks from the 1.12 +// indexed_free_lists. Looks for a chunk with size that is a multiple 1.13 +// of "word_sz" and if found, splits it into "word_sz" chunks and add 1.14 +// to the free list "fl". "n" is the maximum number of chunks to 1.15 +// be added to "fl". 1.16 +bool CompactibleFreeListSpace:: par_get_chunk_of_blocks_IFL(size_t word_sz, size_t n, AdaptiveFreeList<FreeChunk>* fl) { 1.17 1.18 // We'll try all multiples of word_sz in the indexed set, starting with 1.19 // word_sz itself and, if CMSSplitIndexedFreeListBlocks, try larger multiples, 1.20 @@ -2844,11 +2846,15 @@ 1.21 Mutex::_no_safepoint_check_flag); 1.22 ssize_t births = _indexedFreeList[word_sz].split_births() + num; 1.23 _indexedFreeList[word_sz].set_split_births(births); 1.24 - return; 1.25 + return true; 1.26 } 1.27 } 1.28 + return found; 1.29 } 1.30 - // Otherwise, we'll split a block from the dictionary. 1.31 +} 1.32 + 1.33 +FreeChunk* CompactibleFreeListSpace::get_n_way_chunk_to_split(size_t word_sz, size_t n) { 1.34 + 1.35 FreeChunk* fc = NULL; 1.36 FreeChunk* rem_fc = NULL; 1.37 size_t rem; 1.38 @@ -2859,16 +2865,12 @@ 1.39 fc = dictionary()->get_chunk(MAX2(n * word_sz, _dictionary->min_size()), 1.40 FreeBlockDictionary<FreeChunk>::atLeast); 1.41 if (fc != NULL) { 1.42 - _bt.allocated((HeapWord*)fc, fc->size(), true /* reducing */); // update _unallocated_blk 1.43 - dictionary()->dict_census_update(fc->size(), 1.44 - true /*split*/, 1.45 - false /*birth*/); 1.46 break; 1.47 } else { 1.48 n--; 1.49 } 1.50 } 1.51 - if (fc == NULL) return; 1.52 + if (fc == NULL) return NULL; 1.53 // Otherwise, split up that block. 1.54 assert((ssize_t)n >= 1, "Control point invariant"); 1.55 assert(fc->is_free(), "Error: should be a free block"); 1.56 @@ -2890,10 +2892,14 @@ 1.57 // dictionary and return, leaving "fl" empty. 1.58 if (n == 0) { 1.59 returnChunkToDictionary(fc); 1.60 - assert(fl->count() == 0, "We never allocated any blocks"); 1.61 - return; 1.62 + return NULL; 1.63 } 1.64 1.65 + _bt.allocated((HeapWord*)fc, fc->size(), true /* reducing */); // update _unallocated_blk 1.66 + dictionary()->dict_census_update(fc->size(), 1.67 + true /*split*/, 1.68 + false /*birth*/); 1.69 + 1.70 // First return the remainder, if any. 1.71 // Note that we hold the lock until we decide if we're going to give 1.72 // back the remainder to the dictionary, since a concurrent allocation 1.73 @@ -2926,7 +2932,24 @@ 1.74 _indexedFreeList[rem].return_chunk_at_head(rem_fc); 1.75 smallSplitBirth(rem); 1.76 } 1.77 - assert((ssize_t)n > 0 && fc != NULL, "Consistency"); 1.78 + assert(n * word_sz == fc->size(), 1.79 + err_msg("Chunk size " SIZE_FORMAT " is not exactly splittable by " 1.80 + SIZE_FORMAT " sized chunks of size " SIZE_FORMAT, 1.81 + fc->size(), n, word_sz)); 1.82 + return fc; 1.83 +} 1.84 + 1.85 +void CompactibleFreeListSpace:: par_get_chunk_of_blocks_dictionary(size_t word_sz, size_t targetted_number_of_chunks, AdaptiveFreeList<FreeChunk>* fl) { 1.86 + 1.87 + FreeChunk* fc = get_n_way_chunk_to_split(word_sz, targetted_number_of_chunks); 1.88 + 1.89 + if (fc == NULL) { 1.90 + return; 1.91 + } 1.92 + 1.93 + size_t n = fc->size() / word_sz; 1.94 + 1.95 + assert((ssize_t)n > 0, "Consistency"); 1.96 // Now do the splitting up. 1.97 // Must do this in reverse order, so that anybody attempting to 1.98 // access the main chunk sees it as a single free block until we 1.99 @@ -2974,6 +2997,20 @@ 1.100 assert(fl->tail()->next() == NULL, "List invariant."); 1.101 } 1.102 1.103 +void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, AdaptiveFreeList<FreeChunk>* fl) { 1.104 + assert(fl->count() == 0, "Precondition."); 1.105 + assert(word_sz < CompactibleFreeListSpace::IndexSetSize, 1.106 + "Precondition"); 1.107 + 1.108 + if (par_get_chunk_of_blocks_IFL(word_sz, n, fl)) { 1.109 + // Got it 1.110 + return; 1.111 + } 1.112 + 1.113 + // Otherwise, we'll split a block from the dictionary. 1.114 + par_get_chunk_of_blocks_dictionary(word_sz, n, fl); 1.115 +} 1.116 + 1.117 // Set up the space's par_seq_tasks structure for work claiming 1.118 // for parallel rescan. See CMSParRemarkTask where this is currently used. 1.119 // XXX Need to suitably abstract and generalize this and the next