annotate src/share/vm/gc_implementation/parallelScavenge/psScavenge.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 850fdf70db2b
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 2002-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
a61af66fc99e Initial load
duke
parents:
diff changeset
26 # include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27 # include "incls/_psScavenge.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
28
a61af66fc99e Initial load
duke
parents:
diff changeset
29 HeapWord* PSScavenge::_to_space_top_before_gc = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
30 int PSScavenge::_consecutive_skipped_scavenges = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
31 ReferenceProcessor* PSScavenge::_ref_processor = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
32 CardTableExtension* PSScavenge::_card_table = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
33 bool PSScavenge::_survivor_overflow = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
34 int PSScavenge::_tenuring_threshold = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
35 HeapWord* PSScavenge::_young_generation_boundary = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
36 elapsedTimer PSScavenge::_accumulated_time;
a61af66fc99e Initial load
duke
parents:
diff changeset
37 GrowableArray<markOop>* PSScavenge::_preserved_mark_stack = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
38 GrowableArray<oop>* PSScavenge::_preserved_oop_stack = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
39 CollectorCounters* PSScavenge::_counters = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
40
a61af66fc99e Initial load
duke
parents:
diff changeset
41 // Define before use
a61af66fc99e Initial load
duke
parents:
diff changeset
42 class PSIsAliveClosure: public BoolObjectClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
43 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
44 void do_object(oop p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
45 assert(false, "Do not call.");
a61af66fc99e Initial load
duke
parents:
diff changeset
46 }
a61af66fc99e Initial load
duke
parents:
diff changeset
47 bool do_object_b(oop p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
48 return (!PSScavenge::is_obj_in_young((HeapWord*) p)) || p->is_forwarded();
a61af66fc99e Initial load
duke
parents:
diff changeset
49 }
a61af66fc99e Initial load
duke
parents:
diff changeset
50 };
a61af66fc99e Initial load
duke
parents:
diff changeset
51
a61af66fc99e Initial load
duke
parents:
diff changeset
52 PSIsAliveClosure PSScavenge::_is_alive_closure;
a61af66fc99e Initial load
duke
parents:
diff changeset
53
a61af66fc99e Initial load
duke
parents:
diff changeset
54 class PSKeepAliveClosure: public OopClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
55 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
56 MutableSpace* _to_space;
a61af66fc99e Initial load
duke
parents:
diff changeset
57 PSPromotionManager* _promotion_manager;
a61af66fc99e Initial load
duke
parents:
diff changeset
58
a61af66fc99e Initial load
duke
parents:
diff changeset
59 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
60 PSKeepAliveClosure(PSPromotionManager* pm) : _promotion_manager(pm) {
a61af66fc99e Initial load
duke
parents:
diff changeset
61 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
62 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
63 _to_space = heap->young_gen()->to_space();
a61af66fc99e Initial load
duke
parents:
diff changeset
64
a61af66fc99e Initial load
duke
parents:
diff changeset
65 assert(_promotion_manager != NULL, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
66 }
a61af66fc99e Initial load
duke
parents:
diff changeset
67
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
68 template <class T> void do_oop_work(T* p) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
69 assert (!oopDesc::is_null(*p), "expected non-null ref");
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
70 assert ((oopDesc::load_decode_heap_oop_not_null(p))->is_oop(),
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
71 "expected an oop while scanning weak refs");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 // Weak refs may be visited more than once.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
74 if (PSScavenge::should_scavenge(p, _to_space)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
75 PSScavenge::copy_and_push_safe_barrier(_promotion_manager, p);
a61af66fc99e Initial load
duke
parents:
diff changeset
76 }
a61af66fc99e Initial load
duke
parents:
diff changeset
77 }
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
78 virtual void do_oop(oop* p) { PSKeepAliveClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
79 virtual void do_oop(narrowOop* p) { PSKeepAliveClosure::do_oop_work(p); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
80 };
a61af66fc99e Initial load
duke
parents:
diff changeset
81
a61af66fc99e Initial load
duke
parents:
diff changeset
82 class PSEvacuateFollowersClosure: public VoidClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
83 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
84 PSPromotionManager* _promotion_manager;
a61af66fc99e Initial load
duke
parents:
diff changeset
85 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
86 PSEvacuateFollowersClosure(PSPromotionManager* pm) : _promotion_manager(pm) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
87
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
88 virtual void do_void() {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
89 assert(_promotion_manager != NULL, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
90 _promotion_manager->drain_stacks(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
91 guarantee(_promotion_manager->stacks_empty(),
a61af66fc99e Initial load
duke
parents:
diff changeset
92 "stacks should be empty at this point");
a61af66fc99e Initial load
duke
parents:
diff changeset
93 }
a61af66fc99e Initial load
duke
parents:
diff changeset
94 };
a61af66fc99e Initial load
duke
parents:
diff changeset
95
a61af66fc99e Initial load
duke
parents:
diff changeset
96 class PSPromotionFailedClosure : public ObjectClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
97 virtual void do_object(oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
98 if (obj->is_forwarded()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
99 obj->init_mark();
a61af66fc99e Initial load
duke
parents:
diff changeset
100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
102 };
a61af66fc99e Initial load
duke
parents:
diff changeset
103
a61af66fc99e Initial load
duke
parents:
diff changeset
104 class PSRefProcTaskProxy: public GCTask {
a61af66fc99e Initial load
duke
parents:
diff changeset
105 typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
a61af66fc99e Initial load
duke
parents:
diff changeset
106 ProcessTask & _rp_task;
a61af66fc99e Initial load
duke
parents:
diff changeset
107 uint _work_id;
a61af66fc99e Initial load
duke
parents:
diff changeset
108 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
109 PSRefProcTaskProxy(ProcessTask & rp_task, uint work_id)
a61af66fc99e Initial load
duke
parents:
diff changeset
110 : _rp_task(rp_task),
a61af66fc99e Initial load
duke
parents:
diff changeset
111 _work_id(work_id)
a61af66fc99e Initial load
duke
parents:
diff changeset
112 { }
a61af66fc99e Initial load
duke
parents:
diff changeset
113
a61af66fc99e Initial load
duke
parents:
diff changeset
114 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
115 virtual char* name() { return (char *)"Process referents by policy in parallel"; }
a61af66fc99e Initial load
duke
parents:
diff changeset
116 virtual void do_it(GCTaskManager* manager, uint which);
a61af66fc99e Initial load
duke
parents:
diff changeset
117 };
a61af66fc99e Initial load
duke
parents:
diff changeset
118
a61af66fc99e Initial load
duke
parents:
diff changeset
119 void PSRefProcTaskProxy::do_it(GCTaskManager* manager, uint which)
a61af66fc99e Initial load
duke
parents:
diff changeset
120 {
a61af66fc99e Initial load
duke
parents:
diff changeset
121 PSPromotionManager* promotion_manager =
a61af66fc99e Initial load
duke
parents:
diff changeset
122 PSPromotionManager::gc_thread_promotion_manager(which);
a61af66fc99e Initial load
duke
parents:
diff changeset
123 assert(promotion_manager != NULL, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
124 PSKeepAliveClosure keep_alive(promotion_manager);
a61af66fc99e Initial load
duke
parents:
diff changeset
125 PSEvacuateFollowersClosure evac_followers(promotion_manager);
a61af66fc99e Initial load
duke
parents:
diff changeset
126 PSIsAliveClosure is_alive;
a61af66fc99e Initial load
duke
parents:
diff changeset
127 _rp_task.work(_work_id, is_alive, keep_alive, evac_followers);
a61af66fc99e Initial load
duke
parents:
diff changeset
128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
129
a61af66fc99e Initial load
duke
parents:
diff changeset
130 class PSRefEnqueueTaskProxy: public GCTask {
a61af66fc99e Initial load
duke
parents:
diff changeset
131 typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask;
a61af66fc99e Initial load
duke
parents:
diff changeset
132 EnqueueTask& _enq_task;
a61af66fc99e Initial load
duke
parents:
diff changeset
133 uint _work_id;
a61af66fc99e Initial load
duke
parents:
diff changeset
134
a61af66fc99e Initial load
duke
parents:
diff changeset
135 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
136 PSRefEnqueueTaskProxy(EnqueueTask& enq_task, uint work_id)
a61af66fc99e Initial load
duke
parents:
diff changeset
137 : _enq_task(enq_task),
a61af66fc99e Initial load
duke
parents:
diff changeset
138 _work_id(work_id)
a61af66fc99e Initial load
duke
parents:
diff changeset
139 { }
a61af66fc99e Initial load
duke
parents:
diff changeset
140
a61af66fc99e Initial load
duke
parents:
diff changeset
141 virtual char* name() { return (char *)"Enqueue reference objects in parallel"; }
a61af66fc99e Initial load
duke
parents:
diff changeset
142 virtual void do_it(GCTaskManager* manager, uint which)
a61af66fc99e Initial load
duke
parents:
diff changeset
143 {
a61af66fc99e Initial load
duke
parents:
diff changeset
144 _enq_task.work(_work_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
146 };
a61af66fc99e Initial load
duke
parents:
diff changeset
147
a61af66fc99e Initial load
duke
parents:
diff changeset
148 class PSRefProcTaskExecutor: public AbstractRefProcTaskExecutor {
a61af66fc99e Initial load
duke
parents:
diff changeset
149 virtual void execute(ProcessTask& task);
a61af66fc99e Initial load
duke
parents:
diff changeset
150 virtual void execute(EnqueueTask& task);
a61af66fc99e Initial load
duke
parents:
diff changeset
151 };
a61af66fc99e Initial load
duke
parents:
diff changeset
152
a61af66fc99e Initial load
duke
parents:
diff changeset
153 void PSRefProcTaskExecutor::execute(ProcessTask& task)
a61af66fc99e Initial load
duke
parents:
diff changeset
154 {
a61af66fc99e Initial load
duke
parents:
diff changeset
155 GCTaskQueue* q = GCTaskQueue::create();
a61af66fc99e Initial load
duke
parents:
diff changeset
156 for(uint i=0; i<ParallelGCThreads; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
157 q->enqueue(new PSRefProcTaskProxy(task, i));
a61af66fc99e Initial load
duke
parents:
diff changeset
158 }
a61af66fc99e Initial load
duke
parents:
diff changeset
159 ParallelTaskTerminator terminator(
a61af66fc99e Initial load
duke
parents:
diff changeset
160 ParallelScavengeHeap::gc_task_manager()->workers(),
a61af66fc99e Initial load
duke
parents:
diff changeset
161 UseDepthFirstScavengeOrder ?
a61af66fc99e Initial load
duke
parents:
diff changeset
162 (TaskQueueSetSuper*) PSPromotionManager::stack_array_depth()
a61af66fc99e Initial load
duke
parents:
diff changeset
163 : (TaskQueueSetSuper*) PSPromotionManager::stack_array_breadth());
a61af66fc99e Initial load
duke
parents:
diff changeset
164 if (task.marks_oops_alive() && ParallelGCThreads > 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
165 for (uint j=0; j<ParallelGCThreads; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
166 q->enqueue(new StealTask(&terminator));
a61af66fc99e Initial load
duke
parents:
diff changeset
167 }
a61af66fc99e Initial load
duke
parents:
diff changeset
168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
169 ParallelScavengeHeap::gc_task_manager()->execute_and_wait(q);
a61af66fc99e Initial load
duke
parents:
diff changeset
170 }
a61af66fc99e Initial load
duke
parents:
diff changeset
171
a61af66fc99e Initial load
duke
parents:
diff changeset
172
a61af66fc99e Initial load
duke
parents:
diff changeset
173 void PSRefProcTaskExecutor::execute(EnqueueTask& task)
a61af66fc99e Initial load
duke
parents:
diff changeset
174 {
a61af66fc99e Initial load
duke
parents:
diff changeset
175 GCTaskQueue* q = GCTaskQueue::create();
a61af66fc99e Initial load
duke
parents:
diff changeset
176 for(uint i=0; i<ParallelGCThreads; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
177 q->enqueue(new PSRefEnqueueTaskProxy(task, i));
a61af66fc99e Initial load
duke
parents:
diff changeset
178 }
a61af66fc99e Initial load
duke
parents:
diff changeset
179 ParallelScavengeHeap::gc_task_manager()->execute_and_wait(q);
a61af66fc99e Initial load
duke
parents:
diff changeset
180 }
a61af66fc99e Initial load
duke
parents:
diff changeset
181
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // This method contains all heap specific policy for invoking scavenge.
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // PSScavenge::invoke_no_policy() will do nothing but attempt to
a61af66fc99e Initial load
duke
parents:
diff changeset
184 // scavenge. It will not clean up after failed promotions, bail out if
a61af66fc99e Initial load
duke
parents:
diff changeset
185 // we've exceeded policy time limits, or any other special behavior.
a61af66fc99e Initial load
duke
parents:
diff changeset
186 // All such policy should be placed here.
a61af66fc99e Initial load
duke
parents:
diff changeset
187 //
a61af66fc99e Initial load
duke
parents:
diff changeset
188 // Note that this method should only be called from the vm_thread while
a61af66fc99e Initial load
duke
parents:
diff changeset
189 // at a safepoint!
a61af66fc99e Initial load
duke
parents:
diff changeset
190 void PSScavenge::invoke()
a61af66fc99e Initial load
duke
parents:
diff changeset
191 {
a61af66fc99e Initial load
duke
parents:
diff changeset
192 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
193 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
194 assert(!Universe::heap()->is_gc_active(), "not reentrant");
a61af66fc99e Initial load
duke
parents:
diff changeset
195
a61af66fc99e Initial load
duke
parents:
diff changeset
196 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
197 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
198
a61af66fc99e Initial load
duke
parents:
diff changeset
199 PSAdaptiveSizePolicy* policy = heap->size_policy();
a61af66fc99e Initial load
duke
parents:
diff changeset
200
a61af66fc99e Initial load
duke
parents:
diff changeset
201 // Before each allocation/collection attempt, find out from the
a61af66fc99e Initial load
duke
parents:
diff changeset
202 // policy object if GCs are, on the whole, taking too long. If so,
a61af66fc99e Initial load
duke
parents:
diff changeset
203 // bail out without attempting a collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
204 if (!policy->gc_time_limit_exceeded()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
205 IsGCActiveMark mark;
a61af66fc99e Initial load
duke
parents:
diff changeset
206
a61af66fc99e Initial load
duke
parents:
diff changeset
207 bool scavenge_was_done = PSScavenge::invoke_no_policy();
a61af66fc99e Initial load
duke
parents:
diff changeset
208
a61af66fc99e Initial load
duke
parents:
diff changeset
209 PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
210 if (UsePerfData)
a61af66fc99e Initial load
duke
parents:
diff changeset
211 counters->update_full_follows_scavenge(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
212 if (!scavenge_was_done ||
a61af66fc99e Initial load
duke
parents:
diff changeset
213 policy->should_full_GC(heap->old_gen()->free_in_bytes())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
214 if (UsePerfData)
a61af66fc99e Initial load
duke
parents:
diff changeset
215 counters->update_full_follows_scavenge(full_follows_scavenge);
a61af66fc99e Initial load
duke
parents:
diff changeset
216
a61af66fc99e Initial load
duke
parents:
diff changeset
217 GCCauseSetter gccs(heap, GCCause::_adaptive_size_policy);
a61af66fc99e Initial load
duke
parents:
diff changeset
218 if (UseParallelOldGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
219 PSParallelCompact::invoke_no_policy(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
220 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
221 PSMarkSweep::invoke_no_policy(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
222 }
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
a61af66fc99e Initial load
duke
parents:
diff changeset
227 // This method contains no policy. You should probably
a61af66fc99e Initial load
duke
parents:
diff changeset
228 // be calling invoke() instead.
a61af66fc99e Initial load
duke
parents:
diff changeset
229 bool PSScavenge::invoke_no_policy() {
a61af66fc99e Initial load
duke
parents:
diff changeset
230 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
231 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
232
a61af66fc99e Initial load
duke
parents:
diff changeset
233 TimeStamp scavenge_entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
234 TimeStamp scavenge_midpoint;
a61af66fc99e Initial load
duke
parents:
diff changeset
235 TimeStamp scavenge_exit;
a61af66fc99e Initial load
duke
parents:
diff changeset
236
a61af66fc99e Initial load
duke
parents:
diff changeset
237 scavenge_entry.update();
a61af66fc99e Initial load
duke
parents:
diff changeset
238
a61af66fc99e Initial load
duke
parents:
diff changeset
239 if (GC_locker::check_active_before_gc()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
240 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
242
a61af66fc99e Initial load
duke
parents:
diff changeset
243 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
244 GCCause::Cause gc_cause = heap->gc_cause();
a61af66fc99e Initial load
duke
parents:
diff changeset
245 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
246
a61af66fc99e Initial load
duke
parents:
diff changeset
247 // Check for potential problems.
a61af66fc99e Initial load
duke
parents:
diff changeset
248 if (!should_attempt_scavenge()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
249 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
250 }
a61af66fc99e Initial load
duke
parents:
diff changeset
251
a61af66fc99e Initial load
duke
parents:
diff changeset
252 bool promotion_failure_occurred = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
253
a61af66fc99e Initial load
duke
parents:
diff changeset
254 PSYoungGen* young_gen = heap->young_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
255 PSOldGen* old_gen = heap->old_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
256 PSPermGen* perm_gen = heap->perm_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
257 PSAdaptiveSizePolicy* size_policy = heap->size_policy();
a61af66fc99e Initial load
duke
parents:
diff changeset
258 heap->increment_total_collections();
a61af66fc99e Initial load
duke
parents:
diff changeset
259
a61af66fc99e Initial load
duke
parents:
diff changeset
260 AdaptiveSizePolicyOutput(size_policy, heap->total_collections());
a61af66fc99e Initial load
duke
parents:
diff changeset
261
a61af66fc99e Initial load
duke
parents:
diff changeset
262 if ((gc_cause != GCCause::_java_lang_system_gc) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
263 UseAdaptiveSizePolicyWithSystemGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
264 // Gather the feedback data for eden occupancy.
a61af66fc99e Initial load
duke
parents:
diff changeset
265 young_gen->eden_space()->accumulate_statistics();
a61af66fc99e Initial load
duke
parents:
diff changeset
266 }
a61af66fc99e Initial load
duke
parents:
diff changeset
267
263
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
268 if (ZapUnusedHeapArea) {
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
269 // Save information needed to minimize mangling
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
270 heap->record_gen_tops_before_GC();
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
271 }
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
272
0
a61af66fc99e Initial load
duke
parents:
diff changeset
273 if (PrintHeapAtGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
274 Universe::print_heap_before_gc();
a61af66fc99e Initial load
duke
parents:
diff changeset
275 }
a61af66fc99e Initial load
duke
parents:
diff changeset
276
a61af66fc99e Initial load
duke
parents:
diff changeset
277 assert(!NeverTenure || _tenuring_threshold == markOopDesc::max_age + 1, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
278 assert(!AlwaysTenure || _tenuring_threshold == 0, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
279
a61af66fc99e Initial load
duke
parents:
diff changeset
280 size_t prev_used = heap->used();
a61af66fc99e Initial load
duke
parents:
diff changeset
281 assert(promotion_failed() == false, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
282
a61af66fc99e Initial load
duke
parents:
diff changeset
283 // Fill in TLABs
a61af66fc99e Initial load
duke
parents:
diff changeset
284 heap->accumulate_statistics_all_tlabs();
a61af66fc99e Initial load
duke
parents:
diff changeset
285 heap->ensure_parsability(true); // retire TLABs
a61af66fc99e Initial load
duke
parents:
diff changeset
286
a61af66fc99e Initial load
duke
parents:
diff changeset
287 if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
288 HandleMark hm; // Discard invalid handles created during verification
a61af66fc99e Initial load
duke
parents:
diff changeset
289 gclog_or_tty->print(" VerifyBeforeGC:");
a61af66fc99e Initial load
duke
parents:
diff changeset
290 Universe::verify(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
291 }
a61af66fc99e Initial load
duke
parents:
diff changeset
292
a61af66fc99e Initial load
duke
parents:
diff changeset
293 {
a61af66fc99e Initial load
duke
parents:
diff changeset
294 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
295 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
296
a61af66fc99e Initial load
duke
parents:
diff changeset
297 gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
a61af66fc99e Initial load
duke
parents:
diff changeset
298 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
299 TraceTime t1("GC", PrintGC, !PrintGCDetails, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
300 TraceCollectorStats tcs(counters());
a61af66fc99e Initial load
duke
parents:
diff changeset
301 TraceMemoryManagerStats tms(false /* not full GC */);
a61af66fc99e Initial load
duke
parents:
diff changeset
302
a61af66fc99e Initial load
duke
parents:
diff changeset
303 if (TraceGen0Time) accumulated_time()->start();
a61af66fc99e Initial load
duke
parents:
diff changeset
304
a61af66fc99e Initial load
duke
parents:
diff changeset
305 // Let the size policy know we're starting
a61af66fc99e Initial load
duke
parents:
diff changeset
306 size_policy->minor_collection_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
307
a61af66fc99e Initial load
duke
parents:
diff changeset
308 // Verify the object start arrays.
a61af66fc99e Initial load
duke
parents:
diff changeset
309 if (VerifyObjectStartArray &&
a61af66fc99e Initial load
duke
parents:
diff changeset
310 VerifyBeforeGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
311 old_gen->verify_object_start_array();
a61af66fc99e Initial load
duke
parents:
diff changeset
312 perm_gen->verify_object_start_array();
a61af66fc99e Initial load
duke
parents:
diff changeset
313 }
a61af66fc99e Initial load
duke
parents:
diff changeset
314
a61af66fc99e Initial load
duke
parents:
diff changeset
315 // Verify no unmarked old->young roots
a61af66fc99e Initial load
duke
parents:
diff changeset
316 if (VerifyRememberedSets) {
a61af66fc99e Initial load
duke
parents:
diff changeset
317 CardTableExtension::verify_all_young_refs_imprecise();
a61af66fc99e Initial load
duke
parents:
diff changeset
318 }
a61af66fc99e Initial load
duke
parents:
diff changeset
319
a61af66fc99e Initial load
duke
parents:
diff changeset
320 if (!ScavengeWithObjectsInToSpace) {
a61af66fc99e Initial load
duke
parents:
diff changeset
321 assert(young_gen->to_space()->is_empty(),
a61af66fc99e Initial load
duke
parents:
diff changeset
322 "Attempt to scavenge with live objects in to_space");
263
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
323 young_gen->to_space()->clear(SpaceDecorator::Mangle);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
324 } else if (ZapUnusedHeapArea) {
a61af66fc99e Initial load
duke
parents:
diff changeset
325 young_gen->to_space()->mangle_unused_area();
a61af66fc99e Initial load
duke
parents:
diff changeset
326 }
a61af66fc99e Initial load
duke
parents:
diff changeset
327 save_to_space_top_before_gc();
a61af66fc99e Initial load
duke
parents:
diff changeset
328
a61af66fc99e Initial load
duke
parents:
diff changeset
329 NOT_PRODUCT(reference_processor()->verify_no_references_recorded());
a61af66fc99e Initial load
duke
parents:
diff changeset
330 COMPILER2_PRESENT(DerivedPointerTable::clear());
a61af66fc99e Initial load
duke
parents:
diff changeset
331
a61af66fc99e Initial load
duke
parents:
diff changeset
332 reference_processor()->enable_discovery();
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 269
diff changeset
333 reference_processor()->snap_policy(false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
334
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // We track how much was promoted to the next generation for
a61af66fc99e Initial load
duke
parents:
diff changeset
336 // the AdaptiveSizePolicy.
a61af66fc99e Initial load
duke
parents:
diff changeset
337 size_t old_gen_used_before = old_gen->used_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
338
a61af66fc99e Initial load
duke
parents:
diff changeset
339 // For PrintGCDetails
a61af66fc99e Initial load
duke
parents:
diff changeset
340 size_t young_gen_used_before = young_gen->used_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
341
a61af66fc99e Initial load
duke
parents:
diff changeset
342 // Reset our survivor overflow.
a61af66fc99e Initial load
duke
parents:
diff changeset
343 set_survivor_overflow(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
344
a61af66fc99e Initial load
duke
parents:
diff changeset
345 // We need to save the old/perm top values before
a61af66fc99e Initial load
duke
parents:
diff changeset
346 // creating the promotion_manager. We pass the top
a61af66fc99e Initial load
duke
parents:
diff changeset
347 // values to the card_table, to prevent it from
a61af66fc99e Initial load
duke
parents:
diff changeset
348 // straying into the promotion labs.
a61af66fc99e Initial load
duke
parents:
diff changeset
349 HeapWord* old_top = old_gen->object_space()->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
350 HeapWord* perm_top = perm_gen->object_space()->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
351
a61af66fc99e Initial load
duke
parents:
diff changeset
352 // Release all previously held resources
a61af66fc99e Initial load
duke
parents:
diff changeset
353 gc_task_manager()->release_all_resources();
a61af66fc99e Initial load
duke
parents:
diff changeset
354
a61af66fc99e Initial load
duke
parents:
diff changeset
355 PSPromotionManager::pre_scavenge();
a61af66fc99e Initial load
duke
parents:
diff changeset
356
a61af66fc99e Initial load
duke
parents:
diff changeset
357 // We'll use the promotion manager again later.
a61af66fc99e Initial load
duke
parents:
diff changeset
358 PSPromotionManager* promotion_manager = PSPromotionManager::vm_thread_promotion_manager();
a61af66fc99e Initial load
duke
parents:
diff changeset
359 {
a61af66fc99e Initial load
duke
parents:
diff changeset
360 // TraceTime("Roots");
a61af66fc99e Initial load
duke
parents:
diff changeset
361
a61af66fc99e Initial load
duke
parents:
diff changeset
362 GCTaskQueue* q = GCTaskQueue::create();
a61af66fc99e Initial load
duke
parents:
diff changeset
363
a61af66fc99e Initial load
duke
parents:
diff changeset
364 for(uint i=0; i<ParallelGCThreads; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
365 q->enqueue(new OldToYoungRootsTask(old_gen, old_top, i));
a61af66fc99e Initial load
duke
parents:
diff changeset
366 }
a61af66fc99e Initial load
duke
parents:
diff changeset
367
a61af66fc99e Initial load
duke
parents:
diff changeset
368 q->enqueue(new SerialOldToYoungRootsTask(perm_gen, perm_top));
a61af66fc99e Initial load
duke
parents:
diff changeset
369
a61af66fc99e Initial load
duke
parents:
diff changeset
370 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::universe));
a61af66fc99e Initial load
duke
parents:
diff changeset
371 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jni_handles));
a61af66fc99e Initial load
duke
parents:
diff changeset
372 // We scan the thread roots in parallel
a61af66fc99e Initial load
duke
parents:
diff changeset
373 Threads::create_thread_roots_tasks(q);
a61af66fc99e Initial load
duke
parents:
diff changeset
374 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::object_synchronizer));
a61af66fc99e Initial load
duke
parents:
diff changeset
375 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::flat_profiler));
a61af66fc99e Initial load
duke
parents:
diff changeset
376 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::management));
a61af66fc99e Initial load
duke
parents:
diff changeset
377 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::system_dictionary));
a61af66fc99e Initial load
duke
parents:
diff changeset
378 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmti));
a61af66fc99e Initial load
duke
parents:
diff changeset
379
a61af66fc99e Initial load
duke
parents:
diff changeset
380 ParallelTaskTerminator terminator(
a61af66fc99e Initial load
duke
parents:
diff changeset
381 gc_task_manager()->workers(),
a61af66fc99e Initial load
duke
parents:
diff changeset
382 promotion_manager->depth_first() ?
a61af66fc99e Initial load
duke
parents:
diff changeset
383 (TaskQueueSetSuper*) promotion_manager->stack_array_depth()
a61af66fc99e Initial load
duke
parents:
diff changeset
384 : (TaskQueueSetSuper*) promotion_manager->stack_array_breadth());
a61af66fc99e Initial load
duke
parents:
diff changeset
385 if (ParallelGCThreads>1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
386 for (uint j=0; j<ParallelGCThreads; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
387 q->enqueue(new StealTask(&terminator));
a61af66fc99e Initial load
duke
parents:
diff changeset
388 }
a61af66fc99e Initial load
duke
parents:
diff changeset
389 }
a61af66fc99e Initial load
duke
parents:
diff changeset
390
a61af66fc99e Initial load
duke
parents:
diff changeset
391 gc_task_manager()->execute_and_wait(q);
a61af66fc99e Initial load
duke
parents:
diff changeset
392 }
a61af66fc99e Initial load
duke
parents:
diff changeset
393
a61af66fc99e Initial load
duke
parents:
diff changeset
394 scavenge_midpoint.update();
a61af66fc99e Initial load
duke
parents:
diff changeset
395
a61af66fc99e Initial load
duke
parents:
diff changeset
396 // Process reference objects discovered during scavenge
a61af66fc99e Initial load
duke
parents:
diff changeset
397 {
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 269
diff changeset
398 reference_processor()->snap_policy(false); // not always_clear
0
a61af66fc99e Initial load
duke
parents:
diff changeset
399 PSKeepAliveClosure keep_alive(promotion_manager);
a61af66fc99e Initial load
duke
parents:
diff changeset
400 PSEvacuateFollowersClosure evac_followers(promotion_manager);
a61af66fc99e Initial load
duke
parents:
diff changeset
401 if (reference_processor()->processing_is_mt()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
402 PSRefProcTaskExecutor task_executor;
a61af66fc99e Initial load
duke
parents:
diff changeset
403 reference_processor()->process_discovered_references(
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 269
diff changeset
404 &_is_alive_closure, &keep_alive, &evac_followers, &task_executor);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
405 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
406 reference_processor()->process_discovered_references(
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 269
diff changeset
407 &_is_alive_closure, &keep_alive, &evac_followers, NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
408 }
a61af66fc99e Initial load
duke
parents:
diff changeset
409 }
a61af66fc99e Initial load
duke
parents:
diff changeset
410
a61af66fc99e Initial load
duke
parents:
diff changeset
411 // Enqueue reference objects discovered during scavenge.
a61af66fc99e Initial load
duke
parents:
diff changeset
412 if (reference_processor()->processing_is_mt()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
413 PSRefProcTaskExecutor task_executor;
a61af66fc99e Initial load
duke
parents:
diff changeset
414 reference_processor()->enqueue_discovered_references(&task_executor);
a61af66fc99e Initial load
duke
parents:
diff changeset
415 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
416 reference_processor()->enqueue_discovered_references(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
418
a61af66fc99e Initial load
duke
parents:
diff changeset
419 // Finally, flush the promotion_manager's labs, and deallocate its stacks.
a61af66fc99e Initial load
duke
parents:
diff changeset
420 assert(promotion_manager->claimed_stack_empty(), "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
421 PSPromotionManager::post_scavenge();
a61af66fc99e Initial load
duke
parents:
diff changeset
422
a61af66fc99e Initial load
duke
parents:
diff changeset
423 promotion_failure_occurred = promotion_failed();
a61af66fc99e Initial load
duke
parents:
diff changeset
424 if (promotion_failure_occurred) {
a61af66fc99e Initial load
duke
parents:
diff changeset
425 clean_up_failed_promotion();
a61af66fc99e Initial load
duke
parents:
diff changeset
426 if (PrintGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
427 gclog_or_tty->print("--");
a61af66fc99e Initial load
duke
parents:
diff changeset
428 }
a61af66fc99e Initial load
duke
parents:
diff changeset
429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
430
a61af66fc99e Initial load
duke
parents:
diff changeset
431 // Let the size policy know we're done. Note that we count promotion
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // failure cleanup time as part of the collection (otherwise, we're
a61af66fc99e Initial load
duke
parents:
diff changeset
433 // implicitly saying it's mutator time).
a61af66fc99e Initial load
duke
parents:
diff changeset
434 size_policy->minor_collection_end(gc_cause);
a61af66fc99e Initial load
duke
parents:
diff changeset
435
a61af66fc99e Initial load
duke
parents:
diff changeset
436 if (!promotion_failure_occurred) {
a61af66fc99e Initial load
duke
parents:
diff changeset
437 // Swap the survivor spaces.
263
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
438
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
439
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
440 young_gen->eden_space()->clear(SpaceDecorator::Mangle);
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
441 young_gen->from_space()->clear(SpaceDecorator::Mangle);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
442 young_gen->swap_spaces();
a61af66fc99e Initial load
duke
parents:
diff changeset
443
a61af66fc99e Initial load
duke
parents:
diff changeset
444 size_t survived = young_gen->from_space()->used_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
445 size_t promoted = old_gen->used_in_bytes() - old_gen_used_before;
a61af66fc99e Initial load
duke
parents:
diff changeset
446 size_policy->update_averages(_survivor_overflow, survived, promoted);
a61af66fc99e Initial load
duke
parents:
diff changeset
447
a61af66fc99e Initial load
duke
parents:
diff changeset
448 if (UseAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
449 // Calculate the new survivor size and tenuring threshold
a61af66fc99e Initial load
duke
parents:
diff changeset
450
a61af66fc99e Initial load
duke
parents:
diff changeset
451 if (PrintAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
452 gclog_or_tty->print("AdaptiveSizeStart: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
453 gclog_or_tty->stamp();
a61af66fc99e Initial load
duke
parents:
diff changeset
454 gclog_or_tty->print_cr(" collection: %d ",
a61af66fc99e Initial load
duke
parents:
diff changeset
455 heap->total_collections());
a61af66fc99e Initial load
duke
parents:
diff changeset
456
a61af66fc99e Initial load
duke
parents:
diff changeset
457 if (Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
458 gclog_or_tty->print("old_gen_capacity: %d young_gen_capacity: %d"
a61af66fc99e Initial load
duke
parents:
diff changeset
459 " perm_gen_capacity: %d ",
a61af66fc99e Initial load
duke
parents:
diff changeset
460 old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
461 perm_gen->capacity_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
462 }
a61af66fc99e Initial load
duke
parents:
diff changeset
463 }
a61af66fc99e Initial load
duke
parents:
diff changeset
464
a61af66fc99e Initial load
duke
parents:
diff changeset
465
a61af66fc99e Initial load
duke
parents:
diff changeset
466 if (UsePerfData) {
a61af66fc99e Initial load
duke
parents:
diff changeset
467 PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
468 counters->update_old_eden_size(
a61af66fc99e Initial load
duke
parents:
diff changeset
469 size_policy->calculated_eden_size_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
470 counters->update_old_promo_size(
a61af66fc99e Initial load
duke
parents:
diff changeset
471 size_policy->calculated_promo_size_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
472 counters->update_old_capacity(old_gen->capacity_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
473 counters->update_young_capacity(young_gen->capacity_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
474 counters->update_survived(survived);
a61af66fc99e Initial load
duke
parents:
diff changeset
475 counters->update_promoted(promoted);
a61af66fc99e Initial load
duke
parents:
diff changeset
476 counters->update_survivor_overflowed(_survivor_overflow);
a61af66fc99e Initial load
duke
parents:
diff changeset
477 }
a61af66fc99e Initial load
duke
parents:
diff changeset
478
a61af66fc99e Initial load
duke
parents:
diff changeset
479 size_t survivor_limit =
a61af66fc99e Initial load
duke
parents:
diff changeset
480 size_policy->max_survivor_size(young_gen->max_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
481 _tenuring_threshold =
a61af66fc99e Initial load
duke
parents:
diff changeset
482 size_policy->compute_survivor_space_size_and_threshold(
a61af66fc99e Initial load
duke
parents:
diff changeset
483 _survivor_overflow,
a61af66fc99e Initial load
duke
parents:
diff changeset
484 _tenuring_threshold,
a61af66fc99e Initial load
duke
parents:
diff changeset
485 survivor_limit);
a61af66fc99e Initial load
duke
parents:
diff changeset
486
a61af66fc99e Initial load
duke
parents:
diff changeset
487 if (PrintTenuringDistribution) {
a61af66fc99e Initial load
duke
parents:
diff changeset
488 gclog_or_tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
489 gclog_or_tty->print_cr("Desired survivor size %ld bytes, new threshold %d (max %d)",
a61af66fc99e Initial load
duke
parents:
diff changeset
490 size_policy->calculated_survivor_size_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
491 _tenuring_threshold, MaxTenuringThreshold);
a61af66fc99e Initial load
duke
parents:
diff changeset
492 }
a61af66fc99e Initial load
duke
parents:
diff changeset
493
a61af66fc99e Initial load
duke
parents:
diff changeset
494 if (UsePerfData) {
a61af66fc99e Initial load
duke
parents:
diff changeset
495 PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
496 counters->update_tenuring_threshold(_tenuring_threshold);
a61af66fc99e Initial load
duke
parents:
diff changeset
497 counters->update_survivor_size_counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
498 }
a61af66fc99e Initial load
duke
parents:
diff changeset
499
a61af66fc99e Initial load
duke
parents:
diff changeset
500 // Do call at minor collections?
a61af66fc99e Initial load
duke
parents:
diff changeset
501 // Don't check if the size_policy is ready at this
a61af66fc99e Initial load
duke
parents:
diff changeset
502 // level. Let the size_policy check that internally.
a61af66fc99e Initial load
duke
parents:
diff changeset
503 if (UseAdaptiveSizePolicy &&
a61af66fc99e Initial load
duke
parents:
diff changeset
504 UseAdaptiveGenerationSizePolicyAtMinorCollection &&
a61af66fc99e Initial load
duke
parents:
diff changeset
505 ((gc_cause != GCCause::_java_lang_system_gc) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
506 UseAdaptiveSizePolicyWithSystemGC)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
507
a61af66fc99e Initial load
duke
parents:
diff changeset
508 // Calculate optimial free space amounts
a61af66fc99e Initial load
duke
parents:
diff changeset
509 assert(young_gen->max_size() >
a61af66fc99e Initial load
duke
parents:
diff changeset
510 young_gen->from_space()->capacity_in_bytes() +
a61af66fc99e Initial load
duke
parents:
diff changeset
511 young_gen->to_space()->capacity_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
512 "Sizes of space in young gen are out-of-bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
513 size_t max_eden_size = young_gen->max_size() -
a61af66fc99e Initial load
duke
parents:
diff changeset
514 young_gen->from_space()->capacity_in_bytes() -
a61af66fc99e Initial load
duke
parents:
diff changeset
515 young_gen->to_space()->capacity_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
516 size_policy->compute_generation_free_space(young_gen->used_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
517 young_gen->eden_space()->used_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
518 old_gen->used_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
519 perm_gen->used_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
520 young_gen->eden_space()->capacity_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
521 old_gen->max_gen_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
522 max_eden_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
523 false /* full gc*/,
a61af66fc99e Initial load
duke
parents:
diff changeset
524 gc_cause);
a61af66fc99e Initial load
duke
parents:
diff changeset
525
a61af66fc99e Initial load
duke
parents:
diff changeset
526 }
a61af66fc99e Initial load
duke
parents:
diff changeset
527 // Resize the young generation at every collection
a61af66fc99e Initial load
duke
parents:
diff changeset
528 // even if new sizes have not been calculated. This is
a61af66fc99e Initial load
duke
parents:
diff changeset
529 // to allow resizes that may have been inhibited by the
a61af66fc99e Initial load
duke
parents:
diff changeset
530 // relative location of the "to" and "from" spaces.
a61af66fc99e Initial load
duke
parents:
diff changeset
531
a61af66fc99e Initial load
duke
parents:
diff changeset
532 // Resizing the old gen at minor collects can cause increases
a61af66fc99e Initial load
duke
parents:
diff changeset
533 // that don't feed back to the generation sizing policy until
a61af66fc99e Initial load
duke
parents:
diff changeset
534 // a major collection. Don't resize the old gen here.
a61af66fc99e Initial load
duke
parents:
diff changeset
535
a61af66fc99e Initial load
duke
parents:
diff changeset
536 heap->resize_young_gen(size_policy->calculated_eden_size_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
537 size_policy->calculated_survivor_size_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
538
a61af66fc99e Initial load
duke
parents:
diff changeset
539 if (PrintAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
540 gclog_or_tty->print_cr("AdaptiveSizeStop: collection: %d ",
a61af66fc99e Initial load
duke
parents:
diff changeset
541 heap->total_collections());
a61af66fc99e Initial load
duke
parents:
diff changeset
542 }
a61af66fc99e Initial load
duke
parents:
diff changeset
543 }
a61af66fc99e Initial load
duke
parents:
diff changeset
544
a61af66fc99e Initial load
duke
parents:
diff changeset
545 // Update the structure of the eden. With NUMA-eden CPU hotplugging or offlining can
a61af66fc99e Initial load
duke
parents:
diff changeset
546 // cause the change of the heap layout. Make sure eden is reshaped if that's the case.
a61af66fc99e Initial load
duke
parents:
diff changeset
547 // Also update() will case adaptive NUMA chunk resizing.
a61af66fc99e Initial load
duke
parents:
diff changeset
548 assert(young_gen->eden_space()->is_empty(), "eden space should be empty now");
a61af66fc99e Initial load
duke
parents:
diff changeset
549 young_gen->eden_space()->update();
a61af66fc99e Initial load
duke
parents:
diff changeset
550
a61af66fc99e Initial load
duke
parents:
diff changeset
551 heap->gc_policy_counters()->update_counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
552
a61af66fc99e Initial load
duke
parents:
diff changeset
553 heap->resize_all_tlabs();
a61af66fc99e Initial load
duke
parents:
diff changeset
554
a61af66fc99e Initial load
duke
parents:
diff changeset
555 assert(young_gen->to_space()->is_empty(), "to space should be empty now");
a61af66fc99e Initial load
duke
parents:
diff changeset
556 }
a61af66fc99e Initial load
duke
parents:
diff changeset
557
a61af66fc99e Initial load
duke
parents:
diff changeset
558 COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
a61af66fc99e Initial load
duke
parents:
diff changeset
559
a61af66fc99e Initial load
duke
parents:
diff changeset
560 NOT_PRODUCT(reference_processor()->verify_no_references_recorded());
a61af66fc99e Initial load
duke
parents:
diff changeset
561
a61af66fc99e Initial load
duke
parents:
diff changeset
562 // Re-verify object start arrays
a61af66fc99e Initial load
duke
parents:
diff changeset
563 if (VerifyObjectStartArray &&
a61af66fc99e Initial load
duke
parents:
diff changeset
564 VerifyAfterGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
565 old_gen->verify_object_start_array();
a61af66fc99e Initial load
duke
parents:
diff changeset
566 perm_gen->verify_object_start_array();
a61af66fc99e Initial load
duke
parents:
diff changeset
567 }
a61af66fc99e Initial load
duke
parents:
diff changeset
568
a61af66fc99e Initial load
duke
parents:
diff changeset
569 // Verify all old -> young cards are now precise
a61af66fc99e Initial load
duke
parents:
diff changeset
570 if (VerifyRememberedSets) {
a61af66fc99e Initial load
duke
parents:
diff changeset
571 // Precise verification will give false positives. Until this is fixed,
a61af66fc99e Initial load
duke
parents:
diff changeset
572 // use imprecise verification.
a61af66fc99e Initial load
duke
parents:
diff changeset
573 // CardTableExtension::verify_all_young_refs_precise();
a61af66fc99e Initial load
duke
parents:
diff changeset
574 CardTableExtension::verify_all_young_refs_imprecise();
a61af66fc99e Initial load
duke
parents:
diff changeset
575 }
a61af66fc99e Initial load
duke
parents:
diff changeset
576
a61af66fc99e Initial load
duke
parents:
diff changeset
577 if (TraceGen0Time) accumulated_time()->stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
578
a61af66fc99e Initial load
duke
parents:
diff changeset
579 if (PrintGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
580 if (PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
581 // Don't print a GC timestamp here. This is after the GC so
a61af66fc99e Initial load
duke
parents:
diff changeset
582 // would be confusing.
a61af66fc99e Initial load
duke
parents:
diff changeset
583 young_gen->print_used_change(young_gen_used_before);
a61af66fc99e Initial load
duke
parents:
diff changeset
584 }
a61af66fc99e Initial load
duke
parents:
diff changeset
585 heap->print_heap_change(prev_used);
a61af66fc99e Initial load
duke
parents:
diff changeset
586 }
a61af66fc99e Initial load
duke
parents:
diff changeset
587
a61af66fc99e Initial load
duke
parents:
diff changeset
588 // Track memory usage and detect low memory
a61af66fc99e Initial load
duke
parents:
diff changeset
589 MemoryService::track_memory_usage();
a61af66fc99e Initial load
duke
parents:
diff changeset
590 heap->update_counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
591 }
a61af66fc99e Initial load
duke
parents:
diff changeset
592
a61af66fc99e Initial load
duke
parents:
diff changeset
593 if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
594 HandleMark hm; // Discard invalid handles created during verification
a61af66fc99e Initial load
duke
parents:
diff changeset
595 gclog_or_tty->print(" VerifyAfterGC:");
a61af66fc99e Initial load
duke
parents:
diff changeset
596 Universe::verify(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
597 }
a61af66fc99e Initial load
duke
parents:
diff changeset
598
a61af66fc99e Initial load
duke
parents:
diff changeset
599 if (PrintHeapAtGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
600 Universe::print_heap_after_gc();
a61af66fc99e Initial load
duke
parents:
diff changeset
601 }
a61af66fc99e Initial load
duke
parents:
diff changeset
602
263
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
603 if (ZapUnusedHeapArea) {
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
604 young_gen->eden_space()->check_mangled_unused_area_complete();
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
605 young_gen->from_space()->check_mangled_unused_area_complete();
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
606 young_gen->to_space()->check_mangled_unused_area_complete();
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
607 }
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
608
0
a61af66fc99e Initial load
duke
parents:
diff changeset
609 scavenge_exit.update();
a61af66fc99e Initial load
duke
parents:
diff changeset
610
a61af66fc99e Initial load
duke
parents:
diff changeset
611 if (PrintGCTaskTimeStamps) {
a61af66fc99e Initial load
duke
parents:
diff changeset
612 tty->print_cr("VM-Thread " INT64_FORMAT " " INT64_FORMAT " " INT64_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
613 scavenge_entry.ticks(), scavenge_midpoint.ticks(),
a61af66fc99e Initial load
duke
parents:
diff changeset
614 scavenge_exit.ticks());
a61af66fc99e Initial load
duke
parents:
diff changeset
615 gc_task_manager()->print_task_time_stamps();
a61af66fc99e Initial load
duke
parents:
diff changeset
616 }
a61af66fc99e Initial load
duke
parents:
diff changeset
617
a61af66fc99e Initial load
duke
parents:
diff changeset
618 return !promotion_failure_occurred;
a61af66fc99e Initial load
duke
parents:
diff changeset
619 }
a61af66fc99e Initial load
duke
parents:
diff changeset
620
a61af66fc99e Initial load
duke
parents:
diff changeset
621 // This method iterates over all objects in the young generation,
a61af66fc99e Initial load
duke
parents:
diff changeset
622 // unforwarding markOops. It then restores any preserved mark oops,
a61af66fc99e Initial load
duke
parents:
diff changeset
623 // and clears the _preserved_mark_stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
624 void PSScavenge::clean_up_failed_promotion() {
a61af66fc99e Initial load
duke
parents:
diff changeset
625 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
626 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
627 assert(promotion_failed(), "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
628
a61af66fc99e Initial load
duke
parents:
diff changeset
629 PSYoungGen* young_gen = heap->young_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
630
a61af66fc99e Initial load
duke
parents:
diff changeset
631 {
a61af66fc99e Initial load
duke
parents:
diff changeset
632 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
633
a61af66fc99e Initial load
duke
parents:
diff changeset
634 // Unforward all pointers in the young gen.
a61af66fc99e Initial load
duke
parents:
diff changeset
635 PSPromotionFailedClosure unforward_closure;
a61af66fc99e Initial load
duke
parents:
diff changeset
636 young_gen->object_iterate(&unforward_closure);
a61af66fc99e Initial load
duke
parents:
diff changeset
637
a61af66fc99e Initial load
duke
parents:
diff changeset
638 if (PrintGC && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
639 gclog_or_tty->print_cr("Restoring %d marks",
a61af66fc99e Initial load
duke
parents:
diff changeset
640 _preserved_oop_stack->length());
a61af66fc99e Initial load
duke
parents:
diff changeset
641 }
a61af66fc99e Initial load
duke
parents:
diff changeset
642
a61af66fc99e Initial load
duke
parents:
diff changeset
643 // Restore any saved marks.
a61af66fc99e Initial load
duke
parents:
diff changeset
644 for (int i=0; i < _preserved_oop_stack->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
645 oop obj = _preserved_oop_stack->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
646 markOop mark = _preserved_mark_stack->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
647 obj->set_mark(mark);
a61af66fc99e Initial load
duke
parents:
diff changeset
648 }
a61af66fc99e Initial load
duke
parents:
diff changeset
649
a61af66fc99e Initial load
duke
parents:
diff changeset
650 // Deallocate the preserved mark and oop stacks.
a61af66fc99e Initial load
duke
parents:
diff changeset
651 // The stacks were allocated as CHeap objects, so
a61af66fc99e Initial load
duke
parents:
diff changeset
652 // we must call delete to prevent mem leaks.
a61af66fc99e Initial load
duke
parents:
diff changeset
653 delete _preserved_mark_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
654 _preserved_mark_stack = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
655 delete _preserved_oop_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
656 _preserved_oop_stack = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
657 }
a61af66fc99e Initial load
duke
parents:
diff changeset
658
a61af66fc99e Initial load
duke
parents:
diff changeset
659 // Reset the PromotionFailureALot counters.
a61af66fc99e Initial load
duke
parents:
diff changeset
660 NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();)
a61af66fc99e Initial load
duke
parents:
diff changeset
661 }
a61af66fc99e Initial load
duke
parents:
diff changeset
662
a61af66fc99e Initial load
duke
parents:
diff changeset
663 // This method is called whenever an attempt to promote an object
a61af66fc99e Initial load
duke
parents:
diff changeset
664 // fails. Some markOops will need preserving, some will not. Note
a61af66fc99e Initial load
duke
parents:
diff changeset
665 // that the entire eden is traversed after a failed promotion, with
a61af66fc99e Initial load
duke
parents:
diff changeset
666 // all forwarded headers replaced by the default markOop. This means
a61af66fc99e Initial load
duke
parents:
diff changeset
667 // it is not neccessary to preserve most markOops.
a61af66fc99e Initial load
duke
parents:
diff changeset
668 void PSScavenge::oop_promotion_failed(oop obj, markOop obj_mark) {
a61af66fc99e Initial load
duke
parents:
diff changeset
669 if (_preserved_mark_stack == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
670 ThreadCritical tc; // Lock and retest
a61af66fc99e Initial load
duke
parents:
diff changeset
671 if (_preserved_mark_stack == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
672 assert(_preserved_oop_stack == NULL, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
673 _preserved_mark_stack = new (ResourceObj::C_HEAP) GrowableArray<markOop>(40, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
674 _preserved_oop_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(40, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
675 }
a61af66fc99e Initial load
duke
parents:
diff changeset
676 }
a61af66fc99e Initial load
duke
parents:
diff changeset
677
a61af66fc99e Initial load
duke
parents:
diff changeset
678 // Because we must hold the ThreadCritical lock before using
a61af66fc99e Initial load
duke
parents:
diff changeset
679 // the stacks, we should be safe from observing partial allocations,
a61af66fc99e Initial load
duke
parents:
diff changeset
680 // which are also guarded by the ThreadCritical lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
681 if (obj_mark->must_be_preserved_for_promotion_failure(obj)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
682 ThreadCritical tc;
a61af66fc99e Initial load
duke
parents:
diff changeset
683 _preserved_oop_stack->push(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
684 _preserved_mark_stack->push(obj_mark);
a61af66fc99e Initial load
duke
parents:
diff changeset
685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
686 }
a61af66fc99e Initial load
duke
parents:
diff changeset
687
a61af66fc99e Initial load
duke
parents:
diff changeset
688 bool PSScavenge::should_attempt_scavenge() {
a61af66fc99e Initial load
duke
parents:
diff changeset
689 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
690 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
691 PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
692
a61af66fc99e Initial load
duke
parents:
diff changeset
693 if (UsePerfData) {
a61af66fc99e Initial load
duke
parents:
diff changeset
694 counters->update_scavenge_skipped(not_skipped);
a61af66fc99e Initial load
duke
parents:
diff changeset
695 }
a61af66fc99e Initial load
duke
parents:
diff changeset
696
a61af66fc99e Initial load
duke
parents:
diff changeset
697 PSYoungGen* young_gen = heap->young_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
698 PSOldGen* old_gen = heap->old_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
699
a61af66fc99e Initial load
duke
parents:
diff changeset
700 if (!ScavengeWithObjectsInToSpace) {
a61af66fc99e Initial load
duke
parents:
diff changeset
701 // Do not attempt to promote unless to_space is empty
a61af66fc99e Initial load
duke
parents:
diff changeset
702 if (!young_gen->to_space()->is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
703 _consecutive_skipped_scavenges++;
a61af66fc99e Initial load
duke
parents:
diff changeset
704 if (UsePerfData) {
a61af66fc99e Initial load
duke
parents:
diff changeset
705 counters->update_scavenge_skipped(to_space_not_empty);
a61af66fc99e Initial load
duke
parents:
diff changeset
706 }
a61af66fc99e Initial load
duke
parents:
diff changeset
707 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
708 }
a61af66fc99e Initial load
duke
parents:
diff changeset
709 }
a61af66fc99e Initial load
duke
parents:
diff changeset
710
a61af66fc99e Initial load
duke
parents:
diff changeset
711 // Test to see if the scavenge will likely fail.
a61af66fc99e Initial load
duke
parents:
diff changeset
712 PSAdaptiveSizePolicy* policy = heap->size_policy();
a61af66fc99e Initial load
duke
parents:
diff changeset
713
a61af66fc99e Initial load
duke
parents:
diff changeset
714 // A similar test is done in the policy's should_full_GC(). If this is
a61af66fc99e Initial load
duke
parents:
diff changeset
715 // changed, decide if that test should also be changed.
a61af66fc99e Initial load
duke
parents:
diff changeset
716 size_t avg_promoted = (size_t) policy->padded_average_promoted_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
717 size_t promotion_estimate = MIN2(avg_promoted, young_gen->used_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
718 bool result = promotion_estimate < old_gen->free_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
719
a61af66fc99e Initial load
duke
parents:
diff changeset
720 if (PrintGCDetails && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
721 gclog_or_tty->print(result ? " do scavenge: " : " skip scavenge: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
722 gclog_or_tty->print_cr(" average_promoted " SIZE_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
723 " padded_average_promoted " SIZE_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
724 " free in old gen " SIZE_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
725 (size_t) policy->average_promoted_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
726 (size_t) policy->padded_average_promoted_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
727 old_gen->free_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
728 if (young_gen->used_in_bytes() <
a61af66fc99e Initial load
duke
parents:
diff changeset
729 (size_t) policy->padded_average_promoted_in_bytes()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
730 gclog_or_tty->print_cr(" padded_promoted_average is greater"
a61af66fc99e Initial load
duke
parents:
diff changeset
731 " than maximum promotion = " SIZE_FORMAT, young_gen->used_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
732 }
a61af66fc99e Initial load
duke
parents:
diff changeset
733 }
a61af66fc99e Initial load
duke
parents:
diff changeset
734
a61af66fc99e Initial load
duke
parents:
diff changeset
735 if (result) {
a61af66fc99e Initial load
duke
parents:
diff changeset
736 _consecutive_skipped_scavenges = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
737 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
738 _consecutive_skipped_scavenges++;
a61af66fc99e Initial load
duke
parents:
diff changeset
739 if (UsePerfData) {
a61af66fc99e Initial load
duke
parents:
diff changeset
740 counters->update_scavenge_skipped(promoted_too_large);
a61af66fc99e Initial load
duke
parents:
diff changeset
741 }
a61af66fc99e Initial load
duke
parents:
diff changeset
742 }
a61af66fc99e Initial load
duke
parents:
diff changeset
743 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
744 }
a61af66fc99e Initial load
duke
parents:
diff changeset
745
a61af66fc99e Initial load
duke
parents:
diff changeset
746 // Used to add tasks
a61af66fc99e Initial load
duke
parents:
diff changeset
747 GCTaskManager* const PSScavenge::gc_task_manager() {
a61af66fc99e Initial load
duke
parents:
diff changeset
748 assert(ParallelScavengeHeap::gc_task_manager() != NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
749 "shouldn't return NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
750 return ParallelScavengeHeap::gc_task_manager();
a61af66fc99e Initial load
duke
parents:
diff changeset
751 }
a61af66fc99e Initial load
duke
parents:
diff changeset
752
a61af66fc99e Initial load
duke
parents:
diff changeset
753 void PSScavenge::initialize() {
a61af66fc99e Initial load
duke
parents:
diff changeset
754 // Arguments must have been parsed
a61af66fc99e Initial load
duke
parents:
diff changeset
755
a61af66fc99e Initial load
duke
parents:
diff changeset
756 if (AlwaysTenure) {
a61af66fc99e Initial load
duke
parents:
diff changeset
757 _tenuring_threshold = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
758 } else if (NeverTenure) {
a61af66fc99e Initial load
duke
parents:
diff changeset
759 _tenuring_threshold = markOopDesc::max_age + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
760 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
761 // We want to smooth out our startup times for the AdaptiveSizePolicy
a61af66fc99e Initial load
duke
parents:
diff changeset
762 _tenuring_threshold = (UseAdaptiveSizePolicy) ? InitialTenuringThreshold :
a61af66fc99e Initial load
duke
parents:
diff changeset
763 MaxTenuringThreshold;
a61af66fc99e Initial load
duke
parents:
diff changeset
764 }
a61af66fc99e Initial load
duke
parents:
diff changeset
765
a61af66fc99e Initial load
duke
parents:
diff changeset
766 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
767 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
768
a61af66fc99e Initial load
duke
parents:
diff changeset
769 PSYoungGen* young_gen = heap->young_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
770 PSOldGen* old_gen = heap->old_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
771 PSPermGen* perm_gen = heap->perm_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
772
a61af66fc99e Initial load
duke
parents:
diff changeset
773 // Set boundary between young_gen and old_gen
a61af66fc99e Initial load
duke
parents:
diff changeset
774 assert(perm_gen->reserved().end() <= old_gen->object_space()->bottom(),
a61af66fc99e Initial load
duke
parents:
diff changeset
775 "perm above old");
a61af66fc99e Initial load
duke
parents:
diff changeset
776 assert(old_gen->reserved().end() <= young_gen->eden_space()->bottom(),
a61af66fc99e Initial load
duke
parents:
diff changeset
777 "old above young");
a61af66fc99e Initial load
duke
parents:
diff changeset
778 _young_generation_boundary = young_gen->eden_space()->bottom();
a61af66fc99e Initial load
duke
parents:
diff changeset
779
a61af66fc99e Initial load
duke
parents:
diff changeset
780 // Initialize ref handling object for scavenging.
a61af66fc99e Initial load
duke
parents:
diff changeset
781 MemRegion mr = young_gen->reserved();
a61af66fc99e Initial load
duke
parents:
diff changeset
782 _ref_processor = ReferenceProcessor::create_ref_processor(
a61af66fc99e Initial load
duke
parents:
diff changeset
783 mr, // span
a61af66fc99e Initial load
duke
parents:
diff changeset
784 true, // atomic_discovery
a61af66fc99e Initial load
duke
parents:
diff changeset
785 true, // mt_discovery
a61af66fc99e Initial load
duke
parents:
diff changeset
786 NULL, // is_alive_non_header
a61af66fc99e Initial load
duke
parents:
diff changeset
787 ParallelGCThreads,
a61af66fc99e Initial load
duke
parents:
diff changeset
788 ParallelRefProcEnabled);
a61af66fc99e Initial load
duke
parents:
diff changeset
789
a61af66fc99e Initial load
duke
parents:
diff changeset
790 // Cache the cardtable
a61af66fc99e Initial load
duke
parents:
diff changeset
791 BarrierSet* bs = Universe::heap()->barrier_set();
a61af66fc99e Initial load
duke
parents:
diff changeset
792 assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind");
a61af66fc99e Initial load
duke
parents:
diff changeset
793 _card_table = (CardTableExtension*)bs;
a61af66fc99e Initial load
duke
parents:
diff changeset
794
a61af66fc99e Initial load
duke
parents:
diff changeset
795 _counters = new CollectorCounters("PSScavenge", 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
796 }