< prev index next >

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

Print this page




  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "gc/shared/cardTableModRefBS.hpp"
  27 #include "gc/shared/cardTableRS.hpp"
  28 #include "gc/shared/collectedHeap.hpp"
  29 #include "gc/shared/genCollectedHeap.hpp"
  30 #include "gc/shared/space.inline.hpp"
  31 #include "memory/allocation.inline.hpp"
  32 #include "memory/virtualspace.hpp"
  33 #include "oops/oop.inline.hpp"
  34 #include "runtime/java.hpp"
  35 #include "runtime/mutexLocker.hpp"
  36 #include "runtime/orderAccess.inline.hpp"
  37 #include "runtime/vmThread.hpp"
  38 
  39 void CardTableModRefBS::non_clean_card_iterate_parallel_work(Space* sp, MemRegion mr,
  40                                                              OopsInGenClosure* cl,
  41                                                              CardTableRS* ct,
  42                                                              int n_threads) {
  43   assert(n_threads > 0, "Error: expected n_threads > 0");
  44   assert((n_threads == 1 && ParallelGCThreads == 0) ||
  45          n_threads <= (int)ParallelGCThreads,
  46          "# worker threads != # requested!");
  47   assert(!Thread::current()->is_VM_thread() || (n_threads == 1), "There is only 1 VM thread");
  48   assert(UseDynamicNumberOfGCThreads ||
  49          !FLAG_IS_DEFAULT(ParallelGCThreads) ||
  50          n_threads == (int)ParallelGCThreads,
  51          "# worker threads != # requested!");
  52   // Make sure the LNC array is valid for the space.
  53   jbyte**   lowest_non_clean;
  54   uintptr_t lowest_non_clean_base_chunk_index;
  55   size_t    lowest_non_clean_chunk_size;
  56   get_LNC_array_for_space(sp, lowest_non_clean,
  57                           lowest_non_clean_base_chunk_index,
  58                           lowest_non_clean_chunk_size);
  59 
  60   uint n_strides = n_threads * ParGCStridesPerThread;
  61   SequentialSubTasksDone* pst = sp->par_seq_tasks();
  62   // Sets the condition for completion of the subtask (how many threads
  63   // need to finish in order to be done).
  64   pst->set_n_threads(n_threads);
  65   pst->set_n_tasks(n_strides);
  66 
  67   uint stride = 0;
  68   while (!pst->is_task_claimed(/* reference */ stride)) {
  69     process_stride(sp, mr, stride, n_strides, cl, ct,

  70                    lowest_non_clean,
  71                    lowest_non_clean_base_chunk_index,
  72                    lowest_non_clean_chunk_size);
  73   }
  74   if (pst->all_tasks_completed()) {
  75     // Clear lowest_non_clean array for next time.
  76     intptr_t first_chunk_index = addr_to_chunk_index(mr.start());
  77     uintptr_t last_chunk_index  = addr_to_chunk_index(mr.last());
  78     for (uintptr_t ch = first_chunk_index; ch <= last_chunk_index; ch++) {
  79       intptr_t ind = ch - lowest_non_clean_base_chunk_index;
  80       assert(0 <= ind && ind < (intptr_t)lowest_non_clean_chunk_size,
  81              "Bounds error");
  82       lowest_non_clean[ind] = NULL;
  83     }
  84   }
  85 }
  86 
  87 void
  88 CardTableModRefBS::
  89 process_stride(Space* sp,


 115                                 (n_strides - start_chunk_stride_num + stride) *
 116                                 ParGCCardsPerStrideChunk);
 117   }
 118 
 119   while (chunk_card_start < end_card) {
 120     // Even though we go from lower to higher addresses below, the
 121     // strided parallelism can interleave the actual processing of the
 122     // dirty pages in various ways. For a specific chunk within this
 123     // stride, we take care to avoid double scanning or missing a card
 124     // by suitably initializing the "min_done" field in process_chunk_boundaries()
 125     // below, together with the dirty region extension accomplished in
 126     // DirtyCardToOopClosure::do_MemRegion().
 127     jbyte*    chunk_card_end = chunk_card_start + ParGCCardsPerStrideChunk;
 128     // Invariant: chunk_mr should be fully contained within the "used" region.
 129     MemRegion chunk_mr       = MemRegion(addr_for(chunk_card_start),
 130                                          chunk_card_end >= end_card ?
 131                                            used.end() : addr_for(chunk_card_end));
 132     assert(chunk_mr.word_size() > 0, "[chunk_card_start > used_end)");
 133     assert(used.contains(chunk_mr), "chunk_mr should be subset of used");
 134 



 135     DirtyCardToOopClosure* dcto_cl = sp->new_dcto_cl(cl, precision(),
 136                                                      cl->gen_boundary());
 137     ClearNoncleanCardWrapper clear_cl(dcto_cl, ct);

 138 
 139 
 140     // Process the chunk.
 141     process_chunk_boundaries(sp,
 142                              dcto_cl,
 143                              chunk_mr,
 144                              used,
 145                              lowest_non_clean,
 146                              lowest_non_clean_base_chunk_index,
 147                              lowest_non_clean_chunk_size);
 148 
 149     // We want the LNC array updates above in process_chunk_boundaries
 150     // to be visible before any of the card table value changes as a
 151     // result of the dirty card iteration below.
 152     OrderAccess::storestore();
 153 
 154     // We want to clear the cards: clear_cl here does the work of finding
 155     // contiguous dirty ranges of cards to process and clear.
 156     clear_cl.do_MemRegion(chunk_mr);
 157 




  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "gc/shared/cardTableModRefBS.hpp"
  27 #include "gc/shared/cardTableRS.hpp"
  28 #include "gc/shared/collectedHeap.hpp"
  29 #include "gc/shared/genCollectedHeap.hpp"
  30 #include "gc/shared/space.inline.hpp"
  31 #include "memory/allocation.inline.hpp"
  32 #include "memory/virtualspace.hpp"
  33 #include "oops/oop.inline.hpp"
  34 #include "runtime/java.hpp"
  35 #include "runtime/mutexLocker.hpp"
  36 #include "runtime/orderAccess.inline.hpp"
  37 #include "runtime/vmThread.hpp"
  38 
  39 void CardTableModRefBS::non_clean_card_iterate_parallel_work(Space* sp, MemRegion mr,
  40                                                              OopsInGenClosure* cl,
  41                                                              CardTableRS* ct,
  42                                                              uint n_threads) {
  43   assert(n_threads > 0, "Error: expected n_threads > 0");
  44   assert(n_threads <= (uint)ParallelGCThreads,
  45          err_msg("Error: n_threads: %u > ParallelGCThreads: %u", n_threads, (uint)ParallelGCThreads));
  46 





  47   // Make sure the LNC array is valid for the space.
  48   jbyte**   lowest_non_clean;
  49   uintptr_t lowest_non_clean_base_chunk_index;
  50   size_t    lowest_non_clean_chunk_size;
  51   get_LNC_array_for_space(sp, lowest_non_clean,
  52                           lowest_non_clean_base_chunk_index,
  53                           lowest_non_clean_chunk_size);
  54 
  55   uint n_strides = n_threads * ParGCStridesPerThread;
  56   SequentialSubTasksDone* pst = sp->par_seq_tasks();
  57   // Sets the condition for completion of the subtask (how many threads
  58   // need to finish in order to be done).
  59   pst->set_n_threads(n_threads);
  60   pst->set_n_tasks(n_strides);
  61 
  62   uint stride = 0;
  63   while (!pst->is_task_claimed(/* reference */ stride)) {
  64     process_stride(sp, mr, stride, n_strides,
  65                    cl, ct,
  66                    lowest_non_clean,
  67                    lowest_non_clean_base_chunk_index,
  68                    lowest_non_clean_chunk_size);
  69   }
  70   if (pst->all_tasks_completed()) {
  71     // Clear lowest_non_clean array for next time.
  72     intptr_t first_chunk_index = addr_to_chunk_index(mr.start());
  73     uintptr_t last_chunk_index  = addr_to_chunk_index(mr.last());
  74     for (uintptr_t ch = first_chunk_index; ch <= last_chunk_index; ch++) {
  75       intptr_t ind = ch - lowest_non_clean_base_chunk_index;
  76       assert(0 <= ind && ind < (intptr_t)lowest_non_clean_chunk_size,
  77              "Bounds error");
  78       lowest_non_clean[ind] = NULL;
  79     }
  80   }
  81 }
  82 
  83 void
  84 CardTableModRefBS::
  85 process_stride(Space* sp,


 111                                 (n_strides - start_chunk_stride_num + stride) *
 112                                 ParGCCardsPerStrideChunk);
 113   }
 114 
 115   while (chunk_card_start < end_card) {
 116     // Even though we go from lower to higher addresses below, the
 117     // strided parallelism can interleave the actual processing of the
 118     // dirty pages in various ways. For a specific chunk within this
 119     // stride, we take care to avoid double scanning or missing a card
 120     // by suitably initializing the "min_done" field in process_chunk_boundaries()
 121     // below, together with the dirty region extension accomplished in
 122     // DirtyCardToOopClosure::do_MemRegion().
 123     jbyte*    chunk_card_end = chunk_card_start + ParGCCardsPerStrideChunk;
 124     // Invariant: chunk_mr should be fully contained within the "used" region.
 125     MemRegion chunk_mr       = MemRegion(addr_for(chunk_card_start),
 126                                          chunk_card_end >= end_card ?
 127                                            used.end() : addr_for(chunk_card_end));
 128     assert(chunk_mr.word_size() > 0, "[chunk_card_start > used_end)");
 129     assert(used.contains(chunk_mr), "chunk_mr should be subset of used");
 130 
 131     // This function is used by the parallel card table iteration.
 132     const bool parallel = true;
 133 
 134     DirtyCardToOopClosure* dcto_cl = sp->new_dcto_cl(cl, precision(),
 135                                                      cl->gen_boundary(),
 136                                                      parallel);
 137     ClearNoncleanCardWrapper clear_cl(dcto_cl, ct, parallel);
 138 
 139 
 140     // Process the chunk.
 141     process_chunk_boundaries(sp,
 142                              dcto_cl,
 143                              chunk_mr,
 144                              used,
 145                              lowest_non_clean,
 146                              lowest_non_clean_base_chunk_index,
 147                              lowest_non_clean_chunk_size);
 148 
 149     // We want the LNC array updates above in process_chunk_boundaries
 150     // to be visible before any of the card table value changes as a
 151     // result of the dirty card iteration below.
 152     OrderAccess::storestore();
 153 
 154     // We want to clear the cards: clear_cl here does the work of finding
 155     // contiguous dirty ranges of cards to process and clear.
 156     clear_cl.do_MemRegion(chunk_mr);
 157 


< prev index next >