annotate src/share/vm/memory/genMarkSweep.cpp @ 453:c96030fff130

6684579: SoftReference processing can be made more efficient Summary: For current soft-ref clearing policies, we can decide at marking time if a soft-reference will definitely not be cleared, postponing the decision of whether it will definitely be cleared to the final reference processing phase. This can be especially beneficial in the case of concurrent collectors where the marking is usually concurrent but reference processing is usually not. Reviewed-by: jmasa
author ysr
date Thu, 20 Nov 2008 16:56:09 -0800
parents 1ee8caae33af
children 27a80744a83b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
196
d1605aabd0a1 6719955: Update copyright year
xdono
parents: 113
diff changeset
2 * Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 #include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 #include "incls/_genMarkSweep.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp,
a61af66fc99e Initial load
duke
parents:
diff changeset
29 bool clear_all_softrefs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
30 assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
31
a61af66fc99e Initial load
duke
parents:
diff changeset
32 // hook up weak ref data so it can be used during Mark-Sweep
a61af66fc99e Initial load
duke
parents:
diff changeset
33 assert(ref_processor() == NULL, "no stomping");
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 356
diff changeset
34 assert(rp != NULL, "should be non-NULL");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
35 _ref_processor = rp;
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 356
diff changeset
36 rp->snap_policy(clear_all_softrefs);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
37
a61af66fc99e Initial load
duke
parents:
diff changeset
38 TraceTime t1("Full GC", PrintGC && !PrintGCDetails, true, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
39
a61af66fc99e Initial load
duke
parents:
diff changeset
40 // When collecting the permanent generation methodOops may be moving,
a61af66fc99e Initial load
duke
parents:
diff changeset
41 // so we either have to flush all bcp data or convert it into bci.
a61af66fc99e Initial load
duke
parents:
diff changeset
42 CodeCache::gc_prologue();
a61af66fc99e Initial load
duke
parents:
diff changeset
43 Threads::gc_prologue();
a61af66fc99e Initial load
duke
parents:
diff changeset
44
a61af66fc99e Initial load
duke
parents:
diff changeset
45 // Increment the invocation count for the permanent generation, since it is
a61af66fc99e Initial load
duke
parents:
diff changeset
46 // implicitly collected whenever we do a full mark sweep collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
47 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
48 gch->perm_gen()->stat_record()->invocations++;
a61af66fc99e Initial load
duke
parents:
diff changeset
49
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // Capture heap size before collection for printing.
a61af66fc99e Initial load
duke
parents:
diff changeset
51 size_t gch_prev_used = gch->used();
a61af66fc99e Initial load
duke
parents:
diff changeset
52
a61af66fc99e Initial load
duke
parents:
diff changeset
53 // Some of the card table updates below assume that the perm gen is
a61af66fc99e Initial load
duke
parents:
diff changeset
54 // also being collected.
a61af66fc99e Initial load
duke
parents:
diff changeset
55 assert(level == gch->n_gens() - 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
56 "All generations are being collected, ergo perm gen too.");
a61af66fc99e Initial load
duke
parents:
diff changeset
57
a61af66fc99e Initial load
duke
parents:
diff changeset
58 // Capture used regions for each generation that will be
a61af66fc99e Initial load
duke
parents:
diff changeset
59 // subject to collection, so that card table adjustments can
a61af66fc99e Initial load
duke
parents:
diff changeset
60 // be made intelligently (see clear / invalidate further below).
a61af66fc99e Initial load
duke
parents:
diff changeset
61 gch->save_used_regions(level, true /* perm */);
a61af66fc99e Initial load
duke
parents:
diff changeset
62
a61af66fc99e Initial load
duke
parents:
diff changeset
63 allocate_stacks();
a61af66fc99e Initial load
duke
parents:
diff changeset
64
a61af66fc99e Initial load
duke
parents:
diff changeset
65 mark_sweep_phase1(level, clear_all_softrefs);
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67 mark_sweep_phase2();
a61af66fc99e Initial load
duke
parents:
diff changeset
68
a61af66fc99e Initial load
duke
parents:
diff changeset
69 // Don't add any more derived pointers during phase3
a61af66fc99e Initial load
duke
parents:
diff changeset
70 COMPILER2_PRESENT(assert(DerivedPointerTable::is_active(), "Sanity"));
a61af66fc99e Initial load
duke
parents:
diff changeset
71 COMPILER2_PRESENT(DerivedPointerTable::set_active(false));
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 mark_sweep_phase3(level);
a61af66fc99e Initial load
duke
parents:
diff changeset
74
a61af66fc99e Initial load
duke
parents:
diff changeset
75 VALIDATE_MARK_SWEEP_ONLY(
a61af66fc99e Initial load
duke
parents:
diff changeset
76 if (ValidateMarkSweep) {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
77 guarantee(_root_refs_stack->length() == 0, "should be empty by now");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
78 }
a61af66fc99e Initial load
duke
parents:
diff changeset
79 )
a61af66fc99e Initial load
duke
parents:
diff changeset
80
a61af66fc99e Initial load
duke
parents:
diff changeset
81 mark_sweep_phase4();
a61af66fc99e Initial load
duke
parents:
diff changeset
82
a61af66fc99e Initial load
duke
parents:
diff changeset
83 VALIDATE_MARK_SWEEP_ONLY(
a61af66fc99e Initial load
duke
parents:
diff changeset
84 if (ValidateMarkSweep) {
a61af66fc99e Initial load
duke
parents:
diff changeset
85 guarantee(_live_oops->length() == _live_oops_moved_to->length(),
a61af66fc99e Initial load
duke
parents:
diff changeset
86 "should be the same size");
a61af66fc99e Initial load
duke
parents:
diff changeset
87 }
a61af66fc99e Initial load
duke
parents:
diff changeset
88 )
a61af66fc99e Initial load
duke
parents:
diff changeset
89
a61af66fc99e Initial load
duke
parents:
diff changeset
90 restore_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
91
a61af66fc99e Initial load
duke
parents:
diff changeset
92 // Set saved marks for allocation profiler (and other things? -- dld)
a61af66fc99e Initial load
duke
parents:
diff changeset
93 // (Should this be in general part?)
a61af66fc99e Initial load
duke
parents:
diff changeset
94 gch->save_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
95
a61af66fc99e Initial load
duke
parents:
diff changeset
96 deallocate_stacks();
a61af66fc99e Initial load
duke
parents:
diff changeset
97
a61af66fc99e Initial load
duke
parents:
diff changeset
98 // If compaction completely evacuated all generations younger than this
a61af66fc99e Initial load
duke
parents:
diff changeset
99 // one, then we can clear the card table. Otherwise, we must invalidate
a61af66fc99e Initial load
duke
parents:
diff changeset
100 // it (consider all cards dirty). In the future, we might consider doing
a61af66fc99e Initial load
duke
parents:
diff changeset
101 // compaction within generations only, and doing card-table sliding.
a61af66fc99e Initial load
duke
parents:
diff changeset
102 bool all_empty = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
103 for (int i = 0; all_empty && i < level; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
104 Generation* g = gch->get_gen(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
105 all_empty = all_empty && gch->get_gen(i)->used() == 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
107 GenRemSet* rs = gch->rem_set();
a61af66fc99e Initial load
duke
parents:
diff changeset
108 // Clear/invalidate below make use of the "prev_used_regions" saved earlier.
a61af66fc99e Initial load
duke
parents:
diff changeset
109 if (all_empty) {
a61af66fc99e Initial load
duke
parents:
diff changeset
110 // We've evacuated all generations below us.
a61af66fc99e Initial load
duke
parents:
diff changeset
111 Generation* g = gch->get_gen(level);
a61af66fc99e Initial load
duke
parents:
diff changeset
112 rs->clear_into_younger(g, true /* perm */);
a61af66fc99e Initial load
duke
parents:
diff changeset
113 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
114 // Invalidate the cards corresponding to the currently used
a61af66fc99e Initial load
duke
parents:
diff changeset
115 // region and clear those corresponding to the evacuated region
a61af66fc99e Initial load
duke
parents:
diff changeset
116 // of all generations just collected (i.e. level and younger).
a61af66fc99e Initial load
duke
parents:
diff changeset
117 rs->invalidate_or_clear(gch->get_gen(level),
a61af66fc99e Initial load
duke
parents:
diff changeset
118 true /* younger */,
a61af66fc99e Initial load
duke
parents:
diff changeset
119 true /* perm */);
a61af66fc99e Initial load
duke
parents:
diff changeset
120 }
a61af66fc99e Initial load
duke
parents:
diff changeset
121
a61af66fc99e Initial load
duke
parents:
diff changeset
122 Threads::gc_epilogue();
a61af66fc99e Initial load
duke
parents:
diff changeset
123 CodeCache::gc_epilogue();
a61af66fc99e Initial load
duke
parents:
diff changeset
124
a61af66fc99e Initial load
duke
parents:
diff changeset
125 if (PrintGC && !PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
126 gch->print_heap_change(gch_prev_used);
a61af66fc99e Initial load
duke
parents:
diff changeset
127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
128
a61af66fc99e Initial load
duke
parents:
diff changeset
129 // refs processing: clean slate
a61af66fc99e Initial load
duke
parents:
diff changeset
130 _ref_processor = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
131
a61af66fc99e Initial load
duke
parents:
diff changeset
132 // Update heap occupancy information which is used as
a61af66fc99e Initial load
duke
parents:
diff changeset
133 // input to soft ref clearing policy at the next gc.
a61af66fc99e Initial load
duke
parents:
diff changeset
134 Universe::update_heap_info_at_gc();
a61af66fc99e Initial load
duke
parents:
diff changeset
135
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // Update time of last gc for all generations we collected
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // (which curently is all the generations in the heap).
a61af66fc99e Initial load
duke
parents:
diff changeset
138 gch->update_time_of_last_gc(os::javaTimeMillis());
a61af66fc99e Initial load
duke
parents:
diff changeset
139 }
a61af66fc99e Initial load
duke
parents:
diff changeset
140
a61af66fc99e Initial load
duke
parents:
diff changeset
141 void GenMarkSweep::allocate_stacks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
142 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
143 // Scratch request on behalf of oldest generation; will do no
a61af66fc99e Initial load
duke
parents:
diff changeset
144 // allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
145 ScratchBlock* scratch = gch->gather_scratch(gch->_gens[gch->_n_gens-1], 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
146
a61af66fc99e Initial load
duke
parents:
diff changeset
147 // $$$ To cut a corner, we'll only use the first scratch block, and then
a61af66fc99e Initial load
duke
parents:
diff changeset
148 // revert to malloc.
a61af66fc99e Initial load
duke
parents:
diff changeset
149 if (scratch != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
150 _preserved_count_max =
a61af66fc99e Initial load
duke
parents:
diff changeset
151 scratch->num_words * HeapWordSize / sizeof(PreservedMark);
a61af66fc99e Initial load
duke
parents:
diff changeset
152 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
153 _preserved_count_max = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
154 }
a61af66fc99e Initial load
duke
parents:
diff changeset
155
a61af66fc99e Initial load
duke
parents:
diff changeset
156 _preserved_marks = (PreservedMark*)scratch;
a61af66fc99e Initial load
duke
parents:
diff changeset
157 _preserved_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
158 _preserved_mark_stack = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
159 _preserved_oop_stack = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
160
a61af66fc99e Initial load
duke
parents:
diff changeset
161 _marking_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(4000, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
162
a61af66fc99e Initial load
duke
parents:
diff changeset
163 int size = SystemDictionary::number_of_classes() * 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
164 _revisit_klass_stack = new (ResourceObj::C_HEAP) GrowableArray<Klass*>(size, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
165
a61af66fc99e Initial load
duke
parents:
diff changeset
166 #ifdef VALIDATE_MARK_SWEEP
a61af66fc99e Initial load
duke
parents:
diff changeset
167 if (ValidateMarkSweep) {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
168 _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
169 _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
170 _adjusted_pointers = new (ResourceObj::C_HEAP) GrowableArray<void*>(100, true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
171 _live_oops = new (ResourceObj::C_HEAP) GrowableArray<oop>(100, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
172 _live_oops_moved_to = new (ResourceObj::C_HEAP) GrowableArray<oop>(100, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
173 _live_oops_size = new (ResourceObj::C_HEAP) GrowableArray<size_t>(100, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
174 }
a61af66fc99e Initial load
duke
parents:
diff changeset
175 if (RecordMarkSweepCompaction) {
a61af66fc99e Initial load
duke
parents:
diff changeset
176 if (_cur_gc_live_oops == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
177 _cur_gc_live_oops = new(ResourceObj::C_HEAP) GrowableArray<HeapWord*>(100, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
178 _cur_gc_live_oops_moved_to = new(ResourceObj::C_HEAP) GrowableArray<HeapWord*>(100, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
179 _cur_gc_live_oops_size = new(ResourceObj::C_HEAP) GrowableArray<size_t>(100, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
180 _last_gc_live_oops = new(ResourceObj::C_HEAP) GrowableArray<HeapWord*>(100, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
181 _last_gc_live_oops_moved_to = new(ResourceObj::C_HEAP) GrowableArray<HeapWord*>(100, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
182 _last_gc_live_oops_size = new(ResourceObj::C_HEAP) GrowableArray<size_t>(100, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
183 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
184 _cur_gc_live_oops->clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
185 _cur_gc_live_oops_moved_to->clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
186 _cur_gc_live_oops_size->clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
187 }
a61af66fc99e Initial load
duke
parents:
diff changeset
188 }
a61af66fc99e Initial load
duke
parents:
diff changeset
189 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
190 }
a61af66fc99e Initial load
duke
parents:
diff changeset
191
a61af66fc99e Initial load
duke
parents:
diff changeset
192
a61af66fc99e Initial load
duke
parents:
diff changeset
193 void GenMarkSweep::deallocate_stacks() {
263
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
194
356
tonyp
parents: 269
diff changeset
195 if (!UseG1GC) {
tonyp
parents: 269
diff changeset
196 GenCollectedHeap* gch = GenCollectedHeap::heap();
tonyp
parents: 269
diff changeset
197 gch->release_scratch();
tonyp
parents: 269
diff changeset
198 }
263
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
199
0
a61af66fc99e Initial load
duke
parents:
diff changeset
200 if (_preserved_oop_stack) {
a61af66fc99e Initial load
duke
parents:
diff changeset
201 delete _preserved_mark_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
202 _preserved_mark_stack = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
203 delete _preserved_oop_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
204 _preserved_oop_stack = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
206
a61af66fc99e Initial load
duke
parents:
diff changeset
207 delete _marking_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
208 delete _revisit_klass_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
209
a61af66fc99e Initial load
duke
parents:
diff changeset
210 #ifdef VALIDATE_MARK_SWEEP
a61af66fc99e Initial load
duke
parents:
diff changeset
211 if (ValidateMarkSweep) {
a61af66fc99e Initial load
duke
parents:
diff changeset
212 delete _root_refs_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
213 delete _other_refs_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
214 delete _adjusted_pointers;
a61af66fc99e Initial load
duke
parents:
diff changeset
215 delete _live_oops;
a61af66fc99e Initial load
duke
parents:
diff changeset
216 delete _live_oops_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
217 delete _live_oops_moved_to;
a61af66fc99e Initial load
duke
parents:
diff changeset
218 _live_oops_index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
219 _live_oops_index_at_perm = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
221 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
223
a61af66fc99e Initial load
duke
parents:
diff changeset
224 void GenMarkSweep::mark_sweep_phase1(int level,
a61af66fc99e Initial load
duke
parents:
diff changeset
225 bool clear_all_softrefs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
226 // Recursively traverse all live objects and mark them
a61af66fc99e Initial load
duke
parents:
diff changeset
227 EventMark m("1 mark object");
a61af66fc99e Initial load
duke
parents:
diff changeset
228 TraceTime tm("phase 1", PrintGC && Verbose, true, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
229 trace(" 1");
a61af66fc99e Initial load
duke
parents:
diff changeset
230
a61af66fc99e Initial load
duke
parents:
diff changeset
231 VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking(false));
a61af66fc99e Initial load
duke
parents:
diff changeset
232
a61af66fc99e Initial load
duke
parents:
diff changeset
233 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
234
a61af66fc99e Initial load
duke
parents:
diff changeset
235 // Because follow_root_closure is created statically, cannot
a61af66fc99e Initial load
duke
parents:
diff changeset
236 // use OopsInGenClosure constructor which takes a generation,
a61af66fc99e Initial load
duke
parents:
diff changeset
237 // as the Universe has not been created when the static constructors
a61af66fc99e Initial load
duke
parents:
diff changeset
238 // are run.
a61af66fc99e Initial load
duke
parents:
diff changeset
239 follow_root_closure.set_orig_generation(gch->get_gen(level));
a61af66fc99e Initial load
duke
parents:
diff changeset
240
a61af66fc99e Initial load
duke
parents:
diff changeset
241 gch->gen_process_strong_roots(level,
a61af66fc99e Initial load
duke
parents:
diff changeset
242 false, // Younger gens are not roots.
a61af66fc99e Initial load
duke
parents:
diff changeset
243 true, // Collecting permanent generation.
a61af66fc99e Initial load
duke
parents:
diff changeset
244 SharedHeap::SO_SystemClasses,
a61af66fc99e Initial load
duke
parents:
diff changeset
245 &follow_root_closure, &follow_root_closure);
a61af66fc99e Initial load
duke
parents:
diff changeset
246
a61af66fc99e Initial load
duke
parents:
diff changeset
247 // Process reference objects found during marking
a61af66fc99e Initial load
duke
parents:
diff changeset
248 {
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 356
diff changeset
249 ref_processor()->snap_policy(clear_all_softrefs);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
250 ref_processor()->process_discovered_references(
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 356
diff changeset
251 &is_alive, &keep_alive, &follow_stack_closure, NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
252 }
a61af66fc99e Initial load
duke
parents:
diff changeset
253
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // Follow system dictionary roots and unload classes
a61af66fc99e Initial load
duke
parents:
diff changeset
255 bool purged_class = SystemDictionary::do_unloading(&is_alive);
a61af66fc99e Initial load
duke
parents:
diff changeset
256
a61af66fc99e Initial load
duke
parents:
diff changeset
257 // Follow code cache roots
a61af66fc99e Initial load
duke
parents:
diff changeset
258 CodeCache::do_unloading(&is_alive, &keep_alive, purged_class);
a61af66fc99e Initial load
duke
parents:
diff changeset
259 follow_stack(); // Flush marking stack
a61af66fc99e Initial load
duke
parents:
diff changeset
260
a61af66fc99e Initial load
duke
parents:
diff changeset
261 // Update subklass/sibling/implementor links of live klasses
a61af66fc99e Initial load
duke
parents:
diff changeset
262 follow_weak_klass_links();
a61af66fc99e Initial load
duke
parents:
diff changeset
263 assert(_marking_stack->is_empty(), "just drained");
a61af66fc99e Initial load
duke
parents:
diff changeset
264
a61af66fc99e Initial load
duke
parents:
diff changeset
265 // Visit symbol and interned string tables and delete unmarked oops
a61af66fc99e Initial load
duke
parents:
diff changeset
266 SymbolTable::unlink(&is_alive);
a61af66fc99e Initial load
duke
parents:
diff changeset
267 StringTable::unlink(&is_alive);
a61af66fc99e Initial load
duke
parents:
diff changeset
268
a61af66fc99e Initial load
duke
parents:
diff changeset
269 assert(_marking_stack->is_empty(), "stack should be empty by now");
a61af66fc99e Initial load
duke
parents:
diff changeset
270 }
a61af66fc99e Initial load
duke
parents:
diff changeset
271
a61af66fc99e Initial load
duke
parents:
diff changeset
272
a61af66fc99e Initial load
duke
parents:
diff changeset
273 void GenMarkSweep::mark_sweep_phase2() {
a61af66fc99e Initial load
duke
parents:
diff changeset
274 // Now all live objects are marked, compute the new object addresses.
a61af66fc99e Initial load
duke
parents:
diff changeset
275
a61af66fc99e Initial load
duke
parents:
diff changeset
276 // It is imperative that we traverse perm_gen LAST. If dead space is
a61af66fc99e Initial load
duke
parents:
diff changeset
277 // allowed a range of dead object may get overwritten by a dead int
a61af66fc99e Initial load
duke
parents:
diff changeset
278 // array. If perm_gen is not traversed last a klassOop may get
a61af66fc99e Initial load
duke
parents:
diff changeset
279 // overwritten. This is fine since it is dead, but if the class has dead
a61af66fc99e Initial load
duke
parents:
diff changeset
280 // instances we have to skip them, and in order to find their size we
a61af66fc99e Initial load
duke
parents:
diff changeset
281 // need the klassOop!
a61af66fc99e Initial load
duke
parents:
diff changeset
282 //
a61af66fc99e Initial load
duke
parents:
diff changeset
283 // It is not required that we traverse spaces in the same order in
a61af66fc99e Initial load
duke
parents:
diff changeset
284 // phase2, phase3 and phase4, but the ValidateMarkSweep live oops
a61af66fc99e Initial load
duke
parents:
diff changeset
285 // tracking expects us to do so. See comment under phase4.
a61af66fc99e Initial load
duke
parents:
diff changeset
286
a61af66fc99e Initial load
duke
parents:
diff changeset
287 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
288 Generation* pg = gch->perm_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
289
a61af66fc99e Initial load
duke
parents:
diff changeset
290 EventMark m("2 compute new addresses");
a61af66fc99e Initial load
duke
parents:
diff changeset
291 TraceTime tm("phase 2", PrintGC && Verbose, true, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
292 trace("2");
a61af66fc99e Initial load
duke
parents:
diff changeset
293
a61af66fc99e Initial load
duke
parents:
diff changeset
294 VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking(false));
a61af66fc99e Initial load
duke
parents:
diff changeset
295
a61af66fc99e Initial load
duke
parents:
diff changeset
296 gch->prepare_for_compaction();
a61af66fc99e Initial load
duke
parents:
diff changeset
297
a61af66fc99e Initial load
duke
parents:
diff changeset
298 VALIDATE_MARK_SWEEP_ONLY(_live_oops_index_at_perm = _live_oops_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
299 CompactPoint perm_cp(pg, NULL, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
300 pg->prepare_for_compaction(&perm_cp);
a61af66fc99e Initial load
duke
parents:
diff changeset
301 }
a61af66fc99e Initial load
duke
parents:
diff changeset
302
a61af66fc99e Initial load
duke
parents:
diff changeset
303 class GenAdjustPointersClosure: public GenCollectedHeap::GenClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
304 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
305 void do_generation(Generation* gen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
306 gen->adjust_pointers();
a61af66fc99e Initial load
duke
parents:
diff changeset
307 }
a61af66fc99e Initial load
duke
parents:
diff changeset
308 };
a61af66fc99e Initial load
duke
parents:
diff changeset
309
a61af66fc99e Initial load
duke
parents:
diff changeset
310 void GenMarkSweep::mark_sweep_phase3(int level) {
a61af66fc99e Initial load
duke
parents:
diff changeset
311 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
312 Generation* pg = gch->perm_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
313
a61af66fc99e Initial load
duke
parents:
diff changeset
314 // Adjust the pointers to reflect the new locations
a61af66fc99e Initial load
duke
parents:
diff changeset
315 EventMark m("3 adjust pointers");
a61af66fc99e Initial load
duke
parents:
diff changeset
316 TraceTime tm("phase 3", PrintGC && Verbose, true, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
317 trace("3");
a61af66fc99e Initial load
duke
parents:
diff changeset
318
a61af66fc99e Initial load
duke
parents:
diff changeset
319 VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking(false));
a61af66fc99e Initial load
duke
parents:
diff changeset
320
a61af66fc99e Initial load
duke
parents:
diff changeset
321 // Needs to be done before the system dictionary is adjusted.
a61af66fc99e Initial load
duke
parents:
diff changeset
322 pg->pre_adjust_pointers();
a61af66fc99e Initial load
duke
parents:
diff changeset
323
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // Because the two closures below are created statically, cannot
a61af66fc99e Initial load
duke
parents:
diff changeset
325 // use OopsInGenClosure constructor which takes a generation,
a61af66fc99e Initial load
duke
parents:
diff changeset
326 // as the Universe has not been created when the static constructors
a61af66fc99e Initial load
duke
parents:
diff changeset
327 // are run.
a61af66fc99e Initial load
duke
parents:
diff changeset
328 adjust_root_pointer_closure.set_orig_generation(gch->get_gen(level));
a61af66fc99e Initial load
duke
parents:
diff changeset
329 adjust_pointer_closure.set_orig_generation(gch->get_gen(level));
a61af66fc99e Initial load
duke
parents:
diff changeset
330
a61af66fc99e Initial load
duke
parents:
diff changeset
331 gch->gen_process_strong_roots(level,
a61af66fc99e Initial load
duke
parents:
diff changeset
332 false, // Younger gens are not roots.
a61af66fc99e Initial load
duke
parents:
diff changeset
333 true, // Collecting permanent generation.
a61af66fc99e Initial load
duke
parents:
diff changeset
334 SharedHeap::SO_AllClasses,
a61af66fc99e Initial load
duke
parents:
diff changeset
335 &adjust_root_pointer_closure,
a61af66fc99e Initial load
duke
parents:
diff changeset
336 &adjust_root_pointer_closure);
a61af66fc99e Initial load
duke
parents:
diff changeset
337
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // Now adjust pointers in remaining weak roots. (All of which should
a61af66fc99e Initial load
duke
parents:
diff changeset
339 // have been cleared if they pointed to non-surviving objects.)
a61af66fc99e Initial load
duke
parents:
diff changeset
340 gch->gen_process_weak_roots(&adjust_root_pointer_closure,
a61af66fc99e Initial load
duke
parents:
diff changeset
341 &adjust_pointer_closure);
a61af66fc99e Initial load
duke
parents:
diff changeset
342
a61af66fc99e Initial load
duke
parents:
diff changeset
343 adjust_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
344 GenAdjustPointersClosure blk;
a61af66fc99e Initial load
duke
parents:
diff changeset
345 gch->generation_iterate(&blk, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
346 pg->adjust_pointers();
a61af66fc99e Initial load
duke
parents:
diff changeset
347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
348
a61af66fc99e Initial load
duke
parents:
diff changeset
349 class GenCompactClosure: public GenCollectedHeap::GenClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
350 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
351 void do_generation(Generation* gen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
352 gen->compact();
a61af66fc99e Initial load
duke
parents:
diff changeset
353 }
a61af66fc99e Initial load
duke
parents:
diff changeset
354 };
a61af66fc99e Initial load
duke
parents:
diff changeset
355
a61af66fc99e Initial load
duke
parents:
diff changeset
356 void GenMarkSweep::mark_sweep_phase4() {
a61af66fc99e Initial load
duke
parents:
diff changeset
357 // All pointers are now adjusted, move objects accordingly
a61af66fc99e Initial load
duke
parents:
diff changeset
358
a61af66fc99e Initial load
duke
parents:
diff changeset
359 // It is imperative that we traverse perm_gen first in phase4. All
a61af66fc99e Initial load
duke
parents:
diff changeset
360 // classes must be allocated earlier than their instances, and traversing
a61af66fc99e Initial load
duke
parents:
diff changeset
361 // perm_gen first makes sure that all klassOops have moved to their new
a61af66fc99e Initial load
duke
parents:
diff changeset
362 // location before any instance does a dispatch through it's klass!
a61af66fc99e Initial load
duke
parents:
diff changeset
363
a61af66fc99e Initial load
duke
parents:
diff changeset
364 // The ValidateMarkSweep live oops tracking expects us to traverse spaces
a61af66fc99e Initial load
duke
parents:
diff changeset
365 // in the same order in phase2, phase3 and phase4. We don't quite do that
a61af66fc99e Initial load
duke
parents:
diff changeset
366 // here (perm_gen first rather than last), so we tell the validate code
a61af66fc99e Initial load
duke
parents:
diff changeset
367 // to use a higher index (saved from phase2) when verifying perm_gen.
a61af66fc99e Initial load
duke
parents:
diff changeset
368 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
369 Generation* pg = gch->perm_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
370
a61af66fc99e Initial load
duke
parents:
diff changeset
371 EventMark m("4 compact heap");
a61af66fc99e Initial load
duke
parents:
diff changeset
372 TraceTime tm("phase 4", PrintGC && Verbose, true, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
373 trace("4");
a61af66fc99e Initial load
duke
parents:
diff changeset
374
a61af66fc99e Initial load
duke
parents:
diff changeset
375 VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking(true));
a61af66fc99e Initial load
duke
parents:
diff changeset
376
a61af66fc99e Initial load
duke
parents:
diff changeset
377 pg->compact();
a61af66fc99e Initial load
duke
parents:
diff changeset
378
a61af66fc99e Initial load
duke
parents:
diff changeset
379 VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking(false));
a61af66fc99e Initial load
duke
parents:
diff changeset
380
a61af66fc99e Initial load
duke
parents:
diff changeset
381 GenCompactClosure blk;
a61af66fc99e Initial load
duke
parents:
diff changeset
382 gch->generation_iterate(&blk, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
383
a61af66fc99e Initial load
duke
parents:
diff changeset
384 VALIDATE_MARK_SWEEP_ONLY(compaction_complete());
a61af66fc99e Initial load
duke
parents:
diff changeset
385
a61af66fc99e Initial load
duke
parents:
diff changeset
386 pg->post_compact(); // Shared spaces verification.
a61af66fc99e Initial load
duke
parents:
diff changeset
387 }