Mercurial > hg > graal-compiler
annotate src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp @ 1091:6aa7255741f3
6906727: UseCompressedOops: some card-marking fixes related to object arrays
Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17).
Reviewed-by: kvn, coleenp, jmasa
author | ysr |
---|---|
date | Thu, 03 Dec 2009 15:01:57 -0800 |
parents | a1423fe86a18 |
children | 2a1472c30599 |
rev | line source |
---|---|
0 | 1 /* |
948 | 2 * Copyright 2005-2009 Sun Microsystems, Inc. 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 * | |
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | |
21 * have any questions. | |
22 * | |
23 */ | |
24 | |
25 # include "incls/_precompiled.incl" | |
26 # include "incls/_pcTasks.cpp.incl" | |
27 | |
28 // | |
29 // ThreadRootsMarkingTask | |
30 // | |
31 | |
32 void ThreadRootsMarkingTask::do_it(GCTaskManager* manager, uint which) { | |
33 assert(Universe::heap()->is_gc_active(), "called outside gc"); | |
34 | |
35 ResourceMark rm; | |
36 | |
37 NOT_PRODUCT(TraceTime tm("ThreadRootsMarkingTask", | |
38 PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty)); | |
39 ParCompactionManager* cm = | |
40 ParCompactionManager::gc_thread_compaction_manager(which); | |
41 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
|
42 CodeBlobToOopClosure mark_and_push_in_blobs(&mark_and_push_closure, /*do_marking=*/ true); |
0 | 43 |
44 if (_java_thread != NULL) | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
375
diff
changeset
|
45 _java_thread->oops_do(&mark_and_push_closure, &mark_and_push_in_blobs); |
0 | 46 |
47 if (_vm_thread != NULL) | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
375
diff
changeset
|
48 _vm_thread->oops_do(&mark_and_push_closure, &mark_and_push_in_blobs); |
0 | 49 |
50 // Do the real work | |
51 cm->drain_marking_stacks(&mark_and_push_closure); | |
52 } | |
53 | |
54 | |
55 void MarkFromRootsTask::do_it(GCTaskManager* manager, uint which) { | |
56 assert(Universe::heap()->is_gc_active(), "called outside gc"); | |
57 | |
58 NOT_PRODUCT(TraceTime tm("MarkFromRootsTask", | |
59 PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty)); | |
60 ParCompactionManager* cm = | |
61 ParCompactionManager::gc_thread_compaction_manager(which); | |
62 assert(cm->stacks_have_been_allocated(), | |
941 | 63 "Stack space has not been allocated"); |
0 | 64 PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm); |
65 | |
66 switch (_root_type) { | |
67 case universe: | |
68 Universe::oops_do(&mark_and_push_closure); | |
69 break; | |
70 | |
71 case reference_processing: | |
72 ReferenceProcessor::oops_do(&mark_and_push_closure); | |
73 break; | |
74 | |
75 case jni_handles: | |
76 JNIHandles::oops_do(&mark_and_push_closure); | |
77 break; | |
78 | |
79 case threads: | |
80 { | |
81 ResourceMark rm; | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
375
diff
changeset
|
82 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
|
83 Threads::oops_do(&mark_and_push_closure, &each_active_code_blob); |
0 | 84 } |
85 break; | |
86 | |
87 case object_synchronizer: | |
88 ObjectSynchronizer::oops_do(&mark_and_push_closure); | |
89 break; | |
90 | |
91 case flat_profiler: | |
92 FlatProfiler::oops_do(&mark_and_push_closure); | |
93 break; | |
94 | |
95 case management: | |
96 Management::oops_do(&mark_and_push_closure); | |
97 break; | |
98 | |
99 case jvmti: | |
100 JvmtiExport::oops_do(&mark_and_push_closure); | |
101 break; | |
102 | |
103 case system_dictionary: | |
104 SystemDictionary::always_strong_oops_do(&mark_and_push_closure); | |
105 break; | |
106 | |
107 case vm_symbols: | |
108 vmSymbols::oops_do(&mark_and_push_closure); | |
109 break; | |
110 | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
375
diff
changeset
|
111 case code_cache: |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
375
diff
changeset
|
112 // 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
|
113 //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
|
114 break; |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
375
diff
changeset
|
115 |
0 | 116 default: |
117 fatal("Unknown root type"); | |
118 } | |
119 | |
120 // Do the real work | |
121 cm->drain_marking_stacks(&mark_and_push_closure); | |
122 // cm->deallocate_stacks(); | |
123 } | |
124 | |
125 | |
126 // | |
127 // RefProcTaskProxy | |
128 // | |
129 | |
130 void RefProcTaskProxy::do_it(GCTaskManager* manager, uint which) | |
131 { | |
132 assert(Universe::heap()->is_gc_active(), "called outside gc"); | |
133 | |
134 NOT_PRODUCT(TraceTime tm("RefProcTask", | |
135 PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty)); | |
136 ParCompactionManager* cm = | |
137 ParCompactionManager::gc_thread_compaction_manager(which); | |
138 assert(cm->stacks_have_been_allocated(), | |
941 | 139 "Stack space has not been allocated"); |
0 | 140 PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm); |
141 PSParallelCompact::FollowStackClosure follow_stack_closure(cm); | |
142 _rp_task.work(_work_id, *PSParallelCompact::is_alive_closure(), | |
143 mark_and_push_closure, follow_stack_closure); | |
144 } | |
145 | |
146 // | |
147 // RefProcTaskExecutor | |
148 // | |
149 | |
150 void RefProcTaskExecutor::execute(ProcessTask& task) | |
151 { | |
152 ParallelScavengeHeap* heap = PSParallelCompact::gc_heap(); | |
153 uint parallel_gc_threads = heap->gc_task_manager()->workers(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
154 RegionTaskQueueSet* qset = ParCompactionManager::region_array(); |
0 | 155 ParallelTaskTerminator terminator(parallel_gc_threads, qset); |
156 GCTaskQueue* q = GCTaskQueue::create(); | |
157 for(uint i=0; i<parallel_gc_threads; i++) { | |
158 q->enqueue(new RefProcTaskProxy(task, i)); | |
159 } | |
160 if (task.marks_oops_alive()) { | |
161 if (parallel_gc_threads>1) { | |
162 for (uint j=0; j<parallel_gc_threads; j++) { | |
163 q->enqueue(new StealMarkingTask(&terminator)); | |
164 } | |
165 } | |
166 } | |
167 PSParallelCompact::gc_task_manager()->execute_and_wait(q); | |
168 } | |
169 | |
170 void RefProcTaskExecutor::execute(EnqueueTask& task) | |
171 { | |
172 ParallelScavengeHeap* heap = PSParallelCompact::gc_heap(); | |
173 uint parallel_gc_threads = heap->gc_task_manager()->workers(); | |
174 GCTaskQueue* q = GCTaskQueue::create(); | |
175 for(uint i=0; i<parallel_gc_threads; i++) { | |
176 q->enqueue(new RefEnqueueTaskProxy(task, i)); | |
177 } | |
178 PSParallelCompact::gc_task_manager()->execute_and_wait(q); | |
179 } | |
180 | |
181 // | |
182 // StealMarkingTask | |
183 // | |
184 | |
185 StealMarkingTask::StealMarkingTask(ParallelTaskTerminator* t) : | |
186 _terminator(t) {} | |
187 | |
188 void StealMarkingTask::do_it(GCTaskManager* manager, uint which) { | |
189 assert(Universe::heap()->is_gc_active(), "called outside gc"); | |
190 | |
191 NOT_PRODUCT(TraceTime tm("StealMarkingTask", | |
192 PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty)); | |
193 | |
194 ParCompactionManager* cm = | |
195 ParCompactionManager::gc_thread_compaction_manager(which); | |
196 PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm); | |
197 | |
198 oop obj = NULL; | |
199 int random_seed = 17; | |
200 while(true) { | |
201 if (ParCompactionManager::steal(which, &random_seed, obj)) { | |
202 obj->follow_contents(cm); | |
203 cm->drain_marking_stacks(&mark_and_push_closure); | |
204 } else { | |
205 if (terminator()->offer_termination()) { | |
206 break; | |
207 } | |
208 } | |
209 } | |
210 } | |
211 | |
212 // | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
213 // StealRegionCompactionTask |
0 | 214 // |
215 | |
216 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
217 StealRegionCompactionTask::StealRegionCompactionTask(ParallelTaskTerminator* t): |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
218 _terminator(t) {} |
0 | 219 |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
220 void StealRegionCompactionTask::do_it(GCTaskManager* manager, uint which) { |
0 | 221 assert(Universe::heap()->is_gc_active(), "called outside gc"); |
222 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
223 NOT_PRODUCT(TraceTime tm("StealRegionCompactionTask", |
0 | 224 PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty)); |
225 | |
226 ParCompactionManager* cm = | |
227 ParCompactionManager::gc_thread_compaction_manager(which); | |
228 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
229 // Has to drain stacks first because there may be regions on |
0 | 230 // preloaded onto the stack and this thread may never have |
231 // done a draining task. Are the draining tasks needed? | |
232 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
233 cm->drain_region_stacks(); |
0 | 234 |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
235 size_t region_index = 0; |
0 | 236 int random_seed = 17; |
237 | |
238 // If we're the termination task, try 10 rounds of stealing before | |
239 // setting the termination flag | |
240 | |
241 while(true) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
242 if (ParCompactionManager::steal(which, &random_seed, region_index)) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
243 PSParallelCompact::fill_and_update_region(cm, region_index); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
244 cm->drain_region_stacks(); |
0 | 245 } else { |
246 if (terminator()->offer_termination()) { | |
247 break; | |
248 } | |
249 // Go around again. | |
250 } | |
251 } | |
252 return; | |
253 } | |
254 | |
255 UpdateDensePrefixTask::UpdateDensePrefixTask( | |
256 PSParallelCompact::SpaceId space_id, | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
257 size_t region_index_start, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
258 size_t region_index_end) : |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
259 _space_id(space_id), _region_index_start(region_index_start), |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
260 _region_index_end(region_index_end) {} |
0 | 261 |
262 void UpdateDensePrefixTask::do_it(GCTaskManager* manager, uint which) { | |
263 | |
264 NOT_PRODUCT(TraceTime tm("UpdateDensePrefixTask", | |
265 PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty)); | |
266 | |
267 ParCompactionManager* cm = | |
268 ParCompactionManager::gc_thread_compaction_manager(which); | |
269 | |
270 PSParallelCompact::update_and_deadwood_in_dense_prefix(cm, | |
271 _space_id, | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
272 _region_index_start, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
273 _region_index_end); |
0 | 274 } |
275 | |
276 void DrainStacksCompactionTask::do_it(GCTaskManager* manager, uint which) { | |
277 assert(Universe::heap()->is_gc_active(), "called outside gc"); | |
278 | |
279 NOT_PRODUCT(TraceTime tm("DrainStacksCompactionTask", | |
280 PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty)); | |
281 | |
282 ParCompactionManager* cm = | |
283 ParCompactionManager::gc_thread_compaction_manager(which); | |
284 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
285 // Process any regions already in the compaction managers stacks. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
196
diff
changeset
|
286 cm->drain_region_stacks(); |
0 | 287 } |