Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp @ 4095:bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
Summary: Select number of GC threads dynamically based on heap usage and number of Java threads
Reviewed-by: johnc, ysr, jcoomes
author | jmasa |
---|---|
date | Tue, 09 Aug 2011 10:16:01 -0700 |
parents | f95d63e2154a |
children | 7913e93dca52 |
comparison
equal
deleted
inserted
replaced
4094:3a298e04d914 | 4095:bca17e38de00 |
---|---|
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"); |