68 MinChunkSize = min_chunk_size_in_bytes / BytesPerWord;
69
70 assert(IndexSetStart == 0 && IndexSetStride == 0, "already set");
71 IndexSetStart = MinChunkSize;
72 IndexSetStride = MinObjAlignment;
73 }
74
75 // Constructor
76 CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs, MemRegion mr) :
77 _bt(bs, mr),
78 // free list locks are in the range of values taken by _lockRank
79 // This range currently is [_leaf+2, _leaf+3]
80 // Note: this requires that CFLspace c'tors
81 // are called serially in the order in which the locks are
82 // are acquired in the program text. This is true today.
83 _freelistLock(_lockRank--, "CompactibleFreeListSpace._lock", true,
84 Monitor::_safepoint_check_sometimes),
85 _parDictionaryAllocLock(Mutex::leaf - 1, // == rank(ExpandHeap_lock) - 1
86 "CompactibleFreeListSpace._dict_par_lock", true,
87 Monitor::_safepoint_check_never),
88 _rescan_task_size(CardTableModRefBS::card_size_in_words * BitsPerWord *
89 CMSRescanMultiple),
90 _marking_task_size(CardTableModRefBS::card_size_in_words * BitsPerWord *
91 CMSConcMarkMultiple),
92 _collector(NULL),
93 _preconsumptionDirtyCardClosure(NULL)
94 {
95 assert(sizeof(FreeChunk) / BytesPerWord <= MinChunkSize,
96 "FreeChunk is larger than expected");
97 _bt.set_space(this);
98 initialize(mr, SpaceDecorator::Clear, SpaceDecorator::Mangle);
99
100 _dictionary = new AFLBinaryTreeDictionary(mr);
101
102 assert(_dictionary != NULL, "CMS dictionary initialization");
103 // The indexed free lists are initially all empty and are lazily
104 // filled in on demand. Initialize the array elements to NULL.
105 initializeIndexedFreeListArray();
106
107 _smallLinearAllocBlock.set(0, 0, 1024*SmallForLinearAlloc,
108 SmallForLinearAlloc);
109
110 // CMSIndexedFreeListReplenish should be at least 1
589 bool _parallel;
590 protected:
591 // Override.
592 #define walk_mem_region_with_cl_DECL(ClosureType) \
593 virtual void walk_mem_region_with_cl(MemRegion mr, \
594 HeapWord* bottom, HeapWord* top, \
595 ClosureType* cl); \
596 void walk_mem_region_with_cl_par(MemRegion mr, \
597 HeapWord* bottom, HeapWord* top, \
598 ClosureType* cl); \
599 void walk_mem_region_with_cl_nopar(MemRegion mr, \
600 HeapWord* bottom, HeapWord* top, \
601 ClosureType* cl)
602 walk_mem_region_with_cl_DECL(ExtendedOopClosure);
603 walk_mem_region_with_cl_DECL(FilteringClosure);
604
605 public:
606 FreeListSpaceDCTOC(CompactibleFreeListSpace* sp,
607 CMSCollector* collector,
608 ExtendedOopClosure* cl,
609 CardTableModRefBS::PrecisionStyle precision,
610 HeapWord* boundary,
611 bool parallel) :
612 FilteringDCTOC(sp, cl, precision, boundary),
613 _cfls(sp), _collector(collector), _parallel(parallel) {}
614 };
615
616 // We de-virtualize the block-related calls below, since we know that our
617 // space is a CompactibleFreeListSpace.
618
619 #define FreeListSpaceDCTOC__walk_mem_region_with_cl_DEFN(ClosureType) \
620 void FreeListSpaceDCTOC::walk_mem_region_with_cl(MemRegion mr, \
621 HeapWord* bottom, \
622 HeapWord* top, \
623 ClosureType* cl) { \
624 if (_parallel) { \
625 walk_mem_region_with_cl_par(mr, bottom, top, cl); \
626 } else { \
627 walk_mem_region_with_cl_nopar(mr, bottom, top, cl); \
628 } \
629 } \
673 if (_cfls->CompactibleFreeListSpace::block_is_obj_nopar(bottom) && \
674 !_cfls->CompactibleFreeListSpace::obj_allocated_since_save_marks( \
675 oop(bottom)) && \
676 !_collector->CMSCollector::is_dead_obj(oop(bottom))) { \
677 size_t word_sz = oop(bottom)->oop_iterate_size(cl, mr); \
678 bottom += _cfls->adjustObjectSize(word_sz); \
679 } else { \
680 bottom += _cfls->CompactibleFreeListSpace::block_size_nopar(bottom); \
681 } \
682 } \
683 }
684
685 // (There are only two of these, rather than N, because the split is due
686 // only to the introduction of the FilteringClosure, a local part of the
687 // impl of this abstraction.)
688 FreeListSpaceDCTOC__walk_mem_region_with_cl_DEFN(ExtendedOopClosure)
689 FreeListSpaceDCTOC__walk_mem_region_with_cl_DEFN(FilteringClosure)
690
691 DirtyCardToOopClosure*
692 CompactibleFreeListSpace::new_dcto_cl(ExtendedOopClosure* cl,
693 CardTableModRefBS::PrecisionStyle precision,
694 HeapWord* boundary,
695 bool parallel) {
696 return new FreeListSpaceDCTOC(this, _collector, cl, precision, boundary, parallel);
697 }
698
699
700 // Note on locking for the space iteration functions:
701 // since the collector's iteration activities are concurrent with
702 // allocation activities by mutators, absent a suitable mutual exclusion
703 // mechanism the iterators may go awry. For instance a block being iterated
704 // may suddenly be allocated or divided up and part of it allocated and
705 // so on.
706
707 // Apply the given closure to each block in the space.
708 void CompactibleFreeListSpace::blk_iterate_careful(BlkClosureCareful* cl) {
709 assert_lock_strong(freelistLock());
710 HeapWord *cur, *limit;
711 for (cur = bottom(), limit = end(); cur < limit;
712 cur += cl->do_blk_careful(cur));
713 }
2811
2812 // TRAP
2813 assert(fl->tail()->next() == NULL, "List invariant.");
2814 }
2815
2816 void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, AdaptiveFreeList<FreeChunk>* fl) {
2817 assert(fl->count() == 0, "Precondition.");
2818 assert(word_sz < CompactibleFreeListSpace::IndexSetSize,
2819 "Precondition");
2820
2821 if (par_get_chunk_of_blocks_IFL(word_sz, n, fl)) {
2822 // Got it
2823 return;
2824 }
2825
2826 // Otherwise, we'll split a block from the dictionary.
2827 par_get_chunk_of_blocks_dictionary(word_sz, n, fl);
2828 }
2829
2830 const size_t CompactibleFreeListSpace::max_flag_size_for_task_size() const {
2831 const size_t ergo_max = _old_gen->reserved().word_size() / (CardTableModRefBS::card_size_in_words * BitsPerWord);
2832 return ergo_max;
2833 }
2834
2835 // Set up the space's par_seq_tasks structure for work claiming
2836 // for parallel rescan. See CMSParRemarkTask where this is currently used.
2837 // XXX Need to suitably abstract and generalize this and the next
2838 // method into one.
2839 void
2840 CompactibleFreeListSpace::
2841 initialize_sequential_subtasks_for_rescan(int n_threads) {
2842 // The "size" of each task is fixed according to rescan_task_size.
2843 assert(n_threads > 0, "Unexpected n_threads argument");
2844 const size_t task_size = rescan_task_size();
2845 size_t n_tasks = (used_region().word_size() + task_size - 1)/task_size;
2846 assert((n_tasks == 0) == used_region().is_empty(), "n_tasks incorrect");
2847 assert(n_tasks == 0 ||
2848 ((used_region().start() + (n_tasks - 1)*task_size < used_region().end()) &&
2849 (used_region().start() + n_tasks*task_size >= used_region().end())),
2850 "n_tasks calculation incorrect");
2851 SequentialSubTasksDone* pst = conc_par_seq_tasks();
2852 assert(!pst->valid(), "Clobbering existing data?");
2853 // Sets the condition for completion of the subtask (how many threads
2854 // need to finish in order to be done).
2855 pst->set_n_threads(n_threads);
2856 pst->set_n_tasks((int)n_tasks);
2857 }
2858
2859 // Set up the space's par_seq_tasks structure for work claiming
2860 // for parallel concurrent marking. See CMSConcMarkTask where this is currently used.
2861 void
2862 CompactibleFreeListSpace::
2863 initialize_sequential_subtasks_for_marking(int n_threads,
2864 HeapWord* low) {
2865 // The "size" of each task is fixed according to rescan_task_size.
2866 assert(n_threads > 0, "Unexpected n_threads argument");
2867 const size_t task_size = marking_task_size();
2868 assert(task_size > CardTableModRefBS::card_size_in_words &&
2869 (task_size % CardTableModRefBS::card_size_in_words == 0),
2870 "Otherwise arithmetic below would be incorrect");
2871 MemRegion span = _old_gen->reserved();
2872 if (low != NULL) {
2873 if (span.contains(low)) {
2874 // Align low down to a card boundary so that
2875 // we can use block_offset_careful() on span boundaries.
2876 HeapWord* aligned_low = (HeapWord*)align_size_down((uintptr_t)low,
2877 CardTableModRefBS::card_size);
2878 // Clip span prefix at aligned_low
2879 span = span.intersection(MemRegion(aligned_low, span.end()));
2880 } else if (low > span.end()) {
2881 span = MemRegion(low, low); // Null region
2882 } // else use entire span
2883 }
2884 assert(span.is_empty() ||
2885 ((uintptr_t)span.start() % CardTableModRefBS::card_size == 0),
2886 "span should start at a card boundary");
2887 size_t n_tasks = (span.word_size() + task_size - 1)/task_size;
2888 assert((n_tasks == 0) == span.is_empty(), "Inconsistency");
2889 assert(n_tasks == 0 ||
2890 ((span.start() + (n_tasks - 1)*task_size < span.end()) &&
2891 (span.start() + n_tasks*task_size >= span.end())),
2892 "n_tasks calculation incorrect");
2893 SequentialSubTasksDone* pst = conc_par_seq_tasks();
2894 assert(!pst->valid(), "Clobbering existing data?");
2895 // Sets the condition for completion of the subtask (how many threads
2896 // need to finish in order to be done).
2897 pst->set_n_threads(n_threads);
2898 pst->set_n_tasks((int)n_tasks);
2899 }
|
68 MinChunkSize = min_chunk_size_in_bytes / BytesPerWord;
69
70 assert(IndexSetStart == 0 && IndexSetStride == 0, "already set");
71 IndexSetStart = MinChunkSize;
72 IndexSetStride = MinObjAlignment;
73 }
74
75 // Constructor
76 CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs, MemRegion mr) :
77 _bt(bs, mr),
78 // free list locks are in the range of values taken by _lockRank
79 // This range currently is [_leaf+2, _leaf+3]
80 // Note: this requires that CFLspace c'tors
81 // are called serially in the order in which the locks are
82 // are acquired in the program text. This is true today.
83 _freelistLock(_lockRank--, "CompactibleFreeListSpace._lock", true,
84 Monitor::_safepoint_check_sometimes),
85 _parDictionaryAllocLock(Mutex::leaf - 1, // == rank(ExpandHeap_lock) - 1
86 "CompactibleFreeListSpace._dict_par_lock", true,
87 Monitor::_safepoint_check_never),
88 _rescan_task_size(CardTable::card_size_in_words * BitsPerWord *
89 CMSRescanMultiple),
90 _marking_task_size(CardTable::card_size_in_words * BitsPerWord *
91 CMSConcMarkMultiple),
92 _collector(NULL),
93 _preconsumptionDirtyCardClosure(NULL)
94 {
95 assert(sizeof(FreeChunk) / BytesPerWord <= MinChunkSize,
96 "FreeChunk is larger than expected");
97 _bt.set_space(this);
98 initialize(mr, SpaceDecorator::Clear, SpaceDecorator::Mangle);
99
100 _dictionary = new AFLBinaryTreeDictionary(mr);
101
102 assert(_dictionary != NULL, "CMS dictionary initialization");
103 // The indexed free lists are initially all empty and are lazily
104 // filled in on demand. Initialize the array elements to NULL.
105 initializeIndexedFreeListArray();
106
107 _smallLinearAllocBlock.set(0, 0, 1024*SmallForLinearAlloc,
108 SmallForLinearAlloc);
109
110 // CMSIndexedFreeListReplenish should be at least 1
589 bool _parallel;
590 protected:
591 // Override.
592 #define walk_mem_region_with_cl_DECL(ClosureType) \
593 virtual void walk_mem_region_with_cl(MemRegion mr, \
594 HeapWord* bottom, HeapWord* top, \
595 ClosureType* cl); \
596 void walk_mem_region_with_cl_par(MemRegion mr, \
597 HeapWord* bottom, HeapWord* top, \
598 ClosureType* cl); \
599 void walk_mem_region_with_cl_nopar(MemRegion mr, \
600 HeapWord* bottom, HeapWord* top, \
601 ClosureType* cl)
602 walk_mem_region_with_cl_DECL(ExtendedOopClosure);
603 walk_mem_region_with_cl_DECL(FilteringClosure);
604
605 public:
606 FreeListSpaceDCTOC(CompactibleFreeListSpace* sp,
607 CMSCollector* collector,
608 ExtendedOopClosure* cl,
609 CardTable::PrecisionStyle precision,
610 HeapWord* boundary,
611 bool parallel) :
612 FilteringDCTOC(sp, cl, precision, boundary),
613 _cfls(sp), _collector(collector), _parallel(parallel) {}
614 };
615
616 // We de-virtualize the block-related calls below, since we know that our
617 // space is a CompactibleFreeListSpace.
618
619 #define FreeListSpaceDCTOC__walk_mem_region_with_cl_DEFN(ClosureType) \
620 void FreeListSpaceDCTOC::walk_mem_region_with_cl(MemRegion mr, \
621 HeapWord* bottom, \
622 HeapWord* top, \
623 ClosureType* cl) { \
624 if (_parallel) { \
625 walk_mem_region_with_cl_par(mr, bottom, top, cl); \
626 } else { \
627 walk_mem_region_with_cl_nopar(mr, bottom, top, cl); \
628 } \
629 } \
673 if (_cfls->CompactibleFreeListSpace::block_is_obj_nopar(bottom) && \
674 !_cfls->CompactibleFreeListSpace::obj_allocated_since_save_marks( \
675 oop(bottom)) && \
676 !_collector->CMSCollector::is_dead_obj(oop(bottom))) { \
677 size_t word_sz = oop(bottom)->oop_iterate_size(cl, mr); \
678 bottom += _cfls->adjustObjectSize(word_sz); \
679 } else { \
680 bottom += _cfls->CompactibleFreeListSpace::block_size_nopar(bottom); \
681 } \
682 } \
683 }
684
685 // (There are only two of these, rather than N, because the split is due
686 // only to the introduction of the FilteringClosure, a local part of the
687 // impl of this abstraction.)
688 FreeListSpaceDCTOC__walk_mem_region_with_cl_DEFN(ExtendedOopClosure)
689 FreeListSpaceDCTOC__walk_mem_region_with_cl_DEFN(FilteringClosure)
690
691 DirtyCardToOopClosure*
692 CompactibleFreeListSpace::new_dcto_cl(ExtendedOopClosure* cl,
693 CardTable::PrecisionStyle precision,
694 HeapWord* boundary,
695 bool parallel) {
696 return new FreeListSpaceDCTOC(this, _collector, cl, precision, boundary, parallel);
697 }
698
699
700 // Note on locking for the space iteration functions:
701 // since the collector's iteration activities are concurrent with
702 // allocation activities by mutators, absent a suitable mutual exclusion
703 // mechanism the iterators may go awry. For instance a block being iterated
704 // may suddenly be allocated or divided up and part of it allocated and
705 // so on.
706
707 // Apply the given closure to each block in the space.
708 void CompactibleFreeListSpace::blk_iterate_careful(BlkClosureCareful* cl) {
709 assert_lock_strong(freelistLock());
710 HeapWord *cur, *limit;
711 for (cur = bottom(), limit = end(); cur < limit;
712 cur += cl->do_blk_careful(cur));
713 }
2811
2812 // TRAP
2813 assert(fl->tail()->next() == NULL, "List invariant.");
2814 }
2815
2816 void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, AdaptiveFreeList<FreeChunk>* fl) {
2817 assert(fl->count() == 0, "Precondition.");
2818 assert(word_sz < CompactibleFreeListSpace::IndexSetSize,
2819 "Precondition");
2820
2821 if (par_get_chunk_of_blocks_IFL(word_sz, n, fl)) {
2822 // Got it
2823 return;
2824 }
2825
2826 // Otherwise, we'll split a block from the dictionary.
2827 par_get_chunk_of_blocks_dictionary(word_sz, n, fl);
2828 }
2829
2830 const size_t CompactibleFreeListSpace::max_flag_size_for_task_size() const {
2831 const size_t ergo_max = _old_gen->reserved().word_size() / (CardTable::card_size_in_words * BitsPerWord);
2832 return ergo_max;
2833 }
2834
2835 // Set up the space's par_seq_tasks structure for work claiming
2836 // for parallel rescan. See CMSParRemarkTask where this is currently used.
2837 // XXX Need to suitably abstract and generalize this and the next
2838 // method into one.
2839 void
2840 CompactibleFreeListSpace::
2841 initialize_sequential_subtasks_for_rescan(int n_threads) {
2842 // The "size" of each task is fixed according to rescan_task_size.
2843 assert(n_threads > 0, "Unexpected n_threads argument");
2844 const size_t task_size = rescan_task_size();
2845 size_t n_tasks = (used_region().word_size() + task_size - 1)/task_size;
2846 assert((n_tasks == 0) == used_region().is_empty(), "n_tasks incorrect");
2847 assert(n_tasks == 0 ||
2848 ((used_region().start() + (n_tasks - 1)*task_size < used_region().end()) &&
2849 (used_region().start() + n_tasks*task_size >= used_region().end())),
2850 "n_tasks calculation incorrect");
2851 SequentialSubTasksDone* pst = conc_par_seq_tasks();
2852 assert(!pst->valid(), "Clobbering existing data?");
2853 // Sets the condition for completion of the subtask (how many threads
2854 // need to finish in order to be done).
2855 pst->set_n_threads(n_threads);
2856 pst->set_n_tasks((int)n_tasks);
2857 }
2858
2859 // Set up the space's par_seq_tasks structure for work claiming
2860 // for parallel concurrent marking. See CMSConcMarkTask where this is currently used.
2861 void
2862 CompactibleFreeListSpace::
2863 initialize_sequential_subtasks_for_marking(int n_threads,
2864 HeapWord* low) {
2865 // The "size" of each task is fixed according to rescan_task_size.
2866 assert(n_threads > 0, "Unexpected n_threads argument");
2867 const size_t task_size = marking_task_size();
2868 assert(task_size > CardTable::card_size_in_words &&
2869 (task_size % CardTable::card_size_in_words == 0),
2870 "Otherwise arithmetic below would be incorrect");
2871 MemRegion span = _old_gen->reserved();
2872 if (low != NULL) {
2873 if (span.contains(low)) {
2874 // Align low down to a card boundary so that
2875 // we can use block_offset_careful() on span boundaries.
2876 HeapWord* aligned_low = (HeapWord*)align_size_down((uintptr_t)low,
2877 CardTable::card_size);
2878 // Clip span prefix at aligned_low
2879 span = span.intersection(MemRegion(aligned_low, span.end()));
2880 } else if (low > span.end()) {
2881 span = MemRegion(low, low); // Null region
2882 } // else use entire span
2883 }
2884 assert(span.is_empty() ||
2885 ((uintptr_t)span.start() % CardTable::card_size == 0),
2886 "span should start at a card boundary");
2887 size_t n_tasks = (span.word_size() + task_size - 1)/task_size;
2888 assert((n_tasks == 0) == span.is_empty(), "Inconsistency");
2889 assert(n_tasks == 0 ||
2890 ((span.start() + (n_tasks - 1)*task_size < span.end()) &&
2891 (span.start() + n_tasks*task_size >= span.end())),
2892 "n_tasks calculation incorrect");
2893 SequentialSubTasksDone* pst = conc_par_seq_tasks();
2894 assert(!pst->valid(), "Clobbering existing data?");
2895 // Sets the condition for completion of the subtask (how many threads
2896 // need to finish in order to be done).
2897 pst->set_n_threads(n_threads);
2898 pst->set_n_tasks((int)n_tasks);
2899 }
|