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 |