Mercurial > hg > graal-jvmci-8
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 |