37 #include "oops/oop.pcgc.inline.hpp" |
37 #include "oops/oop.pcgc.inline.hpp" |
38 #include "utilities/stack.inline.hpp" |
38 #include "utilities/stack.inline.hpp" |
39 |
39 |
40 PSOldGen* ParCompactionManager::_old_gen = NULL; |
40 PSOldGen* ParCompactionManager::_old_gen = NULL; |
41 ParCompactionManager** ParCompactionManager::_manager_array = NULL; |
41 ParCompactionManager** ParCompactionManager::_manager_array = NULL; |
|
42 |
|
43 RegionTaskQueue** ParCompactionManager::_region_list = NULL; |
|
44 |
42 OopTaskQueueSet* ParCompactionManager::_stack_array = NULL; |
45 OopTaskQueueSet* ParCompactionManager::_stack_array = NULL; |
43 ParCompactionManager::ObjArrayTaskQueueSet* |
46 ParCompactionManager::ObjArrayTaskQueueSet* |
44 ParCompactionManager::_objarray_queues = NULL; |
47 ParCompactionManager::_objarray_queues = NULL; |
45 ObjectStartArray* ParCompactionManager::_start_array = NULL; |
48 ObjectStartArray* ParCompactionManager::_start_array = NULL; |
46 ParMarkBitMap* ParCompactionManager::_mark_bitmap = NULL; |
49 ParMarkBitMap* ParCompactionManager::_mark_bitmap = NULL; |
47 RegionTaskQueueSet* ParCompactionManager::_region_array = NULL; |
50 RegionTaskQueueSet* ParCompactionManager::_region_array = NULL; |
48 |
51 |
|
52 uint* ParCompactionManager::_recycled_stack_index = NULL; |
|
53 int ParCompactionManager::_recycled_top = -1; |
|
54 int ParCompactionManager::_recycled_bottom = -1; |
|
55 |
49 ParCompactionManager::ParCompactionManager() : |
56 ParCompactionManager::ParCompactionManager() : |
50 _action(CopyAndUpdate) { |
57 _action(CopyAndUpdate), |
|
58 _region_stack(NULL), |
|
59 _region_stack_index((uint)max_uintx) { |
51 |
60 |
52 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); |
61 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); |
53 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); |
62 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); |
54 |
63 |
55 _old_gen = heap->old_gen(); |
64 _old_gen = heap->old_gen(); |
56 _start_array = old_gen()->start_array(); |
65 _start_array = old_gen()->start_array(); |
57 |
66 |
58 marking_stack()->initialize(); |
67 marking_stack()->initialize(); |
59 _objarray_stack.initialize(); |
68 _objarray_stack.initialize(); |
60 region_stack()->initialize(); |
69 } |
|
70 |
|
71 ParCompactionManager::~ParCompactionManager() { |
|
72 delete _recycled_stack_index; |
61 } |
73 } |
62 |
74 |
63 void ParCompactionManager::initialize(ParMarkBitMap* mbm) { |
75 void ParCompactionManager::initialize(ParMarkBitMap* mbm) { |
64 assert(PSParallelCompact::gc_task_manager() != NULL, |
76 assert(PSParallelCompact::gc_task_manager() != NULL, |
65 "Needed for initialization"); |
77 "Needed for initialization"); |
69 uint parallel_gc_threads = PSParallelCompact::gc_task_manager()->workers(); |
81 uint parallel_gc_threads = PSParallelCompact::gc_task_manager()->workers(); |
70 |
82 |
71 assert(_manager_array == NULL, "Attempt to initialize twice"); |
83 assert(_manager_array == NULL, "Attempt to initialize twice"); |
72 _manager_array = NEW_C_HEAP_ARRAY(ParCompactionManager*, parallel_gc_threads+1 ); |
84 _manager_array = NEW_C_HEAP_ARRAY(ParCompactionManager*, parallel_gc_threads+1 ); |
73 guarantee(_manager_array != NULL, "Could not allocate manager_array"); |
85 guarantee(_manager_array != NULL, "Could not allocate manager_array"); |
|
86 |
|
87 _region_list = NEW_C_HEAP_ARRAY(RegionTaskQueue*, |
|
88 parallel_gc_threads+1); |
|
89 guarantee(_region_list != NULL, "Could not initialize promotion manager"); |
|
90 |
|
91 _recycled_stack_index = NEW_C_HEAP_ARRAY(uint, parallel_gc_threads); |
|
92 |
|
93 // parallel_gc-threads + 1 to be consistent with the number of |
|
94 // compaction managers. |
|
95 for(uint i=0; i<parallel_gc_threads + 1; i++) { |
|
96 _region_list[i] = new RegionTaskQueue(); |
|
97 region_list(i)->initialize(); |
|
98 } |
74 |
99 |
75 _stack_array = new OopTaskQueueSet(parallel_gc_threads); |
100 _stack_array = new OopTaskQueueSet(parallel_gc_threads); |
76 guarantee(_stack_array != NULL, "Could not allocate stack_array"); |
101 guarantee(_stack_array != NULL, "Could not allocate stack_array"); |
77 _objarray_queues = new ObjArrayTaskQueueSet(parallel_gc_threads); |
102 _objarray_queues = new ObjArrayTaskQueueSet(parallel_gc_threads); |
78 guarantee(_objarray_queues != NULL, "Could not allocate objarray_queues"); |
103 guarantee(_objarray_queues != NULL, "Could not allocate objarray_queues"); |
83 for(uint i=0; i<parallel_gc_threads; i++) { |
108 for(uint i=0; i<parallel_gc_threads; i++) { |
84 _manager_array[i] = new ParCompactionManager(); |
109 _manager_array[i] = new ParCompactionManager(); |
85 guarantee(_manager_array[i] != NULL, "Could not create ParCompactionManager"); |
110 guarantee(_manager_array[i] != NULL, "Could not create ParCompactionManager"); |
86 stack_array()->register_queue(i, _manager_array[i]->marking_stack()); |
111 stack_array()->register_queue(i, _manager_array[i]->marking_stack()); |
87 _objarray_queues->register_queue(i, &_manager_array[i]->_objarray_stack); |
112 _objarray_queues->register_queue(i, &_manager_array[i]->_objarray_stack); |
88 region_array()->register_queue(i, _manager_array[i]->region_stack()); |
113 region_array()->register_queue(i, region_list(i)); |
89 } |
114 } |
90 |
115 |
91 // The VMThread gets its own ParCompactionManager, which is not available |
116 // The VMThread gets its own ParCompactionManager, which is not available |
92 // for work stealing. |
117 // for work stealing. |
93 _manager_array[parallel_gc_threads] = new ParCompactionManager(); |
118 _manager_array[parallel_gc_threads] = new ParCompactionManager(); |
95 "Could not create ParCompactionManager"); |
120 "Could not create ParCompactionManager"); |
96 assert(PSParallelCompact::gc_task_manager()->workers() != 0, |
121 assert(PSParallelCompact::gc_task_manager()->workers() != 0, |
97 "Not initialized?"); |
122 "Not initialized?"); |
98 } |
123 } |
99 |
124 |
|
125 int ParCompactionManager::pop_recycled_stack_index() { |
|
126 assert(_recycled_bottom <= _recycled_top, "list is empty"); |
|
127 // Get the next available index |
|
128 if (_recycled_bottom < _recycled_top) { |
|
129 uint cur, next, last; |
|
130 do { |
|
131 cur = _recycled_bottom; |
|
132 next = cur + 1; |
|
133 last = Atomic::cmpxchg(next, &_recycled_bottom, cur); |
|
134 } while (cur != last); |
|
135 return _recycled_stack_index[next]; |
|
136 } else { |
|
137 return -1; |
|
138 } |
|
139 } |
|
140 |
|
141 void ParCompactionManager::push_recycled_stack_index(uint v) { |
|
142 // Get the next available index |
|
143 int cur = Atomic::add(1, &_recycled_top); |
|
144 _recycled_stack_index[cur] = v; |
|
145 assert(_recycled_bottom <= _recycled_top, "list top and bottom are wrong"); |
|
146 } |
|
147 |
100 bool ParCompactionManager::should_update() { |
148 bool ParCompactionManager::should_update() { |
101 assert(action() != NotValid, "Action is not set"); |
149 assert(action() != NotValid, "Action is not set"); |
102 return (action() == ParCompactionManager::Update) || |
150 return (action() == ParCompactionManager::Update) || |
103 (action() == ParCompactionManager::CopyAndUpdate) || |
151 (action() == ParCompactionManager::CopyAndUpdate) || |
104 (action() == ParCompactionManager::UpdateAndCopy); |
152 (action() == ParCompactionManager::UpdateAndCopy); |
117 } |
165 } |
118 |
166 |
119 bool ParCompactionManager::should_reset_only() { |
167 bool ParCompactionManager::should_reset_only() { |
120 assert(action() != NotValid, "Action is not set"); |
168 assert(action() != NotValid, "Action is not set"); |
121 return action() == ParCompactionManager::ResetObjects; |
169 return action() == ParCompactionManager::ResetObjects; |
|
170 } |
|
171 |
|
172 void ParCompactionManager::region_list_push(uint list_index, |
|
173 size_t region_index) { |
|
174 region_list(list_index)->push(region_index); |
|
175 } |
|
176 |
|
177 void ParCompactionManager::verify_region_list_empty(uint list_index) { |
|
178 assert(region_list(list_index)->is_empty(), "Not empty"); |
122 } |
179 } |
123 |
180 |
124 ParCompactionManager* |
181 ParCompactionManager* |
125 ParCompactionManager::gc_thread_compaction_manager(int index) { |
182 ParCompactionManager::gc_thread_compaction_manager(int index) { |
126 assert(index >= 0 && index < (int)ParallelGCThreads, "index out of range"); |
183 assert(index >= 0 && index < (int)ParallelGCThreads, "index out of range"); |