comparison src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp @ 20520:4001310db3f5

8026303: CMS: JVM intermittently crashes with "FreeList of size 258 violates Conservation Principle" assert Reviewed-by: tschatzl, brutisso
author jmasa
date Thu, 21 Nov 2013 09:57:00 -0800
parents 6c523f5d5440
children a28b7832203a c2844108a708
comparison
equal deleted inserted replaced
20519:b29261b17343 20520:4001310db3f5
2731 _num_blocks[i] = 0; 2731 _num_blocks[i] = 0;
2732 } 2732 }
2733 } 2733 }
2734 } 2734 }
2735 2735
2736 void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, AdaptiveFreeList<FreeChunk>* fl) { 2736 // Used by par_get_chunk_of_blocks() for the chunks from the
2737 assert(fl->count() == 0, "Precondition."); 2737 // indexed_free_lists. Looks for a chunk with size that is a multiple
2738 assert(word_sz < CompactibleFreeListSpace::IndexSetSize, 2738 // of "word_sz" and if found, splits it into "word_sz" chunks and add
2739 "Precondition"); 2739 // to the free list "fl". "n" is the maximum number of chunks to
2740 // be added to "fl".
2741 bool CompactibleFreeListSpace:: par_get_chunk_of_blocks_IFL(size_t word_sz, size_t n, AdaptiveFreeList<FreeChunk>* fl) {
2740 2742
2741 // We'll try all multiples of word_sz in the indexed set, starting with 2743 // We'll try all multiples of word_sz in the indexed set, starting with
2742 // word_sz itself and, if CMSSplitIndexedFreeListBlocks, try larger multiples, 2744 // word_sz itself and, if CMSSplitIndexedFreeListBlocks, try larger multiples,
2743 // then try getting a big chunk and splitting it. 2745 // then try getting a big chunk and splitting it.
2744 { 2746 {
2815 size_t num = fl->count(); 2817 size_t num = fl->count();
2816 MutexLockerEx x(_indexedFreeListParLocks[word_sz], 2818 MutexLockerEx x(_indexedFreeListParLocks[word_sz],
2817 Mutex::_no_safepoint_check_flag); 2819 Mutex::_no_safepoint_check_flag);
2818 ssize_t births = _indexedFreeList[word_sz].split_births() + num; 2820 ssize_t births = _indexedFreeList[word_sz].split_births() + num;
2819 _indexedFreeList[word_sz].set_split_births(births); 2821 _indexedFreeList[word_sz].set_split_births(births);
2820 return; 2822 return true;
2821 } 2823 }
2822 } 2824 }
2823 } 2825 return found;
2824 // Otherwise, we'll split a block from the dictionary. 2826 }
2827 }
2828
2829 FreeChunk* CompactibleFreeListSpace::get_n_way_chunk_to_split(size_t word_sz, size_t n) {
2830
2825 FreeChunk* fc = NULL; 2831 FreeChunk* fc = NULL;
2826 FreeChunk* rem_fc = NULL; 2832 FreeChunk* rem_fc = NULL;
2827 size_t rem; 2833 size_t rem;
2828 { 2834 {
2829 MutexLockerEx x(parDictionaryAllocLock(), 2835 MutexLockerEx x(parDictionaryAllocLock(),
2830 Mutex::_no_safepoint_check_flag); 2836 Mutex::_no_safepoint_check_flag);
2831 while (n > 0) { 2837 while (n > 0) {
2832 fc = dictionary()->get_chunk(MAX2(n * word_sz, _dictionary->min_size()), 2838 fc = dictionary()->get_chunk(MAX2(n * word_sz, _dictionary->min_size()),
2833 FreeBlockDictionary<FreeChunk>::atLeast); 2839 FreeBlockDictionary<FreeChunk>::atLeast);
2834 if (fc != NULL) { 2840 if (fc != NULL) {
2835 _bt.allocated((HeapWord*)fc, fc->size(), true /* reducing */); // update _unallocated_blk
2836 dictionary()->dict_census_update(fc->size(),
2837 true /*split*/,
2838 false /*birth*/);
2839 break; 2841 break;
2840 } else { 2842 } else {
2841 n--; 2843 n--;
2842 } 2844 }
2843 } 2845 }
2844 if (fc == NULL) return; 2846 if (fc == NULL) return NULL;
2845 // Otherwise, split up that block. 2847 // Otherwise, split up that block.
2846 assert((ssize_t)n >= 1, "Control point invariant"); 2848 assert((ssize_t)n >= 1, "Control point invariant");
2847 assert(fc->is_free(), "Error: should be a free block"); 2849 assert(fc->is_free(), "Error: should be a free block");
2848 _bt.verify_single_block((HeapWord*)fc, fc->size()); 2850 _bt.verify_single_block((HeapWord*)fc, fc->size());
2849 const size_t nn = fc->size() / word_sz; 2851 const size_t nn = fc->size() / word_sz;
2861 // enough to leave a viable remainder. We are unable to 2863 // enough to leave a viable remainder. We are unable to
2862 // allocate even one block. Return fc to the 2864 // allocate even one block. Return fc to the
2863 // dictionary and return, leaving "fl" empty. 2865 // dictionary and return, leaving "fl" empty.
2864 if (n == 0) { 2866 if (n == 0) {
2865 returnChunkToDictionary(fc); 2867 returnChunkToDictionary(fc);
2866 assert(fl->count() == 0, "We never allocated any blocks"); 2868 return NULL;
2867 return; 2869 }
2868 } 2870
2871 _bt.allocated((HeapWord*)fc, fc->size(), true /* reducing */); // update _unallocated_blk
2872 dictionary()->dict_census_update(fc->size(),
2873 true /*split*/,
2874 false /*birth*/);
2869 2875
2870 // First return the remainder, if any. 2876 // First return the remainder, if any.
2871 // Note that we hold the lock until we decide if we're going to give 2877 // Note that we hold the lock until we decide if we're going to give
2872 // back the remainder to the dictionary, since a concurrent allocation 2878 // back the remainder to the dictionary, since a concurrent allocation
2873 // may otherwise see the heap as empty. (We're willing to take that 2879 // may otherwise see the heap as empty. (We're willing to take that
2897 Mutex::_no_safepoint_check_flag); 2903 Mutex::_no_safepoint_check_flag);
2898 _bt.verify_not_unallocated((HeapWord*)rem_fc, rem_fc->size()); 2904 _bt.verify_not_unallocated((HeapWord*)rem_fc, rem_fc->size());
2899 _indexedFreeList[rem].return_chunk_at_head(rem_fc); 2905 _indexedFreeList[rem].return_chunk_at_head(rem_fc);
2900 smallSplitBirth(rem); 2906 smallSplitBirth(rem);
2901 } 2907 }
2902 assert((ssize_t)n > 0 && fc != NULL, "Consistency"); 2908 assert(n * word_sz == fc->size(),
2909 err_msg("Chunk size " SIZE_FORMAT " is not exactly splittable by "
2910 SIZE_FORMAT " sized chunks of size " SIZE_FORMAT,
2911 fc->size(), n, word_sz));
2912 return fc;
2913 }
2914
2915 void CompactibleFreeListSpace:: par_get_chunk_of_blocks_dictionary(size_t word_sz, size_t targetted_number_of_chunks, AdaptiveFreeList<FreeChunk>* fl) {
2916
2917 FreeChunk* fc = get_n_way_chunk_to_split(word_sz, targetted_number_of_chunks);
2918
2919 if (fc == NULL) {
2920 return;
2921 }
2922
2923 size_t n = fc->size() / word_sz;
2924
2925 assert((ssize_t)n > 0, "Consistency");
2903 // Now do the splitting up. 2926 // Now do the splitting up.
2904 // Must do this in reverse order, so that anybody attempting to 2927 // Must do this in reverse order, so that anybody attempting to
2905 // access the main chunk sees it as a single free block until we 2928 // access the main chunk sees it as a single free block until we
2906 // change it. 2929 // change it.
2907 size_t fc_size = n * word_sz; 2930 size_t fc_size = n * word_sz;
2943 // _indexedFreeList[word_sz].set_surplus(new_surplus); 2966 // _indexedFreeList[word_sz].set_surplus(new_surplus);
2944 } 2967 }
2945 2968
2946 // TRAP 2969 // TRAP
2947 assert(fl->tail()->next() == NULL, "List invariant."); 2970 assert(fl->tail()->next() == NULL, "List invariant.");
2971 }
2972
2973 void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, AdaptiveFreeList<FreeChunk>* fl) {
2974 assert(fl->count() == 0, "Precondition.");
2975 assert(word_sz < CompactibleFreeListSpace::IndexSetSize,
2976 "Precondition");
2977
2978 if (par_get_chunk_of_blocks_IFL(word_sz, n, fl)) {
2979 // Got it
2980 return;
2981 }
2982
2983 // Otherwise, we'll split a block from the dictionary.
2984 par_get_chunk_of_blocks_dictionary(word_sz, n, fl);
2948 } 2985 }
2949 2986
2950 // Set up the space's par_seq_tasks structure for work claiming 2987 // Set up the space's par_seq_tasks structure for work claiming
2951 // for parallel rescan. See CMSParRemarkTask where this is currently used. 2988 // for parallel rescan. See CMSParRemarkTask where this is currently used.
2952 // XXX Need to suitably abstract and generalize this and the next 2989 // XXX Need to suitably abstract and generalize this and the next