Mercurial > hg > graal-jvmci-8
annotate src/share/vm/gc_implementation/g1/g1MarkSweep.cpp @ 1705:2d160770d2e5
6814437: G1: remove the _new_refs array
Summary: The per-worker _new_refs array is used to hold references that point into the collection set. It is populated during RSet updating and subsequently processed. In the event of an evacuation failure it processed again to recreate the RSets of regions in the collection set. Remove the per-worker _new_refs array by processing the references directly. Use a DirtyCardQueue to hold the cards containing the references so that the RSets of regions in the collection set can be recreated when handling an evacuation failure.
Reviewed-by: iveresov, jmasa, tonyp
author | johnc |
---|---|
date | Mon, 02 Aug 2010 12:51:43 -0700 |
parents | c18cbe5936b8 |
children | 894b1d7c7e01 |
rev | line source |
---|---|
342 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1387
diff
changeset
|
2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. |
342 | 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:
1387
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1387
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:
1387
diff
changeset
|
21 * questions. |
342 | 22 * |
23 */ | |
24 | |
25 #include "incls/_precompiled.incl" | |
26 #include "incls/_g1MarkSweep.cpp.incl" | |
27 | |
28 class HeapRegion; | |
29 | |
30 void G1MarkSweep::invoke_at_safepoint(ReferenceProcessor* rp, | |
31 bool clear_all_softrefs) { | |
32 assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint"); | |
33 | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
34 SharedHeap* sh = SharedHeap::heap(); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
35 #ifdef ASSERT |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
36 if (sh->collector_policy()->should_clear_all_soft_refs()) { |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
37 assert(clear_all_softrefs, "Policy should have been checked earler"); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
38 } |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
39 #endif |
342 | 40 // hook up weak ref data so it can be used during Mark-Sweep |
41 assert(GenMarkSweep::ref_processor() == NULL, "no stomping"); | |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
358
diff
changeset
|
42 assert(rp != NULL, "should be non-NULL"); |
342 | 43 GenMarkSweep::_ref_processor = rp; |
457
27a80744a83b
6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents:
453
diff
changeset
|
44 rp->setup_policy(clear_all_softrefs); |
342 | 45 |
46 // When collecting the permanent generation methodOops may be moving, | |
47 // so we either have to flush all bcp data or convert it into bci. | |
48 CodeCache::gc_prologue(); | |
49 Threads::gc_prologue(); | |
50 | |
51 // Increment the invocation count for the permanent generation, since it is | |
52 // implicitly collected whenever we do a full mark sweep collection. | |
53 sh->perm_gen()->stat_record()->invocations++; | |
54 | |
55 bool marked_for_unloading = false; | |
56 | |
57 allocate_stacks(); | |
58 | |
358
8651a65ac4b4
6735416: G1: runThese javasoft.sqe.tests.lang.thrd011.thrd01101.thrd01101 fails
iveresov
parents:
342
diff
changeset
|
59 // We should save the marks of the currently locked biased monitors. |
8651a65ac4b4
6735416: G1: runThese javasoft.sqe.tests.lang.thrd011.thrd01101.thrd01101 fails
iveresov
parents:
342
diff
changeset
|
60 // The marking doesn't preserve the marks of biased objects. |
8651a65ac4b4
6735416: G1: runThese javasoft.sqe.tests.lang.thrd011.thrd01101.thrd01101 fails
iveresov
parents:
342
diff
changeset
|
61 BiasedLocking::preserve_marks(); |
8651a65ac4b4
6735416: G1: runThese javasoft.sqe.tests.lang.thrd011.thrd01101.thrd01101 fails
iveresov
parents:
342
diff
changeset
|
62 |
342 | 63 mark_sweep_phase1(marked_for_unloading, clear_all_softrefs); |
64 | |
751 | 65 if (VerifyDuringGC) { |
342 | 66 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
67 g1h->checkConcurrentMark(); | |
68 } | |
69 | |
70 mark_sweep_phase2(); | |
71 | |
72 // Don't add any more derived pointers during phase3 | |
73 COMPILER2_PRESENT(DerivedPointerTable::set_active(false)); | |
74 | |
75 mark_sweep_phase3(); | |
76 | |
77 mark_sweep_phase4(); | |
78 | |
79 GenMarkSweep::restore_marks(); | |
358
8651a65ac4b4
6735416: G1: runThese javasoft.sqe.tests.lang.thrd011.thrd01101.thrd01101 fails
iveresov
parents:
342
diff
changeset
|
80 BiasedLocking::restore_marks(); |
342 | 81 GenMarkSweep::deallocate_stacks(); |
82 | |
83 // We must invalidate the perm-gen rs, so that it gets rebuilt. | |
84 GenRemSet* rs = sh->rem_set(); | |
85 rs->invalidate(sh->perm_gen()->used_region(), true /*whole_heap*/); | |
86 | |
87 // "free at last gc" is calculated from these. | |
88 // CHF: cheating for now!!! | |
89 // Universe::set_heap_capacity_at_last_gc(Universe::heap()->capacity()); | |
90 // Universe::set_heap_used_at_last_gc(Universe::heap()->used()); | |
91 | |
92 Threads::gc_epilogue(); | |
93 CodeCache::gc_epilogue(); | |
94 | |
95 // refs processing: clean slate | |
96 GenMarkSweep::_ref_processor = NULL; | |
97 } | |
98 | |
99 | |
100 void G1MarkSweep::allocate_stacks() { | |
101 GenMarkSweep::_preserved_count_max = 0; | |
102 GenMarkSweep::_preserved_marks = NULL; | |
103 GenMarkSweep::_preserved_count = 0; | |
104 GenMarkSweep::_preserved_mark_stack = NULL; | |
105 GenMarkSweep::_preserved_oop_stack = NULL; | |
106 | |
107 GenMarkSweep::_marking_stack = | |
108 new (ResourceObj::C_HEAP) GrowableArray<oop>(4000, true); | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
993
diff
changeset
|
109 GenMarkSweep::_objarray_stack = |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
993
diff
changeset
|
110 new (ResourceObj::C_HEAP) GrowableArray<ObjArrayTask>(50, true); |
342 | 111 |
941 | 112 int size = SystemDictionary::number_of_classes() * 2; |
342 | 113 GenMarkSweep::_revisit_klass_stack = |
941 | 114 new (ResourceObj::C_HEAP) GrowableArray<Klass*>(size, true); |
115 // (#klass/k)^2 for k ~ 10 appears a better fit, but this will have to do | |
116 // for now until we have a chance to work out a more optimal setting. | |
117 GenMarkSweep::_revisit_mdo_stack = | |
118 new (ResourceObj::C_HEAP) GrowableArray<DataLayout*>(size*2, true); | |
119 | |
342 | 120 } |
121 | |
122 void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading, | |
123 bool clear_all_softrefs) { | |
124 // Recursively traverse all live objects and mark them | |
125 EventMark m("1 mark object"); | |
126 TraceTime tm("phase 1", PrintGC && Verbose, true, gclog_or_tty); | |
127 GenMarkSweep::trace(" 1"); | |
128 | |
129 SharedHeap* sh = SharedHeap::heap(); | |
130 | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
131 sh->process_strong_roots(true, // activeate StrongRootsScope |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
132 true, // Collecting permanent generation. |
342 | 133 SharedHeap::SO_SystemClasses, |
134 &GenMarkSweep::follow_root_closure, | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
135 &GenMarkSweep::follow_code_root_closure, |
342 | 136 &GenMarkSweep::follow_root_closure); |
137 | |
138 // Process reference objects found during marking | |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
358
diff
changeset
|
139 ReferenceProcessor* rp = GenMarkSweep::ref_processor(); |
457
27a80744a83b
6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents:
453
diff
changeset
|
140 rp->setup_policy(clear_all_softrefs); |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
358
diff
changeset
|
141 rp->process_discovered_references(&GenMarkSweep::is_alive, |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
358
diff
changeset
|
142 &GenMarkSweep::keep_alive, |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
358
diff
changeset
|
143 &GenMarkSweep::follow_stack_closure, |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
358
diff
changeset
|
144 NULL); |
342 | 145 |
146 // Follow system dictionary roots and unload classes | |
147 bool purged_class = SystemDictionary::do_unloading(&GenMarkSweep::is_alive); | |
148 assert(GenMarkSweep::_marking_stack->is_empty(), | |
149 "stack should be empty by now"); | |
150 | |
151 // Follow code cache roots (has to be done after system dictionary, | |
152 // assumes all live klasses are marked) | |
153 CodeCache::do_unloading(&GenMarkSweep::is_alive, | |
154 &GenMarkSweep::keep_alive, | |
155 purged_class); | |
941 | 156 GenMarkSweep::follow_stack(); |
342 | 157 |
158 // Update subklass/sibling/implementor links of live klasses | |
159 GenMarkSweep::follow_weak_klass_links(); | |
160 assert(GenMarkSweep::_marking_stack->is_empty(), | |
161 "stack should be empty by now"); | |
162 | |
941 | 163 // Visit memoized MDO's and clear any unmarked weak refs |
164 GenMarkSweep::follow_mdo_weak_refs(); | |
165 assert(GenMarkSweep::_marking_stack->is_empty(), "just drained"); | |
166 | |
167 | |
342 | 168 // Visit symbol and interned string tables and delete unmarked oops |
169 SymbolTable::unlink(&GenMarkSweep::is_alive); | |
170 StringTable::unlink(&GenMarkSweep::is_alive); | |
171 | |
172 assert(GenMarkSweep::_marking_stack->is_empty(), | |
173 "stack should be empty by now"); | |
174 } | |
175 | |
176 class G1PrepareCompactClosure: public HeapRegionClosure { | |
177 ModRefBarrierSet* _mrbs; | |
178 CompactPoint _cp; | |
179 | |
180 void free_humongous_region(HeapRegion* hr) { | |
181 HeapWord* bot = hr->bottom(); | |
182 HeapWord* end = hr->end(); | |
183 assert(hr->startsHumongous(), | |
184 "Only the start of a humongous region should be freed."); | |
185 G1CollectedHeap::heap()->free_region(hr); | |
186 hr->prepare_for_compaction(&_cp); | |
187 // Also clear the part of the card table that will be unused after | |
188 // compaction. | |
189 _mrbs->clear(MemRegion(hr->compaction_top(), hr->end())); | |
190 } | |
191 | |
192 public: | |
677 | 193 G1PrepareCompactClosure(CompactibleSpace* cs) : |
342 | 194 _cp(NULL, cs, cs->initialize_threshold()), |
677 | 195 _mrbs(G1CollectedHeap::heap()->mr_bs()) |
342 | 196 {} |
197 bool doHeapRegion(HeapRegion* hr) { | |
198 if (hr->isHumongous()) { | |
199 if (hr->startsHumongous()) { | |
200 oop obj = oop(hr->bottom()); | |
201 if (obj->is_gc_marked()) { | |
202 obj->forward_to(obj); | |
203 } else { | |
204 free_humongous_region(hr); | |
205 } | |
206 } else { | |
207 assert(hr->continuesHumongous(), "Invalid humongous."); | |
208 } | |
209 } else { | |
210 hr->prepare_for_compaction(&_cp); | |
211 // Also clear the part of the card table that will be unused after | |
212 // compaction. | |
213 _mrbs->clear(MemRegion(hr->compaction_top(), hr->end())); | |
214 } | |
215 return false; | |
216 } | |
217 }; | |
677 | 218 |
219 // Finds the first HeapRegion. | |
342 | 220 class FindFirstRegionClosure: public HeapRegionClosure { |
221 HeapRegion* _a_region; | |
222 public: | |
677 | 223 FindFirstRegionClosure() : _a_region(NULL) {} |
342 | 224 bool doHeapRegion(HeapRegion* r) { |
677 | 225 _a_region = r; |
226 return true; | |
342 | 227 } |
228 HeapRegion* result() { return _a_region; } | |
229 }; | |
230 | |
231 void G1MarkSweep::mark_sweep_phase2() { | |
232 // Now all live objects are marked, compute the new object addresses. | |
233 | |
234 // It is imperative that we traverse perm_gen LAST. If dead space is | |
235 // allowed a range of dead object may get overwritten by a dead int | |
236 // array. If perm_gen is not traversed last a klassOop may get | |
237 // overwritten. This is fine since it is dead, but if the class has dead | |
238 // instances we have to skip them, and in order to find their size we | |
239 // need the klassOop! | |
240 // | |
241 // It is not required that we traverse spaces in the same order in | |
242 // phase2, phase3 and phase4, but the ValidateMarkSweep live oops | |
243 // tracking expects us to do so. See comment under phase4. | |
244 | |
245 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
246 Generation* pg = g1h->perm_gen(); | |
247 | |
248 EventMark m("2 compute new addresses"); | |
249 TraceTime tm("phase 2", PrintGC && Verbose, true, gclog_or_tty); | |
250 GenMarkSweep::trace("2"); | |
251 | |
677 | 252 FindFirstRegionClosure cl; |
342 | 253 g1h->heap_region_iterate(&cl); |
254 HeapRegion *r = cl.result(); | |
255 CompactibleSpace* sp = r; | |
256 if (r->isHumongous() && oop(r->bottom())->is_gc_marked()) { | |
257 sp = r->next_compaction_space(); | |
258 } | |
259 | |
677 | 260 G1PrepareCompactClosure blk(sp); |
342 | 261 g1h->heap_region_iterate(&blk); |
262 | |
263 CompactPoint perm_cp(pg, NULL, NULL); | |
264 pg->prepare_for_compaction(&perm_cp); | |
265 } | |
266 | |
267 class G1AdjustPointersClosure: public HeapRegionClosure { | |
268 public: | |
269 bool doHeapRegion(HeapRegion* r) { | |
270 if (r->isHumongous()) { | |
271 if (r->startsHumongous()) { | |
272 // We must adjust the pointers on the single H object. | |
273 oop obj = oop(r->bottom()); | |
274 debug_only(GenMarkSweep::track_interior_pointers(obj)); | |
275 // point all the oops to the new location | |
276 obj->adjust_pointers(); | |
277 debug_only(GenMarkSweep::check_interior_pointers()); | |
278 } | |
279 } else { | |
280 // This really ought to be "as_CompactibleSpace"... | |
281 r->adjust_pointers(); | |
282 } | |
283 return false; | |
284 } | |
285 }; | |
286 | |
287 void G1MarkSweep::mark_sweep_phase3() { | |
288 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
289 Generation* pg = g1h->perm_gen(); | |
290 | |
291 // Adjust the pointers to reflect the new locations | |
292 EventMark m("3 adjust pointers"); | |
293 TraceTime tm("phase 3", PrintGC && Verbose, true, gclog_or_tty); | |
294 GenMarkSweep::trace("3"); | |
295 | |
296 SharedHeap* sh = SharedHeap::heap(); | |
297 | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
298 sh->process_strong_roots(true, // activate StrongRootsScope |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
299 true, // Collecting permanent generation. |
342 | 300 SharedHeap::SO_AllClasses, |
301 &GenMarkSweep::adjust_root_pointer_closure, | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
302 NULL, // do not touch code cache here |
342 | 303 &GenMarkSweep::adjust_pointer_closure); |
304 | |
305 g1h->ref_processor()->weak_oops_do(&GenMarkSweep::adjust_root_pointer_closure); | |
306 | |
307 // Now adjust pointers in remaining weak roots. (All of which should | |
308 // have been cleared if they pointed to non-surviving objects.) | |
309 g1h->g1_process_weak_roots(&GenMarkSweep::adjust_root_pointer_closure, | |
310 &GenMarkSweep::adjust_pointer_closure); | |
311 | |
312 GenMarkSweep::adjust_marks(); | |
313 | |
314 G1AdjustPointersClosure blk; | |
315 g1h->heap_region_iterate(&blk); | |
316 pg->adjust_pointers(); | |
317 } | |
318 | |
319 class G1SpaceCompactClosure: public HeapRegionClosure { | |
320 public: | |
321 G1SpaceCompactClosure() {} | |
322 | |
323 bool doHeapRegion(HeapRegion* hr) { | |
324 if (hr->isHumongous()) { | |
325 if (hr->startsHumongous()) { | |
326 oop obj = oop(hr->bottom()); | |
327 if (obj->is_gc_marked()) { | |
328 obj->init_mark(); | |
329 } else { | |
330 assert(hr->is_empty(), "Should have been cleared in phase 2."); | |
331 } | |
332 hr->reset_during_compaction(); | |
333 } | |
334 } else { | |
335 hr->compact(); | |
336 } | |
337 return false; | |
338 } | |
339 }; | |
340 | |
341 void G1MarkSweep::mark_sweep_phase4() { | |
342 // All pointers are now adjusted, move objects accordingly | |
343 | |
344 // It is imperative that we traverse perm_gen first in phase4. All | |
345 // classes must be allocated earlier than their instances, and traversing | |
346 // perm_gen first makes sure that all klassOops have moved to their new | |
347 // location before any instance does a dispatch through it's klass! | |
348 | |
349 // The ValidateMarkSweep live oops tracking expects us to traverse spaces | |
350 // in the same order in phase2, phase3 and phase4. We don't quite do that | |
351 // here (perm_gen first rather than last), so we tell the validate code | |
352 // to use a higher index (saved from phase2) when verifying perm_gen. | |
353 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
354 Generation* pg = g1h->perm_gen(); | |
355 | |
356 EventMark m("4 compact heap"); | |
357 TraceTime tm("phase 4", PrintGC && Verbose, true, gclog_or_tty); | |
358 GenMarkSweep::trace("4"); | |
359 | |
360 pg->compact(); | |
361 | |
362 G1SpaceCompactClosure blk; | |
363 g1h->heap_region_iterate(&blk); | |
364 | |
365 } | |
366 | |
367 // Local Variables: *** | |
368 // c-indentation-style: gnu *** | |
369 // End: *** |