Mercurial > hg > graal-compiler
comparison src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp @ 20216:570cb6369f17
8019342: G1: High "Other" time most likely due to card redirtying
Summary: Parallelize card redirtying to decrease the time it takes.
Reviewed-by: brutisso
author | tschatzl |
---|---|
date | Mon, 21 Jul 2014 09:40:19 +0200 |
parents | 8847586c9037 |
children | c2844108a708 |
comparison
equal
deleted
inserted
replaced
20215:983092f35ff7 | 20216:570cb6369f17 |
---|---|
71 }; | 71 }; |
72 | 72 |
73 | 73 |
74 | 74 |
75 class DirtyCardQueueSet: public PtrQueueSet { | 75 class DirtyCardQueueSet: public PtrQueueSet { |
76 CardTableEntryClosure* _closure; | 76 // The closure used in mut_process_buffer(). |
77 CardTableEntryClosure* _mut_process_closure; | |
77 | 78 |
78 DirtyCardQueue _shared_dirty_card_queue; | 79 DirtyCardQueue _shared_dirty_card_queue; |
79 | 80 |
80 // Override. | 81 // Override. |
81 bool mut_process_buffer(void** buf); | 82 bool mut_process_buffer(void** buf); |
86 // The number of completed buffers processed by mutator and rs thread, | 87 // The number of completed buffers processed by mutator and rs thread, |
87 // respectively. | 88 // respectively. |
88 jint _processed_buffers_mut; | 89 jint _processed_buffers_mut; |
89 jint _processed_buffers_rs_thread; | 90 jint _processed_buffers_rs_thread; |
90 | 91 |
92 // Current buffer node used for parallel iteration. | |
93 BufferNode* volatile _cur_par_buffer_node; | |
91 public: | 94 public: |
92 DirtyCardQueueSet(bool notify_when_complete = true); | 95 DirtyCardQueueSet(bool notify_when_complete = true); |
93 | 96 |
94 void initialize(Monitor* cbl_mon, Mutex* fl_lock, | 97 void initialize(CardTableEntryClosure* cl, Monitor* cbl_mon, Mutex* fl_lock, |
95 int process_completed_threshold, | 98 int process_completed_threshold, |
96 int max_completed_queue, | 99 int max_completed_queue, |
97 Mutex* lock, PtrQueueSet* fl_owner = NULL); | 100 Mutex* lock, PtrQueueSet* fl_owner = NULL); |
98 | 101 |
99 // The number of parallel ids that can be claimed to allow collector or | 102 // The number of parallel ids that can be claimed to allow collector or |
100 // mutator threads to do card-processing work. | 103 // mutator threads to do card-processing work. |
101 static uint num_par_ids(); | 104 static uint num_par_ids(); |
102 | 105 |
103 static void handle_zero_index_for_thread(JavaThread* t); | 106 static void handle_zero_index_for_thread(JavaThread* t); |
104 | 107 |
105 // Register "blk" as "the closure" for all queues. Only one such closure | 108 // Apply the given closure to all entries in all currently-active buffers. |
106 // is allowed. The "apply_closure_to_completed_buffer" method will apply | 109 // This should only be applied at a safepoint. (Currently must not be called |
107 // this closure to a completed buffer, and "iterate_closure_all_threads" | 110 // in parallel; this should change in the future.) If "consume" is true, |
108 // applies it to partially-filled buffers (the latter should only be done | 111 // processed entries are discarded. |
109 // with the world stopped). | 112 void iterate_closure_all_threads(CardTableEntryClosure* cl, |
110 void set_closure(CardTableEntryClosure* closure); | 113 bool consume = true, |
111 | |
112 // If there is a registered closure for buffers, apply it to all entries | |
113 // in all currently-active buffers. This should only be applied at a | |
114 // safepoint. (Currently must not be called in parallel; this should | |
115 // change in the future.) If "consume" is true, processed entries are | |
116 // discarded. | |
117 void iterate_closure_all_threads(bool consume = true, | |
118 uint worker_i = 0); | 114 uint worker_i = 0); |
119 | |
120 // If there exists some completed buffer, pop it, then apply the | |
121 // registered closure to all its elements, nulling out those elements | |
122 // processed. If all elements are processed, returns "true". If no | |
123 // completed buffers exist, returns false. If a completed buffer exists, | |
124 // but is only partially completed before a "yield" happens, the | |
125 // partially completed buffer (with its processed elements set to NULL) | |
126 // is returned to the completed buffer set, and this call returns false. | |
127 bool apply_closure_to_completed_buffer(uint worker_i = 0, | |
128 int stop_at = 0, | |
129 bool during_pause = false); | |
130 | 115 |
131 // If there exists some completed buffer, pop it, then apply the | 116 // If there exists some completed buffer, pop it, then apply the |
132 // specified closure to all its elements, nulling out those elements | 117 // specified closure to all its elements, nulling out those elements |
133 // processed. If all elements are processed, returns "true". If no | 118 // processed. If all elements are processed, returns "true". If no |
134 // completed buffers exist, returns false. If a completed buffer exists, | 119 // completed buffers exist, returns false. If a completed buffer exists, |
147 | 132 |
148 BufferNode* get_completed_buffer(int stop_at); | 133 BufferNode* get_completed_buffer(int stop_at); |
149 | 134 |
150 // Applies the current closure to all completed buffers, | 135 // Applies the current closure to all completed buffers, |
151 // non-consumptively. | 136 // non-consumptively. |
152 void apply_closure_to_all_completed_buffers(); | 137 void apply_closure_to_all_completed_buffers(CardTableEntryClosure* cl); |
138 | |
139 void reset_for_par_iteration() { _cur_par_buffer_node = _completed_buffers_head; } | |
140 // Applies the current closure to all completed buffers, non-consumptively. | |
141 // Parallel version. | |
142 void par_apply_closure_to_all_completed_buffers(CardTableEntryClosure* cl); | |
153 | 143 |
154 DirtyCardQueue* shared_dirty_card_queue() { | 144 DirtyCardQueue* shared_dirty_card_queue() { |
155 return &_shared_dirty_card_queue; | 145 return &_shared_dirty_card_queue; |
156 } | 146 } |
157 | 147 |