Mercurial > hg > graal-compiler
annotate src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp @ 2149:7e37af9d69ef
7011379: G1: overly long concurrent marking cycles
Summary: This changeset introduces filtering of SATB buffers at the point when they are about to be enqueued. If this filtering clears enough entries on each buffer, the buffer can then be re-used and not enqueued. This cuts down the number of SATB buffers that need to be processed by the concurrent marking threads.
Reviewed-by: johnc, ysr
author | tonyp |
---|---|
date | Wed, 19 Jan 2011 09:35:17 -0500 |
parents | f95d63e2154a |
children | 3582bf76420e |
rev | line source |
---|---|
0 | 1 /* |
1972 | 2 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1311
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1311
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1311
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/systemDictionary.hpp" | |
27 #include "code/codeCache.hpp" | |
28 #include "gc_implementation/parallelScavenge/pcTasks.hpp" | |
29 #include "gc_implementation/parallelScavenge/psParallelCompact.hpp" | |
30 #include "gc_interface/collectedHeap.hpp" | |
31 #include "memory/universe.hpp" | |
32 #include "oops/objArrayKlass.inline.hpp" | |
33 #include "oops/oop.inline.hpp" | |
34 #include "oops/oop.pcgc.inline.hpp" | |
35 #include "prims/jvmtiExport.hpp" | |
36 #include "runtime/fprofiler.hpp" | |
37 #include "runtime/jniHandles.hpp" | |
38 #include "runtime/thread.hpp" | |
39 #include "runtime/vmThread.hpp" | |
40 #include "services/management.hpp" | |
0 | 41 |
42 // | |
43 // ThreadRootsMarkingTask | |
44 // | |
45 | |
46 void ThreadRootsMarkingTask::do_it(GCTaskManager* manager, uint which) { | |
47 assert(Universe::heap()->is_gc_active(), "called outside gc"); | |
48 | |
49 ResourceMark rm; | |
50 | |
51 NOT_PRODUCT(TraceTime tm("ThreadRootsMarkingTask", | |
52 PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty)); | |
53 ParCompactionManager* cm = | |
54 ParCompactionManager::gc_thread_compaction_manager(which); | |
55 PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm); | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
375
diff
changeset
|
56 CodeBlobToOopClosure mark_and_push_in_blobs(&mark_and_push_closure, /*do_marking=*/ true); |
0 | 57 |
58 if (_java_thread != NULL) | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
375
diff
changeset
|
59 _java_thread->oops_do(&mark_and_push_closure, &mark_and_push_in_blobs); |
0 | 60 |
61 if (_vm_thread != NULL) | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
375
diff
changeset
|
62 _vm_thread->oops_do(&mark_and_push_closure, &mark_and_push_in_blobs); |
0 | 63 |
64 // Do the real work | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1000
diff
changeset
|
65 cm->follow_marking_stacks(); |
0 | 66 } |
67 | |
68 | |
69 void MarkFromRootsTask::do_it(GCTaskManager* manager, uint which) { | |
70 assert(Universe::heap()->is_gc_active(), "called outside gc"); | |
71 | |
72 NOT_PRODUCT(TraceTime tm("MarkFromRootsTask", | |
73 PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty)); | |
74 ParCompactionManager* cm = | |
75 ParCompactionManager::gc_thread_compaction_manager(which); | |
76 PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm); | |
77 | |
78 switch (_root_type) { | |
79 case universe: | |
80 Universe::oops_do(&mark_and_push_closure); | |
81 break; | |
82 | |
83 case reference_processing: | |
84 ReferenceProcessor::oops_do(&mark_and_push_closure); | |
85 break; | |
86 | |
87 case jni_handles: | |
88 JNIHandles::oops_do(&mark_and_push_closure); | |
89 break; | |
90 | |
91 case threads: | |
92 { | |
93 ResourceMark rm; | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
375
diff
changeset
|
94 CodeBlobToOopClosure each_active_code_blob(&mark_and_push_closure, /*do_marking=*/ true); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
375
diff
changeset
|
95 Threads::oops_do(&mark_and_push_closure, &each_active_code_blob); |
0 | 96 } |
97 break; | |
98 | |
99 case object_synchronizer: | |
100 ObjectSynchronizer::oops_do(&mark_and_push_closure); | |
101 break; | |
102 | |
103 case flat_profiler: | |
104 FlatProfiler::oops_do(&mark_and_push_closure); | |
105 break; | |
106 | |
107 case management: | |
108 Management::oops_do(&mark_and_push_closure); | |
109 break; | |
110 | |
111 case jvmti: | |
112 JvmtiExport::oops_do(&mark_and_push_closure); | |
113 break; | |
114 | |
115 case system_dictionary: | |
116 SystemDictionary::always_strong_oops_do(&mark_and_push_closure); | |
117 break; | |
118 | |
119 case vm_symbols: | |
120 vmSymbols::oops_do(&mark_and_push_closure); | |
121 break; | |
122 | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
375
diff
changeset
|
123 case code_cache: |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
375
diff
changeset
|
124 // Do not treat nmethods as strong roots for mark/sweep, since we can unload them. |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
375
diff
changeset
|
125 //CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure(&mark_and_push_closure)); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
375
diff
changeset
|
126 break; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
375
diff
changeset
|
127 |
0 | 128 default: |
129 fatal("Unknown root type"); | |
130 } | |
131 | |
132 // Do the real work | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1000
diff
changeset
|
133 cm->follow_marking_stacks(); |
0 | 134 } |
135 | |
136 | |
137 // | |
138 // RefProcTaskProxy | |
139 // | |
140 | |
141 void RefProcTaskProxy::do_it(GCTaskManager* manager, uint which) | |
142 { | |
143 assert(Universe::heap()->is_gc_active(), "called outside gc"); | |
144 | |
145 NOT_PRODUCT(TraceTime tm("RefProcTask", | |
146 PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty)); | |
147 ParCompactionManager* cm = | |
148 ParCompactionManager::gc_thread_compaction_manager(which); | |
149 PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm); | |
150 PSParallelCompact::FollowStackClosure follow_stack_closure(cm); | |
151 _rp_task.work(_work_id, *PSParallelCompact::is_alive_closure(), | |
152 mark_and_push_closure, follow_stack_closure); | |
153 } | |
154 | |
155 // | |
156 // RefProcTaskExecutor | |
157 // | |
158 | |
159 void RefProcTaskExecutor::execute(ProcessTask& task) | |
160 { | |
161 ParallelScavengeHeap* heap = PSParallelCompact::gc_heap(); | |
162 uint parallel_gc_threads = heap->gc_task_manager()->workers(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
163 RegionTaskQueueSet* qset = ParCompactionManager::region_array(); |
0 | 164 ParallelTaskTerminator terminator(parallel_gc_threads, qset); |
165 GCTaskQueue* q = GCTaskQueue::create(); | |
166 for(uint i=0; i<parallel_gc_threads; i++) { | |
167 q->enqueue(new RefProcTaskProxy(task, i)); | |
168 } | |
169 if (task.marks_oops_alive()) { | |
170 if (parallel_gc_threads>1) { | |
171 for (uint j=0; j<parallel_gc_threads; j++) { | |
172 q->enqueue(new StealMarkingTask(&terminator)); | |
173 } | |
174 } | |
175 } | |
176 PSParallelCompact::gc_task_manager()->execute_and_wait(q); | |
177 } | |
178 | |
179 void RefProcTaskExecutor::execute(EnqueueTask& task) | |
180 { | |
181 ParallelScavengeHeap* heap = PSParallelCompact::gc_heap(); | |
182 uint parallel_gc_threads = heap->gc_task_manager()->workers(); | |
183 GCTaskQueue* q = GCTaskQueue::create(); | |
184 for(uint i=0; i<parallel_gc_threads; i++) { | |
185 q->enqueue(new RefEnqueueTaskProxy(task, i)); | |
186 } | |
187 PSParallelCompact::gc_task_manager()->execute_and_wait(q); | |
188 } | |
189 | |
190 // | |
191 // StealMarkingTask | |
192 // | |
193 | |
194 StealMarkingTask::StealMarkingTask(ParallelTaskTerminator* t) : | |
195 _terminator(t) {} | |
196 | |
197 void StealMarkingTask::do_it(GCTaskManager* manager, uint which) { | |
198 assert(Universe::heap()->is_gc_active(), "called outside gc"); | |
199 | |
200 NOT_PRODUCT(TraceTime tm("StealMarkingTask", | |
201 PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty)); | |
202 | |
203 ParCompactionManager* cm = | |
204 ParCompactionManager::gc_thread_compaction_manager(which); | |
205 PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm); | |
206 | |
207 oop obj = NULL; | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1000
diff
changeset
|
208 ObjArrayTask task; |
0 | 209 int random_seed = 17; |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1000
diff
changeset
|
210 do { |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1000
diff
changeset
|
211 while (ParCompactionManager::steal_objarray(which, &random_seed, task)) { |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1000
diff
changeset
|
212 objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint(); |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1000
diff
changeset
|
213 k->oop_follow_contents(cm, task.obj(), task.index()); |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1000
diff
changeset
|
214 cm->follow_marking_stacks(); |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1000
diff
changeset
|
215 } |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1000
diff
changeset
|
216 while (ParCompactionManager::steal(which, &random_seed, obj)) { |
0 | 217 obj->follow_contents(cm); |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1000
diff
changeset
|
218 cm->follow_marking_stacks(); |
0 | 219 } |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1000
diff
changeset
|
220 } while (!terminator()->offer_termination()); |
0 | 221 } |
222 | |
223 // | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
224 // StealRegionCompactionTask |
0 | 225 // |
226 | |
227 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
228 StealRegionCompactionTask::StealRegionCompactionTask(ParallelTaskTerminator* t): |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
229 _terminator(t) {} |
0 | 230 |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
231 void StealRegionCompactionTask::do_it(GCTaskManager* manager, uint which) { |
0 | 232 assert(Universe::heap()->is_gc_active(), "called outside gc"); |
233 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
234 NOT_PRODUCT(TraceTime tm("StealRegionCompactionTask", |
0 | 235 PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty)); |
236 | |
237 ParCompactionManager* cm = | |
238 ParCompactionManager::gc_thread_compaction_manager(which); | |
239 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
240 // Has to drain stacks first because there may be regions on |
0 | 241 // preloaded onto the stack and this thread may never have |
242 // done a draining task. Are the draining tasks needed? | |
243 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
244 cm->drain_region_stacks(); |
0 | 245 |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
246 size_t region_index = 0; |
0 | 247 int random_seed = 17; |
248 | |
249 // If we're the termination task, try 10 rounds of stealing before | |
250 // setting the termination flag | |
251 | |
252 while(true) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
253 if (ParCompactionManager::steal(which, &random_seed, region_index)) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
254 PSParallelCompact::fill_and_update_region(cm, region_index); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
255 cm->drain_region_stacks(); |
0 | 256 } else { |
257 if (terminator()->offer_termination()) { | |
258 break; | |
259 } | |
260 // Go around again. | |
261 } | |
262 } | |
263 return; | |
264 } | |
265 | |
266 UpdateDensePrefixTask::UpdateDensePrefixTask( | |
267 PSParallelCompact::SpaceId space_id, | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
268 size_t region_index_start, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
269 size_t region_index_end) : |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
270 _space_id(space_id), _region_index_start(region_index_start), |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
271 _region_index_end(region_index_end) {} |
0 | 272 |
273 void UpdateDensePrefixTask::do_it(GCTaskManager* manager, uint which) { | |
274 | |
275 NOT_PRODUCT(TraceTime tm("UpdateDensePrefixTask", | |
276 PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty)); | |
277 | |
278 ParCompactionManager* cm = | |
279 ParCompactionManager::gc_thread_compaction_manager(which); | |
280 | |
281 PSParallelCompact::update_and_deadwood_in_dense_prefix(cm, | |
282 _space_id, | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
283 _region_index_start, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
284 _region_index_end); |
0 | 285 } |
286 | |
287 void DrainStacksCompactionTask::do_it(GCTaskManager* manager, uint which) { | |
288 assert(Universe::heap()->is_gc_active(), "called outside gc"); | |
289 | |
290 NOT_PRODUCT(TraceTime tm("DrainStacksCompactionTask", | |
291 PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty)); | |
292 | |
293 ParCompactionManager* cm = | |
294 ParCompactionManager::gc_thread_compaction_manager(which); | |
295 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
296 // Process any regions already in the compaction managers stacks. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
297 cm->drain_region_stacks(); |
0 | 298 } |