annotate src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp @ 1091:6aa7255741f3

6906727: UseCompressedOops: some card-marking fixes related to object arrays Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17). Reviewed-by: kvn, coleenp, jmasa
author ysr
date Thu, 03 Dec 2009 15:01:57 -0800
parents 148e5441d916
children 0bfd3fb24150
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
579
0fbdb4381b99 6814575: Update copyright year
xdono
parents: 546
diff changeset
2 * Copyright 2002-2009 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();
457
27a80744a83b 6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents: 453
diff changeset
333 reference_processor()->setup_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");
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 579
diff changeset
361 ParallelScavengeHeap::ParStrongRootsScope psrs;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
362
a61af66fc99e Initial load
duke
parents:
diff changeset
363 GCTaskQueue* q = GCTaskQueue::create();
a61af66fc99e Initial load
duke
parents:
diff changeset
364
a61af66fc99e Initial load
duke
parents:
diff changeset
365 for(uint i=0; i<ParallelGCThreads; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
366 q->enqueue(new OldToYoungRootsTask(old_gen, old_top, i));
a61af66fc99e Initial load
duke
parents:
diff changeset
367 }
a61af66fc99e Initial load
duke
parents:
diff changeset
368
a61af66fc99e Initial load
duke
parents:
diff changeset
369 q->enqueue(new SerialOldToYoungRootsTask(perm_gen, perm_top));
a61af66fc99e Initial load
duke
parents:
diff changeset
370
a61af66fc99e Initial load
duke
parents:
diff changeset
371 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::universe));
a61af66fc99e Initial load
duke
parents:
diff changeset
372 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jni_handles));
a61af66fc99e Initial load
duke
parents:
diff changeset
373 // We scan the thread roots in parallel
a61af66fc99e Initial load
duke
parents:
diff changeset
374 Threads::create_thread_roots_tasks(q);
a61af66fc99e Initial load
duke
parents:
diff changeset
375 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::object_synchronizer));
a61af66fc99e Initial load
duke
parents:
diff changeset
376 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::flat_profiler));
a61af66fc99e Initial load
duke
parents:
diff changeset
377 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::management));
a61af66fc99e Initial load
duke
parents:
diff changeset
378 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::system_dictionary));
a61af66fc99e Initial load
duke
parents:
diff changeset
379 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmti));
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 579
diff changeset
380 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::code_cache));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
381
a61af66fc99e Initial load
duke
parents:
diff changeset
382 ParallelTaskTerminator terminator(
a61af66fc99e Initial load
duke
parents:
diff changeset
383 gc_task_manager()->workers(),
a61af66fc99e Initial load
duke
parents:
diff changeset
384 promotion_manager->depth_first() ?
a61af66fc99e Initial load
duke
parents:
diff changeset
385 (TaskQueueSetSuper*) promotion_manager->stack_array_depth()
a61af66fc99e Initial load
duke
parents:
diff changeset
386 : (TaskQueueSetSuper*) promotion_manager->stack_array_breadth());
a61af66fc99e Initial load
duke
parents:
diff changeset
387 if (ParallelGCThreads>1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
388 for (uint j=0; j<ParallelGCThreads; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
389 q->enqueue(new StealTask(&terminator));
a61af66fc99e Initial load
duke
parents:
diff changeset
390 }
a61af66fc99e Initial load
duke
parents:
diff changeset
391 }
a61af66fc99e Initial load
duke
parents:
diff changeset
392
a61af66fc99e Initial load
duke
parents:
diff changeset
393 gc_task_manager()->execute_and_wait(q);
a61af66fc99e Initial load
duke
parents:
diff changeset
394 }
a61af66fc99e Initial load
duke
parents:
diff changeset
395
a61af66fc99e Initial load
duke
parents:
diff changeset
396 scavenge_midpoint.update();
a61af66fc99e Initial load
duke
parents:
diff changeset
397
a61af66fc99e Initial load
duke
parents:
diff changeset
398 // Process reference objects discovered during scavenge
a61af66fc99e Initial load
duke
parents:
diff changeset
399 {
457
27a80744a83b 6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents: 453
diff changeset
400 reference_processor()->setup_policy(false); // not always_clear
0
a61af66fc99e Initial load
duke
parents:
diff changeset
401 PSKeepAliveClosure keep_alive(promotion_manager);
a61af66fc99e Initial load
duke
parents:
diff changeset
402 PSEvacuateFollowersClosure evac_followers(promotion_manager);
a61af66fc99e Initial load
duke
parents:
diff changeset
403 if (reference_processor()->processing_is_mt()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
404 PSRefProcTaskExecutor task_executor;
a61af66fc99e Initial load
duke
parents:
diff changeset
405 reference_processor()->process_discovered_references(
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 269
diff changeset
406 &_is_alive_closure, &keep_alive, &evac_followers, &task_executor);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
407 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
408 reference_processor()->process_discovered_references(
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 269
diff changeset
409 &_is_alive_closure, &keep_alive, &evac_followers, NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
410 }
a61af66fc99e Initial load
duke
parents:
diff changeset
411 }
a61af66fc99e Initial load
duke
parents:
diff changeset
412
a61af66fc99e Initial load
duke
parents:
diff changeset
413 // Enqueue reference objects discovered during scavenge.
a61af66fc99e Initial load
duke
parents:
diff changeset
414 if (reference_processor()->processing_is_mt()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
415 PSRefProcTaskExecutor task_executor;
a61af66fc99e Initial load
duke
parents:
diff changeset
416 reference_processor()->enqueue_discovered_references(&task_executor);
a61af66fc99e Initial load
duke
parents:
diff changeset
417 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
418 reference_processor()->enqueue_discovered_references(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
419 }
a61af66fc99e Initial load
duke
parents:
diff changeset
420
a61af66fc99e Initial load
duke
parents:
diff changeset
421 // Finally, flush the promotion_manager's labs, and deallocate its stacks.
a61af66fc99e Initial load
duke
parents:
diff changeset
422 assert(promotion_manager->claimed_stack_empty(), "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
423 PSPromotionManager::post_scavenge();
a61af66fc99e Initial load
duke
parents:
diff changeset
424
a61af66fc99e Initial load
duke
parents:
diff changeset
425 promotion_failure_occurred = promotion_failed();
a61af66fc99e Initial load
duke
parents:
diff changeset
426 if (promotion_failure_occurred) {
a61af66fc99e Initial load
duke
parents:
diff changeset
427 clean_up_failed_promotion();
a61af66fc99e Initial load
duke
parents:
diff changeset
428 if (PrintGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
429 gclog_or_tty->print("--");
a61af66fc99e Initial load
duke
parents:
diff changeset
430 }
a61af66fc99e Initial load
duke
parents:
diff changeset
431 }
a61af66fc99e Initial load
duke
parents:
diff changeset
432
a61af66fc99e Initial load
duke
parents:
diff changeset
433 // Let the size policy know we're done. Note that we count promotion
a61af66fc99e Initial load
duke
parents:
diff changeset
434 // failure cleanup time as part of the collection (otherwise, we're
a61af66fc99e Initial load
duke
parents:
diff changeset
435 // implicitly saying it's mutator time).
a61af66fc99e Initial load
duke
parents:
diff changeset
436 size_policy->minor_collection_end(gc_cause);
a61af66fc99e Initial load
duke
parents:
diff changeset
437
a61af66fc99e Initial load
duke
parents:
diff changeset
438 if (!promotion_failure_occurred) {
a61af66fc99e Initial load
duke
parents:
diff changeset
439 // Swap the survivor spaces.
263
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
440
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
441
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
442 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
443 young_gen->from_space()->clear(SpaceDecorator::Mangle);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
444 young_gen->swap_spaces();
a61af66fc99e Initial load
duke
parents:
diff changeset
445
a61af66fc99e Initial load
duke
parents:
diff changeset
446 size_t survived = young_gen->from_space()->used_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
447 size_t promoted = old_gen->used_in_bytes() - old_gen_used_before;
a61af66fc99e Initial load
duke
parents:
diff changeset
448 size_policy->update_averages(_survivor_overflow, survived, promoted);
a61af66fc99e Initial load
duke
parents:
diff changeset
449
a61af66fc99e Initial load
duke
parents:
diff changeset
450 if (UseAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
451 // Calculate the new survivor size and tenuring threshold
a61af66fc99e Initial load
duke
parents:
diff changeset
452
a61af66fc99e Initial load
duke
parents:
diff changeset
453 if (PrintAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
454 gclog_or_tty->print("AdaptiveSizeStart: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
455 gclog_or_tty->stamp();
a61af66fc99e Initial load
duke
parents:
diff changeset
456 gclog_or_tty->print_cr(" collection: %d ",
a61af66fc99e Initial load
duke
parents:
diff changeset
457 heap->total_collections());
a61af66fc99e Initial load
duke
parents:
diff changeset
458
a61af66fc99e Initial load
duke
parents:
diff changeset
459 if (Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
460 gclog_or_tty->print("old_gen_capacity: %d young_gen_capacity: %d"
a61af66fc99e Initial load
duke
parents:
diff changeset
461 " perm_gen_capacity: %d ",
a61af66fc99e Initial load
duke
parents:
diff changeset
462 old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
463 perm_gen->capacity_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
464 }
a61af66fc99e Initial load
duke
parents:
diff changeset
465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
466
a61af66fc99e Initial load
duke
parents:
diff changeset
467
a61af66fc99e Initial load
duke
parents:
diff changeset
468 if (UsePerfData) {
a61af66fc99e Initial load
duke
parents:
diff changeset
469 PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
470 counters->update_old_eden_size(
a61af66fc99e Initial load
duke
parents:
diff changeset
471 size_policy->calculated_eden_size_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
472 counters->update_old_promo_size(
a61af66fc99e Initial load
duke
parents:
diff changeset
473 size_policy->calculated_promo_size_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
474 counters->update_old_capacity(old_gen->capacity_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
475 counters->update_young_capacity(young_gen->capacity_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
476 counters->update_survived(survived);
a61af66fc99e Initial load
duke
parents:
diff changeset
477 counters->update_promoted(promoted);
a61af66fc99e Initial load
duke
parents:
diff changeset
478 counters->update_survivor_overflowed(_survivor_overflow);
a61af66fc99e Initial load
duke
parents:
diff changeset
479 }
a61af66fc99e Initial load
duke
parents:
diff changeset
480
a61af66fc99e Initial load
duke
parents:
diff changeset
481 size_t survivor_limit =
a61af66fc99e Initial load
duke
parents:
diff changeset
482 size_policy->max_survivor_size(young_gen->max_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
483 _tenuring_threshold =
a61af66fc99e Initial load
duke
parents:
diff changeset
484 size_policy->compute_survivor_space_size_and_threshold(
a61af66fc99e Initial load
duke
parents:
diff changeset
485 _survivor_overflow,
a61af66fc99e Initial load
duke
parents:
diff changeset
486 _tenuring_threshold,
a61af66fc99e Initial load
duke
parents:
diff changeset
487 survivor_limit);
a61af66fc99e Initial load
duke
parents:
diff changeset
488
a61af66fc99e Initial load
duke
parents:
diff changeset
489 if (PrintTenuringDistribution) {
a61af66fc99e Initial load
duke
parents:
diff changeset
490 gclog_or_tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
491 gclog_or_tty->print_cr("Desired survivor size %ld bytes, new threshold %d (max %d)",
a61af66fc99e Initial load
duke
parents:
diff changeset
492 size_policy->calculated_survivor_size_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
493 _tenuring_threshold, MaxTenuringThreshold);
a61af66fc99e Initial load
duke
parents:
diff changeset
494 }
a61af66fc99e Initial load
duke
parents:
diff changeset
495
a61af66fc99e Initial load
duke
parents:
diff changeset
496 if (UsePerfData) {
a61af66fc99e Initial load
duke
parents:
diff changeset
497 PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
498 counters->update_tenuring_threshold(_tenuring_threshold);
a61af66fc99e Initial load
duke
parents:
diff changeset
499 counters->update_survivor_size_counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
500 }
a61af66fc99e Initial load
duke
parents:
diff changeset
501
a61af66fc99e Initial load
duke
parents:
diff changeset
502 // Do call at minor collections?
a61af66fc99e Initial load
duke
parents:
diff changeset
503 // Don't check if the size_policy is ready at this
a61af66fc99e Initial load
duke
parents:
diff changeset
504 // level. Let the size_policy check that internally.
a61af66fc99e Initial load
duke
parents:
diff changeset
505 if (UseAdaptiveSizePolicy &&
a61af66fc99e Initial load
duke
parents:
diff changeset
506 UseAdaptiveGenerationSizePolicyAtMinorCollection &&
a61af66fc99e Initial load
duke
parents:
diff changeset
507 ((gc_cause != GCCause::_java_lang_system_gc) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
508 UseAdaptiveSizePolicyWithSystemGC)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
509
a61af66fc99e Initial load
duke
parents:
diff changeset
510 // Calculate optimial free space amounts
a61af66fc99e Initial load
duke
parents:
diff changeset
511 assert(young_gen->max_size() >
a61af66fc99e Initial load
duke
parents:
diff changeset
512 young_gen->from_space()->capacity_in_bytes() +
a61af66fc99e Initial load
duke
parents:
diff changeset
513 young_gen->to_space()->capacity_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
514 "Sizes of space in young gen are out-of-bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
515 size_t max_eden_size = young_gen->max_size() -
a61af66fc99e Initial load
duke
parents:
diff changeset
516 young_gen->from_space()->capacity_in_bytes() -
a61af66fc99e Initial load
duke
parents:
diff changeset
517 young_gen->to_space()->capacity_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
518 size_policy->compute_generation_free_space(young_gen->used_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
519 young_gen->eden_space()->used_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
520 old_gen->used_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
521 perm_gen->used_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
522 young_gen->eden_space()->capacity_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
523 old_gen->max_gen_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
524 max_eden_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
525 false /* full gc*/,
a61af66fc99e Initial load
duke
parents:
diff changeset
526 gc_cause);
a61af66fc99e Initial load
duke
parents:
diff changeset
527
a61af66fc99e Initial load
duke
parents:
diff changeset
528 }
a61af66fc99e Initial load
duke
parents:
diff changeset
529 // Resize the young generation at every collection
a61af66fc99e Initial load
duke
parents:
diff changeset
530 // even if new sizes have not been calculated. This is
a61af66fc99e Initial load
duke
parents:
diff changeset
531 // to allow resizes that may have been inhibited by the
a61af66fc99e Initial load
duke
parents:
diff changeset
532 // relative location of the "to" and "from" spaces.
a61af66fc99e Initial load
duke
parents:
diff changeset
533
a61af66fc99e Initial load
duke
parents:
diff changeset
534 // Resizing the old gen at minor collects can cause increases
a61af66fc99e Initial load
duke
parents:
diff changeset
535 // that don't feed back to the generation sizing policy until
a61af66fc99e Initial load
duke
parents:
diff changeset
536 // a major collection. Don't resize the old gen here.
a61af66fc99e Initial load
duke
parents:
diff changeset
537
a61af66fc99e Initial load
duke
parents:
diff changeset
538 heap->resize_young_gen(size_policy->calculated_eden_size_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
539 size_policy->calculated_survivor_size_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
540
a61af66fc99e Initial load
duke
parents:
diff changeset
541 if (PrintAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
542 gclog_or_tty->print_cr("AdaptiveSizeStop: collection: %d ",
a61af66fc99e Initial load
duke
parents:
diff changeset
543 heap->total_collections());
a61af66fc99e Initial load
duke
parents:
diff changeset
544 }
a61af66fc99e Initial load
duke
parents:
diff changeset
545 }
a61af66fc99e Initial load
duke
parents:
diff changeset
546
a61af66fc99e Initial load
duke
parents:
diff changeset
547 // Update the structure of the eden. With NUMA-eden CPU hotplugging or offlining can
a61af66fc99e Initial load
duke
parents:
diff changeset
548 // cause the change of the heap layout. Make sure eden is reshaped if that's the case.
a61af66fc99e Initial load
duke
parents:
diff changeset
549 // Also update() will case adaptive NUMA chunk resizing.
a61af66fc99e Initial load
duke
parents:
diff changeset
550 assert(young_gen->eden_space()->is_empty(), "eden space should be empty now");
a61af66fc99e Initial load
duke
parents:
diff changeset
551 young_gen->eden_space()->update();
a61af66fc99e Initial load
duke
parents:
diff changeset
552
a61af66fc99e Initial load
duke
parents:
diff changeset
553 heap->gc_policy_counters()->update_counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
554
a61af66fc99e Initial load
duke
parents:
diff changeset
555 heap->resize_all_tlabs();
a61af66fc99e Initial load
duke
parents:
diff changeset
556
a61af66fc99e Initial load
duke
parents:
diff changeset
557 assert(young_gen->to_space()->is_empty(), "to space should be empty now");
a61af66fc99e Initial load
duke
parents:
diff changeset
558 }
a61af66fc99e Initial load
duke
parents:
diff changeset
559
a61af66fc99e Initial load
duke
parents:
diff changeset
560 COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
a61af66fc99e Initial load
duke
parents:
diff changeset
561
a61af66fc99e Initial load
duke
parents:
diff changeset
562 NOT_PRODUCT(reference_processor()->verify_no_references_recorded());
a61af66fc99e Initial load
duke
parents:
diff changeset
563
a61af66fc99e Initial load
duke
parents:
diff changeset
564 // Re-verify object start arrays
a61af66fc99e Initial load
duke
parents:
diff changeset
565 if (VerifyObjectStartArray &&
a61af66fc99e Initial load
duke
parents:
diff changeset
566 VerifyAfterGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
567 old_gen->verify_object_start_array();
a61af66fc99e Initial load
duke
parents:
diff changeset
568 perm_gen->verify_object_start_array();
a61af66fc99e Initial load
duke
parents:
diff changeset
569 }
a61af66fc99e Initial load
duke
parents:
diff changeset
570
a61af66fc99e Initial load
duke
parents:
diff changeset
571 // Verify all old -> young cards are now precise
a61af66fc99e Initial load
duke
parents:
diff changeset
572 if (VerifyRememberedSets) {
a61af66fc99e Initial load
duke
parents:
diff changeset
573 // Precise verification will give false positives. Until this is fixed,
a61af66fc99e Initial load
duke
parents:
diff changeset
574 // use imprecise verification.
a61af66fc99e Initial load
duke
parents:
diff changeset
575 // CardTableExtension::verify_all_young_refs_precise();
a61af66fc99e Initial load
duke
parents:
diff changeset
576 CardTableExtension::verify_all_young_refs_imprecise();
a61af66fc99e Initial load
duke
parents:
diff changeset
577 }
a61af66fc99e Initial load
duke
parents:
diff changeset
578
a61af66fc99e Initial load
duke
parents:
diff changeset
579 if (TraceGen0Time) accumulated_time()->stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
580
a61af66fc99e Initial load
duke
parents:
diff changeset
581 if (PrintGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
582 if (PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
583 // Don't print a GC timestamp here. This is after the GC so
a61af66fc99e Initial load
duke
parents:
diff changeset
584 // would be confusing.
a61af66fc99e Initial load
duke
parents:
diff changeset
585 young_gen->print_used_change(young_gen_used_before);
a61af66fc99e Initial load
duke
parents:
diff changeset
586 }
a61af66fc99e Initial load
duke
parents:
diff changeset
587 heap->print_heap_change(prev_used);
a61af66fc99e Initial load
duke
parents:
diff changeset
588 }
a61af66fc99e Initial load
duke
parents:
diff changeset
589
a61af66fc99e Initial load
duke
parents:
diff changeset
590 // Track memory usage and detect low memory
a61af66fc99e Initial load
duke
parents:
diff changeset
591 MemoryService::track_memory_usage();
a61af66fc99e Initial load
duke
parents:
diff changeset
592 heap->update_counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
593 }
a61af66fc99e Initial load
duke
parents:
diff changeset
594
a61af66fc99e Initial load
duke
parents:
diff changeset
595 if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
596 HandleMark hm; // Discard invalid handles created during verification
a61af66fc99e Initial load
duke
parents:
diff changeset
597 gclog_or_tty->print(" VerifyAfterGC:");
a61af66fc99e Initial load
duke
parents:
diff changeset
598 Universe::verify(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
599 }
a61af66fc99e Initial load
duke
parents:
diff changeset
600
a61af66fc99e Initial load
duke
parents:
diff changeset
601 if (PrintHeapAtGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
602 Universe::print_heap_after_gc();
a61af66fc99e Initial load
duke
parents:
diff changeset
603 }
a61af66fc99e Initial load
duke
parents:
diff changeset
604
263
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
605 if (ZapUnusedHeapArea) {
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
606 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
607 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
608 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
609 }
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
610
0
a61af66fc99e Initial load
duke
parents:
diff changeset
611 scavenge_exit.update();
a61af66fc99e Initial load
duke
parents:
diff changeset
612
a61af66fc99e Initial load
duke
parents:
diff changeset
613 if (PrintGCTaskTimeStamps) {
a61af66fc99e Initial load
duke
parents:
diff changeset
614 tty->print_cr("VM-Thread " INT64_FORMAT " " INT64_FORMAT " " INT64_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
615 scavenge_entry.ticks(), scavenge_midpoint.ticks(),
a61af66fc99e Initial load
duke
parents:
diff changeset
616 scavenge_exit.ticks());
a61af66fc99e Initial load
duke
parents:
diff changeset
617 gc_task_manager()->print_task_time_stamps();
a61af66fc99e Initial load
duke
parents:
diff changeset
618 }
a61af66fc99e Initial load
duke
parents:
diff changeset
619
546
05c6d52fa7a9 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 457
diff changeset
620 #ifdef TRACESPINNING
05c6d52fa7a9 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 457
diff changeset
621 ParallelTaskTerminator::print_termination_counts();
05c6d52fa7a9 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 457
diff changeset
622 #endif
05c6d52fa7a9 6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents: 457
diff changeset
623
0
a61af66fc99e Initial load
duke
parents:
diff changeset
624 return !promotion_failure_occurred;
a61af66fc99e Initial load
duke
parents:
diff changeset
625 }
a61af66fc99e Initial load
duke
parents:
diff changeset
626
a61af66fc99e Initial load
duke
parents:
diff changeset
627 // This method iterates over all objects in the young generation,
a61af66fc99e Initial load
duke
parents:
diff changeset
628 // unforwarding markOops. It then restores any preserved mark oops,
a61af66fc99e Initial load
duke
parents:
diff changeset
629 // and clears the _preserved_mark_stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
630 void PSScavenge::clean_up_failed_promotion() {
a61af66fc99e Initial load
duke
parents:
diff changeset
631 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
632 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
633 assert(promotion_failed(), "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
634
a61af66fc99e Initial load
duke
parents:
diff changeset
635 PSYoungGen* young_gen = heap->young_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
636
a61af66fc99e Initial load
duke
parents:
diff changeset
637 {
a61af66fc99e Initial load
duke
parents:
diff changeset
638 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
639
a61af66fc99e Initial load
duke
parents:
diff changeset
640 // Unforward all pointers in the young gen.
a61af66fc99e Initial load
duke
parents:
diff changeset
641 PSPromotionFailedClosure unforward_closure;
a61af66fc99e Initial load
duke
parents:
diff changeset
642 young_gen->object_iterate(&unforward_closure);
a61af66fc99e Initial load
duke
parents:
diff changeset
643
a61af66fc99e Initial load
duke
parents:
diff changeset
644 if (PrintGC && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
645 gclog_or_tty->print_cr("Restoring %d marks",
a61af66fc99e Initial load
duke
parents:
diff changeset
646 _preserved_oop_stack->length());
a61af66fc99e Initial load
duke
parents:
diff changeset
647 }
a61af66fc99e Initial load
duke
parents:
diff changeset
648
a61af66fc99e Initial load
duke
parents:
diff changeset
649 // Restore any saved marks.
a61af66fc99e Initial load
duke
parents:
diff changeset
650 for (int i=0; i < _preserved_oop_stack->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
651 oop obj = _preserved_oop_stack->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
652 markOop mark = _preserved_mark_stack->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
653 obj->set_mark(mark);
a61af66fc99e Initial load
duke
parents:
diff changeset
654 }
a61af66fc99e Initial load
duke
parents:
diff changeset
655
a61af66fc99e Initial load
duke
parents:
diff changeset
656 // Deallocate the preserved mark and oop stacks.
a61af66fc99e Initial load
duke
parents:
diff changeset
657 // The stacks were allocated as CHeap objects, so
a61af66fc99e Initial load
duke
parents:
diff changeset
658 // we must call delete to prevent mem leaks.
a61af66fc99e Initial load
duke
parents:
diff changeset
659 delete _preserved_mark_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
660 _preserved_mark_stack = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
661 delete _preserved_oop_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
662 _preserved_oop_stack = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
663 }
a61af66fc99e Initial load
duke
parents:
diff changeset
664
a61af66fc99e Initial load
duke
parents:
diff changeset
665 // Reset the PromotionFailureALot counters.
a61af66fc99e Initial load
duke
parents:
diff changeset
666 NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();)
a61af66fc99e Initial load
duke
parents:
diff changeset
667 }
a61af66fc99e Initial load
duke
parents:
diff changeset
668
a61af66fc99e Initial load
duke
parents:
diff changeset
669 // This method is called whenever an attempt to promote an object
a61af66fc99e Initial load
duke
parents:
diff changeset
670 // fails. Some markOops will need preserving, some will not. Note
a61af66fc99e Initial load
duke
parents:
diff changeset
671 // that the entire eden is traversed after a failed promotion, with
a61af66fc99e Initial load
duke
parents:
diff changeset
672 // all forwarded headers replaced by the default markOop. This means
a61af66fc99e Initial load
duke
parents:
diff changeset
673 // it is not neccessary to preserve most markOops.
a61af66fc99e Initial load
duke
parents:
diff changeset
674 void PSScavenge::oop_promotion_failed(oop obj, markOop obj_mark) {
a61af66fc99e Initial load
duke
parents:
diff changeset
675 if (_preserved_mark_stack == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
676 ThreadCritical tc; // Lock and retest
a61af66fc99e Initial load
duke
parents:
diff changeset
677 if (_preserved_mark_stack == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
678 assert(_preserved_oop_stack == NULL, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
679 _preserved_mark_stack = new (ResourceObj::C_HEAP) GrowableArray<markOop>(40, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
680 _preserved_oop_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(40, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
681 }
a61af66fc99e Initial load
duke
parents:
diff changeset
682 }
a61af66fc99e Initial load
duke
parents:
diff changeset
683
a61af66fc99e Initial load
duke
parents:
diff changeset
684 // Because we must hold the ThreadCritical lock before using
a61af66fc99e Initial load
duke
parents:
diff changeset
685 // the stacks, we should be safe from observing partial allocations,
a61af66fc99e Initial load
duke
parents:
diff changeset
686 // which are also guarded by the ThreadCritical lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
687 if (obj_mark->must_be_preserved_for_promotion_failure(obj)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
688 ThreadCritical tc;
a61af66fc99e Initial load
duke
parents:
diff changeset
689 _preserved_oop_stack->push(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
690 _preserved_mark_stack->push(obj_mark);
a61af66fc99e Initial load
duke
parents:
diff changeset
691 }
a61af66fc99e Initial load
duke
parents:
diff changeset
692 }
a61af66fc99e Initial load
duke
parents:
diff changeset
693
a61af66fc99e Initial load
duke
parents:
diff changeset
694 bool PSScavenge::should_attempt_scavenge() {
a61af66fc99e Initial load
duke
parents:
diff changeset
695 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
696 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
697 PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
698
a61af66fc99e Initial load
duke
parents:
diff changeset
699 if (UsePerfData) {
a61af66fc99e Initial load
duke
parents:
diff changeset
700 counters->update_scavenge_skipped(not_skipped);
a61af66fc99e Initial load
duke
parents:
diff changeset
701 }
a61af66fc99e Initial load
duke
parents:
diff changeset
702
a61af66fc99e Initial load
duke
parents:
diff changeset
703 PSYoungGen* young_gen = heap->young_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
704 PSOldGen* old_gen = heap->old_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
705
a61af66fc99e Initial load
duke
parents:
diff changeset
706 if (!ScavengeWithObjectsInToSpace) {
a61af66fc99e Initial load
duke
parents:
diff changeset
707 // Do not attempt to promote unless to_space is empty
a61af66fc99e Initial load
duke
parents:
diff changeset
708 if (!young_gen->to_space()->is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
709 _consecutive_skipped_scavenges++;
a61af66fc99e Initial load
duke
parents:
diff changeset
710 if (UsePerfData) {
a61af66fc99e Initial load
duke
parents:
diff changeset
711 counters->update_scavenge_skipped(to_space_not_empty);
a61af66fc99e Initial load
duke
parents:
diff changeset
712 }
a61af66fc99e Initial load
duke
parents:
diff changeset
713 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
714 }
a61af66fc99e Initial load
duke
parents:
diff changeset
715 }
a61af66fc99e Initial load
duke
parents:
diff changeset
716
a61af66fc99e Initial load
duke
parents:
diff changeset
717 // Test to see if the scavenge will likely fail.
a61af66fc99e Initial load
duke
parents:
diff changeset
718 PSAdaptiveSizePolicy* policy = heap->size_policy();
a61af66fc99e Initial load
duke
parents:
diff changeset
719
a61af66fc99e Initial load
duke
parents:
diff changeset
720 // A similar test is done in the policy's should_full_GC(). If this is
a61af66fc99e Initial load
duke
parents:
diff changeset
721 // changed, decide if that test should also be changed.
a61af66fc99e Initial load
duke
parents:
diff changeset
722 size_t avg_promoted = (size_t) policy->padded_average_promoted_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
723 size_t promotion_estimate = MIN2(avg_promoted, young_gen->used_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
724 bool result = promotion_estimate < old_gen->free_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
725
a61af66fc99e Initial load
duke
parents:
diff changeset
726 if (PrintGCDetails && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
727 gclog_or_tty->print(result ? " do scavenge: " : " skip scavenge: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
728 gclog_or_tty->print_cr(" average_promoted " SIZE_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
729 " padded_average_promoted " SIZE_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
730 " free in old gen " SIZE_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
731 (size_t) policy->average_promoted_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
732 (size_t) policy->padded_average_promoted_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
733 old_gen->free_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
734 if (young_gen->used_in_bytes() <
a61af66fc99e Initial load
duke
parents:
diff changeset
735 (size_t) policy->padded_average_promoted_in_bytes()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
736 gclog_or_tty->print_cr(" padded_promoted_average is greater"
a61af66fc99e Initial load
duke
parents:
diff changeset
737 " than maximum promotion = " SIZE_FORMAT, young_gen->used_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
738 }
a61af66fc99e Initial load
duke
parents:
diff changeset
739 }
a61af66fc99e Initial load
duke
parents:
diff changeset
740
a61af66fc99e Initial load
duke
parents:
diff changeset
741 if (result) {
a61af66fc99e Initial load
duke
parents:
diff changeset
742 _consecutive_skipped_scavenges = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
743 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
744 _consecutive_skipped_scavenges++;
a61af66fc99e Initial load
duke
parents:
diff changeset
745 if (UsePerfData) {
a61af66fc99e Initial load
duke
parents:
diff changeset
746 counters->update_scavenge_skipped(promoted_too_large);
a61af66fc99e Initial load
duke
parents:
diff changeset
747 }
a61af66fc99e Initial load
duke
parents:
diff changeset
748 }
a61af66fc99e Initial load
duke
parents:
diff changeset
749 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
750 }
a61af66fc99e Initial load
duke
parents:
diff changeset
751
a61af66fc99e Initial load
duke
parents:
diff changeset
752 // Used to add tasks
a61af66fc99e Initial load
duke
parents:
diff changeset
753 GCTaskManager* const PSScavenge::gc_task_manager() {
a61af66fc99e Initial load
duke
parents:
diff changeset
754 assert(ParallelScavengeHeap::gc_task_manager() != NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
755 "shouldn't return NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
756 return ParallelScavengeHeap::gc_task_manager();
a61af66fc99e Initial load
duke
parents:
diff changeset
757 }
a61af66fc99e Initial load
duke
parents:
diff changeset
758
a61af66fc99e Initial load
duke
parents:
diff changeset
759 void PSScavenge::initialize() {
a61af66fc99e Initial load
duke
parents:
diff changeset
760 // Arguments must have been parsed
a61af66fc99e Initial load
duke
parents:
diff changeset
761
a61af66fc99e Initial load
duke
parents:
diff changeset
762 if (AlwaysTenure) {
a61af66fc99e Initial load
duke
parents:
diff changeset
763 _tenuring_threshold = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
764 } else if (NeverTenure) {
a61af66fc99e Initial load
duke
parents:
diff changeset
765 _tenuring_threshold = markOopDesc::max_age + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
766 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
767 // We want to smooth out our startup times for the AdaptiveSizePolicy
a61af66fc99e Initial load
duke
parents:
diff changeset
768 _tenuring_threshold = (UseAdaptiveSizePolicy) ? InitialTenuringThreshold :
a61af66fc99e Initial load
duke
parents:
diff changeset
769 MaxTenuringThreshold;
a61af66fc99e Initial load
duke
parents:
diff changeset
770 }
a61af66fc99e Initial load
duke
parents:
diff changeset
771
a61af66fc99e Initial load
duke
parents:
diff changeset
772 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
773 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
774
a61af66fc99e Initial load
duke
parents:
diff changeset
775 PSYoungGen* young_gen = heap->young_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
776 PSOldGen* old_gen = heap->old_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
777 PSPermGen* perm_gen = heap->perm_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
778
a61af66fc99e Initial load
duke
parents:
diff changeset
779 // Set boundary between young_gen and old_gen
a61af66fc99e Initial load
duke
parents:
diff changeset
780 assert(perm_gen->reserved().end() <= old_gen->object_space()->bottom(),
a61af66fc99e Initial load
duke
parents:
diff changeset
781 "perm above old");
a61af66fc99e Initial load
duke
parents:
diff changeset
782 assert(old_gen->reserved().end() <= young_gen->eden_space()->bottom(),
a61af66fc99e Initial load
duke
parents:
diff changeset
783 "old above young");
a61af66fc99e Initial load
duke
parents:
diff changeset
784 _young_generation_boundary = young_gen->eden_space()->bottom();
a61af66fc99e Initial load
duke
parents:
diff changeset
785
a61af66fc99e Initial load
duke
parents:
diff changeset
786 // Initialize ref handling object for scavenging.
a61af66fc99e Initial load
duke
parents:
diff changeset
787 MemRegion mr = young_gen->reserved();
a61af66fc99e Initial load
duke
parents:
diff changeset
788 _ref_processor = ReferenceProcessor::create_ref_processor(
a61af66fc99e Initial load
duke
parents:
diff changeset
789 mr, // span
a61af66fc99e Initial load
duke
parents:
diff changeset
790 true, // atomic_discovery
a61af66fc99e Initial load
duke
parents:
diff changeset
791 true, // mt_discovery
a61af66fc99e Initial load
duke
parents:
diff changeset
792 NULL, // is_alive_non_header
a61af66fc99e Initial load
duke
parents:
diff changeset
793 ParallelGCThreads,
a61af66fc99e Initial load
duke
parents:
diff changeset
794 ParallelRefProcEnabled);
a61af66fc99e Initial load
duke
parents:
diff changeset
795
a61af66fc99e Initial load
duke
parents:
diff changeset
796 // Cache the cardtable
a61af66fc99e Initial load
duke
parents:
diff changeset
797 BarrierSet* bs = Universe::heap()->barrier_set();
a61af66fc99e Initial load
duke
parents:
diff changeset
798 assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind");
a61af66fc99e Initial load
duke
parents:
diff changeset
799 _card_table = (CardTableExtension*)bs;
a61af66fc99e Initial load
duke
parents:
diff changeset
800
a61af66fc99e Initial load
duke
parents:
diff changeset
801 _counters = new CollectorCounters("PSScavenge", 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
802 }