Mercurial > hg > graal-jvmci-8
annotate src/share/vm/memory/genMarkSweep.cpp @ 1994:6cd6d394f280
7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
7002546: regression on SpecJbb2005 on 7b118 comparing to 7b117 on small heaps
Summary: Relaxed assertion checking related to incremental_collection_failed flag to allow for ExplicitGCInvokesConcurrent behaviour where we do not want a failing scavenge to bail to a stop-world collection. Parameterized incremental_collection_will_fail() so we can selectively use, or not use, as appropriate, the statistical prediction at specific use sites. This essentially reverts the scavenge bail-out logic to what it was prior to some recent changes that had inadvertently started using the statistical prediction which can be noisy in the presence of bursty loads. Added some associated verbose non-product debugging messages.
Reviewed-by: johnc, tonyp
author | ysr |
---|---|
date | Tue, 07 Dec 2010 21:55:53 -0800 |
parents | f95d63e2154a |
children | 9afee0b9fc1d |
rev | line source |
---|---|
0 | 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. |
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:
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. |
0 | 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_interface/collectedHeap.inline.hpp" | |
33 #include "memory/genCollectedHeap.hpp" | |
34 #include "memory/genMarkSweep.hpp" | |
35 #include "memory/genOopClosures.inline.hpp" | |
36 #include "memory/generation.inline.hpp" | |
37 #include "memory/modRefBarrierSet.hpp" | |
38 #include "memory/referencePolicy.hpp" | |
39 #include "memory/space.hpp" | |
40 #include "oops/instanceRefKlass.hpp" | |
41 #include "oops/oop.inline.hpp" | |
42 #include "prims/jvmtiExport.hpp" | |
43 #include "runtime/fprofiler.hpp" | |
44 #include "runtime/handles.inline.hpp" | |
45 #include "runtime/synchronizer.hpp" | |
46 #include "runtime/vmThread.hpp" | |
47 #include "utilities/copy.hpp" | |
48 #include "utilities/events.hpp" | |
49 #ifdef TARGET_OS_FAMILY_linux | |
50 # include "thread_linux.inline.hpp" | |
51 #endif | |
52 #ifdef TARGET_OS_FAMILY_solaris | |
53 # include "thread_solaris.inline.hpp" | |
54 #endif | |
55 #ifdef TARGET_OS_FAMILY_windows | |
56 # include "thread_windows.inline.hpp" | |
57 #endif | |
0 | 58 |
59 void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp, | |
60 bool clear_all_softrefs) { | |
61 assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint"); | |
62 | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
63 GenCollectedHeap* gch = GenCollectedHeap::heap(); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
64 #ifdef ASSERT |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
65 if (gch->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
|
66 assert(clear_all_softrefs, "Policy should have been checked earlier"); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
67 } |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
68 #endif |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
69 |
0 | 70 // hook up weak ref data so it can be used during Mark-Sweep |
71 assert(ref_processor() == NULL, "no stomping"); | |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
356
diff
changeset
|
72 assert(rp != NULL, "should be non-NULL"); |
0 | 73 _ref_processor = rp; |
457
27a80744a83b
6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents:
453
diff
changeset
|
74 rp->setup_policy(clear_all_softrefs); |
0 | 75 |
76 TraceTime t1("Full GC", PrintGC && !PrintGCDetails, true, gclog_or_tty); | |
77 | |
78 // When collecting the permanent generation methodOops may be moving, | |
79 // so we either have to flush all bcp data or convert it into bci. | |
80 CodeCache::gc_prologue(); | |
81 Threads::gc_prologue(); | |
82 | |
83 // Increment the invocation count for the permanent generation, since it is | |
84 // implicitly collected whenever we do a full mark sweep collection. | |
85 gch->perm_gen()->stat_record()->invocations++; | |
86 | |
87 // Capture heap size before collection for printing. | |
88 size_t gch_prev_used = gch->used(); | |
89 | |
90 // Some of the card table updates below assume that the perm gen is | |
91 // also being collected. | |
92 assert(level == gch->n_gens() - 1, | |
93 "All generations are being collected, ergo perm gen too."); | |
94 | |
95 // Capture used regions for each generation that will be | |
96 // subject to collection, so that card table adjustments can | |
97 // be made intelligently (see clear / invalidate further below). | |
98 gch->save_used_regions(level, true /* perm */); | |
99 | |
100 allocate_stacks(); | |
101 | |
102 mark_sweep_phase1(level, clear_all_softrefs); | |
103 | |
104 mark_sweep_phase2(); | |
105 | |
106 // Don't add any more derived pointers during phase3 | |
107 COMPILER2_PRESENT(assert(DerivedPointerTable::is_active(), "Sanity")); | |
108 COMPILER2_PRESENT(DerivedPointerTable::set_active(false)); | |
109 | |
110 mark_sweep_phase3(level); | |
111 | |
112 VALIDATE_MARK_SWEEP_ONLY( | |
113 if (ValidateMarkSweep) { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
114 guarantee(_root_refs_stack->length() == 0, "should be empty by now"); |
0 | 115 } |
116 ) | |
117 | |
118 mark_sweep_phase4(); | |
119 | |
120 VALIDATE_MARK_SWEEP_ONLY( | |
121 if (ValidateMarkSweep) { | |
122 guarantee(_live_oops->length() == _live_oops_moved_to->length(), | |
123 "should be the same size"); | |
124 } | |
125 ) | |
126 | |
127 restore_marks(); | |
128 | |
129 // Set saved marks for allocation profiler (and other things? -- dld) | |
130 // (Should this be in general part?) | |
131 gch->save_marks(); | |
132 | |
133 deallocate_stacks(); | |
134 | |
135 // If compaction completely evacuated all generations younger than this | |
136 // one, then we can clear the card table. Otherwise, we must invalidate | |
137 // it (consider all cards dirty). In the future, we might consider doing | |
138 // compaction within generations only, and doing card-table sliding. | |
139 bool all_empty = true; | |
140 for (int i = 0; all_empty && i < level; i++) { | |
141 Generation* g = gch->get_gen(i); | |
142 all_empty = all_empty && gch->get_gen(i)->used() == 0; | |
143 } | |
144 GenRemSet* rs = gch->rem_set(); | |
145 // Clear/invalidate below make use of the "prev_used_regions" saved earlier. | |
146 if (all_empty) { | |
147 // We've evacuated all generations below us. | |
148 Generation* g = gch->get_gen(level); | |
149 rs->clear_into_younger(g, true /* perm */); | |
150 } else { | |
151 // Invalidate the cards corresponding to the currently used | |
152 // region and clear those corresponding to the evacuated region | |
153 // of all generations just collected (i.e. level and younger). | |
154 rs->invalidate_or_clear(gch->get_gen(level), | |
155 true /* younger */, | |
156 true /* perm */); | |
157 } | |
158 | |
159 Threads::gc_epilogue(); | |
160 CodeCache::gc_epilogue(); | |
161 | |
162 if (PrintGC && !PrintGCDetails) { | |
163 gch->print_heap_change(gch_prev_used); | |
164 } | |
165 | |
166 // refs processing: clean slate | |
167 _ref_processor = NULL; | |
168 | |
169 // Update heap occupancy information which is used as | |
170 // input to soft ref clearing policy at the next gc. | |
171 Universe::update_heap_info_at_gc(); | |
172 | |
173 // Update time of last gc for all generations we collected | |
174 // (which curently is all the generations in the heap). | |
175 gch->update_time_of_last_gc(os::javaTimeMillis()); | |
176 } | |
177 | |
178 void GenMarkSweep::allocate_stacks() { | |
179 GenCollectedHeap* gch = GenCollectedHeap::heap(); | |
180 // Scratch request on behalf of oldest generation; will do no | |
181 // allocation. | |
182 ScratchBlock* scratch = gch->gather_scratch(gch->_gens[gch->_n_gens-1], 0); | |
183 | |
184 // $$$ To cut a corner, we'll only use the first scratch block, and then | |
185 // revert to malloc. | |
186 if (scratch != NULL) { | |
187 _preserved_count_max = | |
188 scratch->num_words * HeapWordSize / sizeof(PreservedMark); | |
189 } else { | |
190 _preserved_count_max = 0; | |
191 } | |
192 | |
193 _preserved_marks = (PreservedMark*)scratch; | |
194 _preserved_count = 0; | |
195 | |
196 #ifdef VALIDATE_MARK_SWEEP | |
197 if (ValidateMarkSweep) { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
198 _root_refs_stack = new (ResourceObj::C_HEAP) GrowableArray<void*>(100, true); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
199 _other_refs_stack = new (ResourceObj::C_HEAP) GrowableArray<void*>(100, true); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
200 _adjusted_pointers = new (ResourceObj::C_HEAP) GrowableArray<void*>(100, true); |
0 | 201 _live_oops = new (ResourceObj::C_HEAP) GrowableArray<oop>(100, true); |
202 _live_oops_moved_to = new (ResourceObj::C_HEAP) GrowableArray<oop>(100, true); | |
203 _live_oops_size = new (ResourceObj::C_HEAP) GrowableArray<size_t>(100, true); | |
204 } | |
205 if (RecordMarkSweepCompaction) { | |
206 if (_cur_gc_live_oops == NULL) { | |
207 _cur_gc_live_oops = new(ResourceObj::C_HEAP) GrowableArray<HeapWord*>(100, true); | |
208 _cur_gc_live_oops_moved_to = new(ResourceObj::C_HEAP) GrowableArray<HeapWord*>(100, true); | |
209 _cur_gc_live_oops_size = new(ResourceObj::C_HEAP) GrowableArray<size_t>(100, true); | |
210 _last_gc_live_oops = new(ResourceObj::C_HEAP) GrowableArray<HeapWord*>(100, true); | |
211 _last_gc_live_oops_moved_to = new(ResourceObj::C_HEAP) GrowableArray<HeapWord*>(100, true); | |
212 _last_gc_live_oops_size = new(ResourceObj::C_HEAP) GrowableArray<size_t>(100, true); | |
213 } else { | |
214 _cur_gc_live_oops->clear(); | |
215 _cur_gc_live_oops_moved_to->clear(); | |
216 _cur_gc_live_oops_size->clear(); | |
217 } | |
218 } | |
219 #endif | |
220 } | |
221 | |
222 | |
223 void GenMarkSweep::deallocate_stacks() { | |
356 | 224 if (!UseG1GC) { |
225 GenCollectedHeap* gch = GenCollectedHeap::heap(); | |
226 gch->release_scratch(); | |
227 } | |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
228 |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1552
diff
changeset
|
229 _preserved_mark_stack.clear(true); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1552
diff
changeset
|
230 _preserved_oop_stack.clear(true); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1552
diff
changeset
|
231 _marking_stack.clear(); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1552
diff
changeset
|
232 _objarray_stack.clear(true); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1552
diff
changeset
|
233 _revisit_klass_stack.clear(true); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1552
diff
changeset
|
234 _revisit_mdo_stack.clear(true); |
0 | 235 |
236 #ifdef VALIDATE_MARK_SWEEP | |
237 if (ValidateMarkSweep) { | |
238 delete _root_refs_stack; | |
239 delete _other_refs_stack; | |
240 delete _adjusted_pointers; | |
241 delete _live_oops; | |
242 delete _live_oops_size; | |
243 delete _live_oops_moved_to; | |
244 _live_oops_index = 0; | |
245 _live_oops_index_at_perm = 0; | |
246 } | |
247 #endif | |
248 } | |
249 | |
250 void GenMarkSweep::mark_sweep_phase1(int level, | |
251 bool clear_all_softrefs) { | |
252 // Recursively traverse all live objects and mark them | |
253 EventMark m("1 mark object"); | |
254 TraceTime tm("phase 1", PrintGC && Verbose, true, gclog_or_tty); | |
255 trace(" 1"); | |
256 | |
257 VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking(false)); | |
258 | |
259 GenCollectedHeap* gch = GenCollectedHeap::heap(); | |
260 | |
261 // Because follow_root_closure is created statically, cannot | |
262 // use OopsInGenClosure constructor which takes a generation, | |
263 // as the Universe has not been created when the static constructors | |
264 // are run. | |
265 follow_root_closure.set_orig_generation(gch->get_gen(level)); | |
266 | |
267 gch->gen_process_strong_roots(level, | |
268 false, // Younger gens are not roots. | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
457
diff
changeset
|
269 true, // activate StrongRootsScope |
0 | 270 true, // Collecting permanent generation. |
271 SharedHeap::SO_SystemClasses, | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
457
diff
changeset
|
272 &follow_root_closure, |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
457
diff
changeset
|
273 true, // walk code active on stacks |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
457
diff
changeset
|
274 &follow_root_closure); |
0 | 275 |
276 // Process reference objects found during marking | |
277 { | |
457
27a80744a83b
6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents:
453
diff
changeset
|
278 ref_processor()->setup_policy(clear_all_softrefs); |
0 | 279 ref_processor()->process_discovered_references( |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
356
diff
changeset
|
280 &is_alive, &keep_alive, &follow_stack_closure, NULL); |
0 | 281 } |
282 | |
283 // Follow system dictionary roots and unload classes | |
284 bool purged_class = SystemDictionary::do_unloading(&is_alive); | |
285 | |
286 // Follow code cache roots | |
287 CodeCache::do_unloading(&is_alive, &keep_alive, purged_class); | |
288 follow_stack(); // Flush marking stack | |
289 | |
290 // Update subklass/sibling/implementor links of live klasses | |
291 follow_weak_klass_links(); | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1552
diff
changeset
|
292 assert(_marking_stack.is_empty(), "just drained"); |
0 | 293 |
941 | 294 // Visit memoized MDO's and clear any unmarked weak refs |
295 follow_mdo_weak_refs(); | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1552
diff
changeset
|
296 assert(_marking_stack.is_empty(), "just drained"); |
941 | 297 |
0 | 298 // Visit symbol and interned string tables and delete unmarked oops |
299 SymbolTable::unlink(&is_alive); | |
300 StringTable::unlink(&is_alive); | |
301 | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1552
diff
changeset
|
302 assert(_marking_stack.is_empty(), "stack should be empty by now"); |
0 | 303 } |
304 | |
305 | |
306 void GenMarkSweep::mark_sweep_phase2() { | |
307 // Now all live objects are marked, compute the new object addresses. | |
308 | |
309 // It is imperative that we traverse perm_gen LAST. If dead space is | |
310 // allowed a range of dead object may get overwritten by a dead int | |
311 // array. If perm_gen is not traversed last a klassOop may get | |
312 // overwritten. This is fine since it is dead, but if the class has dead | |
313 // instances we have to skip them, and in order to find their size we | |
314 // need the klassOop! | |
315 // | |
316 // It is not required that we traverse spaces in the same order in | |
317 // phase2, phase3 and phase4, but the ValidateMarkSweep live oops | |
318 // tracking expects us to do so. See comment under phase4. | |
319 | |
320 GenCollectedHeap* gch = GenCollectedHeap::heap(); | |
321 Generation* pg = gch->perm_gen(); | |
322 | |
323 EventMark m("2 compute new addresses"); | |
324 TraceTime tm("phase 2", PrintGC && Verbose, true, gclog_or_tty); | |
325 trace("2"); | |
326 | |
327 VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking(false)); | |
328 | |
329 gch->prepare_for_compaction(); | |
330 | |
331 VALIDATE_MARK_SWEEP_ONLY(_live_oops_index_at_perm = _live_oops_index); | |
332 CompactPoint perm_cp(pg, NULL, NULL); | |
333 pg->prepare_for_compaction(&perm_cp); | |
334 } | |
335 | |
336 class GenAdjustPointersClosure: public GenCollectedHeap::GenClosure { | |
337 public: | |
338 void do_generation(Generation* gen) { | |
339 gen->adjust_pointers(); | |
340 } | |
341 }; | |
342 | |
343 void GenMarkSweep::mark_sweep_phase3(int level) { | |
344 GenCollectedHeap* gch = GenCollectedHeap::heap(); | |
345 Generation* pg = gch->perm_gen(); | |
346 | |
347 // Adjust the pointers to reflect the new locations | |
348 EventMark m("3 adjust pointers"); | |
349 TraceTime tm("phase 3", PrintGC && Verbose, true, gclog_or_tty); | |
350 trace("3"); | |
351 | |
352 VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking(false)); | |
353 | |
354 // Needs to be done before the system dictionary is adjusted. | |
355 pg->pre_adjust_pointers(); | |
356 | |
357 // Because the two closures below are created statically, cannot | |
358 // use OopsInGenClosure constructor which takes a generation, | |
359 // as the Universe has not been created when the static constructors | |
360 // are run. | |
361 adjust_root_pointer_closure.set_orig_generation(gch->get_gen(level)); | |
362 adjust_pointer_closure.set_orig_generation(gch->get_gen(level)); | |
363 | |
364 gch->gen_process_strong_roots(level, | |
365 false, // Younger gens are not roots. | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
457
diff
changeset
|
366 true, // activate StrongRootsScope |
0 | 367 true, // Collecting permanent generation. |
368 SharedHeap::SO_AllClasses, | |
369 &adjust_root_pointer_closure, | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
457
diff
changeset
|
370 false, // do not walk code |
0 | 371 &adjust_root_pointer_closure); |
372 | |
373 // Now adjust pointers in remaining weak roots. (All of which should | |
374 // have been cleared if they pointed to non-surviving objects.) | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
457
diff
changeset
|
375 CodeBlobToOopClosure adjust_code_pointer_closure(&adjust_pointer_closure, |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
457
diff
changeset
|
376 /*do_marking=*/ false); |
0 | 377 gch->gen_process_weak_roots(&adjust_root_pointer_closure, |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
457
diff
changeset
|
378 &adjust_code_pointer_closure, |
0 | 379 &adjust_pointer_closure); |
380 | |
381 adjust_marks(); | |
382 GenAdjustPointersClosure blk; | |
383 gch->generation_iterate(&blk, true); | |
384 pg->adjust_pointers(); | |
385 } | |
386 | |
387 class GenCompactClosure: public GenCollectedHeap::GenClosure { | |
388 public: | |
389 void do_generation(Generation* gen) { | |
390 gen->compact(); | |
391 } | |
392 }; | |
393 | |
394 void GenMarkSweep::mark_sweep_phase4() { | |
395 // All pointers are now adjusted, move objects accordingly | |
396 | |
397 // It is imperative that we traverse perm_gen first in phase4. All | |
398 // classes must be allocated earlier than their instances, and traversing | |
399 // perm_gen first makes sure that all klassOops have moved to their new | |
400 // location before any instance does a dispatch through it's klass! | |
401 | |
402 // The ValidateMarkSweep live oops tracking expects us to traverse spaces | |
403 // in the same order in phase2, phase3 and phase4. We don't quite do that | |
404 // here (perm_gen first rather than last), so we tell the validate code | |
405 // to use a higher index (saved from phase2) when verifying perm_gen. | |
406 GenCollectedHeap* gch = GenCollectedHeap::heap(); | |
407 Generation* pg = gch->perm_gen(); | |
408 | |
409 EventMark m("4 compact heap"); | |
410 TraceTime tm("phase 4", PrintGC && Verbose, true, gclog_or_tty); | |
411 trace("4"); | |
412 | |
413 VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking(true)); | |
414 | |
415 pg->compact(); | |
416 | |
417 VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking(false)); | |
418 | |
419 GenCompactClosure blk; | |
420 gch->generation_iterate(&blk, true); | |
421 | |
422 VALIDATE_MARK_SWEEP_ONLY(compaction_complete()); | |
423 | |
424 pg->post_compact(); // Shared spaces verification. | |
425 } |