annotate src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.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 eb28cf662f56
children 27a80744a83b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
337
9ee9cf798b59 6754988: Update copyright year
xdono
parents: 263
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/_psMarkSweep.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 elapsedTimer PSMarkSweep::_accumulated_time;
a61af66fc99e Initial load
duke
parents:
diff changeset
29 unsigned int PSMarkSweep::_total_invocations = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
30 jlong PSMarkSweep::_time_of_last_gc = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
31 CollectorCounters* PSMarkSweep::_counters = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
32
a61af66fc99e Initial load
duke
parents:
diff changeset
33 void PSMarkSweep::initialize() {
a61af66fc99e Initial load
duke
parents:
diff changeset
34 MemRegion mr = Universe::heap()->reserved_region();
a61af66fc99e Initial load
duke
parents:
diff changeset
35 _ref_processor = new ReferenceProcessor(mr,
a61af66fc99e Initial load
duke
parents:
diff changeset
36 true, // atomic_discovery
a61af66fc99e Initial load
duke
parents:
diff changeset
37 false); // mt_discovery
374
a4b729f5b611 6716466: par compact - remove VerifyParallelOldWithMarkSweep code
jcoomes
parents: 263
diff changeset
38 _counters = new CollectorCounters("PSMarkSweep", 1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
39 }
a61af66fc99e Initial load
duke
parents:
diff changeset
40
a61af66fc99e Initial load
duke
parents:
diff changeset
41 // This method contains all heap specific policy for invoking mark sweep.
a61af66fc99e Initial load
duke
parents:
diff changeset
42 // PSMarkSweep::invoke_no_policy() will only attempt to mark-sweep-compact
a61af66fc99e Initial load
duke
parents:
diff changeset
43 // the heap. It will do nothing further. If we need to bail out for policy
a61af66fc99e Initial load
duke
parents:
diff changeset
44 // reasons, scavenge before full gc, or any other specialized behavior, it
a61af66fc99e Initial load
duke
parents:
diff changeset
45 // needs to be added here.
a61af66fc99e Initial load
duke
parents:
diff changeset
46 //
a61af66fc99e Initial load
duke
parents:
diff changeset
47 // Note that this method should only be called from the vm_thread while
a61af66fc99e Initial load
duke
parents:
diff changeset
48 // at a safepoint!
a61af66fc99e Initial load
duke
parents:
diff changeset
49 void PSMarkSweep::invoke(bool maximum_heap_compaction) {
a61af66fc99e Initial load
duke
parents:
diff changeset
50 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
51 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
52 assert(!Universe::heap()->is_gc_active(), "not reentrant");
a61af66fc99e Initial load
duke
parents:
diff changeset
53
a61af66fc99e Initial load
duke
parents:
diff changeset
54 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
55 GCCause::Cause gc_cause = heap->gc_cause();
a61af66fc99e Initial load
duke
parents:
diff changeset
56 PSAdaptiveSizePolicy* policy = heap->size_policy();
a61af66fc99e Initial load
duke
parents:
diff changeset
57
a61af66fc99e Initial load
duke
parents:
diff changeset
58 // Before each allocation/collection attempt, find out from the
a61af66fc99e Initial load
duke
parents:
diff changeset
59 // policy object if GCs are, on the whole, taking too long. If so,
a61af66fc99e Initial load
duke
parents:
diff changeset
60 // bail out without attempting a collection. The exceptions are
a61af66fc99e Initial load
duke
parents:
diff changeset
61 // for explicitly requested GC's.
a61af66fc99e Initial load
duke
parents:
diff changeset
62 if (!policy->gc_time_limit_exceeded() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
63 GCCause::is_user_requested_gc(gc_cause) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
64 GCCause::is_serviceability_requested_gc(gc_cause)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
65 IsGCActiveMark mark;
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67 if (ScavengeBeforeFullGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
68 PSScavenge::invoke_no_policy();
a61af66fc99e Initial load
duke
parents:
diff changeset
69 }
a61af66fc99e Initial load
duke
parents:
diff changeset
70
a61af66fc99e Initial load
duke
parents:
diff changeset
71 int count = (maximum_heap_compaction)?1:MarkSweepAlwaysCompactCount;
a61af66fc99e Initial load
duke
parents:
diff changeset
72 IntFlagSetting flag_setting(MarkSweepAlwaysCompactCount, count);
a61af66fc99e Initial load
duke
parents:
diff changeset
73 PSMarkSweep::invoke_no_policy(maximum_heap_compaction);
a61af66fc99e Initial load
duke
parents:
diff changeset
74 }
a61af66fc99e Initial load
duke
parents:
diff changeset
75 }
a61af66fc99e Initial load
duke
parents:
diff changeset
76
a61af66fc99e Initial load
duke
parents:
diff changeset
77 // This method contains no policy. You should probably
a61af66fc99e Initial load
duke
parents:
diff changeset
78 // be calling invoke() instead.
a61af66fc99e Initial load
duke
parents:
diff changeset
79 void PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
80 assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
81 assert(ref_processor() != NULL, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
82
a61af66fc99e Initial load
duke
parents:
diff changeset
83 if (GC_locker::check_active_before_gc()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
84 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
85 }
a61af66fc99e Initial load
duke
parents:
diff changeset
86
a61af66fc99e Initial load
duke
parents:
diff changeset
87 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
88 GCCause::Cause gc_cause = heap->gc_cause();
a61af66fc99e Initial load
duke
parents:
diff changeset
89 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
90 PSAdaptiveSizePolicy* size_policy = heap->size_policy();
a61af66fc99e Initial load
duke
parents:
diff changeset
91
a61af66fc99e Initial load
duke
parents:
diff changeset
92 PSYoungGen* young_gen = heap->young_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
93 PSOldGen* old_gen = heap->old_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
94 PSPermGen* perm_gen = heap->perm_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
95
a61af66fc99e Initial load
duke
parents:
diff changeset
96 // Increment the invocation count
a61af66fc99e Initial load
duke
parents:
diff changeset
97 heap->increment_total_collections(true /* full */);
a61af66fc99e Initial load
duke
parents:
diff changeset
98
263
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 0
diff changeset
99 // Save information needed to minimize mangling
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 0
diff changeset
100 heap->record_gen_tops_before_GC();
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 0
diff changeset
101
0
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // We need to track unique mark sweep invocations as well.
a61af66fc99e Initial load
duke
parents:
diff changeset
103 _total_invocations++;
a61af66fc99e Initial load
duke
parents:
diff changeset
104
a61af66fc99e Initial load
duke
parents:
diff changeset
105 AdaptiveSizePolicyOutput(size_policy, heap->total_collections());
a61af66fc99e Initial load
duke
parents:
diff changeset
106
a61af66fc99e Initial load
duke
parents:
diff changeset
107 if (PrintHeapAtGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
108 Universe::print_heap_before_gc();
a61af66fc99e Initial load
duke
parents:
diff changeset
109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
110
a61af66fc99e Initial load
duke
parents:
diff changeset
111 // Fill in TLABs
a61af66fc99e Initial load
duke
parents:
diff changeset
112 heap->accumulate_statistics_all_tlabs();
a61af66fc99e Initial load
duke
parents:
diff changeset
113 heap->ensure_parsability(true); // retire TLABs
a61af66fc99e Initial load
duke
parents:
diff changeset
114
a61af66fc99e Initial load
duke
parents:
diff changeset
115 if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
116 HandleMark hm; // Discard invalid handles created during verification
a61af66fc99e Initial load
duke
parents:
diff changeset
117 gclog_or_tty->print(" VerifyBeforeGC:");
a61af66fc99e Initial load
duke
parents:
diff changeset
118 Universe::verify(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
120
a61af66fc99e Initial load
duke
parents:
diff changeset
121 // Verify object start arrays
a61af66fc99e Initial load
duke
parents:
diff changeset
122 if (VerifyObjectStartArray &&
a61af66fc99e Initial load
duke
parents:
diff changeset
123 VerifyBeforeGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
124 old_gen->verify_object_start_array();
a61af66fc99e Initial load
duke
parents:
diff changeset
125 perm_gen->verify_object_start_array();
a61af66fc99e Initial load
duke
parents:
diff changeset
126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
127
a61af66fc99e Initial load
duke
parents:
diff changeset
128 // Filled in below to track the state of the young gen after the collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
129 bool eden_empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
130 bool survivors_empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
131 bool young_gen_empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
132
a61af66fc99e Initial load
duke
parents:
diff changeset
133 {
a61af66fc99e Initial load
duke
parents:
diff changeset
134 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
135 const bool is_system_gc = gc_cause == GCCause::_java_lang_system_gc;
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // This is useful for debugging but don't change the output the
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // the customer sees.
a61af66fc99e Initial load
duke
parents:
diff changeset
138 const char* gc_cause_str = "Full GC";
a61af66fc99e Initial load
duke
parents:
diff changeset
139 if (is_system_gc && PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
140 gc_cause_str = "Full GC (System)";
a61af66fc99e Initial load
duke
parents:
diff changeset
141 }
a61af66fc99e Initial load
duke
parents:
diff changeset
142 gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
a61af66fc99e Initial load
duke
parents:
diff changeset
143 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
144 TraceTime t1(gc_cause_str, PrintGC, !PrintGCDetails, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
145 TraceCollectorStats tcs(counters());
a61af66fc99e Initial load
duke
parents:
diff changeset
146 TraceMemoryManagerStats tms(true /* Full GC */);
a61af66fc99e Initial load
duke
parents:
diff changeset
147
a61af66fc99e Initial load
duke
parents:
diff changeset
148 if (TraceGen1Time) accumulated_time()->start();
a61af66fc99e Initial load
duke
parents:
diff changeset
149
a61af66fc99e Initial load
duke
parents:
diff changeset
150 // Let the size policy know we're starting
a61af66fc99e Initial load
duke
parents:
diff changeset
151 size_policy->major_collection_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
152
a61af66fc99e Initial load
duke
parents:
diff changeset
153 // When collecting the permanent generation methodOops may be moving,
a61af66fc99e Initial load
duke
parents:
diff changeset
154 // so we either have to flush all bcp data or convert it into bci.
a61af66fc99e Initial load
duke
parents:
diff changeset
155 CodeCache::gc_prologue();
a61af66fc99e Initial load
duke
parents:
diff changeset
156 Threads::gc_prologue();
a61af66fc99e Initial load
duke
parents:
diff changeset
157 BiasedLocking::preserve_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
158
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // Capture heap size before collection for printing.
a61af66fc99e Initial load
duke
parents:
diff changeset
160 size_t prev_used = heap->used();
a61af66fc99e Initial load
duke
parents:
diff changeset
161
a61af66fc99e Initial load
duke
parents:
diff changeset
162 // Capture perm gen size before collection for sizing.
a61af66fc99e Initial load
duke
parents:
diff changeset
163 size_t perm_gen_prev_used = perm_gen->used_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
164
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // For PrintGCDetails
a61af66fc99e Initial load
duke
parents:
diff changeset
166 size_t old_gen_prev_used = old_gen->used_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
167 size_t young_gen_prev_used = young_gen->used_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
168
a61af66fc99e Initial load
duke
parents:
diff changeset
169 allocate_stacks();
a61af66fc99e Initial load
duke
parents:
diff changeset
170
a61af66fc99e Initial load
duke
parents:
diff changeset
171 NOT_PRODUCT(ref_processor()->verify_no_references_recorded());
a61af66fc99e Initial load
duke
parents:
diff changeset
172 COMPILER2_PRESENT(DerivedPointerTable::clear());
a61af66fc99e Initial load
duke
parents:
diff changeset
173
a61af66fc99e Initial load
duke
parents:
diff changeset
174 ref_processor()->enable_discovery();
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 380
diff changeset
175 ref_processor()->snap_policy(clear_all_softrefs);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
176
a61af66fc99e Initial load
duke
parents:
diff changeset
177 mark_sweep_phase1(clear_all_softrefs);
a61af66fc99e Initial load
duke
parents:
diff changeset
178
a61af66fc99e Initial load
duke
parents:
diff changeset
179 mark_sweep_phase2();
a61af66fc99e Initial load
duke
parents:
diff changeset
180
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // Don't add any more derived pointers during phase3
a61af66fc99e Initial load
duke
parents:
diff changeset
182 COMPILER2_PRESENT(assert(DerivedPointerTable::is_active(), "Sanity"));
a61af66fc99e Initial load
duke
parents:
diff changeset
183 COMPILER2_PRESENT(DerivedPointerTable::set_active(false));
a61af66fc99e Initial load
duke
parents:
diff changeset
184
a61af66fc99e Initial load
duke
parents:
diff changeset
185 mark_sweep_phase3();
a61af66fc99e Initial load
duke
parents:
diff changeset
186
a61af66fc99e Initial load
duke
parents:
diff changeset
187 mark_sweep_phase4();
a61af66fc99e Initial load
duke
parents:
diff changeset
188
a61af66fc99e Initial load
duke
parents:
diff changeset
189 restore_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
190
a61af66fc99e Initial load
duke
parents:
diff changeset
191 deallocate_stacks();
a61af66fc99e Initial load
duke
parents:
diff changeset
192
263
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 0
diff changeset
193 if (ZapUnusedHeapArea) {
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 0
diff changeset
194 // Do a complete mangle (top to end) because the usage for
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 0
diff changeset
195 // scratch does not maintain a top pointer.
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 0
diff changeset
196 young_gen->to_space()->mangle_unused_area_complete();
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 0
diff changeset
197 }
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 0
diff changeset
198
0
a61af66fc99e Initial load
duke
parents:
diff changeset
199 eden_empty = young_gen->eden_space()->is_empty();
a61af66fc99e Initial load
duke
parents:
diff changeset
200 if (!eden_empty) {
a61af66fc99e Initial load
duke
parents:
diff changeset
201 eden_empty = absorb_live_data_from_eden(size_policy, young_gen, old_gen);
a61af66fc99e Initial load
duke
parents:
diff changeset
202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
203
a61af66fc99e Initial load
duke
parents:
diff changeset
204 // Update heap occupancy information which is used as
a61af66fc99e Initial load
duke
parents:
diff changeset
205 // input to soft ref clearing policy at the next gc.
a61af66fc99e Initial load
duke
parents:
diff changeset
206 Universe::update_heap_info_at_gc();
a61af66fc99e Initial load
duke
parents:
diff changeset
207
a61af66fc99e Initial load
duke
parents:
diff changeset
208 survivors_empty = young_gen->from_space()->is_empty() &&
263
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 0
diff changeset
209 young_gen->to_space()->is_empty();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
210 young_gen_empty = eden_empty && survivors_empty;
a61af66fc99e Initial load
duke
parents:
diff changeset
211
a61af66fc99e Initial load
duke
parents:
diff changeset
212 BarrierSet* bs = heap->barrier_set();
a61af66fc99e Initial load
duke
parents:
diff changeset
213 if (bs->is_a(BarrierSet::ModRef)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
214 ModRefBarrierSet* modBS = (ModRefBarrierSet*)bs;
a61af66fc99e Initial load
duke
parents:
diff changeset
215 MemRegion old_mr = heap->old_gen()->reserved();
a61af66fc99e Initial load
duke
parents:
diff changeset
216 MemRegion perm_mr = heap->perm_gen()->reserved();
a61af66fc99e Initial load
duke
parents:
diff changeset
217 assert(perm_mr.end() <= old_mr.start(), "Generations out of order");
a61af66fc99e Initial load
duke
parents:
diff changeset
218
a61af66fc99e Initial load
duke
parents:
diff changeset
219 if (young_gen_empty) {
a61af66fc99e Initial load
duke
parents:
diff changeset
220 modBS->clear(MemRegion(perm_mr.start(), old_mr.end()));
a61af66fc99e Initial load
duke
parents:
diff changeset
221 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
222 modBS->invalidate(MemRegion(perm_mr.start(), old_mr.end()));
a61af66fc99e Initial load
duke
parents:
diff changeset
223 }
a61af66fc99e Initial load
duke
parents:
diff changeset
224 }
a61af66fc99e Initial load
duke
parents:
diff changeset
225
a61af66fc99e Initial load
duke
parents:
diff changeset
226 BiasedLocking::restore_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
227 Threads::gc_epilogue();
a61af66fc99e Initial load
duke
parents:
diff changeset
228 CodeCache::gc_epilogue();
a61af66fc99e Initial load
duke
parents:
diff changeset
229
a61af66fc99e Initial load
duke
parents:
diff changeset
230 COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
a61af66fc99e Initial load
duke
parents:
diff changeset
231
a61af66fc99e Initial load
duke
parents:
diff changeset
232 ref_processor()->enqueue_discovered_references(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
233
a61af66fc99e Initial load
duke
parents:
diff changeset
234 // Update time of last GC
a61af66fc99e Initial load
duke
parents:
diff changeset
235 reset_millis_since_last_gc();
a61af66fc99e Initial load
duke
parents:
diff changeset
236
a61af66fc99e Initial load
duke
parents:
diff changeset
237 // Let the size policy know we're done
a61af66fc99e Initial load
duke
parents:
diff changeset
238 size_policy->major_collection_end(old_gen->used_in_bytes(), gc_cause);
a61af66fc99e Initial load
duke
parents:
diff changeset
239
a61af66fc99e Initial load
duke
parents:
diff changeset
240 if (UseAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
241
a61af66fc99e Initial load
duke
parents:
diff changeset
242 if (PrintAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
243 gclog_or_tty->print("AdaptiveSizeStart: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
244 gclog_or_tty->stamp();
a61af66fc99e Initial load
duke
parents:
diff changeset
245 gclog_or_tty->print_cr(" collection: %d ",
a61af66fc99e Initial load
duke
parents:
diff changeset
246 heap->total_collections());
a61af66fc99e Initial load
duke
parents:
diff changeset
247 if (Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
248 gclog_or_tty->print("old_gen_capacity: %d young_gen_capacity: %d"
a61af66fc99e Initial load
duke
parents:
diff changeset
249 " perm_gen_capacity: %d ",
a61af66fc99e Initial load
duke
parents:
diff changeset
250 old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
251 perm_gen->capacity_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
252 }
a61af66fc99e Initial load
duke
parents:
diff changeset
253 }
a61af66fc99e Initial load
duke
parents:
diff changeset
254
a61af66fc99e Initial load
duke
parents:
diff changeset
255 // Don't check if the size_policy is ready here. Let
a61af66fc99e Initial load
duke
parents:
diff changeset
256 // the size_policy check that internally.
a61af66fc99e Initial load
duke
parents:
diff changeset
257 if (UseAdaptiveGenerationSizePolicyAtMajorCollection &&
a61af66fc99e Initial load
duke
parents:
diff changeset
258 ((gc_cause != GCCause::_java_lang_system_gc) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
259 UseAdaptiveSizePolicyWithSystemGC)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
260 // Calculate optimal free space amounts
a61af66fc99e Initial load
duke
parents:
diff changeset
261 assert(young_gen->max_size() >
a61af66fc99e Initial load
duke
parents:
diff changeset
262 young_gen->from_space()->capacity_in_bytes() +
a61af66fc99e Initial load
duke
parents:
diff changeset
263 young_gen->to_space()->capacity_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
264 "Sizes of space in young gen are out-of-bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
265 size_t max_eden_size = young_gen->max_size() -
a61af66fc99e Initial load
duke
parents:
diff changeset
266 young_gen->from_space()->capacity_in_bytes() -
a61af66fc99e Initial load
duke
parents:
diff changeset
267 young_gen->to_space()->capacity_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
268 size_policy->compute_generation_free_space(young_gen->used_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
269 young_gen->eden_space()->used_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
270 old_gen->used_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
271 perm_gen->used_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
272 young_gen->eden_space()->capacity_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
273 old_gen->max_gen_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
274 max_eden_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
275 true /* full gc*/,
a61af66fc99e Initial load
duke
parents:
diff changeset
276 gc_cause);
a61af66fc99e Initial load
duke
parents:
diff changeset
277
a61af66fc99e Initial load
duke
parents:
diff changeset
278 heap->resize_old_gen(size_policy->calculated_old_free_size_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
279
a61af66fc99e Initial load
duke
parents:
diff changeset
280 // Don't resize the young generation at an major collection. A
a61af66fc99e Initial load
duke
parents:
diff changeset
281 // desired young generation size may have been calculated but
a61af66fc99e Initial load
duke
parents:
diff changeset
282 // resizing the young generation complicates the code because the
a61af66fc99e Initial load
duke
parents:
diff changeset
283 // resizing of the old generation may have moved the boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
284 // between the young generation and the old generation. Let the
a61af66fc99e Initial load
duke
parents:
diff changeset
285 // young generation resizing happen at the minor collections.
a61af66fc99e Initial load
duke
parents:
diff changeset
286 }
a61af66fc99e Initial load
duke
parents:
diff changeset
287 if (PrintAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
288 gclog_or_tty->print_cr("AdaptiveSizeStop: collection: %d ",
a61af66fc99e Initial load
duke
parents:
diff changeset
289 heap->total_collections());
a61af66fc99e Initial load
duke
parents:
diff changeset
290 }
a61af66fc99e Initial load
duke
parents:
diff changeset
291 }
a61af66fc99e Initial load
duke
parents:
diff changeset
292
a61af66fc99e Initial load
duke
parents:
diff changeset
293 if (UsePerfData) {
a61af66fc99e Initial load
duke
parents:
diff changeset
294 heap->gc_policy_counters()->update_counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
295 heap->gc_policy_counters()->update_old_capacity(
a61af66fc99e Initial load
duke
parents:
diff changeset
296 old_gen->capacity_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
297 heap->gc_policy_counters()->update_young_capacity(
a61af66fc99e Initial load
duke
parents:
diff changeset
298 young_gen->capacity_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
299 }
a61af66fc99e Initial load
duke
parents:
diff changeset
300
a61af66fc99e Initial load
duke
parents:
diff changeset
301 heap->resize_all_tlabs();
a61af66fc99e Initial load
duke
parents:
diff changeset
302
a61af66fc99e Initial load
duke
parents:
diff changeset
303 // We collected the perm gen, so we'll resize it here.
a61af66fc99e Initial load
duke
parents:
diff changeset
304 perm_gen->compute_new_size(perm_gen_prev_used);
a61af66fc99e Initial load
duke
parents:
diff changeset
305
a61af66fc99e Initial load
duke
parents:
diff changeset
306 if (TraceGen1Time) accumulated_time()->stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
307
a61af66fc99e Initial load
duke
parents:
diff changeset
308 if (PrintGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
309 if (PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
310 // Don't print a GC timestamp here. This is after the GC so
a61af66fc99e Initial load
duke
parents:
diff changeset
311 // would be confusing.
a61af66fc99e Initial load
duke
parents:
diff changeset
312 young_gen->print_used_change(young_gen_prev_used);
a61af66fc99e Initial load
duke
parents:
diff changeset
313 old_gen->print_used_change(old_gen_prev_used);
a61af66fc99e Initial load
duke
parents:
diff changeset
314 }
a61af66fc99e Initial load
duke
parents:
diff changeset
315 heap->print_heap_change(prev_used);
a61af66fc99e Initial load
duke
parents:
diff changeset
316 // Do perm gen after heap becase prev_used does
a61af66fc99e Initial load
duke
parents:
diff changeset
317 // not include the perm gen (done this way in the other
a61af66fc99e Initial load
duke
parents:
diff changeset
318 // collectors).
a61af66fc99e Initial load
duke
parents:
diff changeset
319 if (PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
320 perm_gen->print_used_change(perm_gen_prev_used);
a61af66fc99e Initial load
duke
parents:
diff changeset
321 }
a61af66fc99e Initial load
duke
parents:
diff changeset
322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
323
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // Track memory usage and detect low memory
a61af66fc99e Initial load
duke
parents:
diff changeset
325 MemoryService::track_memory_usage();
a61af66fc99e Initial load
duke
parents:
diff changeset
326 heap->update_counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
327
a61af66fc99e Initial load
duke
parents:
diff changeset
328 if (PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
329 if (size_policy->print_gc_time_limit_would_be_exceeded()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
330 if (size_policy->gc_time_limit_exceeded()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
331 gclog_or_tty->print_cr(" GC time is exceeding GCTimeLimit "
a61af66fc99e Initial load
duke
parents:
diff changeset
332 "of %d%%", GCTimeLimit);
a61af66fc99e Initial load
duke
parents:
diff changeset
333 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
334 gclog_or_tty->print_cr(" GC time would exceed GCTimeLimit "
a61af66fc99e Initial load
duke
parents:
diff changeset
335 "of %d%%", GCTimeLimit);
a61af66fc99e Initial load
duke
parents:
diff changeset
336 }
a61af66fc99e Initial load
duke
parents:
diff changeset
337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
338 size_policy->set_print_gc_time_limit_would_be_exceeded(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
339 }
a61af66fc99e Initial load
duke
parents:
diff changeset
340 }
a61af66fc99e Initial load
duke
parents:
diff changeset
341
a61af66fc99e Initial load
duke
parents:
diff changeset
342 if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
343 HandleMark hm; // Discard invalid handles created during verification
a61af66fc99e Initial load
duke
parents:
diff changeset
344 gclog_or_tty->print(" VerifyAfterGC:");
a61af66fc99e Initial load
duke
parents:
diff changeset
345 Universe::verify(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
346 }
a61af66fc99e Initial load
duke
parents:
diff changeset
347
a61af66fc99e Initial load
duke
parents:
diff changeset
348 // Re-verify object start arrays
a61af66fc99e Initial load
duke
parents:
diff changeset
349 if (VerifyObjectStartArray &&
a61af66fc99e Initial load
duke
parents:
diff changeset
350 VerifyAfterGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
351 old_gen->verify_object_start_array();
a61af66fc99e Initial load
duke
parents:
diff changeset
352 perm_gen->verify_object_start_array();
a61af66fc99e Initial load
duke
parents:
diff changeset
353 }
a61af66fc99e Initial load
duke
parents:
diff changeset
354
263
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 0
diff changeset
355 if (ZapUnusedHeapArea) {
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 0
diff changeset
356 old_gen->object_space()->check_mangled_unused_area_complete();
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 0
diff changeset
357 perm_gen->object_space()->check_mangled_unused_area_complete();
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 0
diff changeset
358 }
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 0
diff changeset
359
0
a61af66fc99e Initial load
duke
parents:
diff changeset
360 NOT_PRODUCT(ref_processor()->verify_no_references_recorded());
a61af66fc99e Initial load
duke
parents:
diff changeset
361
a61af66fc99e Initial load
duke
parents:
diff changeset
362 if (PrintHeapAtGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
363 Universe::print_heap_after_gc();
a61af66fc99e Initial load
duke
parents:
diff changeset
364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
365 }
a61af66fc99e Initial load
duke
parents:
diff changeset
366
a61af66fc99e Initial load
duke
parents:
diff changeset
367 bool PSMarkSweep::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_policy,
a61af66fc99e Initial load
duke
parents:
diff changeset
368 PSYoungGen* young_gen,
a61af66fc99e Initial load
duke
parents:
diff changeset
369 PSOldGen* old_gen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
370 MutableSpace* const eden_space = young_gen->eden_space();
a61af66fc99e Initial load
duke
parents:
diff changeset
371 assert(!eden_space->is_empty(), "eden must be non-empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
372 assert(young_gen->virtual_space()->alignment() ==
a61af66fc99e Initial load
duke
parents:
diff changeset
373 old_gen->virtual_space()->alignment(), "alignments do not match");
a61af66fc99e Initial load
duke
parents:
diff changeset
374
a61af66fc99e Initial load
duke
parents:
diff changeset
375 if (!(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
376 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
377 }
a61af66fc99e Initial load
duke
parents:
diff changeset
378
a61af66fc99e Initial load
duke
parents:
diff changeset
379 // Both generations must be completely committed.
a61af66fc99e Initial load
duke
parents:
diff changeset
380 if (young_gen->virtual_space()->uncommitted_size() != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
381 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
382 }
a61af66fc99e Initial load
duke
parents:
diff changeset
383 if (old_gen->virtual_space()->uncommitted_size() != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
384 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
386
a61af66fc99e Initial load
duke
parents:
diff changeset
387 // Figure out how much to take from eden. Include the average amount promoted
a61af66fc99e Initial load
duke
parents:
diff changeset
388 // in the total; otherwise the next young gen GC will simply bail out to a
a61af66fc99e Initial load
duke
parents:
diff changeset
389 // full GC.
a61af66fc99e Initial load
duke
parents:
diff changeset
390 const size_t alignment = old_gen->virtual_space()->alignment();
a61af66fc99e Initial load
duke
parents:
diff changeset
391 const size_t eden_used = eden_space->used_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
392 const size_t promoted = (size_t)(size_policy->avg_promoted()->padded_average());
a61af66fc99e Initial load
duke
parents:
diff changeset
393 const size_t absorb_size = align_size_up(eden_used + promoted, alignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
394 const size_t eden_capacity = eden_space->capacity_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
395
a61af66fc99e Initial load
duke
parents:
diff changeset
396 if (absorb_size >= eden_capacity) {
a61af66fc99e Initial load
duke
parents:
diff changeset
397 return false; // Must leave some space in eden.
a61af66fc99e Initial load
duke
parents:
diff changeset
398 }
a61af66fc99e Initial load
duke
parents:
diff changeset
399
a61af66fc99e Initial load
duke
parents:
diff changeset
400 const size_t new_young_size = young_gen->capacity_in_bytes() - absorb_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
401 if (new_young_size < young_gen->min_gen_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
402 return false; // Respect young gen minimum size.
a61af66fc99e Initial load
duke
parents:
diff changeset
403 }
a61af66fc99e Initial load
duke
parents:
diff changeset
404
a61af66fc99e Initial load
duke
parents:
diff changeset
405 if (TraceAdaptiveGCBoundary && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
406 gclog_or_tty->print(" absorbing " SIZE_FORMAT "K: "
a61af66fc99e Initial load
duke
parents:
diff changeset
407 "eden " SIZE_FORMAT "K->" SIZE_FORMAT "K "
a61af66fc99e Initial load
duke
parents:
diff changeset
408 "from " SIZE_FORMAT "K, to " SIZE_FORMAT "K "
a61af66fc99e Initial load
duke
parents:
diff changeset
409 "young_gen " SIZE_FORMAT "K->" SIZE_FORMAT "K ",
a61af66fc99e Initial load
duke
parents:
diff changeset
410 absorb_size / K,
a61af66fc99e Initial load
duke
parents:
diff changeset
411 eden_capacity / K, (eden_capacity - absorb_size) / K,
a61af66fc99e Initial load
duke
parents:
diff changeset
412 young_gen->from_space()->used_in_bytes() / K,
a61af66fc99e Initial load
duke
parents:
diff changeset
413 young_gen->to_space()->used_in_bytes() / K,
a61af66fc99e Initial load
duke
parents:
diff changeset
414 young_gen->capacity_in_bytes() / K, new_young_size / K);
a61af66fc99e Initial load
duke
parents:
diff changeset
415 }
a61af66fc99e Initial load
duke
parents:
diff changeset
416
a61af66fc99e Initial load
duke
parents:
diff changeset
417 // Fill the unused part of the old gen.
a61af66fc99e Initial load
duke
parents:
diff changeset
418 MutableSpace* const old_space = old_gen->object_space();
a61af66fc99e Initial load
duke
parents:
diff changeset
419 MemRegion old_gen_unused(old_space->top(), old_space->end());
a61af66fc99e Initial load
duke
parents:
diff changeset
420
a61af66fc99e Initial load
duke
parents:
diff changeset
421 // If the unused part of the old gen cannot be filled, skip
a61af66fc99e Initial load
duke
parents:
diff changeset
422 // absorbing eden.
a61af66fc99e Initial load
duke
parents:
diff changeset
423 if (old_gen_unused.word_size() < SharedHeap::min_fill_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
424 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
425 }
a61af66fc99e Initial load
duke
parents:
diff changeset
426
a61af66fc99e Initial load
duke
parents:
diff changeset
427 if (!old_gen_unused.is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
428 SharedHeap::fill_region_with_object(old_gen_unused);
a61af66fc99e Initial load
duke
parents:
diff changeset
429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
430
a61af66fc99e Initial load
duke
parents:
diff changeset
431 // Take the live data from eden and set both top and end in the old gen to
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // eden top. (Need to set end because reset_after_change() mangles the region
a61af66fc99e Initial load
duke
parents:
diff changeset
433 // from end to virtual_space->high() in debug builds).
a61af66fc99e Initial load
duke
parents:
diff changeset
434 HeapWord* const new_top = eden_space->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
435 old_gen->virtual_space()->expand_into(young_gen->virtual_space(),
a61af66fc99e Initial load
duke
parents:
diff changeset
436 absorb_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
437 young_gen->reset_after_change();
a61af66fc99e Initial load
duke
parents:
diff changeset
438 old_space->set_top(new_top);
a61af66fc99e Initial load
duke
parents:
diff changeset
439 old_space->set_end(new_top);
a61af66fc99e Initial load
duke
parents:
diff changeset
440 old_gen->reset_after_change();
a61af66fc99e Initial load
duke
parents:
diff changeset
441
a61af66fc99e Initial load
duke
parents:
diff changeset
442 // Update the object start array for the filler object and the data from eden.
a61af66fc99e Initial load
duke
parents:
diff changeset
443 ObjectStartArray* const start_array = old_gen->start_array();
a61af66fc99e Initial load
duke
parents:
diff changeset
444 HeapWord* const start = old_gen_unused.start();
a61af66fc99e Initial load
duke
parents:
diff changeset
445 for (HeapWord* addr = start; addr < new_top; addr += oop(addr)->size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
446 start_array->allocate_block(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
447 }
a61af66fc99e Initial load
duke
parents:
diff changeset
448
a61af66fc99e Initial load
duke
parents:
diff changeset
449 // Could update the promoted average here, but it is not typically updated at
a61af66fc99e Initial load
duke
parents:
diff changeset
450 // full GCs and the value to use is unclear. Something like
a61af66fc99e Initial load
duke
parents:
diff changeset
451 //
a61af66fc99e Initial load
duke
parents:
diff changeset
452 // cur_promoted_avg + absorb_size / number_of_scavenges_since_last_full_gc.
a61af66fc99e Initial load
duke
parents:
diff changeset
453
a61af66fc99e Initial load
duke
parents:
diff changeset
454 size_policy->set_bytes_absorbed_from_eden(absorb_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
455 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
456 }
a61af66fc99e Initial load
duke
parents:
diff changeset
457
a61af66fc99e Initial load
duke
parents:
diff changeset
458 void PSMarkSweep::allocate_stacks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
459 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
460 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
461
a61af66fc99e Initial load
duke
parents:
diff changeset
462 PSYoungGen* young_gen = heap->young_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
463
a61af66fc99e Initial load
duke
parents:
diff changeset
464 MutableSpace* to_space = young_gen->to_space();
a61af66fc99e Initial load
duke
parents:
diff changeset
465 _preserved_marks = (PreservedMark*)to_space->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
466 _preserved_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
467
a61af66fc99e Initial load
duke
parents:
diff changeset
468 // We want to calculate the size in bytes first.
a61af66fc99e Initial load
duke
parents:
diff changeset
469 _preserved_count_max = pointer_delta(to_space->end(), to_space->top(), sizeof(jbyte));
a61af66fc99e Initial load
duke
parents:
diff changeset
470 // Now divide by the size of a PreservedMark
a61af66fc99e Initial load
duke
parents:
diff changeset
471 _preserved_count_max /= sizeof(PreservedMark);
a61af66fc99e Initial load
duke
parents:
diff changeset
472
a61af66fc99e Initial load
duke
parents:
diff changeset
473 _preserved_mark_stack = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
474 _preserved_oop_stack = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
475
a61af66fc99e Initial load
duke
parents:
diff changeset
476 _marking_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(4000, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
477
a61af66fc99e Initial load
duke
parents:
diff changeset
478 int size = SystemDictionary::number_of_classes() * 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
479 _revisit_klass_stack = new (ResourceObj::C_HEAP) GrowableArray<Klass*>(size, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
480 }
a61af66fc99e Initial load
duke
parents:
diff changeset
481
a61af66fc99e Initial load
duke
parents:
diff changeset
482
a61af66fc99e Initial load
duke
parents:
diff changeset
483 void PSMarkSweep::deallocate_stacks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
484 if (_preserved_oop_stack) {
a61af66fc99e Initial load
duke
parents:
diff changeset
485 delete _preserved_mark_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
486 _preserved_mark_stack = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
487 delete _preserved_oop_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
488 _preserved_oop_stack = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
489 }
a61af66fc99e Initial load
duke
parents:
diff changeset
490
a61af66fc99e Initial load
duke
parents:
diff changeset
491 delete _marking_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
492 delete _revisit_klass_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
493 }
a61af66fc99e Initial load
duke
parents:
diff changeset
494
a61af66fc99e Initial load
duke
parents:
diff changeset
495 void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
496 // Recursively traverse all live objects and mark them
a61af66fc99e Initial load
duke
parents:
diff changeset
497 EventMark m("1 mark object");
a61af66fc99e Initial load
duke
parents:
diff changeset
498 TraceTime tm("phase 1", PrintGCDetails && Verbose, true, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
499 trace(" 1");
a61af66fc99e Initial load
duke
parents:
diff changeset
500
a61af66fc99e Initial load
duke
parents:
diff changeset
501 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
502 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
503
a61af66fc99e Initial load
duke
parents:
diff changeset
504 // General strong roots.
a61af66fc99e Initial load
duke
parents:
diff changeset
505 Universe::oops_do(mark_and_push_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
506 ReferenceProcessor::oops_do(mark_and_push_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
507 JNIHandles::oops_do(mark_and_push_closure()); // Global (strong) JNI handles
a61af66fc99e Initial load
duke
parents:
diff changeset
508 Threads::oops_do(mark_and_push_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
509 ObjectSynchronizer::oops_do(mark_and_push_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
510 FlatProfiler::oops_do(mark_and_push_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
511 Management::oops_do(mark_and_push_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
512 JvmtiExport::oops_do(mark_and_push_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
513 SystemDictionary::always_strong_oops_do(mark_and_push_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
514 vmSymbols::oops_do(mark_and_push_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
515
a61af66fc99e Initial load
duke
parents:
diff changeset
516 // Flush marking stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
517 follow_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
518
a61af66fc99e Initial load
duke
parents:
diff changeset
519 // Process reference objects found during marking
a61af66fc99e Initial load
duke
parents:
diff changeset
520 {
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 380
diff changeset
521 ref_processor()->snap_policy(clear_all_softrefs);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
522 ref_processor()->process_discovered_references(
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 380
diff changeset
523 is_alive_closure(), mark_and_push_closure(), follow_stack_closure(), NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
524 }
a61af66fc99e Initial load
duke
parents:
diff changeset
525
a61af66fc99e Initial load
duke
parents:
diff changeset
526 // Follow system dictionary roots and unload classes
a61af66fc99e Initial load
duke
parents:
diff changeset
527 bool purged_class = SystemDictionary::do_unloading(is_alive_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
528
a61af66fc99e Initial load
duke
parents:
diff changeset
529 // Follow code cache roots
a61af66fc99e Initial load
duke
parents:
diff changeset
530 CodeCache::do_unloading(is_alive_closure(), mark_and_push_closure(),
a61af66fc99e Initial load
duke
parents:
diff changeset
531 purged_class);
a61af66fc99e Initial load
duke
parents:
diff changeset
532 follow_stack(); // Flush marking stack
a61af66fc99e Initial load
duke
parents:
diff changeset
533
a61af66fc99e Initial load
duke
parents:
diff changeset
534 // Update subklass/sibling/implementor links of live klasses
a61af66fc99e Initial load
duke
parents:
diff changeset
535 follow_weak_klass_links();
a61af66fc99e Initial load
duke
parents:
diff changeset
536 assert(_marking_stack->is_empty(), "just drained");
a61af66fc99e Initial load
duke
parents:
diff changeset
537
a61af66fc99e Initial load
duke
parents:
diff changeset
538 // Visit symbol and interned string tables and delete unmarked oops
a61af66fc99e Initial load
duke
parents:
diff changeset
539 SymbolTable::unlink(is_alive_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
540 StringTable::unlink(is_alive_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
541
a61af66fc99e Initial load
duke
parents:
diff changeset
542 assert(_marking_stack->is_empty(), "stack should be empty by now");
a61af66fc99e Initial load
duke
parents:
diff changeset
543 }
a61af66fc99e Initial load
duke
parents:
diff changeset
544
a61af66fc99e Initial load
duke
parents:
diff changeset
545
a61af66fc99e Initial load
duke
parents:
diff changeset
546 void PSMarkSweep::mark_sweep_phase2() {
a61af66fc99e Initial load
duke
parents:
diff changeset
547 EventMark m("2 compute new addresses");
a61af66fc99e Initial load
duke
parents:
diff changeset
548 TraceTime tm("phase 2", PrintGCDetails && Verbose, true, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
549 trace("2");
a61af66fc99e Initial load
duke
parents:
diff changeset
550
a61af66fc99e Initial load
duke
parents:
diff changeset
551 // Now all live objects are marked, compute the new object addresses.
a61af66fc99e Initial load
duke
parents:
diff changeset
552
a61af66fc99e Initial load
duke
parents:
diff changeset
553 // It is imperative that we traverse perm_gen LAST. If dead space is
a61af66fc99e Initial load
duke
parents:
diff changeset
554 // allowed a range of dead object may get overwritten by a dead int
a61af66fc99e Initial load
duke
parents:
diff changeset
555 // array. If perm_gen is not traversed last a klassOop may get
a61af66fc99e Initial load
duke
parents:
diff changeset
556 // overwritten. This is fine since it is dead, but if the class has dead
a61af66fc99e Initial load
duke
parents:
diff changeset
557 // instances we have to skip them, and in order to find their size we
a61af66fc99e Initial load
duke
parents:
diff changeset
558 // need the klassOop!
a61af66fc99e Initial load
duke
parents:
diff changeset
559 //
a61af66fc99e Initial load
duke
parents:
diff changeset
560 // It is not required that we traverse spaces in the same order in
a61af66fc99e Initial load
duke
parents:
diff changeset
561 // phase2, phase3 and phase4, but the ValidateMarkSweep live oops
a61af66fc99e Initial load
duke
parents:
diff changeset
562 // tracking expects us to do so. See comment under phase4.
a61af66fc99e Initial load
duke
parents:
diff changeset
563
a61af66fc99e Initial load
duke
parents:
diff changeset
564 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
565 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
566
a61af66fc99e Initial load
duke
parents:
diff changeset
567 PSOldGen* old_gen = heap->old_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
568 PSPermGen* perm_gen = heap->perm_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
569
a61af66fc99e Initial load
duke
parents:
diff changeset
570 // Begin compacting into the old gen
a61af66fc99e Initial load
duke
parents:
diff changeset
571 PSMarkSweepDecorator::set_destination_decorator_tenured();
a61af66fc99e Initial load
duke
parents:
diff changeset
572
a61af66fc99e Initial load
duke
parents:
diff changeset
573 // This will also compact the young gen spaces.
a61af66fc99e Initial load
duke
parents:
diff changeset
574 old_gen->precompact();
a61af66fc99e Initial load
duke
parents:
diff changeset
575
a61af66fc99e Initial load
duke
parents:
diff changeset
576 // Compact the perm gen into the perm gen
a61af66fc99e Initial load
duke
parents:
diff changeset
577 PSMarkSweepDecorator::set_destination_decorator_perm_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
578
a61af66fc99e Initial load
duke
parents:
diff changeset
579 perm_gen->precompact();
a61af66fc99e Initial load
duke
parents:
diff changeset
580 }
a61af66fc99e Initial load
duke
parents:
diff changeset
581
a61af66fc99e Initial load
duke
parents:
diff changeset
582 // This should be moved to the shared markSweep code!
a61af66fc99e Initial load
duke
parents:
diff changeset
583 class PSAlwaysTrueClosure: public BoolObjectClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
584 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
585 void do_object(oop p) { ShouldNotReachHere(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
586 bool do_object_b(oop p) { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
587 };
a61af66fc99e Initial load
duke
parents:
diff changeset
588 static PSAlwaysTrueClosure always_true;
a61af66fc99e Initial load
duke
parents:
diff changeset
589
a61af66fc99e Initial load
duke
parents:
diff changeset
590 void PSMarkSweep::mark_sweep_phase3() {
a61af66fc99e Initial load
duke
parents:
diff changeset
591 // Adjust the pointers to reflect the new locations
a61af66fc99e Initial load
duke
parents:
diff changeset
592 EventMark m("3 adjust pointers");
a61af66fc99e Initial load
duke
parents:
diff changeset
593 TraceTime tm("phase 3", PrintGCDetails && Verbose, true, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
594 trace("3");
a61af66fc99e Initial load
duke
parents:
diff changeset
595
a61af66fc99e Initial load
duke
parents:
diff changeset
596 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
597 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
598
a61af66fc99e Initial load
duke
parents:
diff changeset
599 PSYoungGen* young_gen = heap->young_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
600 PSOldGen* old_gen = heap->old_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
601 PSPermGen* perm_gen = heap->perm_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
602
a61af66fc99e Initial load
duke
parents:
diff changeset
603 // General strong roots.
a61af66fc99e Initial load
duke
parents:
diff changeset
604 Universe::oops_do(adjust_root_pointer_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
605 ReferenceProcessor::oops_do(adjust_root_pointer_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
606 JNIHandles::oops_do(adjust_root_pointer_closure()); // Global (strong) JNI handles
a61af66fc99e Initial load
duke
parents:
diff changeset
607 Threads::oops_do(adjust_root_pointer_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
608 ObjectSynchronizer::oops_do(adjust_root_pointer_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
609 FlatProfiler::oops_do(adjust_root_pointer_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
610 Management::oops_do(adjust_root_pointer_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
611 JvmtiExport::oops_do(adjust_root_pointer_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
612 // SO_AllClasses
a61af66fc99e Initial load
duke
parents:
diff changeset
613 SystemDictionary::oops_do(adjust_root_pointer_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
614 vmSymbols::oops_do(adjust_root_pointer_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
615
a61af66fc99e Initial load
duke
parents:
diff changeset
616 // Now adjust pointers in remaining weak roots. (All of which should
a61af66fc99e Initial load
duke
parents:
diff changeset
617 // have been cleared if they pointed to non-surviving objects.)
a61af66fc99e Initial load
duke
parents:
diff changeset
618 // Global (weak) JNI handles
a61af66fc99e Initial load
duke
parents:
diff changeset
619 JNIHandles::weak_oops_do(&always_true, adjust_root_pointer_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
620
a61af66fc99e Initial load
duke
parents:
diff changeset
621 CodeCache::oops_do(adjust_pointer_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
622 SymbolTable::oops_do(adjust_root_pointer_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
623 StringTable::oops_do(adjust_root_pointer_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
624 ref_processor()->weak_oops_do(adjust_root_pointer_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
625 PSScavenge::reference_processor()->weak_oops_do(adjust_root_pointer_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
626
a61af66fc99e Initial load
duke
parents:
diff changeset
627 adjust_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
628
a61af66fc99e Initial load
duke
parents:
diff changeset
629 young_gen->adjust_pointers();
a61af66fc99e Initial load
duke
parents:
diff changeset
630 old_gen->adjust_pointers();
a61af66fc99e Initial load
duke
parents:
diff changeset
631 perm_gen->adjust_pointers();
a61af66fc99e Initial load
duke
parents:
diff changeset
632 }
a61af66fc99e Initial load
duke
parents:
diff changeset
633
a61af66fc99e Initial load
duke
parents:
diff changeset
634 void PSMarkSweep::mark_sweep_phase4() {
a61af66fc99e Initial load
duke
parents:
diff changeset
635 EventMark m("4 compact heap");
a61af66fc99e Initial load
duke
parents:
diff changeset
636 TraceTime tm("phase 4", PrintGCDetails && Verbose, true, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
637 trace("4");
a61af66fc99e Initial load
duke
parents:
diff changeset
638
a61af66fc99e Initial load
duke
parents:
diff changeset
639 // All pointers are now adjusted, move objects accordingly
a61af66fc99e Initial load
duke
parents:
diff changeset
640
a61af66fc99e Initial load
duke
parents:
diff changeset
641 // It is imperative that we traverse perm_gen first in phase4. All
a61af66fc99e Initial load
duke
parents:
diff changeset
642 // classes must be allocated earlier than their instances, and traversing
a61af66fc99e Initial load
duke
parents:
diff changeset
643 // perm_gen first makes sure that all klassOops have moved to their new
a61af66fc99e Initial load
duke
parents:
diff changeset
644 // location before any instance does a dispatch through it's klass!
a61af66fc99e Initial load
duke
parents:
diff changeset
645 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
646 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
647
a61af66fc99e Initial load
duke
parents:
diff changeset
648 PSYoungGen* young_gen = heap->young_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
649 PSOldGen* old_gen = heap->old_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
650 PSPermGen* perm_gen = heap->perm_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
651
a61af66fc99e Initial load
duke
parents:
diff changeset
652 perm_gen->compact();
a61af66fc99e Initial load
duke
parents:
diff changeset
653 old_gen->compact();
a61af66fc99e Initial load
duke
parents:
diff changeset
654 young_gen->compact();
a61af66fc99e Initial load
duke
parents:
diff changeset
655 }
a61af66fc99e Initial load
duke
parents:
diff changeset
656
a61af66fc99e Initial load
duke
parents:
diff changeset
657 jlong PSMarkSweep::millis_since_last_gc() {
a61af66fc99e Initial load
duke
parents:
diff changeset
658 jlong ret_val = os::javaTimeMillis() - _time_of_last_gc;
a61af66fc99e Initial load
duke
parents:
diff changeset
659 // XXX See note in genCollectedHeap::millis_since_last_gc().
a61af66fc99e Initial load
duke
parents:
diff changeset
660 if (ret_val < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
661 NOT_PRODUCT(warning("time warp: %d", ret_val);)
a61af66fc99e Initial load
duke
parents:
diff changeset
662 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
663 }
a61af66fc99e Initial load
duke
parents:
diff changeset
664 return ret_val;
a61af66fc99e Initial load
duke
parents:
diff changeset
665 }
a61af66fc99e Initial load
duke
parents:
diff changeset
666
a61af66fc99e Initial load
duke
parents:
diff changeset
667 void PSMarkSweep::reset_millis_since_last_gc() {
a61af66fc99e Initial load
duke
parents:
diff changeset
668 _time_of_last_gc = os::javaTimeMillis();
a61af66fc99e Initial load
duke
parents:
diff changeset
669 }