Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/g1/g1MarkSweep.cpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | a2f7274eb6ef |
children | 8966c2d65d96 |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
66 assert(rp == G1CollectedHeap::heap()->ref_processor_stw(), "Precondition"); | 66 assert(rp == G1CollectedHeap::heap()->ref_processor_stw(), "Precondition"); |
67 | 67 |
68 GenMarkSweep::_ref_processor = rp; | 68 GenMarkSweep::_ref_processor = rp; |
69 rp->setup_policy(clear_all_softrefs); | 69 rp->setup_policy(clear_all_softrefs); |
70 | 70 |
71 // When collecting the permanent generation methodOops may be moving, | 71 // When collecting the permanent generation Method*s may be moving, |
72 // so we either have to flush all bcp data or convert it into bci. | 72 // so we either have to flush all bcp data or convert it into bci. |
73 CodeCache::gc_prologue(); | 73 CodeCache::gc_prologue(); |
74 Threads::gc_prologue(); | 74 Threads::gc_prologue(); |
75 | 75 |
76 // Increment the invocation count for the permanent generation, since it is | |
77 // implicitly collected whenever we do a full mark sweep collection. | |
78 sh->perm_gen()->stat_record()->invocations++; | |
79 | |
80 bool marked_for_unloading = false; | 76 bool marked_for_unloading = false; |
81 | 77 |
82 allocate_stacks(); | 78 allocate_stacks(); |
83 | 79 |
84 // We should save the marks of the currently locked biased monitors. | 80 // We should save the marks of the currently locked biased monitors. |
97 mark_sweep_phase4(); | 93 mark_sweep_phase4(); |
98 | 94 |
99 GenMarkSweep::restore_marks(); | 95 GenMarkSweep::restore_marks(); |
100 BiasedLocking::restore_marks(); | 96 BiasedLocking::restore_marks(); |
101 GenMarkSweep::deallocate_stacks(); | 97 GenMarkSweep::deallocate_stacks(); |
102 | |
103 // We must invalidate the perm-gen rs, so that it gets rebuilt. | |
104 GenRemSet* rs = sh->rem_set(); | |
105 rs->invalidate(sh->perm_gen()->used_region(), true /*whole_heap*/); | |
106 | 98 |
107 // "free at last gc" is calculated from these. | 99 // "free at last gc" is calculated from these. |
108 // CHF: cheating for now!!! | 100 // CHF: cheating for now!!! |
109 // Universe::set_heap_capacity_at_last_gc(Universe::heap()->capacity()); | 101 // Universe::set_heap_capacity_at_last_gc(Universe::heap()->capacity()); |
110 // Universe::set_heap_used_at_last_gc(Universe::heap()->used()); | 102 // Universe::set_heap_used_at_last_gc(Universe::heap()->used()); |
130 TraceTime tm("phase 1", G1Log::fine() && Verbose, true, gclog_or_tty); | 122 TraceTime tm("phase 1", G1Log::fine() && Verbose, true, gclog_or_tty); |
131 GenMarkSweep::trace(" 1"); | 123 GenMarkSweep::trace(" 1"); |
132 | 124 |
133 SharedHeap* sh = SharedHeap::heap(); | 125 SharedHeap* sh = SharedHeap::heap(); |
134 | 126 |
135 sh->process_strong_roots(true, // activeate StrongRootsScope | 127 // Need cleared claim bits for the strong roots processing |
136 true, // Collecting permanent generation. | 128 ClassLoaderDataGraph::clear_claimed_marks(); |
129 | |
130 sh->process_strong_roots(true, // activate StrongRootsScope | |
131 false, // not scavenging. | |
137 SharedHeap::SO_SystemClasses, | 132 SharedHeap::SO_SystemClasses, |
138 &GenMarkSweep::follow_root_closure, | 133 &GenMarkSweep::follow_root_closure, |
139 &GenMarkSweep::follow_code_root_closure, | 134 &GenMarkSweep::follow_code_root_closure, |
140 &GenMarkSweep::follow_root_closure); | 135 &GenMarkSweep::follow_klass_closure); |
141 | 136 |
142 // Process reference objects found during marking | 137 // Process reference objects found during marking |
143 ReferenceProcessor* rp = GenMarkSweep::ref_processor(); | 138 ReferenceProcessor* rp = GenMarkSweep::ref_processor(); |
144 assert(rp == G1CollectedHeap::heap()->ref_processor_stw(), "Sanity"); | 139 assert(rp == G1CollectedHeap::heap()->ref_processor_stw(), "Sanity"); |
145 | 140 |
160 &GenMarkSweep::keep_alive, | 155 &GenMarkSweep::keep_alive, |
161 purged_class); | 156 purged_class); |
162 GenMarkSweep::follow_stack(); | 157 GenMarkSweep::follow_stack(); |
163 | 158 |
164 // Update subklass/sibling/implementor links of live klasses | 159 // Update subklass/sibling/implementor links of live klasses |
165 GenMarkSweep::follow_weak_klass_links(); | 160 Klass::clean_weak_klass_links(&GenMarkSweep::is_alive); |
166 assert(GenMarkSweep::_marking_stack.is_empty(), | 161 assert(GenMarkSweep::_marking_stack.is_empty(), |
167 "stack should be empty by now"); | 162 "stack should be empty by now"); |
168 | |
169 // Visit memoized MDO's and clear any unmarked weak refs | |
170 GenMarkSweep::follow_mdo_weak_refs(); | |
171 assert(GenMarkSweep::_marking_stack.is_empty(), "just drained"); | |
172 | 163 |
173 // Visit interned string tables and delete unmarked oops | 164 // Visit interned string tables and delete unmarked oops |
174 StringTable::unlink(&GenMarkSweep::is_alive); | 165 StringTable::unlink(&GenMarkSweep::is_alive); |
175 // Clean up unreferenced symbols in symbol table. | 166 // Clean up unreferenced symbols in symbol table. |
176 SymbolTable::unlink(); | 167 SymbolTable::unlink(); |
263 }; | 254 }; |
264 | 255 |
265 void G1MarkSweep::mark_sweep_phase2() { | 256 void G1MarkSweep::mark_sweep_phase2() { |
266 // Now all live objects are marked, compute the new object addresses. | 257 // Now all live objects are marked, compute the new object addresses. |
267 | 258 |
268 // It is imperative that we traverse perm_gen LAST. If dead space is | |
269 // allowed a range of dead object may get overwritten by a dead int | |
270 // array. If perm_gen is not traversed last a klassOop may get | |
271 // overwritten. This is fine since it is dead, but if the class has dead | |
272 // instances we have to skip them, and in order to find their size we | |
273 // need the klassOop! | |
274 // | |
275 // It is not required that we traverse spaces in the same order in | 259 // It is not required that we traverse spaces in the same order in |
276 // phase2, phase3 and phase4, but the ValidateMarkSweep live oops | 260 // phase2, phase3 and phase4, but the ValidateMarkSweep live oops |
277 // tracking expects us to do so. See comment under phase4. | 261 // tracking expects us to do so. See comment under phase4. |
278 | 262 |
279 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | 263 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
280 Generation* pg = g1h->perm_gen(); | |
281 | 264 |
282 TraceTime tm("phase 2", G1Log::fine() && Verbose, true, gclog_or_tty); | 265 TraceTime tm("phase 2", G1Log::fine() && Verbose, true, gclog_or_tty); |
283 GenMarkSweep::trace("2"); | 266 GenMarkSweep::trace("2"); |
284 | 267 |
285 // find the first region | 268 // find the first region |
290 } | 273 } |
291 | 274 |
292 G1PrepareCompactClosure blk(sp); | 275 G1PrepareCompactClosure blk(sp); |
293 g1h->heap_region_iterate(&blk); | 276 g1h->heap_region_iterate(&blk); |
294 blk.update_sets(); | 277 blk.update_sets(); |
295 | |
296 CompactPoint perm_cp(pg, NULL, NULL); | |
297 pg->prepare_for_compaction(&perm_cp); | |
298 } | 278 } |
299 | 279 |
300 class G1AdjustPointersClosure: public HeapRegionClosure { | 280 class G1AdjustPointersClosure: public HeapRegionClosure { |
301 public: | 281 public: |
302 bool doHeapRegion(HeapRegion* r) { | 282 bool doHeapRegion(HeapRegion* r) { |
317 } | 297 } |
318 }; | 298 }; |
319 | 299 |
320 void G1MarkSweep::mark_sweep_phase3() { | 300 void G1MarkSweep::mark_sweep_phase3() { |
321 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | 301 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
322 Generation* pg = g1h->perm_gen(); | |
323 | 302 |
324 // Adjust the pointers to reflect the new locations | 303 // Adjust the pointers to reflect the new locations |
325 TraceTime tm("phase 3", G1Log::fine() && Verbose, true, gclog_or_tty); | 304 TraceTime tm("phase 3", G1Log::fine() && Verbose, true, gclog_or_tty); |
326 GenMarkSweep::trace("3"); | 305 GenMarkSweep::trace("3"); |
327 | 306 |
328 SharedHeap* sh = SharedHeap::heap(); | 307 SharedHeap* sh = SharedHeap::heap(); |
329 | 308 |
309 // Need cleared claim bits for the strong roots processing | |
310 ClassLoaderDataGraph::clear_claimed_marks(); | |
311 | |
330 sh->process_strong_roots(true, // activate StrongRootsScope | 312 sh->process_strong_roots(true, // activate StrongRootsScope |
331 true, // Collecting permanent generation. | 313 false, // not scavenging. |
332 SharedHeap::SO_AllClasses, | 314 SharedHeap::SO_AllClasses, |
333 &GenMarkSweep::adjust_root_pointer_closure, | 315 &GenMarkSweep::adjust_root_pointer_closure, |
334 NULL, // do not touch code cache here | 316 NULL, // do not touch code cache here |
335 &GenMarkSweep::adjust_pointer_closure); | 317 &GenMarkSweep::adjust_klass_closure); |
336 | 318 |
337 assert(GenMarkSweep::ref_processor() == g1h->ref_processor_stw(), "Sanity"); | 319 assert(GenMarkSweep::ref_processor() == g1h->ref_processor_stw(), "Sanity"); |
338 g1h->ref_processor_stw()->weak_oops_do(&GenMarkSweep::adjust_root_pointer_closure); | 320 g1h->ref_processor_stw()->weak_oops_do(&GenMarkSweep::adjust_root_pointer_closure); |
339 | 321 |
340 // Now adjust pointers in remaining weak roots. (All of which should | 322 // Now adjust pointers in remaining weak roots. (All of which should |
344 | 326 |
345 GenMarkSweep::adjust_marks(); | 327 GenMarkSweep::adjust_marks(); |
346 | 328 |
347 G1AdjustPointersClosure blk; | 329 G1AdjustPointersClosure blk; |
348 g1h->heap_region_iterate(&blk); | 330 g1h->heap_region_iterate(&blk); |
349 pg->adjust_pointers(); | |
350 } | 331 } |
351 | 332 |
352 class G1SpaceCompactClosure: public HeapRegionClosure { | 333 class G1SpaceCompactClosure: public HeapRegionClosure { |
353 public: | 334 public: |
354 G1SpaceCompactClosure() {} | 335 G1SpaceCompactClosure() {} |
372 }; | 353 }; |
373 | 354 |
374 void G1MarkSweep::mark_sweep_phase4() { | 355 void G1MarkSweep::mark_sweep_phase4() { |
375 // All pointers are now adjusted, move objects accordingly | 356 // All pointers are now adjusted, move objects accordingly |
376 | 357 |
377 // It is imperative that we traverse perm_gen first in phase4. All | |
378 // classes must be allocated earlier than their instances, and traversing | |
379 // perm_gen first makes sure that all klassOops have moved to their new | |
380 // location before any instance does a dispatch through it's klass! | |
381 | |
382 // The ValidateMarkSweep live oops tracking expects us to traverse spaces | 358 // The ValidateMarkSweep live oops tracking expects us to traverse spaces |
383 // in the same order in phase2, phase3 and phase4. We don't quite do that | 359 // in the same order in phase2, phase3 and phase4. We don't quite do that |
384 // here (perm_gen first rather than last), so we tell the validate code | 360 // here (code and comment not fixed for perm removal), so we tell the validate code |
385 // to use a higher index (saved from phase2) when verifying perm_gen. | 361 // to use a higher index (saved from phase2) when verifying perm_gen. |
386 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | 362 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
387 Generation* pg = g1h->perm_gen(); | |
388 | 363 |
389 TraceTime tm("phase 4", G1Log::fine() && Verbose, true, gclog_or_tty); | 364 TraceTime tm("phase 4", G1Log::fine() && Verbose, true, gclog_or_tty); |
390 GenMarkSweep::trace("4"); | 365 GenMarkSweep::trace("4"); |
391 | 366 |
392 pg->compact(); | |
393 | |
394 G1SpaceCompactClosure blk; | 367 G1SpaceCompactClosure blk; |
395 g1h->heap_region_iterate(&blk); | 368 g1h->heap_region_iterate(&blk); |
396 | 369 |
397 } | 370 } |