< prev index next >

src/share/vm/gc/cms/compactibleFreeListSpace.cpp

Print this page
rev 12906 : [mq]: gc_interface


  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 }
< prev index next >