Mercurial > hg > truffle
annotate src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp @ 1349:547cbe6dacc5
6936709: AsyncGetCallTrace doesn't handle inexact stack walking properly
Reviewed-by: kvn
author | never |
---|---|
date | Thu, 01 Apr 2010 16:06:57 -0700 |
parents | 89e0543e1737 |
children | 2a1472c30599 |
rev | line source |
---|---|
0 | 1 /* |
948 | 2 * Copyright 2005-2009 Sun Microsystems, Inc. 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 * | |
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | |
21 * have any questions. | |
22 * | |
23 */ | |
24 | |
25 #include "incls/_precompiled.incl" | |
26 #include "incls/_psCompactionManager.cpp.incl" | |
27 | |
28 PSOldGen* ParCompactionManager::_old_gen = NULL; | |
29 ParCompactionManager** ParCompactionManager::_manager_array = NULL; | |
30 OopTaskQueueSet* ParCompactionManager::_stack_array = NULL; | |
31 ObjectStartArray* ParCompactionManager::_start_array = NULL; | |
32 ParMarkBitMap* ParCompactionManager::_mark_bitmap = NULL; | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
33 RegionTaskQueueSet* ParCompactionManager::_region_array = NULL; |
0 | 34 |
35 ParCompactionManager::ParCompactionManager() : | |
36 _action(CopyAndUpdate) { | |
37 | |
38 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); | |
39 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); | |
40 | |
41 _old_gen = heap->old_gen(); | |
42 _start_array = old_gen()->start_array(); | |
43 | |
44 | |
45 marking_stack()->initialize(); | |
46 | |
47 // We want the overflow stack to be permanent | |
48 _overflow_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(10, true); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
49 #ifdef USE_RegionTaskQueueWithOverflow |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
50 region_stack()->initialize(); |
0 | 51 #else |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
52 region_stack()->initialize(); |
0 | 53 |
54 // We want the overflow stack to be permanent | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
55 _region_overflow_stack = |
0 | 56 new (ResourceObj::C_HEAP) GrowableArray<size_t>(10, true); |
57 #endif | |
58 | |
59 // Note that _revisit_klass_stack is allocated out of the | |
60 // C heap (as opposed to out of ResourceArena). | |
61 int size = | |
62 (SystemDictionary::number_of_classes() * 2) * 2 / ParallelGCThreads; | |
63 _revisit_klass_stack = new (ResourceObj::C_HEAP) GrowableArray<Klass*>(size, true); | |
941 | 64 // From some experiments (#klass/k)^2 for k = 10 seems a better fit, but this will |
65 // have to do for now until we are able to investigate a more optimal setting. | |
66 _revisit_mdo_stack = new (ResourceObj::C_HEAP) GrowableArray<DataLayout*>(size*2, true); | |
0 | 67 |
68 } | |
69 | |
70 ParCompactionManager::~ParCompactionManager() { | |
71 delete _overflow_stack; | |
72 delete _revisit_klass_stack; | |
941 | 73 delete _revisit_mdo_stack; |
0 | 74 // _manager_array and _stack_array are statics |
75 // shared with all instances of ParCompactionManager | |
76 // should not be deallocated. | |
77 } | |
78 | |
79 void ParCompactionManager::initialize(ParMarkBitMap* mbm) { | |
80 assert(PSParallelCompact::gc_task_manager() != NULL, | |
81 "Needed for initialization"); | |
82 | |
83 _mark_bitmap = mbm; | |
84 | |
85 uint parallel_gc_threads = PSParallelCompact::gc_task_manager()->workers(); | |
86 | |
87 assert(_manager_array == NULL, "Attempt to initialize twice"); | |
88 _manager_array = NEW_C_HEAP_ARRAY(ParCompactionManager*, parallel_gc_threads+1 ); | |
89 guarantee(_manager_array != NULL, "Could not initialize promotion manager"); | |
90 | |
91 _stack_array = new OopTaskQueueSet(parallel_gc_threads); | |
92 guarantee(_stack_array != NULL, "Count not initialize promotion manager"); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
93 _region_array = new RegionTaskQueueSet(parallel_gc_threads); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
94 guarantee(_region_array != NULL, "Count not initialize promotion manager"); |
0 | 95 |
96 // Create and register the ParCompactionManager(s) for the worker threads. | |
97 for(uint i=0; i<parallel_gc_threads; i++) { | |
98 _manager_array[i] = new ParCompactionManager(); | |
99 guarantee(_manager_array[i] != NULL, "Could not create ParCompactionManager"); | |
100 stack_array()->register_queue(i, _manager_array[i]->marking_stack()); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
101 #ifdef USE_RegionTaskQueueWithOverflow |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
102 region_array()->register_queue(i, _manager_array[i]->region_stack()->task_queue()); |
0 | 103 #else |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
104 region_array()->register_queue(i, _manager_array[i]->region_stack()); |
0 | 105 #endif |
106 } | |
107 | |
108 // The VMThread gets its own ParCompactionManager, which is not available | |
109 // for work stealing. | |
110 _manager_array[parallel_gc_threads] = new ParCompactionManager(); | |
111 guarantee(_manager_array[parallel_gc_threads] != NULL, | |
112 "Could not create ParCompactionManager"); | |
113 assert(PSParallelCompact::gc_task_manager()->workers() != 0, | |
114 "Not initialized?"); | |
115 } | |
116 | |
117 bool ParCompactionManager::should_update() { | |
118 assert(action() != NotValid, "Action is not set"); | |
119 return (action() == ParCompactionManager::Update) || | |
120 (action() == ParCompactionManager::CopyAndUpdate) || | |
121 (action() == ParCompactionManager::UpdateAndCopy); | |
122 } | |
123 | |
124 bool ParCompactionManager::should_copy() { | |
125 assert(action() != NotValid, "Action is not set"); | |
126 return (action() == ParCompactionManager::Copy) || | |
127 (action() == ParCompactionManager::CopyAndUpdate) || | |
128 (action() == ParCompactionManager::UpdateAndCopy); | |
129 } | |
130 | |
131 bool ParCompactionManager::should_verify_only() { | |
132 assert(action() != NotValid, "Action is not set"); | |
133 return action() == ParCompactionManager::VerifyUpdate; | |
134 } | |
135 | |
136 bool ParCompactionManager::should_reset_only() { | |
137 assert(action() != NotValid, "Action is not set"); | |
138 return action() == ParCompactionManager::ResetObjects; | |
139 } | |
140 | |
141 // For now save on a stack | |
142 void ParCompactionManager::save_for_scanning(oop m) { | |
143 stack_push(m); | |
144 } | |
145 | |
146 void ParCompactionManager::stack_push(oop obj) { | |
147 | |
148 if(!marking_stack()->push(obj)) { | |
149 overflow_stack()->push(obj); | |
150 } | |
151 } | |
152 | |
153 oop ParCompactionManager::retrieve_for_scanning() { | |
154 | |
155 // Should not be used in the parallel case | |
156 ShouldNotReachHere(); | |
157 return NULL; | |
158 } | |
159 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
160 // Save region on a stack |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
161 void ParCompactionManager::save_for_processing(size_t region_index) { |
0 | 162 #ifdef ASSERT |
163 const ParallelCompactData& sd = PSParallelCompact::summary_data(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
164 ParallelCompactData::RegionData* const region_ptr = sd.region(region_index); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
165 assert(region_ptr->claimed(), "must be claimed"); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
166 assert(region_ptr->_pushed++ == 0, "should only be pushed once"); |
0 | 167 #endif |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
168 region_stack_push(region_index); |
0 | 169 } |
170 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
171 void ParCompactionManager::region_stack_push(size_t region_index) { |
0 | 172 |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
173 #ifdef USE_RegionTaskQueueWithOverflow |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
174 region_stack()->save(region_index); |
0 | 175 #else |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
176 if(!region_stack()->push(region_index)) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
177 region_overflow_stack()->push(region_index); |
0 | 178 } |
179 #endif | |
180 } | |
181 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
182 bool ParCompactionManager::retrieve_for_processing(size_t& region_index) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
183 #ifdef USE_RegionTaskQueueWithOverflow |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
184 return region_stack()->retrieve(region_index); |
0 | 185 #else |
186 // Should not be used in the parallel case | |
187 ShouldNotReachHere(); | |
188 return false; | |
189 #endif | |
190 } | |
191 | |
192 ParCompactionManager* | |
193 ParCompactionManager::gc_thread_compaction_manager(int index) { | |
194 assert(index >= 0 && index < (int)ParallelGCThreads, "index out of range"); | |
195 assert(_manager_array != NULL, "Sanity"); | |
196 return _manager_array[index]; | |
197 } | |
198 | |
199 void ParCompactionManager::reset() { | |
200 for(uint i=0; i<ParallelGCThreads+1; i++) { | |
201 manager_array(i)->revisit_klass_stack()->clear(); | |
941 | 202 manager_array(i)->revisit_mdo_stack()->clear(); |
0 | 203 } |
204 } | |
205 | |
206 void ParCompactionManager::drain_marking_stacks(OopClosure* blk) { | |
207 #ifdef ASSERT | |
208 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); | |
209 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); | |
210 MutableSpace* to_space = heap->young_gen()->to_space(); | |
211 MutableSpace* old_space = heap->old_gen()->object_space(); | |
212 MutableSpace* perm_space = heap->perm_gen()->object_space(); | |
213 #endif /* ASSERT */ | |
214 | |
215 | |
216 do { | |
217 | |
218 // Drain overflow stack first, so other threads can steal from | |
219 // claimed stack while we work. | |
220 while(!overflow_stack()->is_empty()) { | |
221 oop obj = overflow_stack()->pop(); | |
222 obj->follow_contents(this); | |
223 } | |
224 | |
225 oop obj; | |
226 // obj is a reference!!! | |
227 while (marking_stack()->pop_local(obj)) { | |
228 // It would be nice to assert about the type of objects we might | |
229 // pop, but they can come from anywhere, unfortunately. | |
230 obj->follow_contents(this); | |
231 } | |
232 } while((marking_stack()->size() != 0) || (overflow_stack()->length() != 0)); | |
233 | |
234 assert(marking_stack()->size() == 0, "Sanity"); | |
235 assert(overflow_stack()->length() == 0, "Sanity"); | |
236 } | |
237 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
238 void ParCompactionManager::drain_region_overflow_stack() { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
239 size_t region_index = (size_t) -1; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
240 while(region_stack()->retrieve_from_overflow(region_index)) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
241 PSParallelCompact::fill_and_update_region(this, region_index); |
0 | 242 } |
243 } | |
244 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
245 void ParCompactionManager::drain_region_stacks() { |
0 | 246 #ifdef ASSERT |
247 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); | |
248 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); | |
249 MutableSpace* to_space = heap->young_gen()->to_space(); | |
250 MutableSpace* old_space = heap->old_gen()->object_space(); | |
251 MutableSpace* perm_space = heap->perm_gen()->object_space(); | |
252 #endif /* ASSERT */ | |
253 | |
254 #if 1 // def DO_PARALLEL - the serial code hasn't been updated | |
255 do { | |
256 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
257 #ifdef USE_RegionTaskQueueWithOverflow |
0 | 258 // Drain overflow stack first, so other threads can steal from |
259 // claimed stack while we work. | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
260 size_t region_index = (size_t) -1; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
261 while(region_stack()->retrieve_from_overflow(region_index)) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
262 PSParallelCompact::fill_and_update_region(this, region_index); |
0 | 263 } |
264 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
265 while (region_stack()->retrieve_from_stealable_queue(region_index)) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
266 PSParallelCompact::fill_and_update_region(this, region_index); |
0 | 267 } |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
268 } while (!region_stack()->is_empty()); |
0 | 269 #else |
270 // Drain overflow stack first, so other threads can steal from | |
271 // claimed stack while we work. | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
272 while(!region_overflow_stack()->is_empty()) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
273 size_t region_index = region_overflow_stack()->pop(); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
274 PSParallelCompact::fill_and_update_region(this, region_index); |
0 | 275 } |
276 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
277 size_t region_index = -1; |
0 | 278 // obj is a reference!!! |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
279 while (region_stack()->pop_local(region_index)) { |
0 | 280 // It would be nice to assert about the type of objects we might |
281 // pop, but they can come from anywhere, unfortunately. | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
282 PSParallelCompact::fill_and_update_region(this, region_index); |
0 | 283 } |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
284 } while((region_stack()->size() != 0) || |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
285 (region_overflow_stack()->length() != 0)); |
0 | 286 #endif |
287 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
288 #ifdef USE_RegionTaskQueueWithOverflow |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
289 assert(region_stack()->is_empty(), "Sanity"); |
0 | 290 #else |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
291 assert(region_stack()->size() == 0, "Sanity"); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
0
diff
changeset
|
292 assert(region_overflow_stack()->length() == 0, "Sanity"); |
0 | 293 #endif |
294 #else | |
295 oop obj; | |
296 while (obj = retrieve_for_scanning()) { | |
297 obj->follow_contents(this); | |
298 } | |
299 #endif | |
300 } | |
301 | |
302 #ifdef ASSERT | |
303 bool ParCompactionManager::stacks_have_been_allocated() { | |
941 | 304 return (revisit_klass_stack()->data_addr() != NULL && |
305 revisit_mdo_stack()->data_addr() != NULL); | |
0 | 306 } |
307 #endif |