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