67 // 3) SequentialSubTasksDone has an _n_threads that is used in |
67 // 3) SequentialSubTasksDone has an _n_threads that is used in |
68 // a way similar to SubTasksDone and has the same dependency on the |
68 // a way similar to SubTasksDone and has the same dependency on the |
69 // number of active GC workers. CompactibleFreeListSpace and Space |
69 // number of active GC workers. CompactibleFreeListSpace and Space |
70 // have SequentialSubTasksDone's. |
70 // have SequentialSubTasksDone's. |
71 // Example of using SubTasksDone and SequentialSubTasksDone |
71 // Example of using SubTasksDone and SequentialSubTasksDone |
72 // G1CollectedHeap::g1_process_strong_roots() calls |
72 // G1CollectedHeap::g1_process_roots() |
73 // process_strong_roots(false, // no scoping; this is parallel code |
73 // to SharedHeap::process_roots() and uses |
74 // is_scavenging, so, |
|
75 // &buf_scan_non_heap_roots, |
|
76 // &eager_scan_code_roots); |
|
77 // which delegates to SharedHeap::process_strong_roots() and uses |
|
78 // SubTasksDone* _process_strong_tasks to claim tasks. |
74 // SubTasksDone* _process_strong_tasks to claim tasks. |
79 // process_strong_roots() calls |
75 // process_roots() calls |
80 // rem_set()->younger_refs_iterate() |
76 // rem_set()->younger_refs_iterate() |
81 // to scan the card table and which eventually calls down into |
77 // to scan the card table and which eventually calls down into |
82 // CardTableModRefBS::par_non_clean_card_iterate_work(). This method |
78 // CardTableModRefBS::par_non_clean_card_iterate_work(). This method |
83 // uses SequentialSubTasksDone* _pst to claim tasks. |
79 // uses SequentialSubTasksDone* _pst to claim tasks. |
84 // Both SubTasksDone and SequentialSubTasksDone call their method |
80 // Both SubTasksDone and SequentialSubTasksDone call their method |
180 // whose threads invoke "process_strong_roots" must |
176 // whose threads invoke "process_strong_roots" must |
181 // call "change_strong_roots_parity" in sequential code starting such a |
177 // call "change_strong_roots_parity" in sequential code starting such a |
182 // task. (This also means that a parallel thread may only call |
178 // task. (This also means that a parallel thread may only call |
183 // process_strong_roots once.) |
179 // process_strong_roots once.) |
184 // |
180 // |
185 // For calls to process_strong_roots by sequential code, the parity is |
181 // For calls to process_roots by sequential code, the parity is |
186 // updated automatically. |
182 // updated automatically. |
187 // |
183 // |
188 // The idea is that objects representing fine-grained tasks, such as |
184 // The idea is that objects representing fine-grained tasks, such as |
189 // threads, will contain a "parity" field. A task will is claimed in the |
185 // threads, will contain a "parity" field. A task will is claimed in the |
190 // current "process_strong_roots" call only if its parity field is the |
186 // current "process_roots" call only if its parity field is the |
191 // same as the "strong_roots_parity"; task claiming is accomplished by |
187 // same as the "strong_roots_parity"; task claiming is accomplished by |
192 // updating the parity field to the strong_roots_parity with a CAS. |
188 // updating the parity field to the strong_roots_parity with a CAS. |
193 // |
189 // |
194 // If the client meats this spec, then strong_roots_parity() will have |
190 // If the client meats this spec, then strong_roots_parity() will have |
195 // the following properties: |
191 // the following properties: |
196 // a) to return a different value than was returned before the last |
192 // a) to return a different value than was returned before the last |
197 // call to change_strong_roots_parity, and |
193 // call to change_strong_roots_parity, and |
198 // c) to never return a distinguished value (zero) with which such |
194 // c) to never return a distinguished value (zero) with which such |
199 // task-claiming variables may be initialized, to indicate "never |
195 // task-claiming variables may be initialized, to indicate "never |
200 // claimed". |
196 // claimed". |
201 private: |
|
202 void change_strong_roots_parity(); |
|
203 public: |
197 public: |
204 int strong_roots_parity() { return _strong_roots_parity; } |
198 int strong_roots_parity() { return _strong_roots_parity; } |
205 |
199 |
206 // Call these in sequential code around process_strong_roots. |
200 // Call these in sequential code around process_roots. |
207 // strong_roots_prologue calls change_strong_roots_parity, if |
201 // strong_roots_prologue calls change_strong_roots_parity, if |
208 // parallel tasks are enabled. |
202 // parallel tasks are enabled. |
209 class StrongRootsScope : public MarkingCodeBlobClosure::MarkScope { |
203 class StrongRootsScope : public MarkingCodeBlobClosure::MarkScope { |
210 public: |
204 // Used to implement the Thread work barrier. |
211 StrongRootsScope(SharedHeap* outer, bool activate = true); |
205 static Monitor* _lock; |
|
206 |
|
207 SharedHeap* _sh; |
|
208 volatile jint _n_workers_done_with_threads; |
|
209 |
|
210 public: |
|
211 StrongRootsScope(SharedHeap* heap, bool activate = true); |
212 ~StrongRootsScope(); |
212 ~StrongRootsScope(); |
|
213 |
|
214 // Mark that this thread is done with the Threads work. |
|
215 void mark_worker_done_with_threads(uint n_workers); |
|
216 // Wait until all n_workers are done with the Threads work. |
|
217 void wait_until_all_workers_done_with_threads(uint n_workers); |
213 }; |
218 }; |
214 friend class StrongRootsScope; |
219 friend class StrongRootsScope; |
215 |
220 |
|
221 // The current active StrongRootScope |
|
222 StrongRootsScope* _strong_roots_scope; |
|
223 |
|
224 StrongRootsScope* active_strong_roots_scope() const; |
|
225 |
|
226 private: |
|
227 void register_strong_roots_scope(StrongRootsScope* scope); |
|
228 void unregister_strong_roots_scope(StrongRootsScope* scope); |
|
229 void change_strong_roots_parity(); |
|
230 |
|
231 public: |
216 enum ScanningOption { |
232 enum ScanningOption { |
217 SO_None = 0x0, |
233 SO_None = 0x0, |
218 SO_AllClasses = 0x1, |
234 SO_AllCodeCache = 0x8, |
219 SO_SystemClasses = 0x2, |
|
220 SO_Strings = 0x4, |
|
221 SO_AllCodeCache = 0x8, |
|
222 SO_ScavengeCodeCache = 0x10 |
235 SO_ScavengeCodeCache = 0x10 |
223 }; |
236 }; |
224 |
237 |
225 FlexibleWorkGang* workers() const { return _workers; } |
238 FlexibleWorkGang* workers() const { return _workers; } |
226 |
239 |
227 // Invoke the "do_oop" method the closure "roots" on all root locations. |
240 // Invoke the "do_oop" method the closure "roots" on all root locations. |
228 // The "so" argument determines which roots the closure is applied to: |
241 // The "so" argument determines which roots the closure is applied to: |
229 // "SO_None" does none; |
242 // "SO_None" does none; |
230 // "SO_AllClasses" applies the closure to all entries in the SystemDictionary; |
|
231 // "SO_SystemClasses" to all the "system" classes and loaders; |
|
232 // "SO_Strings" applies the closure to all entries in StringTable; |
|
233 // "SO_AllCodeCache" applies the closure to all elements of the CodeCache. |
243 // "SO_AllCodeCache" applies the closure to all elements of the CodeCache. |
234 // "SO_ScavengeCodeCache" applies the closure to elements on the scavenge root list in the CodeCache. |
244 // "SO_ScavengeCodeCache" applies the closure to elements on the scavenge root list in the CodeCache. |
|
245 void process_roots(bool activate_scope, |
|
246 ScanningOption so, |
|
247 OopClosure* strong_roots, |
|
248 OopClosure* weak_roots, |
|
249 CLDClosure* strong_cld_closure, |
|
250 CLDClosure* weak_cld_closure, |
|
251 CodeBlobClosure* code_roots); |
|
252 void process_all_roots(bool activate_scope, |
|
253 ScanningOption so, |
|
254 OopClosure* roots, |
|
255 CLDClosure* cld_closure, |
|
256 CodeBlobClosure* code_roots); |
235 void process_strong_roots(bool activate_scope, |
257 void process_strong_roots(bool activate_scope, |
236 ScanningOption so, |
258 ScanningOption so, |
237 OopClosure* roots, |
259 OopClosure* roots, |
238 KlassClosure* klass_closure); |
260 CLDClosure* cld_closure, |
|
261 CodeBlobClosure* code_roots); |
|
262 |
239 |
263 |
240 // Apply "root_closure" to the JNI weak roots.. |
264 // Apply "root_closure" to the JNI weak roots.. |
241 void process_weak_roots(OopClosure* root_closure); |
265 void process_weak_roots(OopClosure* root_closure); |
242 |
266 |
243 // The functions below are helper functions that a subclass of |
267 // The functions below are helper functions that a subclass of |