Mercurial > hg > truffle
annotate src/share/vm/gc_implementation/g1/g1MarkSweep.cpp @ 2431:02f49b66361a
7026932: G1: No need to abort VM when card count cache expansion fails
Summary: Manage allocation/freeing of the card cache counts and epochs arrays directly so that an allocation failure while attempting to expand these arrays does not abort the JVM. Failure to expand these arrays is not fatal.
Reviewed-by: iveresov, tonyp
author | johnc |
---|---|
date | Mon, 28 Mar 2011 10:58:54 -0700 |
parents | 1216415d8e35 |
children | 6747fd0512e0 |
rev | line source |
---|---|
342 | 1 /* |
2152 | 2 * Copyright (c) 2001, 2011, 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 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/javaClasses.hpp" | |
27 #include "classfile/symbolTable.hpp" | |
28 #include "classfile/systemDictionary.hpp" | |
29 #include "classfile/vmSymbols.hpp" | |
30 #include "code/codeCache.hpp" | |
31 #include "code/icBuffer.hpp" | |
32 #include "gc_implementation/g1/g1MarkSweep.hpp" | |
33 #include "memory/gcLocker.hpp" | |
34 #include "memory/genCollectedHeap.hpp" | |
35 #include "memory/modRefBarrierSet.hpp" | |
36 #include "memory/referencePolicy.hpp" | |
37 #include "memory/space.hpp" | |
38 #include "oops/instanceRefKlass.hpp" | |
39 #include "oops/oop.inline.hpp" | |
40 #include "prims/jvmtiExport.hpp" | |
41 #include "runtime/aprofiler.hpp" | |
42 #include "runtime/biasedLocking.hpp" | |
43 #include "runtime/fprofiler.hpp" | |
44 #include "runtime/synchronizer.hpp" | |
45 #include "runtime/thread.hpp" | |
46 #include "runtime/vmThread.hpp" | |
47 #include "utilities/copy.hpp" | |
48 #include "utilities/events.hpp" | |
342 | 49 |
50 class HeapRegion; | |
51 | |
52 void G1MarkSweep::invoke_at_safepoint(ReferenceProcessor* rp, | |
53 bool clear_all_softrefs) { | |
54 assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint"); | |
55 | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
56 SharedHeap* sh = SharedHeap::heap(); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
57 #ifdef ASSERT |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
58 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
|
59 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
|
60 } |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
61 #endif |
342 | 62 // hook up weak ref data so it can be used during Mark-Sweep |
63 assert(GenMarkSweep::ref_processor() == NULL, "no stomping"); | |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
358
diff
changeset
|
64 assert(rp != NULL, "should be non-NULL"); |
342 | 65 GenMarkSweep::_ref_processor = rp; |
457
27a80744a83b
6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents:
453
diff
changeset
|
66 rp->setup_policy(clear_all_softrefs); |
342 | 67 |
68 // When collecting the permanent generation methodOops may be moving, | |
69 // so we either have to flush all bcp data or convert it into bci. | |
70 CodeCache::gc_prologue(); | |
71 Threads::gc_prologue(); | |
72 | |
73 // Increment the invocation count for the permanent generation, since it is | |
74 // implicitly collected whenever we do a full mark sweep collection. | |
75 sh->perm_gen()->stat_record()->invocations++; | |
76 | |
77 bool marked_for_unloading = false; | |
78 | |
79 allocate_stacks(); | |
80 | |
358
8651a65ac4b4
6735416: G1: runThese javasoft.sqe.tests.lang.thrd011.thrd01101.thrd01101 fails
iveresov
parents:
342
diff
changeset
|
81 // 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
|
82 // 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
|
83 BiasedLocking::preserve_marks(); |
8651a65ac4b4
6735416: G1: runThese javasoft.sqe.tests.lang.thrd011.thrd01101.thrd01101 fails
iveresov
parents:
342
diff
changeset
|
84 |
342 | 85 mark_sweep_phase1(marked_for_unloading, clear_all_softrefs); |
86 | |
751 | 87 if (VerifyDuringGC) { |
342 | 88 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
89 g1h->checkConcurrentMark(); | |
90 } | |
91 | |
92 mark_sweep_phase2(); | |
93 | |
94 // Don't add any more derived pointers during phase3 | |
95 COMPILER2_PRESENT(DerivedPointerTable::set_active(false)); | |
96 | |
97 mark_sweep_phase3(); | |
98 | |
99 mark_sweep_phase4(); | |
100 | |
101 GenMarkSweep::restore_marks(); | |
358
8651a65ac4b4
6735416: G1: runThese javasoft.sqe.tests.lang.thrd011.thrd01101.thrd01101 fails
iveresov
parents:
342
diff
changeset
|
102 BiasedLocking::restore_marks(); |
342 | 103 GenMarkSweep::deallocate_stacks(); |
104 | |
105 // We must invalidate the perm-gen rs, so that it gets rebuilt. | |
106 GenRemSet* rs = sh->rem_set(); | |
107 rs->invalidate(sh->perm_gen()->used_region(), true /*whole_heap*/); | |
108 | |
109 // "free at last gc" is calculated from these. | |
110 // CHF: cheating for now!!! | |
111 // Universe::set_heap_capacity_at_last_gc(Universe::heap()->capacity()); | |
112 // Universe::set_heap_used_at_last_gc(Universe::heap()->used()); | |
113 | |
114 Threads::gc_epilogue(); | |
115 CodeCache::gc_epilogue(); | |
2147
9afee0b9fc1d
7012505: BreakpointWithFullGC.sh fails with Internal Error (src/share/vm/oops/methodOop.cpp:220)
kamg
parents:
1972
diff
changeset
|
116 JvmtiExport::gc_epilogue(); |
342 | 117 |
118 // refs processing: clean slate | |
119 GenMarkSweep::_ref_processor = NULL; | |
120 } | |
121 | |
122 | |
123 void G1MarkSweep::allocate_stacks() { | |
124 GenMarkSweep::_preserved_count_max = 0; | |
125 GenMarkSweep::_preserved_marks = NULL; | |
126 GenMarkSweep::_preserved_count = 0; | |
127 } | |
128 | |
129 void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading, | |
130 bool clear_all_softrefs) { | |
131 // Recursively traverse all live objects and mark them | |
132 EventMark m("1 mark object"); | |
133 TraceTime tm("phase 1", PrintGC && Verbose, true, gclog_or_tty); | |
134 GenMarkSweep::trace(" 1"); | |
135 | |
136 SharedHeap* sh = SharedHeap::heap(); | |
137 | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
138 sh->process_strong_roots(true, // activeate StrongRootsScope |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
139 true, // Collecting permanent generation. |
342 | 140 SharedHeap::SO_SystemClasses, |
141 &GenMarkSweep::follow_root_closure, | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
142 &GenMarkSweep::follow_code_root_closure, |
342 | 143 &GenMarkSweep::follow_root_closure); |
144 | |
145 // Process reference objects found during marking | |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
358
diff
changeset
|
146 ReferenceProcessor* rp = GenMarkSweep::ref_processor(); |
457
27a80744a83b
6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents:
453
diff
changeset
|
147 rp->setup_policy(clear_all_softrefs); |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
358
diff
changeset
|
148 rp->process_discovered_references(&GenMarkSweep::is_alive, |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
358
diff
changeset
|
149 &GenMarkSweep::keep_alive, |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
358
diff
changeset
|
150 &GenMarkSweep::follow_stack_closure, |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
358
diff
changeset
|
151 NULL); |
342 | 152 |
153 // Follow system dictionary roots and unload classes | |
154 bool purged_class = SystemDictionary::do_unloading(&GenMarkSweep::is_alive); | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1552
diff
changeset
|
155 assert(GenMarkSweep::_marking_stack.is_empty(), |
342 | 156 "stack should be empty by now"); |
157 | |
158 // Follow code cache roots (has to be done after system dictionary, | |
159 // assumes all live klasses are marked) | |
160 CodeCache::do_unloading(&GenMarkSweep::is_alive, | |
161 &GenMarkSweep::keep_alive, | |
162 purged_class); | |
941 | 163 GenMarkSweep::follow_stack(); |
342 | 164 |
165 // Update subklass/sibling/implementor links of live klasses | |
166 GenMarkSweep::follow_weak_klass_links(); | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1552
diff
changeset
|
167 assert(GenMarkSweep::_marking_stack.is_empty(), |
342 | 168 "stack should be empty by now"); |
169 | |
941 | 170 // Visit memoized MDO's and clear any unmarked weak refs |
171 GenMarkSweep::follow_mdo_weak_refs(); | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1552
diff
changeset
|
172 assert(GenMarkSweep::_marking_stack.is_empty(), "just drained"); |
941 | 173 |
174 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2153
diff
changeset
|
175 // Visit interned string tables and delete unmarked oops |
342 | 176 StringTable::unlink(&GenMarkSweep::is_alive); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2153
diff
changeset
|
177 // Clean up unreferenced symbols in symbol table. |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2153
diff
changeset
|
178 SymbolTable::unlink(); |
342 | 179 |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1552
diff
changeset
|
180 assert(GenMarkSweep::_marking_stack.is_empty(), |
342 | 181 "stack should be empty by now"); |
182 } | |
183 | |
184 class G1PrepareCompactClosure: public HeapRegionClosure { | |
2152 | 185 G1CollectedHeap* _g1h; |
342 | 186 ModRefBarrierSet* _mrbs; |
187 CompactPoint _cp; | |
2152 | 188 HumongousRegionSet _humongous_proxy_set; |
342 | 189 |
190 void free_humongous_region(HeapRegion* hr) { | |
191 HeapWord* end = hr->end(); | |
2361 | 192 size_t dummy_pre_used; |
193 FreeRegionList dummy_free_list("Dummy Free List for G1MarkSweep"); | |
194 | |
342 | 195 assert(hr->startsHumongous(), |
196 "Only the start of a humongous region should be freed."); | |
2361 | 197 _g1h->free_humongous_region(hr, &dummy_pre_used, &dummy_free_list, |
2152 | 198 &_humongous_proxy_set, false /* par */); |
342 | 199 hr->prepare_for_compaction(&_cp); |
200 // Also clear the part of the card table that will be unused after | |
201 // compaction. | |
2152 | 202 _mrbs->clear(MemRegion(hr->compaction_top(), end)); |
2361 | 203 dummy_free_list.remove_all(); |
342 | 204 } |
205 | |
206 public: | |
2152 | 207 G1PrepareCompactClosure(CompactibleSpace* cs) |
208 : _g1h(G1CollectedHeap::heap()), | |
209 _mrbs(G1CollectedHeap::heap()->mr_bs()), | |
342 | 210 _cp(NULL, cs, cs->initialize_threshold()), |
2152 | 211 _humongous_proxy_set("G1MarkSweep Humongous Proxy Set") { } |
212 | |
213 void update_sets() { | |
214 // We'll recalculate total used bytes and recreate the free list | |
215 // at the end of the GC, so no point in updating those values here. | |
216 _g1h->update_sets_after_freeing_regions(0, /* pre_used */ | |
217 NULL, /* free_list */ | |
218 &_humongous_proxy_set, | |
219 false /* par */); | |
220 } | |
221 | |
342 | 222 bool doHeapRegion(HeapRegion* hr) { |
223 if (hr->isHumongous()) { | |
224 if (hr->startsHumongous()) { | |
225 oop obj = oop(hr->bottom()); | |
226 if (obj->is_gc_marked()) { | |
227 obj->forward_to(obj); | |
228 } else { | |
229 free_humongous_region(hr); | |
230 } | |
231 } else { | |
232 assert(hr->continuesHumongous(), "Invalid humongous."); | |
233 } | |
234 } else { | |
235 hr->prepare_for_compaction(&_cp); | |
236 // Also clear the part of the card table that will be unused after | |
237 // compaction. | |
238 _mrbs->clear(MemRegion(hr->compaction_top(), hr->end())); | |
239 } | |
240 return false; | |
241 } | |
242 }; | |
677 | 243 |
244 // Finds the first HeapRegion. | |
342 | 245 class FindFirstRegionClosure: public HeapRegionClosure { |
246 HeapRegion* _a_region; | |
247 public: | |
677 | 248 FindFirstRegionClosure() : _a_region(NULL) {} |
342 | 249 bool doHeapRegion(HeapRegion* r) { |
677 | 250 _a_region = r; |
251 return true; | |
342 | 252 } |
253 HeapRegion* result() { return _a_region; } | |
254 }; | |
255 | |
256 void G1MarkSweep::mark_sweep_phase2() { | |
257 // Now all live objects are marked, compute the new object addresses. | |
258 | |
259 // It is imperative that we traverse perm_gen LAST. If dead space is | |
260 // allowed a range of dead object may get overwritten by a dead int | |
261 // array. If perm_gen is not traversed last a klassOop may get | |
262 // overwritten. This is fine since it is dead, but if the class has dead | |
263 // instances we have to skip them, and in order to find their size we | |
264 // need the klassOop! | |
265 // | |
266 // It is not required that we traverse spaces in the same order in | |
267 // phase2, phase3 and phase4, but the ValidateMarkSweep live oops | |
268 // tracking expects us to do so. See comment under phase4. | |
269 | |
270 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
271 Generation* pg = g1h->perm_gen(); | |
272 | |
273 EventMark m("2 compute new addresses"); | |
274 TraceTime tm("phase 2", PrintGC && Verbose, true, gclog_or_tty); | |
275 GenMarkSweep::trace("2"); | |
276 | |
677 | 277 FindFirstRegionClosure cl; |
342 | 278 g1h->heap_region_iterate(&cl); |
279 HeapRegion *r = cl.result(); | |
280 CompactibleSpace* sp = r; | |
281 if (r->isHumongous() && oop(r->bottom())->is_gc_marked()) { | |
282 sp = r->next_compaction_space(); | |
283 } | |
284 | |
677 | 285 G1PrepareCompactClosure blk(sp); |
342 | 286 g1h->heap_region_iterate(&blk); |
2152 | 287 blk.update_sets(); |
342 | 288 |
289 CompactPoint perm_cp(pg, NULL, NULL); | |
290 pg->prepare_for_compaction(&perm_cp); | |
291 } | |
292 | |
293 class G1AdjustPointersClosure: public HeapRegionClosure { | |
294 public: | |
295 bool doHeapRegion(HeapRegion* r) { | |
296 if (r->isHumongous()) { | |
297 if (r->startsHumongous()) { | |
298 // We must adjust the pointers on the single H object. | |
299 oop obj = oop(r->bottom()); | |
300 debug_only(GenMarkSweep::track_interior_pointers(obj)); | |
301 // point all the oops to the new location | |
302 obj->adjust_pointers(); | |
303 debug_only(GenMarkSweep::check_interior_pointers()); | |
304 } | |
305 } else { | |
306 // This really ought to be "as_CompactibleSpace"... | |
307 r->adjust_pointers(); | |
308 } | |
309 return false; | |
310 } | |
311 }; | |
312 | |
313 void G1MarkSweep::mark_sweep_phase3() { | |
314 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
315 Generation* pg = g1h->perm_gen(); | |
316 | |
317 // Adjust the pointers to reflect the new locations | |
318 EventMark m("3 adjust pointers"); | |
319 TraceTime tm("phase 3", PrintGC && Verbose, true, gclog_or_tty); | |
320 GenMarkSweep::trace("3"); | |
321 | |
322 SharedHeap* sh = SharedHeap::heap(); | |
323 | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
324 sh->process_strong_roots(true, // activate StrongRootsScope |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
325 true, // Collecting permanent generation. |
342 | 326 SharedHeap::SO_AllClasses, |
327 &GenMarkSweep::adjust_root_pointer_closure, | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
328 NULL, // do not touch code cache here |
342 | 329 &GenMarkSweep::adjust_pointer_closure); |
330 | |
331 g1h->ref_processor()->weak_oops_do(&GenMarkSweep::adjust_root_pointer_closure); | |
332 | |
333 // Now adjust pointers in remaining weak roots. (All of which should | |
334 // have been cleared if they pointed to non-surviving objects.) | |
335 g1h->g1_process_weak_roots(&GenMarkSweep::adjust_root_pointer_closure, | |
336 &GenMarkSweep::adjust_pointer_closure); | |
337 | |
338 GenMarkSweep::adjust_marks(); | |
339 | |
340 G1AdjustPointersClosure blk; | |
341 g1h->heap_region_iterate(&blk); | |
342 pg->adjust_pointers(); | |
343 } | |
344 | |
345 class G1SpaceCompactClosure: public HeapRegionClosure { | |
346 public: | |
347 G1SpaceCompactClosure() {} | |
348 | |
349 bool doHeapRegion(HeapRegion* hr) { | |
350 if (hr->isHumongous()) { | |
351 if (hr->startsHumongous()) { | |
352 oop obj = oop(hr->bottom()); | |
353 if (obj->is_gc_marked()) { | |
354 obj->init_mark(); | |
355 } else { | |
356 assert(hr->is_empty(), "Should have been cleared in phase 2."); | |
357 } | |
358 hr->reset_during_compaction(); | |
359 } | |
360 } else { | |
361 hr->compact(); | |
362 } | |
363 return false; | |
364 } | |
365 }; | |
366 | |
367 void G1MarkSweep::mark_sweep_phase4() { | |
368 // All pointers are now adjusted, move objects accordingly | |
369 | |
370 // It is imperative that we traverse perm_gen first in phase4. All | |
371 // classes must be allocated earlier than their instances, and traversing | |
372 // perm_gen first makes sure that all klassOops have moved to their new | |
373 // location before any instance does a dispatch through it's klass! | |
374 | |
375 // The ValidateMarkSweep live oops tracking expects us to traverse spaces | |
376 // in the same order in phase2, phase3 and phase4. We don't quite do that | |
377 // here (perm_gen first rather than last), so we tell the validate code | |
378 // to use a higher index (saved from phase2) when verifying perm_gen. | |
379 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
380 Generation* pg = g1h->perm_gen(); | |
381 | |
382 EventMark m("4 compact heap"); | |
383 TraceTime tm("phase 4", PrintGC && Verbose, true, gclog_or_tty); | |
384 GenMarkSweep::trace("4"); | |
385 | |
386 pg->compact(); | |
387 | |
388 G1SpaceCompactClosure blk; | |
389 g1h->heap_region_iterate(&blk); | |
390 | |
391 } | |
392 | |
393 // Local Variables: *** | |
394 // c-indentation-style: gnu *** | |
395 // End: *** |