Mercurial > hg > truffle
annotate src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp @ 3772:6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
Summary: Perform a heap verification after the first phase of G1's full GC using objects' mark words to determine liveness. The third parameter of the heap verification routines, which was used in G1 to determine which marking bitmap to use in liveness calculations, has been changed from a boolean to an enum with values defined for using the mark word, and the 'prev' and 'next' bitmaps.
Reviewed-by: tonyp, ysr
author | johnc |
---|---|
date | Tue, 14 Jun 2011 11:01:10 -0700 |
parents | 78542e2b5e35 |
children | 4dfb2df418f2 |
rev | line source |
---|---|
0 | 1 /* |
2369
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2038
diff
changeset
|
2 * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1387
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1387
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1387
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
2379
b099aaf51bf8
6962931: move interned strings out of the perm gen
jcoomes
parents:
2369
diff
changeset
|
26 #include "classfile/symbolTable.hpp" |
1972 | 27 #include "gc_implementation/parallelScavenge/cardTableExtension.hpp" |
28 #include "gc_implementation/parallelScavenge/gcTaskManager.hpp" | |
29 #include "gc_implementation/parallelScavenge/generationSizer.hpp" | |
30 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" | |
31 #include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp" | |
32 #include "gc_implementation/parallelScavenge/psMarkSweep.hpp" | |
33 #include "gc_implementation/parallelScavenge/psParallelCompact.hpp" | |
34 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" | |
35 #include "gc_implementation/parallelScavenge/psTasks.hpp" | |
36 #include "gc_implementation/shared/isGCActiveMark.hpp" | |
37 #include "gc_implementation/shared/spaceDecorator.hpp" | |
38 #include "gc_interface/gcCause.hpp" | |
39 #include "memory/collectorPolicy.hpp" | |
40 #include "memory/gcLocker.inline.hpp" | |
41 #include "memory/referencePolicy.hpp" | |
42 #include "memory/referenceProcessor.hpp" | |
43 #include "memory/resourceArea.hpp" | |
44 #include "oops/oop.inline.hpp" | |
45 #include "oops/oop.psgc.inline.hpp" | |
46 #include "runtime/biasedLocking.hpp" | |
47 #include "runtime/fprofiler.hpp" | |
48 #include "runtime/handles.inline.hpp" | |
49 #include "runtime/threadCritical.hpp" | |
50 #include "runtime/vmThread.hpp" | |
51 #include "runtime/vm_operations.hpp" | |
52 #include "services/memoryService.hpp" | |
53 #include "utilities/stack.inline.hpp" | |
0 | 54 |
55 | |
56 HeapWord* PSScavenge::_to_space_top_before_gc = NULL; | |
57 int PSScavenge::_consecutive_skipped_scavenges = 0; | |
58 ReferenceProcessor* PSScavenge::_ref_processor = NULL; | |
59 CardTableExtension* PSScavenge::_card_table = NULL; | |
60 bool PSScavenge::_survivor_overflow = false; | |
61 int PSScavenge::_tenuring_threshold = 0; | |
62 HeapWord* PSScavenge::_young_generation_boundary = NULL; | |
63 elapsedTimer PSScavenge::_accumulated_time; | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
64 Stack<markOop> PSScavenge::_preserved_mark_stack; |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
65 Stack<oop> PSScavenge::_preserved_oop_stack; |
0 | 66 CollectorCounters* PSScavenge::_counters = NULL; |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
67 bool PSScavenge::_promotion_failed = false; |
0 | 68 |
69 // Define before use | |
70 class PSIsAliveClosure: public BoolObjectClosure { | |
71 public: | |
72 void do_object(oop p) { | |
73 assert(false, "Do not call."); | |
74 } | |
75 bool do_object_b(oop p) { | |
76 return (!PSScavenge::is_obj_in_young((HeapWord*) p)) || p->is_forwarded(); | |
77 } | |
78 }; | |
79 | |
80 PSIsAliveClosure PSScavenge::_is_alive_closure; | |
81 | |
82 class PSKeepAliveClosure: public OopClosure { | |
83 protected: | |
84 MutableSpace* _to_space; | |
85 PSPromotionManager* _promotion_manager; | |
86 | |
87 public: | |
88 PSKeepAliveClosure(PSPromotionManager* pm) : _promotion_manager(pm) { | |
89 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); | |
90 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); | |
91 _to_space = heap->young_gen()->to_space(); | |
92 | |
93 assert(_promotion_manager != NULL, "Sanity"); | |
94 } | |
95 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
96 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
|
97 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
|
98 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
|
99 "expected an oop while scanning weak refs"); |
0 | 100 |
101 // 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
|
102 if (PSScavenge::should_scavenge(p, _to_space)) { |
0 | 103 PSScavenge::copy_and_push_safe_barrier(_promotion_manager, p); |
104 } | |
105 } | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
106 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
|
107 virtual void do_oop(narrowOop* p) { PSKeepAliveClosure::do_oop_work(p); } |
0 | 108 }; |
109 | |
110 class PSEvacuateFollowersClosure: public VoidClosure { | |
111 private: | |
112 PSPromotionManager* _promotion_manager; | |
113 public: | |
114 PSEvacuateFollowersClosure(PSPromotionManager* pm) : _promotion_manager(pm) {} | |
115 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
116 virtual void do_void() { |
0 | 117 assert(_promotion_manager != NULL, "Sanity"); |
118 _promotion_manager->drain_stacks(true); | |
119 guarantee(_promotion_manager->stacks_empty(), | |
120 "stacks should be empty at this point"); | |
121 } | |
122 }; | |
123 | |
124 class PSPromotionFailedClosure : public ObjectClosure { | |
125 virtual void do_object(oop obj) { | |
126 if (obj->is_forwarded()) { | |
127 obj->init_mark(); | |
128 } | |
129 } | |
130 }; | |
131 | |
132 class PSRefProcTaskProxy: public GCTask { | |
133 typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask; | |
134 ProcessTask & _rp_task; | |
135 uint _work_id; | |
136 public: | |
137 PSRefProcTaskProxy(ProcessTask & rp_task, uint work_id) | |
138 : _rp_task(rp_task), | |
139 _work_id(work_id) | |
140 { } | |
141 | |
142 private: | |
143 virtual char* name() { return (char *)"Process referents by policy in parallel"; } | |
144 virtual void do_it(GCTaskManager* manager, uint which); | |
145 }; | |
146 | |
147 void PSRefProcTaskProxy::do_it(GCTaskManager* manager, uint which) | |
148 { | |
149 PSPromotionManager* promotion_manager = | |
150 PSPromotionManager::gc_thread_promotion_manager(which); | |
151 assert(promotion_manager != NULL, "sanity check"); | |
152 PSKeepAliveClosure keep_alive(promotion_manager); | |
153 PSEvacuateFollowersClosure evac_followers(promotion_manager); | |
154 PSIsAliveClosure is_alive; | |
155 _rp_task.work(_work_id, is_alive, keep_alive, evac_followers); | |
156 } | |
157 | |
158 class PSRefEnqueueTaskProxy: public GCTask { | |
159 typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask; | |
160 EnqueueTask& _enq_task; | |
161 uint _work_id; | |
162 | |
163 public: | |
164 PSRefEnqueueTaskProxy(EnqueueTask& enq_task, uint work_id) | |
165 : _enq_task(enq_task), | |
166 _work_id(work_id) | |
167 { } | |
168 | |
169 virtual char* name() { return (char *)"Enqueue reference objects in parallel"; } | |
170 virtual void do_it(GCTaskManager* manager, uint which) | |
171 { | |
172 _enq_task.work(_work_id); | |
173 } | |
174 }; | |
175 | |
176 class PSRefProcTaskExecutor: public AbstractRefProcTaskExecutor { | |
177 virtual void execute(ProcessTask& task); | |
178 virtual void execute(EnqueueTask& task); | |
179 }; | |
180 | |
181 void PSRefProcTaskExecutor::execute(ProcessTask& task) | |
182 { | |
183 GCTaskQueue* q = GCTaskQueue::create(); | |
184 for(uint i=0; i<ParallelGCThreads; i++) { | |
185 q->enqueue(new PSRefProcTaskProxy(task, i)); | |
186 } | |
187 ParallelTaskTerminator terminator( | |
1706
9d7a8ab3736b
6962589: remove breadth first scanning code from parallel gc
tonyp
parents:
1638
diff
changeset
|
188 ParallelScavengeHeap::gc_task_manager()->workers(), |
9d7a8ab3736b
6962589: remove breadth first scanning code from parallel gc
tonyp
parents:
1638
diff
changeset
|
189 (TaskQueueSetSuper*) PSPromotionManager::stack_array_depth()); |
0 | 190 if (task.marks_oops_alive() && ParallelGCThreads > 1) { |
191 for (uint j=0; j<ParallelGCThreads; j++) { | |
192 q->enqueue(new StealTask(&terminator)); | |
193 } | |
194 } | |
195 ParallelScavengeHeap::gc_task_manager()->execute_and_wait(q); | |
196 } | |
197 | |
198 | |
199 void PSRefProcTaskExecutor::execute(EnqueueTask& task) | |
200 { | |
201 GCTaskQueue* q = GCTaskQueue::create(); | |
202 for(uint i=0; i<ParallelGCThreads; i++) { | |
203 q->enqueue(new PSRefEnqueueTaskProxy(task, i)); | |
204 } | |
205 ParallelScavengeHeap::gc_task_manager()->execute_and_wait(q); | |
206 } | |
207 | |
208 // This method contains all heap specific policy for invoking scavenge. | |
209 // PSScavenge::invoke_no_policy() will do nothing but attempt to | |
210 // scavenge. It will not clean up after failed promotions, bail out if | |
211 // we've exceeded policy time limits, or any other special behavior. | |
212 // All such policy should be placed here. | |
213 // | |
214 // Note that this method should only be called from the vm_thread while | |
215 // at a safepoint! | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
216 void PSScavenge::invoke() { |
0 | 217 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); |
218 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread"); | |
219 assert(!Universe::heap()->is_gc_active(), "not reentrant"); | |
220 | |
221 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); | |
222 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); | |
223 | |
224 PSAdaptiveSizePolicy* policy = heap->size_policy(); | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
225 IsGCActiveMark mark; |
0 | 226 |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
227 bool scavenge_was_done = PSScavenge::invoke_no_policy(); |
0 | 228 |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
229 PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters(); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
230 if (UsePerfData) |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
231 counters->update_full_follows_scavenge(0); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
232 if (!scavenge_was_done || |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
233 policy->should_full_GC(heap->old_gen()->free_in_bytes())) { |
0 | 234 if (UsePerfData) |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
235 counters->update_full_follows_scavenge(full_follows_scavenge); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
236 GCCauseSetter gccs(heap, GCCause::_adaptive_size_policy); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
237 CollectorPolicy* cp = heap->collector_policy(); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
238 const bool clear_all_softrefs = cp->should_clear_all_soft_refs(); |
0 | 239 |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
240 if (UseParallelOldGC) { |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
241 PSParallelCompact::invoke_no_policy(clear_all_softrefs); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
242 } else { |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
243 PSMarkSweep::invoke_no_policy(clear_all_softrefs); |
0 | 244 } |
245 } | |
246 } | |
247 | |
248 // This method contains no policy. You should probably | |
249 // be calling invoke() instead. | |
250 bool PSScavenge::invoke_no_policy() { | |
251 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); | |
252 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread"); | |
253 | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
254 assert(_preserved_mark_stack.is_empty(), "should be empty"); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
255 assert(_preserved_oop_stack.is_empty(), "should be empty"); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
256 |
0 | 257 TimeStamp scavenge_entry; |
258 TimeStamp scavenge_midpoint; | |
259 TimeStamp scavenge_exit; | |
260 | |
261 scavenge_entry.update(); | |
262 | |
263 if (GC_locker::check_active_before_gc()) { | |
264 return false; | |
265 } | |
266 | |
267 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); | |
268 GCCause::Cause gc_cause = heap->gc_cause(); | |
269 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); | |
270 | |
271 // Check for potential problems. | |
272 if (!should_attempt_scavenge()) { | |
273 return false; | |
274 } | |
275 | |
276 bool promotion_failure_occurred = false; | |
277 | |
278 PSYoungGen* young_gen = heap->young_gen(); | |
279 PSOldGen* old_gen = heap->old_gen(); | |
280 PSPermGen* perm_gen = heap->perm_gen(); | |
281 PSAdaptiveSizePolicy* size_policy = heap->size_policy(); | |
282 heap->increment_total_collections(); | |
283 | |
284 AdaptiveSizePolicyOutput(size_policy, heap->total_collections()); | |
285 | |
286 if ((gc_cause != GCCause::_java_lang_system_gc) || | |
287 UseAdaptiveSizePolicyWithSystemGC) { | |
288 // Gather the feedback data for eden occupancy. | |
289 young_gen->eden_space()->accumulate_statistics(); | |
290 } | |
291 | |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
292 if (ZapUnusedHeapArea) { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
293 // 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
|
294 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
|
295 } |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
296 |
0 | 297 if (PrintHeapAtGC) { |
298 Universe::print_heap_before_gc(); | |
299 } | |
300 | |
301 assert(!NeverTenure || _tenuring_threshold == markOopDesc::max_age + 1, "Sanity"); | |
302 assert(!AlwaysTenure || _tenuring_threshold == 0, "Sanity"); | |
303 | |
304 size_t prev_used = heap->used(); | |
305 assert(promotion_failed() == false, "Sanity"); | |
306 | |
307 // Fill in TLABs | |
308 heap->accumulate_statistics_all_tlabs(); | |
309 heap->ensure_parsability(true); // retire TLABs | |
310 | |
311 if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) { | |
312 HandleMark hm; // Discard invalid handles created during verification | |
313 gclog_or_tty->print(" VerifyBeforeGC:"); | |
314 Universe::verify(true); | |
315 } | |
316 | |
317 { | |
318 ResourceMark rm; | |
319 HandleMark hm; | |
320 | |
321 gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); | |
322 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); | |
323 TraceTime t1("GC", PrintGC, !PrintGCDetails, gclog_or_tty); | |
324 TraceCollectorStats tcs(counters()); | |
3356
78542e2b5e35
7036199: Adding a notification to the implementation of GarbageCollectorMXBeans
fparain
parents:
2379
diff
changeset
|
325 TraceMemoryManagerStats tms(false /* not full GC */,gc_cause); |
0 | 326 |
327 if (TraceGen0Time) accumulated_time()->start(); | |
328 | |
329 // Let the size policy know we're starting | |
330 size_policy->minor_collection_begin(); | |
331 | |
332 // Verify the object start arrays. | |
333 if (VerifyObjectStartArray && | |
334 VerifyBeforeGC) { | |
335 old_gen->verify_object_start_array(); | |
336 perm_gen->verify_object_start_array(); | |
337 } | |
338 | |
339 // Verify no unmarked old->young roots | |
340 if (VerifyRememberedSets) { | |
341 CardTableExtension::verify_all_young_refs_imprecise(); | |
342 } | |
343 | |
344 if (!ScavengeWithObjectsInToSpace) { | |
345 assert(young_gen->to_space()->is_empty(), | |
346 "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
|
347 young_gen->to_space()->clear(SpaceDecorator::Mangle); |
0 | 348 } else if (ZapUnusedHeapArea) { |
349 young_gen->to_space()->mangle_unused_area(); | |
350 } | |
351 save_to_space_top_before_gc(); | |
352 | |
353 NOT_PRODUCT(reference_processor()->verify_no_references_recorded()); | |
354 COMPILER2_PRESENT(DerivedPointerTable::clear()); | |
355 | |
356 reference_processor()->enable_discovery(); | |
457
27a80744a83b
6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents:
453
diff
changeset
|
357 reference_processor()->setup_policy(false); |
0 | 358 |
359 // We track how much was promoted to the next generation for | |
360 // the AdaptiveSizePolicy. | |
361 size_t old_gen_used_before = old_gen->used_in_bytes(); | |
362 | |
363 // For PrintGCDetails | |
364 size_t young_gen_used_before = young_gen->used_in_bytes(); | |
365 | |
366 // Reset our survivor overflow. | |
367 set_survivor_overflow(false); | |
368 | |
369 // We need to save the old/perm top values before | |
370 // creating the promotion_manager. We pass the top | |
371 // values to the card_table, to prevent it from | |
372 // straying into the promotion labs. | |
373 HeapWord* old_top = old_gen->object_space()->top(); | |
374 HeapWord* perm_top = perm_gen->object_space()->top(); | |
375 | |
376 // Release all previously held resources | |
377 gc_task_manager()->release_all_resources(); | |
378 | |
379 PSPromotionManager::pre_scavenge(); | |
380 | |
381 // We'll use the promotion manager again later. | |
382 PSPromotionManager* promotion_manager = PSPromotionManager::vm_thread_promotion_manager(); | |
383 { | |
384 // TraceTime("Roots"); | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
579
diff
changeset
|
385 ParallelScavengeHeap::ParStrongRootsScope psrs; |
0 | 386 |
387 GCTaskQueue* q = GCTaskQueue::create(); | |
388 | |
389 for(uint i=0; i<ParallelGCThreads; i++) { | |
390 q->enqueue(new OldToYoungRootsTask(old_gen, old_top, i)); | |
391 } | |
392 | |
393 q->enqueue(new SerialOldToYoungRootsTask(perm_gen, perm_top)); | |
394 | |
395 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::universe)); | |
396 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jni_handles)); | |
397 // We scan the thread roots in parallel | |
398 Threads::create_thread_roots_tasks(q); | |
399 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::object_synchronizer)); | |
400 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::flat_profiler)); | |
401 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::management)); | |
402 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::system_dictionary)); | |
403 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmti)); | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
579
diff
changeset
|
404 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::code_cache)); |
0 | 405 |
406 ParallelTaskTerminator terminator( | |
1706
9d7a8ab3736b
6962589: remove breadth first scanning code from parallel gc
tonyp
parents:
1638
diff
changeset
|
407 gc_task_manager()->workers(), |
9d7a8ab3736b
6962589: remove breadth first scanning code from parallel gc
tonyp
parents:
1638
diff
changeset
|
408 (TaskQueueSetSuper*) promotion_manager->stack_array_depth()); |
0 | 409 if (ParallelGCThreads>1) { |
410 for (uint j=0; j<ParallelGCThreads; j++) { | |
411 q->enqueue(new StealTask(&terminator)); | |
412 } | |
413 } | |
414 | |
415 gc_task_manager()->execute_and_wait(q); | |
416 } | |
417 | |
418 scavenge_midpoint.update(); | |
419 | |
420 // Process reference objects discovered during scavenge | |
421 { | |
457
27a80744a83b
6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents:
453
diff
changeset
|
422 reference_processor()->setup_policy(false); // not always_clear |
0 | 423 PSKeepAliveClosure keep_alive(promotion_manager); |
424 PSEvacuateFollowersClosure evac_followers(promotion_manager); | |
425 if (reference_processor()->processing_is_mt()) { | |
426 PSRefProcTaskExecutor task_executor; | |
427 reference_processor()->process_discovered_references( | |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
269
diff
changeset
|
428 &_is_alive_closure, &keep_alive, &evac_followers, &task_executor); |
0 | 429 } else { |
430 reference_processor()->process_discovered_references( | |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
269
diff
changeset
|
431 &_is_alive_closure, &keep_alive, &evac_followers, NULL); |
0 | 432 } |
433 } | |
434 | |
435 // Enqueue reference objects discovered during scavenge. | |
436 if (reference_processor()->processing_is_mt()) { | |
437 PSRefProcTaskExecutor task_executor; | |
438 reference_processor()->enqueue_discovered_references(&task_executor); | |
439 } else { | |
440 reference_processor()->enqueue_discovered_references(NULL); | |
441 } | |
442 | |
2379
b099aaf51bf8
6962931: move interned strings out of the perm gen
jcoomes
parents:
2369
diff
changeset
|
443 if (!JavaObjectsInPerm) { |
b099aaf51bf8
6962931: move interned strings out of the perm gen
jcoomes
parents:
2369
diff
changeset
|
444 // Unlink any dead interned Strings |
b099aaf51bf8
6962931: move interned strings out of the perm gen
jcoomes
parents:
2369
diff
changeset
|
445 StringTable::unlink(&_is_alive_closure); |
b099aaf51bf8
6962931: move interned strings out of the perm gen
jcoomes
parents:
2369
diff
changeset
|
446 // Process the remaining live ones |
b099aaf51bf8
6962931: move interned strings out of the perm gen
jcoomes
parents:
2369
diff
changeset
|
447 PSScavengeRootsClosure root_closure(promotion_manager); |
b099aaf51bf8
6962931: move interned strings out of the perm gen
jcoomes
parents:
2369
diff
changeset
|
448 StringTable::oops_do(&root_closure); |
b099aaf51bf8
6962931: move interned strings out of the perm gen
jcoomes
parents:
2369
diff
changeset
|
449 } |
b099aaf51bf8
6962931: move interned strings out of the perm gen
jcoomes
parents:
2369
diff
changeset
|
450 |
0 | 451 // Finally, flush the promotion_manager's labs, and deallocate its stacks. |
452 PSPromotionManager::post_scavenge(); | |
453 | |
454 promotion_failure_occurred = promotion_failed(); | |
455 if (promotion_failure_occurred) { | |
456 clean_up_failed_promotion(); | |
457 if (PrintGC) { | |
458 gclog_or_tty->print("--"); | |
459 } | |
460 } | |
461 | |
462 // Let the size policy know we're done. Note that we count promotion | |
463 // failure cleanup time as part of the collection (otherwise, we're | |
464 // implicitly saying it's mutator time). | |
465 size_policy->minor_collection_end(gc_cause); | |
466 | |
467 if (!promotion_failure_occurred) { | |
468 // Swap the survivor spaces. | |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
469 |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
470 |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
471 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
|
472 young_gen->from_space()->clear(SpaceDecorator::Mangle); |
0 | 473 young_gen->swap_spaces(); |
474 | |
475 size_t survived = young_gen->from_space()->used_in_bytes(); | |
476 size_t promoted = old_gen->used_in_bytes() - old_gen_used_before; | |
477 size_policy->update_averages(_survivor_overflow, survived, promoted); | |
478 | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
479 // A successful scavenge should restart the GC time limit count which is |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
480 // for full GC's. |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
481 size_policy->reset_gc_overhead_limit_count(); |
0 | 482 if (UseAdaptiveSizePolicy) { |
483 // Calculate the new survivor size and tenuring threshold | |
484 | |
485 if (PrintAdaptiveSizePolicy) { | |
486 gclog_or_tty->print("AdaptiveSizeStart: "); | |
487 gclog_or_tty->stamp(); | |
488 gclog_or_tty->print_cr(" collection: %d ", | |
489 heap->total_collections()); | |
490 | |
491 if (Verbose) { | |
492 gclog_or_tty->print("old_gen_capacity: %d young_gen_capacity: %d" | |
493 " perm_gen_capacity: %d ", | |
494 old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes(), | |
495 perm_gen->capacity_in_bytes()); | |
496 } | |
497 } | |
498 | |
499 | |
500 if (UsePerfData) { | |
501 PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters(); | |
502 counters->update_old_eden_size( | |
503 size_policy->calculated_eden_size_in_bytes()); | |
504 counters->update_old_promo_size( | |
505 size_policy->calculated_promo_size_in_bytes()); | |
506 counters->update_old_capacity(old_gen->capacity_in_bytes()); | |
507 counters->update_young_capacity(young_gen->capacity_in_bytes()); | |
508 counters->update_survived(survived); | |
509 counters->update_promoted(promoted); | |
510 counters->update_survivor_overflowed(_survivor_overflow); | |
511 } | |
512 | |
513 size_t survivor_limit = | |
514 size_policy->max_survivor_size(young_gen->max_size()); | |
515 _tenuring_threshold = | |
516 size_policy->compute_survivor_space_size_and_threshold( | |
517 _survivor_overflow, | |
518 _tenuring_threshold, | |
519 survivor_limit); | |
520 | |
521 if (PrintTenuringDistribution) { | |
522 gclog_or_tty->cr(); | |
523 gclog_or_tty->print_cr("Desired survivor size %ld bytes, new threshold %d (max %d)", | |
524 size_policy->calculated_survivor_size_in_bytes(), | |
525 _tenuring_threshold, MaxTenuringThreshold); | |
526 } | |
527 | |
528 if (UsePerfData) { | |
529 PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters(); | |
530 counters->update_tenuring_threshold(_tenuring_threshold); | |
531 counters->update_survivor_size_counters(); | |
532 } | |
533 | |
534 // Do call at minor collections? | |
535 // Don't check if the size_policy is ready at this | |
536 // level. Let the size_policy check that internally. | |
537 if (UseAdaptiveSizePolicy && | |
538 UseAdaptiveGenerationSizePolicyAtMinorCollection && | |
539 ((gc_cause != GCCause::_java_lang_system_gc) || | |
540 UseAdaptiveSizePolicyWithSystemGC)) { | |
541 | |
542 // Calculate optimial free space amounts | |
543 assert(young_gen->max_size() > | |
544 young_gen->from_space()->capacity_in_bytes() + | |
545 young_gen->to_space()->capacity_in_bytes(), | |
546 "Sizes of space in young gen are out-of-bounds"); | |
547 size_t max_eden_size = young_gen->max_size() - | |
548 young_gen->from_space()->capacity_in_bytes() - | |
549 young_gen->to_space()->capacity_in_bytes(); | |
550 size_policy->compute_generation_free_space(young_gen->used_in_bytes(), | |
551 young_gen->eden_space()->used_in_bytes(), | |
552 old_gen->used_in_bytes(), | |
553 perm_gen->used_in_bytes(), | |
554 young_gen->eden_space()->capacity_in_bytes(), | |
555 old_gen->max_gen_size(), | |
556 max_eden_size, | |
557 false /* full gc*/, | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
558 gc_cause, |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
559 heap->collector_policy()); |
0 | 560 |
561 } | |
562 // Resize the young generation at every collection | |
563 // even if new sizes have not been calculated. This is | |
564 // to allow resizes that may have been inhibited by the | |
565 // relative location of the "to" and "from" spaces. | |
566 | |
567 // Resizing the old gen at minor collects can cause increases | |
568 // that don't feed back to the generation sizing policy until | |
569 // a major collection. Don't resize the old gen here. | |
570 | |
571 heap->resize_young_gen(size_policy->calculated_eden_size_in_bytes(), | |
572 size_policy->calculated_survivor_size_in_bytes()); | |
573 | |
574 if (PrintAdaptiveSizePolicy) { | |
575 gclog_or_tty->print_cr("AdaptiveSizeStop: collection: %d ", | |
576 heap->total_collections()); | |
577 } | |
578 } | |
579 | |
580 // Update the structure of the eden. With NUMA-eden CPU hotplugging or offlining can | |
581 // cause the change of the heap layout. Make sure eden is reshaped if that's the case. | |
582 // Also update() will case adaptive NUMA chunk resizing. | |
583 assert(young_gen->eden_space()->is_empty(), "eden space should be empty now"); | |
584 young_gen->eden_space()->update(); | |
585 | |
586 heap->gc_policy_counters()->update_counters(); | |
587 | |
588 heap->resize_all_tlabs(); | |
589 | |
590 assert(young_gen->to_space()->is_empty(), "to space should be empty now"); | |
591 } | |
592 | |
593 COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); | |
594 | |
595 NOT_PRODUCT(reference_processor()->verify_no_references_recorded()); | |
596 | |
597 // Re-verify object start arrays | |
598 if (VerifyObjectStartArray && | |
599 VerifyAfterGC) { | |
600 old_gen->verify_object_start_array(); | |
601 perm_gen->verify_object_start_array(); | |
602 } | |
603 | |
604 // Verify all old -> young cards are now precise | |
605 if (VerifyRememberedSets) { | |
606 // Precise verification will give false positives. Until this is fixed, | |
607 // use imprecise verification. | |
608 // CardTableExtension::verify_all_young_refs_precise(); | |
609 CardTableExtension::verify_all_young_refs_imprecise(); | |
610 } | |
611 | |
612 if (TraceGen0Time) accumulated_time()->stop(); | |
613 | |
614 if (PrintGC) { | |
615 if (PrintGCDetails) { | |
616 // Don't print a GC timestamp here. This is after the GC so | |
617 // would be confusing. | |
618 young_gen->print_used_change(young_gen_used_before); | |
619 } | |
620 heap->print_heap_change(prev_used); | |
621 } | |
622 | |
623 // Track memory usage and detect low memory | |
624 MemoryService::track_memory_usage(); | |
625 heap->update_counters(); | |
626 } | |
627 | |
628 if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) { | |
629 HandleMark hm; // Discard invalid handles created during verification | |
630 gclog_or_tty->print(" VerifyAfterGC:"); | |
631 Universe::verify(false); | |
632 } | |
633 | |
634 if (PrintHeapAtGC) { | |
635 Universe::print_heap_after_gc(); | |
636 } | |
637 | |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
638 if (ZapUnusedHeapArea) { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
639 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
|
640 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
|
641 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
|
642 } |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
643 |
0 | 644 scavenge_exit.update(); |
645 | |
646 if (PrintGCTaskTimeStamps) { | |
647 tty->print_cr("VM-Thread " INT64_FORMAT " " INT64_FORMAT " " INT64_FORMAT, | |
648 scavenge_entry.ticks(), scavenge_midpoint.ticks(), | |
649 scavenge_exit.ticks()); | |
650 gc_task_manager()->print_task_time_stamps(); | |
651 } | |
652 | |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
457
diff
changeset
|
653 #ifdef TRACESPINNING |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
457
diff
changeset
|
654 ParallelTaskTerminator::print_termination_counts(); |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
457
diff
changeset
|
655 #endif |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
457
diff
changeset
|
656 |
0 | 657 return !promotion_failure_occurred; |
658 } | |
659 | |
660 // This method iterates over all objects in the young generation, | |
661 // unforwarding markOops. It then restores any preserved mark oops, | |
662 // and clears the _preserved_mark_stack. | |
663 void PSScavenge::clean_up_failed_promotion() { | |
664 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); | |
665 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); | |
666 assert(promotion_failed(), "Sanity"); | |
667 | |
668 PSYoungGen* young_gen = heap->young_gen(); | |
669 | |
670 { | |
671 ResourceMark rm; | |
672 | |
673 // Unforward all pointers in the young gen. | |
674 PSPromotionFailedClosure unforward_closure; | |
675 young_gen->object_iterate(&unforward_closure); | |
676 | |
677 if (PrintGC && Verbose) { | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
678 gclog_or_tty->print_cr("Restoring %d marks", _preserved_oop_stack.size()); |
0 | 679 } |
680 | |
681 // Restore any saved marks. | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
682 while (!_preserved_oop_stack.is_empty()) { |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
683 oop obj = _preserved_oop_stack.pop(); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
684 markOop mark = _preserved_mark_stack.pop(); |
0 | 685 obj->set_mark(mark); |
686 } | |
687 | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
688 // Clear the preserved mark and oop stack caches. |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
689 _preserved_mark_stack.clear(true); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
690 _preserved_oop_stack.clear(true); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
691 _promotion_failed = false; |
0 | 692 } |
693 | |
694 // Reset the PromotionFailureALot counters. | |
695 NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();) | |
696 } | |
697 | |
698 // This method is called whenever an attempt to promote an object | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
699 // fails. Some markOops will need preservation, some will not. Note |
0 | 700 // that the entire eden is traversed after a failed promotion, with |
701 // all forwarded headers replaced by the default markOop. This means | |
702 // it is not neccessary to preserve most markOops. | |
703 void PSScavenge::oop_promotion_failed(oop obj, markOop obj_mark) { | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
704 _promotion_failed = true; |
0 | 705 if (obj_mark->must_be_preserved_for_promotion_failure(obj)) { |
2038
74ee0db180fa
6807801: CMS: could save/restore fewer header words during scavenge
ysr
parents:
1972
diff
changeset
|
706 // Should use per-worker private stakcs hetre rather than |
74ee0db180fa
6807801: CMS: could save/restore fewer header words during scavenge
ysr
parents:
1972
diff
changeset
|
707 // locking a common pair of stacks. |
0 | 708 ThreadCritical tc; |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
709 _preserved_oop_stack.push(obj); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
710 _preserved_mark_stack.push(obj_mark); |
0 | 711 } |
712 } | |
713 | |
714 bool PSScavenge::should_attempt_scavenge() { | |
715 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); | |
716 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); | |
717 PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters(); | |
718 | |
719 if (UsePerfData) { | |
720 counters->update_scavenge_skipped(not_skipped); | |
721 } | |
722 | |
723 PSYoungGen* young_gen = heap->young_gen(); | |
724 PSOldGen* old_gen = heap->old_gen(); | |
725 | |
726 if (!ScavengeWithObjectsInToSpace) { | |
727 // Do not attempt to promote unless to_space is empty | |
728 if (!young_gen->to_space()->is_empty()) { | |
729 _consecutive_skipped_scavenges++; | |
730 if (UsePerfData) { | |
731 counters->update_scavenge_skipped(to_space_not_empty); | |
732 } | |
733 return false; | |
734 } | |
735 } | |
736 | |
737 // Test to see if the scavenge will likely fail. | |
738 PSAdaptiveSizePolicy* policy = heap->size_policy(); | |
739 | |
740 // A similar test is done in the policy's should_full_GC(). If this is | |
741 // changed, decide if that test should also be changed. | |
742 size_t avg_promoted = (size_t) policy->padded_average_promoted_in_bytes(); | |
743 size_t promotion_estimate = MIN2(avg_promoted, young_gen->used_in_bytes()); | |
744 bool result = promotion_estimate < old_gen->free_in_bytes(); | |
745 | |
746 if (PrintGCDetails && Verbose) { | |
747 gclog_or_tty->print(result ? " do scavenge: " : " skip scavenge: "); | |
748 gclog_or_tty->print_cr(" average_promoted " SIZE_FORMAT | |
749 " padded_average_promoted " SIZE_FORMAT | |
750 " free in old gen " SIZE_FORMAT, | |
751 (size_t) policy->average_promoted_in_bytes(), | |
752 (size_t) policy->padded_average_promoted_in_bytes(), | |
753 old_gen->free_in_bytes()); | |
754 if (young_gen->used_in_bytes() < | |
755 (size_t) policy->padded_average_promoted_in_bytes()) { | |
756 gclog_or_tty->print_cr(" padded_promoted_average is greater" | |
757 " than maximum promotion = " SIZE_FORMAT, young_gen->used_in_bytes()); | |
758 } | |
759 } | |
760 | |
761 if (result) { | |
762 _consecutive_skipped_scavenges = 0; | |
763 } else { | |
764 _consecutive_skipped_scavenges++; | |
765 if (UsePerfData) { | |
766 counters->update_scavenge_skipped(promoted_too_large); | |
767 } | |
768 } | |
769 return result; | |
770 } | |
771 | |
772 // Used to add tasks | |
773 GCTaskManager* const PSScavenge::gc_task_manager() { | |
774 assert(ParallelScavengeHeap::gc_task_manager() != NULL, | |
775 "shouldn't return NULL"); | |
776 return ParallelScavengeHeap::gc_task_manager(); | |
777 } | |
778 | |
779 void PSScavenge::initialize() { | |
780 // Arguments must have been parsed | |
781 | |
782 if (AlwaysTenure) { | |
783 _tenuring_threshold = 0; | |
784 } else if (NeverTenure) { | |
785 _tenuring_threshold = markOopDesc::max_age + 1; | |
786 } else { | |
787 // We want to smooth out our startup times for the AdaptiveSizePolicy | |
788 _tenuring_threshold = (UseAdaptiveSizePolicy) ? InitialTenuringThreshold : | |
789 MaxTenuringThreshold; | |
790 } | |
791 | |
792 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); | |
793 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); | |
794 | |
795 PSYoungGen* young_gen = heap->young_gen(); | |
796 PSOldGen* old_gen = heap->old_gen(); | |
797 PSPermGen* perm_gen = heap->perm_gen(); | |
798 | |
799 // Set boundary between young_gen and old_gen | |
800 assert(perm_gen->reserved().end() <= old_gen->object_space()->bottom(), | |
801 "perm above old"); | |
802 assert(old_gen->reserved().end() <= young_gen->eden_space()->bottom(), | |
803 "old above young"); | |
804 _young_generation_boundary = young_gen->eden_space()->bottom(); | |
805 | |
806 // Initialize ref handling object for scavenging. | |
807 MemRegion mr = young_gen->reserved(); | |
2369
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2038
diff
changeset
|
808 _ref_processor = |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2038
diff
changeset
|
809 new ReferenceProcessor(mr, // span |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2038
diff
changeset
|
810 ParallelRefProcEnabled && (ParallelGCThreads > 1), // mt processing |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2038
diff
changeset
|
811 (int) ParallelGCThreads, // mt processing degree |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2038
diff
changeset
|
812 true, // mt discovery |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2038
diff
changeset
|
813 (int) ParallelGCThreads, // mt discovery degree |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2038
diff
changeset
|
814 true, // atomic_discovery |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2038
diff
changeset
|
815 NULL, // header provides liveness info |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2038
diff
changeset
|
816 false); // next field updates do not need write barrier |
0 | 817 |
818 // Cache the cardtable | |
819 BarrierSet* bs = Universe::heap()->barrier_set(); | |
820 assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind"); | |
821 _card_table = (CardTableExtension*)bs; | |
822 | |
823 _counters = new CollectorCounters("PSScavenge", 0); | |
824 } |