comparison src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp @ 3287:c48ad6ab8bdf

7037276: Unnecessary double traversal of dirty card windows Summary: Short-circuited an unnecessary double traversal of dirty card windows when iterating younger refs. Also renamed some cardtable methods for more clarity. Reviewed-by: jmasa, stefank, poonam
author ysr
date Wed, 20 Apr 2011 19:19:30 -0700
parents c69b1043dfb1
children fc2b798ab316
comparison
equal deleted inserted replaced
3285:49a67202bc67 3287:c48ad6ab8bdf
31 #include "memory/universe.hpp" 31 #include "memory/universe.hpp"
32 #include "runtime/java.hpp" 32 #include "runtime/java.hpp"
33 #include "runtime/mutexLocker.hpp" 33 #include "runtime/mutexLocker.hpp"
34 #include "runtime/virtualspace.hpp" 34 #include "runtime/virtualspace.hpp"
35 35
36 void CardTableModRefBS::par_non_clean_card_iterate_work(Space* sp, MemRegion mr, 36 void CardTableModRefBS::non_clean_card_iterate_parallel_work(Space* sp, MemRegion mr,
37 DirtyCardToOopClosure* dcto_cl, 37 DirtyCardToOopClosure* dcto_cl,
38 MemRegionClosure* cl, 38 ClearNoncleanCardWrapper* cl,
39 int n_threads) { 39 int n_threads) {
40 if (n_threads > 0) { 40 assert(n_threads > 0, "Error: expected n_threads > 0");
41 assert((n_threads == 1 && ParallelGCThreads == 0) || 41 assert((n_threads == 1 && ParallelGCThreads == 0) ||
42 n_threads <= (int)ParallelGCThreads, 42 n_threads <= (int)ParallelGCThreads,
43 "# worker threads != # requested!"); 43 "# worker threads != # requested!");
44 // Make sure the LNC array is valid for the space. 44 // Make sure the LNC array is valid for the space.
45 jbyte** lowest_non_clean; 45 jbyte** lowest_non_clean;
46 uintptr_t lowest_non_clean_base_chunk_index; 46 uintptr_t lowest_non_clean_base_chunk_index;
47 size_t lowest_non_clean_chunk_size; 47 size_t lowest_non_clean_chunk_size;
48 get_LNC_array_for_space(sp, lowest_non_clean, 48 get_LNC_array_for_space(sp, lowest_non_clean,
49 lowest_non_clean_base_chunk_index, 49 lowest_non_clean_base_chunk_index,
50 lowest_non_clean_chunk_size); 50 lowest_non_clean_chunk_size);
51 51
52 int n_strides = n_threads * StridesPerThread; 52 int n_strides = n_threads * StridesPerThread;
53 SequentialSubTasksDone* pst = sp->par_seq_tasks(); 53 SequentialSubTasksDone* pst = sp->par_seq_tasks();
54 pst->set_n_threads(n_threads); 54 pst->set_n_threads(n_threads);
55 pst->set_n_tasks(n_strides); 55 pst->set_n_tasks(n_strides);
56 56
57 int stride = 0; 57 int stride = 0;
58 while (!pst->is_task_claimed(/* reference */ stride)) { 58 while (!pst->is_task_claimed(/* reference */ stride)) {
59 process_stride(sp, mr, stride, n_strides, dcto_cl, cl, 59 process_stride(sp, mr, stride, n_strides, dcto_cl, cl,
60 lowest_non_clean, 60 lowest_non_clean,
61 lowest_non_clean_base_chunk_index, 61 lowest_non_clean_base_chunk_index,
62 lowest_non_clean_chunk_size); 62 lowest_non_clean_chunk_size);
63 } 63 }
64 if (pst->all_tasks_completed()) { 64 if (pst->all_tasks_completed()) {
65 // Clear lowest_non_clean array for next time. 65 // Clear lowest_non_clean array for next time.
66 intptr_t first_chunk_index = addr_to_chunk_index(mr.start()); 66 intptr_t first_chunk_index = addr_to_chunk_index(mr.start());
67 uintptr_t last_chunk_index = addr_to_chunk_index(mr.last()); 67 uintptr_t last_chunk_index = addr_to_chunk_index(mr.last());
68 for (uintptr_t ch = first_chunk_index; ch <= last_chunk_index; ch++) { 68 for (uintptr_t ch = first_chunk_index; ch <= last_chunk_index; ch++) {
69 intptr_t ind = ch - lowest_non_clean_base_chunk_index; 69 intptr_t ind = ch - lowest_non_clean_base_chunk_index;
70 assert(0 <= ind && ind < (intptr_t)lowest_non_clean_chunk_size, 70 assert(0 <= ind && ind < (intptr_t)lowest_non_clean_chunk_size,
71 "Bounds error"); 71 "Bounds error");
72 lowest_non_clean[ind] = NULL; 72 lowest_non_clean[ind] = NULL;
73 }
74 } 73 }
75 } 74 }
76 } 75 }
77 76
78 void 77 void
79 CardTableModRefBS:: 78 CardTableModRefBS::
80 process_stride(Space* sp, 79 process_stride(Space* sp,
81 MemRegion used, 80 MemRegion used,
82 jint stride, int n_strides, 81 jint stride, int n_strides,
83 DirtyCardToOopClosure* dcto_cl, 82 DirtyCardToOopClosure* dcto_cl,
84 MemRegionClosure* cl, 83 ClearNoncleanCardWrapper* cl,
85 jbyte** lowest_non_clean, 84 jbyte** lowest_non_clean,
86 uintptr_t lowest_non_clean_base_chunk_index, 85 uintptr_t lowest_non_clean_base_chunk_index,
87 size_t lowest_non_clean_chunk_size) { 86 size_t lowest_non_clean_chunk_size) {
88 // We don't have to go downwards here; it wouldn't help anyway, 87 // We don't have to go downwards here; it wouldn't help anyway,
89 // because of parallelism. 88 // because of parallelism.
125 used, 124 used,
126 lowest_non_clean, 125 lowest_non_clean,
127 lowest_non_clean_base_chunk_index, 126 lowest_non_clean_base_chunk_index,
128 lowest_non_clean_chunk_size); 127 lowest_non_clean_chunk_size);
129 128
130 non_clean_card_iterate_work(chunk_mr, cl); 129 // We do not call the non_clean_card_iterate_serial() version because
130 // we want to clear the cards, and the ClearNoncleanCardWrapper closure
131 // itself does the work of finding contiguous dirty ranges of cards to
132 // process (and clear).
133 cl->do_MemRegion(chunk_mr);
131 134
132 // Find the next chunk of the stride. 135 // Find the next chunk of the stride.
133 chunk_card_start += CardsPerStrideChunk * n_strides; 136 chunk_card_start += CardsPerStrideChunk * n_strides;
134 } 137 }
135 } 138 }