1.1 --- a/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp Tue Apr 19 15:46:59 2011 -0400 1.2 +++ b/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp Wed Apr 20 19:19:30 2011 -0700 1.3 @@ -33,44 +33,43 @@ 1.4 #include "runtime/mutexLocker.hpp" 1.5 #include "runtime/virtualspace.hpp" 1.6 1.7 -void CardTableModRefBS::par_non_clean_card_iterate_work(Space* sp, MemRegion mr, 1.8 - DirtyCardToOopClosure* dcto_cl, 1.9 - MemRegionClosure* cl, 1.10 - int n_threads) { 1.11 - if (n_threads > 0) { 1.12 - assert((n_threads == 1 && ParallelGCThreads == 0) || 1.13 - n_threads <= (int)ParallelGCThreads, 1.14 - "# worker threads != # requested!"); 1.15 - // Make sure the LNC array is valid for the space. 1.16 - jbyte** lowest_non_clean; 1.17 - uintptr_t lowest_non_clean_base_chunk_index; 1.18 - size_t lowest_non_clean_chunk_size; 1.19 - get_LNC_array_for_space(sp, lowest_non_clean, 1.20 - lowest_non_clean_base_chunk_index, 1.21 - lowest_non_clean_chunk_size); 1.22 +void CardTableModRefBS::non_clean_card_iterate_parallel_work(Space* sp, MemRegion mr, 1.23 + DirtyCardToOopClosure* dcto_cl, 1.24 + ClearNoncleanCardWrapper* cl, 1.25 + int n_threads) { 1.26 + assert(n_threads > 0, "Error: expected n_threads > 0"); 1.27 + assert((n_threads == 1 && ParallelGCThreads == 0) || 1.28 + n_threads <= (int)ParallelGCThreads, 1.29 + "# worker threads != # requested!"); 1.30 + // Make sure the LNC array is valid for the space. 1.31 + jbyte** lowest_non_clean; 1.32 + uintptr_t lowest_non_clean_base_chunk_index; 1.33 + size_t lowest_non_clean_chunk_size; 1.34 + get_LNC_array_for_space(sp, lowest_non_clean, 1.35 + lowest_non_clean_base_chunk_index, 1.36 + lowest_non_clean_chunk_size); 1.37 1.38 - int n_strides = n_threads * StridesPerThread; 1.39 - SequentialSubTasksDone* pst = sp->par_seq_tasks(); 1.40 - pst->set_n_threads(n_threads); 1.41 - pst->set_n_tasks(n_strides); 1.42 + int n_strides = n_threads * StridesPerThread; 1.43 + SequentialSubTasksDone* pst = sp->par_seq_tasks(); 1.44 + pst->set_n_threads(n_threads); 1.45 + pst->set_n_tasks(n_strides); 1.46 1.47 - int stride = 0; 1.48 - while (!pst->is_task_claimed(/* reference */ stride)) { 1.49 - process_stride(sp, mr, stride, n_strides, dcto_cl, cl, 1.50 - lowest_non_clean, 1.51 - lowest_non_clean_base_chunk_index, 1.52 - lowest_non_clean_chunk_size); 1.53 - } 1.54 - if (pst->all_tasks_completed()) { 1.55 - // Clear lowest_non_clean array for next time. 1.56 - intptr_t first_chunk_index = addr_to_chunk_index(mr.start()); 1.57 - uintptr_t last_chunk_index = addr_to_chunk_index(mr.last()); 1.58 - for (uintptr_t ch = first_chunk_index; ch <= last_chunk_index; ch++) { 1.59 - intptr_t ind = ch - lowest_non_clean_base_chunk_index; 1.60 - assert(0 <= ind && ind < (intptr_t)lowest_non_clean_chunk_size, 1.61 - "Bounds error"); 1.62 - lowest_non_clean[ind] = NULL; 1.63 - } 1.64 + int stride = 0; 1.65 + while (!pst->is_task_claimed(/* reference */ stride)) { 1.66 + process_stride(sp, mr, stride, n_strides, dcto_cl, cl, 1.67 + lowest_non_clean, 1.68 + lowest_non_clean_base_chunk_index, 1.69 + lowest_non_clean_chunk_size); 1.70 + } 1.71 + if (pst->all_tasks_completed()) { 1.72 + // Clear lowest_non_clean array for next time. 1.73 + intptr_t first_chunk_index = addr_to_chunk_index(mr.start()); 1.74 + uintptr_t last_chunk_index = addr_to_chunk_index(mr.last()); 1.75 + for (uintptr_t ch = first_chunk_index; ch <= last_chunk_index; ch++) { 1.76 + intptr_t ind = ch - lowest_non_clean_base_chunk_index; 1.77 + assert(0 <= ind && ind < (intptr_t)lowest_non_clean_chunk_size, 1.78 + "Bounds error"); 1.79 + lowest_non_clean[ind] = NULL; 1.80 } 1.81 } 1.82 } 1.83 @@ -81,7 +80,7 @@ 1.84 MemRegion used, 1.85 jint stride, int n_strides, 1.86 DirtyCardToOopClosure* dcto_cl, 1.87 - MemRegionClosure* cl, 1.88 + ClearNoncleanCardWrapper* cl, 1.89 jbyte** lowest_non_clean, 1.90 uintptr_t lowest_non_clean_base_chunk_index, 1.91 size_t lowest_non_clean_chunk_size) { 1.92 @@ -127,7 +126,11 @@ 1.93 lowest_non_clean_base_chunk_index, 1.94 lowest_non_clean_chunk_size); 1.95 1.96 - non_clean_card_iterate_work(chunk_mr, cl); 1.97 + // We do not call the non_clean_card_iterate_serial() version because 1.98 + // we want to clear the cards, and the ClearNoncleanCardWrapper closure 1.99 + // itself does the work of finding contiguous dirty ranges of cards to 1.100 + // process (and clear). 1.101 + cl->do_MemRegion(chunk_mr); 1.102 1.103 // Find the next chunk of the stride. 1.104 chunk_card_start += CardsPerStrideChunk * n_strides;