1.1 --- a/src/share/vm/utilities/taskqueue.hpp Wed Jun 27 15:23:36 2012 +0200 1.2 +++ b/src/share/vm/utilities/taskqueue.hpp Thu Jun 28 17:03:16 2012 -0400 1.3 @@ -132,8 +132,8 @@ 1.4 } 1.5 #endif // TASKQUEUE_STATS 1.6 1.7 -template <unsigned int N> 1.8 -class TaskQueueSuper: public CHeapObj { 1.9 +template <unsigned int N, MEMFLAGS F> 1.10 +class TaskQueueSuper: public CHeapObj<F> { 1.11 protected: 1.12 // Internal type for indexing the queue; also used for the tag. 1.13 typedef NOT_LP64(uint16_t) LP64_ONLY(uint32_t) idx_t; 1.14 @@ -249,22 +249,27 @@ 1.15 TASKQUEUE_STATS_ONLY(TaskQueueStats stats;) 1.16 }; 1.17 1.18 -template<class E, unsigned int N = TASKQUEUE_SIZE> 1.19 -class GenericTaskQueue: public TaskQueueSuper<N> { 1.20 + 1.21 + 1.22 +template <class E, MEMFLAGS F, unsigned int N = TASKQUEUE_SIZE> 1.23 +class GenericTaskQueue: public TaskQueueSuper<N, F> { 1.24 protected: 1.25 - typedef typename TaskQueueSuper<N>::Age Age; 1.26 - typedef typename TaskQueueSuper<N>::idx_t idx_t; 1.27 + typedef typename TaskQueueSuper<N, F>::Age Age; 1.28 + typedef typename TaskQueueSuper<N, F>::idx_t idx_t; 1.29 1.30 - using TaskQueueSuper<N>::_bottom; 1.31 - using TaskQueueSuper<N>::_age; 1.32 - using TaskQueueSuper<N>::increment_index; 1.33 - using TaskQueueSuper<N>::decrement_index; 1.34 - using TaskQueueSuper<N>::dirty_size; 1.35 + using TaskQueueSuper<N, F>::_bottom; 1.36 + using TaskQueueSuper<N, F>::_age; 1.37 + using TaskQueueSuper<N, F>::increment_index; 1.38 + using TaskQueueSuper<N, F>::decrement_index; 1.39 + using TaskQueueSuper<N, F>::dirty_size; 1.40 1.41 public: 1.42 - using TaskQueueSuper<N>::max_elems; 1.43 - using TaskQueueSuper<N>::size; 1.44 - TASKQUEUE_STATS_ONLY(using TaskQueueSuper<N>::stats;) 1.45 + using TaskQueueSuper<N, F>::max_elems; 1.46 + using TaskQueueSuper<N, F>::size; 1.47 + 1.48 +#if TASKQUEUE_STATS 1.49 + using TaskQueueSuper<N, F>::stats; 1.50 +#endif 1.51 1.52 private: 1.53 // Slow paths for push, pop_local. (pop_global has no fast path.) 1.54 @@ -302,18 +307,18 @@ 1.55 volatile E* _elems; 1.56 }; 1.57 1.58 -template<class E, unsigned int N> 1.59 -GenericTaskQueue<E, N>::GenericTaskQueue() { 1.60 +template<class E, MEMFLAGS F, unsigned int N> 1.61 +GenericTaskQueue<E, F, N>::GenericTaskQueue() { 1.62 assert(sizeof(Age) == sizeof(size_t), "Depends on this."); 1.63 } 1.64 1.65 -template<class E, unsigned int N> 1.66 -void GenericTaskQueue<E, N>::initialize() { 1.67 - _elems = NEW_C_HEAP_ARRAY(E, N); 1.68 +template<class E, MEMFLAGS F, unsigned int N> 1.69 +void GenericTaskQueue<E, F, N>::initialize() { 1.70 + _elems = NEW_C_HEAP_ARRAY(E, N, F); 1.71 } 1.72 1.73 -template<class E, unsigned int N> 1.74 -void GenericTaskQueue<E, N>::oops_do(OopClosure* f) { 1.75 +template<class E, MEMFLAGS F, unsigned int N> 1.76 +void GenericTaskQueue<E, F, N>::oops_do(OopClosure* f) { 1.77 // tty->print_cr("START OopTaskQueue::oops_do"); 1.78 uint iters = size(); 1.79 uint index = _bottom; 1.80 @@ -329,8 +334,8 @@ 1.81 // tty->print_cr("END OopTaskQueue::oops_do"); 1.82 } 1.83 1.84 -template<class E, unsigned int N> 1.85 -bool GenericTaskQueue<E, N>::push_slow(E t, uint dirty_n_elems) { 1.86 +template<class E, MEMFLAGS F, unsigned int N> 1.87 +bool GenericTaskQueue<E, F, N>::push_slow(E t, uint dirty_n_elems) { 1.88 if (dirty_n_elems == N - 1) { 1.89 // Actually means 0, so do the push. 1.90 uint localBot = _bottom; 1.91 @@ -349,8 +354,8 @@ 1.92 // whenever the queue goes empty which it will do here if this thread 1.93 // gets the last task or in pop_global() if the queue wraps (top == 0 1.94 // and pop_global() succeeds, see pop_global()). 1.95 -template<class E, unsigned int N> 1.96 -bool GenericTaskQueue<E, N>::pop_local_slow(uint localBot, Age oldAge) { 1.97 +template<class E, MEMFLAGS F, unsigned int N> 1.98 +bool GenericTaskQueue<E, F, N>::pop_local_slow(uint localBot, Age oldAge) { 1.99 // This queue was observed to contain exactly one element; either this 1.100 // thread will claim it, or a competing "pop_global". In either case, 1.101 // the queue will be logically empty afterwards. Create a new Age value 1.102 @@ -382,8 +387,8 @@ 1.103 return false; 1.104 } 1.105 1.106 -template<class E, unsigned int N> 1.107 -bool GenericTaskQueue<E, N>::pop_global(E& t) { 1.108 +template<class E, MEMFLAGS F, unsigned int N> 1.109 +bool GenericTaskQueue<E, F, N>::pop_global(E& t) { 1.110 Age oldAge = _age.get(); 1.111 uint localBot = _bottom; 1.112 uint n_elems = size(localBot, oldAge.top()); 1.113 @@ -402,9 +407,9 @@ 1.114 return resAge == oldAge; 1.115 } 1.116 1.117 -template<class E, unsigned int N> 1.118 -GenericTaskQueue<E, N>::~GenericTaskQueue() { 1.119 - FREE_C_HEAP_ARRAY(E, _elems); 1.120 +template<class E, MEMFLAGS F, unsigned int N> 1.121 +GenericTaskQueue<E, F, N>::~GenericTaskQueue() { 1.122 + FREE_C_HEAP_ARRAY(E, _elems, F); 1.123 } 1.124 1.125 // OverflowTaskQueue is a TaskQueue that also includes an overflow stack for 1.126 @@ -418,12 +423,12 @@ 1.127 // Note that size() is not hidden--it returns the number of elements in the 1.128 // TaskQueue, and does not include the size of the overflow stack. This 1.129 // simplifies replacement of GenericTaskQueues with OverflowTaskQueues. 1.130 -template<class E, unsigned int N = TASKQUEUE_SIZE> 1.131 -class OverflowTaskQueue: public GenericTaskQueue<E, N> 1.132 +template<class E, MEMFLAGS F, unsigned int N = TASKQUEUE_SIZE> 1.133 +class OverflowTaskQueue: public GenericTaskQueue<E, F, N> 1.134 { 1.135 public: 1.136 - typedef Stack<E> overflow_t; 1.137 - typedef GenericTaskQueue<E, N> taskqueue_t; 1.138 + typedef Stack<E, F> overflow_t; 1.139 + typedef GenericTaskQueue<E, F, N> taskqueue_t; 1.140 1.141 TASKQUEUE_STATS_ONLY(using taskqueue_t::stats;) 1.142 1.143 @@ -445,8 +450,8 @@ 1.144 overflow_t _overflow_stack; 1.145 }; 1.146 1.147 -template <class E, unsigned int N> 1.148 -bool OverflowTaskQueue<E, N>::push(E t) 1.149 +template <class E, MEMFLAGS F, unsigned int N> 1.150 +bool OverflowTaskQueue<E, F, N>::push(E t) 1.151 { 1.152 if (!taskqueue_t::push(t)) { 1.153 overflow_stack()->push(t); 1.154 @@ -455,15 +460,15 @@ 1.155 return true; 1.156 } 1.157 1.158 -template <class E, unsigned int N> 1.159 -bool OverflowTaskQueue<E, N>::pop_overflow(E& t) 1.160 +template <class E, MEMFLAGS F, unsigned int N> 1.161 +bool OverflowTaskQueue<E, F, N>::pop_overflow(E& t) 1.162 { 1.163 if (overflow_empty()) return false; 1.164 t = overflow_stack()->pop(); 1.165 return true; 1.166 } 1.167 1.168 -class TaskQueueSetSuper: public CHeapObj { 1.169 +class TaskQueueSetSuper { 1.170 protected: 1.171 static int randomParkAndMiller(int* seed0); 1.172 public: 1.173 @@ -471,8 +476,11 @@ 1.174 virtual bool peek() = 0; 1.175 }; 1.176 1.177 -template<class T> 1.178 -class GenericTaskQueueSet: public TaskQueueSetSuper { 1.179 +template <MEMFLAGS F> class TaskQueueSetSuperImpl: public CHeapObj<F>, public TaskQueueSetSuper { 1.180 +}; 1.181 + 1.182 +template<class T, MEMFLAGS F> 1.183 +class GenericTaskQueueSet: public TaskQueueSetSuperImpl<F> { 1.184 private: 1.185 uint _n; 1.186 T** _queues; 1.187 @@ -482,7 +490,7 @@ 1.188 1.189 GenericTaskQueueSet(int n) : _n(n) { 1.190 typedef T* GenericTaskQueuePtr; 1.191 - _queues = NEW_C_HEAP_ARRAY(GenericTaskQueuePtr, n); 1.192 + _queues = NEW_C_HEAP_ARRAY(GenericTaskQueuePtr, n, F); 1.193 for (int i = 0; i < n; i++) { 1.194 _queues[i] = NULL; 1.195 } 1.196 @@ -506,19 +514,19 @@ 1.197 bool peek(); 1.198 }; 1.199 1.200 -template<class T> void 1.201 -GenericTaskQueueSet<T>::register_queue(uint i, T* q) { 1.202 +template<class T, MEMFLAGS F> void 1.203 +GenericTaskQueueSet<T, F>::register_queue(uint i, T* q) { 1.204 assert(i < _n, "index out of range."); 1.205 _queues[i] = q; 1.206 } 1.207 1.208 -template<class T> T* 1.209 -GenericTaskQueueSet<T>::queue(uint i) { 1.210 +template<class T, MEMFLAGS F> T* 1.211 +GenericTaskQueueSet<T, F>::queue(uint i) { 1.212 return _queues[i]; 1.213 } 1.214 1.215 -template<class T> bool 1.216 -GenericTaskQueueSet<T>::steal(uint queue_num, int* seed, E& t) { 1.217 +template<class T, MEMFLAGS F> bool 1.218 +GenericTaskQueueSet<T, F>::steal(uint queue_num, int* seed, E& t) { 1.219 for (uint i = 0; i < 2 * _n; i++) { 1.220 if (steal_best_of_2(queue_num, seed, t)) { 1.221 TASKQUEUE_STATS_ONLY(queue(queue_num)->stats.record_steal(true)); 1.222 @@ -529,8 +537,8 @@ 1.223 return false; 1.224 } 1.225 1.226 -template<class T> bool 1.227 -GenericTaskQueueSet<T>::steal_best_of_all(uint queue_num, int* seed, E& t) { 1.228 +template<class T, MEMFLAGS F> bool 1.229 +GenericTaskQueueSet<T, F>::steal_best_of_all(uint queue_num, int* seed, E& t) { 1.230 if (_n > 2) { 1.231 int best_k; 1.232 uint best_sz = 0; 1.233 @@ -553,11 +561,11 @@ 1.234 } 1.235 } 1.236 1.237 -template<class T> bool 1.238 -GenericTaskQueueSet<T>::steal_1_random(uint queue_num, int* seed, E& t) { 1.239 +template<class T, MEMFLAGS F> bool 1.240 +GenericTaskQueueSet<T, F>::steal_1_random(uint queue_num, int* seed, E& t) { 1.241 if (_n > 2) { 1.242 uint k = queue_num; 1.243 - while (k == queue_num) k = randomParkAndMiller(seed) % _n; 1.244 + while (k == queue_num) k = TaskQueueSetSuper::randomParkAndMiller(seed) % _n; 1.245 return _queues[2]->pop_global(t); 1.246 } else if (_n == 2) { 1.247 // Just try the other one. 1.248 @@ -569,13 +577,13 @@ 1.249 } 1.250 } 1.251 1.252 -template<class T> bool 1.253 -GenericTaskQueueSet<T>::steal_best_of_2(uint queue_num, int* seed, E& t) { 1.254 +template<class T, MEMFLAGS F> bool 1.255 +GenericTaskQueueSet<T, F>::steal_best_of_2(uint queue_num, int* seed, E& t) { 1.256 if (_n > 2) { 1.257 uint k1 = queue_num; 1.258 - while (k1 == queue_num) k1 = randomParkAndMiller(seed) % _n; 1.259 + while (k1 == queue_num) k1 = TaskQueueSetSuper::randomParkAndMiller(seed) % _n; 1.260 uint k2 = queue_num; 1.261 - while (k2 == queue_num || k2 == k1) k2 = randomParkAndMiller(seed) % _n; 1.262 + while (k2 == queue_num || k2 == k1) k2 = TaskQueueSetSuper::randomParkAndMiller(seed) % _n; 1.263 // Sample both and try the larger. 1.264 uint sz1 = _queues[k1]->size(); 1.265 uint sz2 = _queues[k2]->size(); 1.266 @@ -591,8 +599,8 @@ 1.267 } 1.268 } 1.269 1.270 -template<class T> 1.271 -bool GenericTaskQueueSet<T>::peek() { 1.272 +template<class T, MEMFLAGS F> 1.273 +bool GenericTaskQueueSet<T, F>::peek() { 1.274 // Try all the queues. 1.275 for (uint j = 0; j < _n; j++) { 1.276 if (_queues[j]->peek()) 1.277 @@ -602,7 +610,7 @@ 1.278 } 1.279 1.280 // When to terminate from the termination protocol. 1.281 -class TerminatorTerminator: public CHeapObj { 1.282 +class TerminatorTerminator: public CHeapObj<mtInternal> { 1.283 public: 1.284 virtual bool should_exit_termination() = 0; 1.285 }; 1.286 @@ -665,8 +673,8 @@ 1.287 #endif 1.288 }; 1.289 1.290 -template<class E, unsigned int N> inline bool 1.291 -GenericTaskQueue<E, N>::push(E t) { 1.292 +template<class E, MEMFLAGS F, unsigned int N> inline bool 1.293 +GenericTaskQueue<E, F, N>::push(E t) { 1.294 uint localBot = _bottom; 1.295 assert((localBot >= 0) && (localBot < N), "_bottom out of range."); 1.296 idx_t top = _age.top(); 1.297 @@ -683,8 +691,8 @@ 1.298 } 1.299 } 1.300 1.301 -template<class E, unsigned int N> inline bool 1.302 -GenericTaskQueue<E, N>::pop_local(E& t) { 1.303 +template<class E, MEMFLAGS F, unsigned int N> inline bool 1.304 +GenericTaskQueue<E, F, N>::pop_local(E& t) { 1.305 uint localBot = _bottom; 1.306 // This value cannot be N-1. That can only occur as a result of 1.307 // the assignment to bottom in this method. If it does, this method 1.308 @@ -715,8 +723,8 @@ 1.309 } 1.310 } 1.311 1.312 -typedef GenericTaskQueue<oop> OopTaskQueue; 1.313 -typedef GenericTaskQueueSet<OopTaskQueue> OopTaskQueueSet; 1.314 +typedef GenericTaskQueue<oop, mtGC> OopTaskQueue; 1.315 +typedef GenericTaskQueueSet<OopTaskQueue, mtGC> OopTaskQueueSet; 1.316 1.317 #ifdef _MSC_VER 1.318 #pragma warning(push) 1.319 @@ -796,11 +804,11 @@ 1.320 #pragma warning(pop) 1.321 #endif 1.322 1.323 -typedef OverflowTaskQueue<StarTask> OopStarTaskQueue; 1.324 -typedef GenericTaskQueueSet<OopStarTaskQueue> OopStarTaskQueueSet; 1.325 +typedef OverflowTaskQueue<StarTask, mtClass> OopStarTaskQueue; 1.326 +typedef GenericTaskQueueSet<OopStarTaskQueue, mtClass> OopStarTaskQueueSet; 1.327 1.328 -typedef OverflowTaskQueue<size_t> RegionTaskQueue; 1.329 -typedef GenericTaskQueueSet<RegionTaskQueue> RegionTaskQueueSet; 1.330 +typedef OverflowTaskQueue<size_t, mtInternal> RegionTaskQueue; 1.331 +typedef GenericTaskQueueSet<RegionTaskQueue, mtClass> RegionTaskQueueSet; 1.332 1.333 1.334 #endif // SHARE_VM_UTILITIES_TASKQUEUE_HPP