26 #include "incls/_psCompactionManager.cpp.incl" |
26 #include "incls/_psCompactionManager.cpp.incl" |
27 |
27 |
28 PSOldGen* ParCompactionManager::_old_gen = NULL; |
28 PSOldGen* ParCompactionManager::_old_gen = NULL; |
29 ParCompactionManager** ParCompactionManager::_manager_array = NULL; |
29 ParCompactionManager** ParCompactionManager::_manager_array = NULL; |
30 OopTaskQueueSet* ParCompactionManager::_stack_array = NULL; |
30 OopTaskQueueSet* ParCompactionManager::_stack_array = NULL; |
|
31 ParCompactionManager::ObjArrayTaskQueueSet* |
|
32 ParCompactionManager::_objarray_queues = NULL; |
31 ObjectStartArray* ParCompactionManager::_start_array = NULL; |
33 ObjectStartArray* ParCompactionManager::_start_array = NULL; |
32 ParMarkBitMap* ParCompactionManager::_mark_bitmap = NULL; |
34 ParMarkBitMap* ParCompactionManager::_mark_bitmap = NULL; |
33 RegionTaskQueueSet* ParCompactionManager::_region_array = NULL; |
35 RegionTaskQueueSet* ParCompactionManager::_region_array = NULL; |
34 |
36 |
35 ParCompactionManager::ParCompactionManager() : |
37 ParCompactionManager::ParCompactionManager() : |
44 |
46 |
45 marking_stack()->initialize(); |
47 marking_stack()->initialize(); |
46 |
48 |
47 // We want the overflow stack to be permanent |
49 // We want the overflow stack to be permanent |
48 _overflow_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(10, true); |
50 _overflow_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(10, true); |
|
51 |
|
52 _objarray_queue.initialize(); |
|
53 _objarray_overflow_stack = |
|
54 new (ResourceObj::C_HEAP) ObjArrayOverflowStack(10, true); |
|
55 |
49 #ifdef USE_RegionTaskQueueWithOverflow |
56 #ifdef USE_RegionTaskQueueWithOverflow |
50 region_stack()->initialize(); |
57 region_stack()->initialize(); |
51 #else |
58 #else |
52 region_stack()->initialize(); |
59 region_stack()->initialize(); |
53 |
60 |
67 |
74 |
68 } |
75 } |
69 |
76 |
70 ParCompactionManager::~ParCompactionManager() { |
77 ParCompactionManager::~ParCompactionManager() { |
71 delete _overflow_stack; |
78 delete _overflow_stack; |
|
79 delete _objarray_overflow_stack; |
72 delete _revisit_klass_stack; |
80 delete _revisit_klass_stack; |
73 delete _revisit_mdo_stack; |
81 delete _revisit_mdo_stack; |
74 // _manager_array and _stack_array are statics |
82 // _manager_array and _stack_array are statics |
75 // shared with all instances of ParCompactionManager |
83 // shared with all instances of ParCompactionManager |
76 // should not be deallocated. |
84 // should not be deallocated. |
84 |
92 |
85 uint parallel_gc_threads = PSParallelCompact::gc_task_manager()->workers(); |
93 uint parallel_gc_threads = PSParallelCompact::gc_task_manager()->workers(); |
86 |
94 |
87 assert(_manager_array == NULL, "Attempt to initialize twice"); |
95 assert(_manager_array == NULL, "Attempt to initialize twice"); |
88 _manager_array = NEW_C_HEAP_ARRAY(ParCompactionManager*, parallel_gc_threads+1 ); |
96 _manager_array = NEW_C_HEAP_ARRAY(ParCompactionManager*, parallel_gc_threads+1 ); |
89 guarantee(_manager_array != NULL, "Could not initialize promotion manager"); |
97 guarantee(_manager_array != NULL, "Could not allocate manager_array"); |
90 |
98 |
91 _stack_array = new OopTaskQueueSet(parallel_gc_threads); |
99 _stack_array = new OopTaskQueueSet(parallel_gc_threads); |
92 guarantee(_stack_array != NULL, "Count not initialize promotion manager"); |
100 guarantee(_stack_array != NULL, "Could not allocate stack_array"); |
|
101 _objarray_queues = new ObjArrayTaskQueueSet(parallel_gc_threads); |
|
102 guarantee(_objarray_queues != NULL, "Could not allocate objarray_queues"); |
93 _region_array = new RegionTaskQueueSet(parallel_gc_threads); |
103 _region_array = new RegionTaskQueueSet(parallel_gc_threads); |
94 guarantee(_region_array != NULL, "Count not initialize promotion manager"); |
104 guarantee(_region_array != NULL, "Could not allocate region_array"); |
95 |
105 |
96 // Create and register the ParCompactionManager(s) for the worker threads. |
106 // Create and register the ParCompactionManager(s) for the worker threads. |
97 for(uint i=0; i<parallel_gc_threads; i++) { |
107 for(uint i=0; i<parallel_gc_threads; i++) { |
98 _manager_array[i] = new ParCompactionManager(); |
108 _manager_array[i] = new ParCompactionManager(); |
99 guarantee(_manager_array[i] != NULL, "Could not create ParCompactionManager"); |
109 guarantee(_manager_array[i] != NULL, "Could not create ParCompactionManager"); |
100 stack_array()->register_queue(i, _manager_array[i]->marking_stack()); |
110 stack_array()->register_queue(i, _manager_array[i]->marking_stack()); |
|
111 _objarray_queues->register_queue(i, &_manager_array[i]->_objarray_queue); |
101 #ifdef USE_RegionTaskQueueWithOverflow |
112 #ifdef USE_RegionTaskQueueWithOverflow |
102 region_array()->register_queue(i, _manager_array[i]->region_stack()->task_queue()); |
113 region_array()->register_queue(i, _manager_array[i]->region_stack()->task_queue()); |
103 #else |
114 #else |
104 region_array()->register_queue(i, _manager_array[i]->region_stack()); |
115 region_array()->register_queue(i, _manager_array[i]->region_stack()); |
105 #endif |
116 #endif |
201 manager_array(i)->revisit_klass_stack()->clear(); |
212 manager_array(i)->revisit_klass_stack()->clear(); |
202 manager_array(i)->revisit_mdo_stack()->clear(); |
213 manager_array(i)->revisit_mdo_stack()->clear(); |
203 } |
214 } |
204 } |
215 } |
205 |
216 |
206 void ParCompactionManager::drain_marking_stacks(OopClosure* blk) { |
217 void ParCompactionManager::follow_marking_stacks() { |
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 { |
218 do { |
217 |
219 // Drain the overflow stack first, to allow stealing from the marking stack. |
218 // Drain overflow stack first, so other threads can steal from |
220 while (!overflow_stack()->is_empty()) { |
219 // claimed stack while we work. |
221 overflow_stack()->pop()->follow_contents(this); |
220 while(!overflow_stack()->is_empty()) { |
222 } |
221 oop obj = overflow_stack()->pop(); |
223 oop obj; |
|
224 while (marking_stack()->pop_local(obj)) { |
222 obj->follow_contents(this); |
225 obj->follow_contents(this); |
223 } |
226 } |
224 |
227 |
225 oop obj; |
228 ObjArrayTask task; |
226 // obj is a reference!!! |
229 while (!_objarray_overflow_stack->is_empty()) { |
227 while (marking_stack()->pop_local(obj)) { |
230 task = _objarray_overflow_stack->pop(); |
228 // It would be nice to assert about the type of objects we might |
231 objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint(); |
229 // pop, but they can come from anywhere, unfortunately. |
232 k->oop_follow_contents(this, task.obj(), task.index()); |
230 obj->follow_contents(this); |
233 } |
231 } |
234 while (_objarray_queue.pop_local(task)) { |
232 } while((marking_stack()->size() != 0) || (overflow_stack()->length() != 0)); |
235 objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint(); |
233 |
236 k->oop_follow_contents(this, task.obj(), task.index()); |
234 assert(marking_stack()->size() == 0, "Sanity"); |
237 } |
235 assert(overflow_stack()->length() == 0, "Sanity"); |
238 } while (!marking_stacks_empty()); |
|
239 |
|
240 assert(marking_stacks_empty(), "Sanity"); |
236 } |
241 } |
237 |
242 |
238 void ParCompactionManager::drain_region_overflow_stack() { |
243 void ParCompactionManager::drain_region_overflow_stack() { |
239 size_t region_index = (size_t) -1; |
244 size_t region_index = (size_t) -1; |
240 while(region_stack()->retrieve_from_overflow(region_index)) { |
245 while(region_stack()->retrieve_from_overflow(region_index)) { |