Mercurial > hg > graal-jvmci-8
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 } |