23 |
23 |
24 #ifndef SHARE_GC_Z_ZVALUE_HPP |
24 #ifndef SHARE_GC_Z_ZVALUE_HPP |
25 #define SHARE_GC_Z_ZVALUE_HPP |
25 #define SHARE_GC_Z_ZVALUE_HPP |
26 |
26 |
27 #include "memory/allocation.hpp" |
27 #include "memory/allocation.hpp" |
28 #include "gc/z/zCPU.hpp" |
28 #include "utilities/globalDefinitions.hpp" |
29 #include "gc/z/zGlobals.hpp" |
29 |
30 #include "gc/z/zNUMA.hpp" |
30 // |
31 #include "gc/z/zThread.hpp" |
31 // Storage |
32 #include "gc/z/zUtils.hpp" |
32 // |
33 #include "runtime/globals.hpp" |
|
34 #include "utilities/align.hpp" |
|
35 |
33 |
36 template <typename S> |
34 template <typename S> |
37 class ZValueStorage : public AllStatic { |
35 class ZValueStorage : public AllStatic { |
38 private: |
36 private: |
39 static uintptr_t _top; |
37 static uintptr_t _top; |
40 static uintptr_t _end; |
38 static uintptr_t _end; |
41 |
39 |
42 public: |
40 public: |
43 static const size_t offset = 4 * K; |
41 static const size_t offset = 4 * K; |
44 |
42 |
45 static uintptr_t alloc(size_t size) { |
43 static uintptr_t alloc(size_t size); |
46 guarantee(size <= offset, "Allocation too large"); |
|
47 |
|
48 // Allocate entry in existing memory block |
|
49 const uintptr_t addr = align_up(_top, S::alignment()); |
|
50 _top = addr + size; |
|
51 |
|
52 if (_top < _end) { |
|
53 // Success |
|
54 return addr; |
|
55 } |
|
56 |
|
57 // Allocate new block of memory |
|
58 const size_t block_alignment = offset; |
|
59 const size_t block_size = offset * S::count(); |
|
60 _top = ZUtils::alloc_aligned(block_alignment, block_size); |
|
61 _end = _top + offset; |
|
62 |
|
63 // Retry allocation |
|
64 return alloc(size); |
|
65 } |
|
66 }; |
44 }; |
67 |
|
68 template <typename T> uintptr_t ZValueStorage<T>::_end = 0; |
|
69 template <typename T> uintptr_t ZValueStorage<T>::_top = 0; |
|
70 |
45 |
71 class ZContendedStorage : public ZValueStorage<ZContendedStorage> { |
46 class ZContendedStorage : public ZValueStorage<ZContendedStorage> { |
72 public: |
47 public: |
73 static size_t alignment() { |
48 static size_t alignment(); |
74 return ZCacheLineSize; |
49 static uint32_t count(); |
75 } |
50 static uint32_t id(); |
76 |
|
77 static uint32_t count() { |
|
78 return 1; |
|
79 } |
|
80 |
|
81 static uint32_t id() { |
|
82 return 0; |
|
83 } |
|
84 }; |
51 }; |
85 |
52 |
86 class ZPerCPUStorage : public ZValueStorage<ZPerCPUStorage> { |
53 class ZPerCPUStorage : public ZValueStorage<ZPerCPUStorage> { |
87 public: |
54 public: |
88 static size_t alignment() { |
55 static size_t alignment(); |
89 return sizeof(uintptr_t); |
56 static uint32_t count(); |
90 } |
57 static uint32_t id(); |
91 |
|
92 static uint32_t count() { |
|
93 return ZCPU::count(); |
|
94 } |
|
95 |
|
96 static uint32_t id() { |
|
97 return ZCPU::id(); |
|
98 } |
|
99 }; |
58 }; |
100 |
59 |
101 class ZPerNUMAStorage : public ZValueStorage<ZPerNUMAStorage> { |
60 class ZPerNUMAStorage : public ZValueStorage<ZPerNUMAStorage> { |
102 public: |
61 public: |
103 static size_t alignment() { |
62 static size_t alignment(); |
104 return sizeof(uintptr_t); |
63 static uint32_t count(); |
105 } |
64 static uint32_t id(); |
106 |
|
107 static uint32_t count() { |
|
108 return ZNUMA::count(); |
|
109 } |
|
110 |
|
111 static uint32_t id() { |
|
112 return ZNUMA::id(); |
|
113 } |
|
114 }; |
65 }; |
115 |
66 |
116 class ZPerWorkerStorage : public ZValueStorage<ZPerWorkerStorage> { |
67 class ZPerWorkerStorage : public ZValueStorage<ZPerWorkerStorage> { |
117 public: |
68 public: |
118 static size_t alignment() { |
69 static size_t alignment(); |
119 return sizeof(uintptr_t); |
70 static uint32_t count(); |
120 } |
71 static uint32_t id(); |
121 |
|
122 static uint32_t count() { |
|
123 return MAX2(ParallelGCThreads, ConcGCThreads); |
|
124 } |
|
125 |
|
126 static uint32_t id() { |
|
127 return ZThread::worker_id(); |
|
128 } |
|
129 }; |
72 }; |
130 |
73 |
131 template <typename S, typename T> |
74 // |
132 class ZValueIterator; |
75 // Value |
|
76 // |
133 |
77 |
134 template <typename S, typename T> |
78 template <typename S, typename T> |
135 class ZValue : public CHeapObj<mtGC> { |
79 class ZValue : public CHeapObj<mtGC> { |
136 private: |
80 private: |
137 const uintptr_t _addr; |
81 const uintptr_t _addr; |
138 |
82 |
139 uintptr_t value_addr(uint32_t value_id) const { |
83 uintptr_t value_addr(uint32_t value_id) const; |
140 return _addr + (value_id * S::offset); |
|
141 } |
|
142 |
84 |
143 public: |
85 public: |
144 ZValue() : |
86 ZValue(); |
145 _addr(S::alloc(sizeof(T))) { |
87 ZValue(const T& value); |
146 // Initialize all instances |
|
147 ZValueIterator<S, T> iter(this); |
|
148 for (T* addr; iter.next(&addr);) { |
|
149 ::new (addr) T; |
|
150 } |
|
151 } |
|
152 |
88 |
153 ZValue(const T& value) : |
89 const T* addr(uint32_t value_id = S::id()) const; |
154 _addr(S::alloc(sizeof(T))) { |
90 T* addr(uint32_t value_id = S::id()); |
155 // Initialize all instances |
|
156 ZValueIterator<S, T> iter(this); |
|
157 for (T* addr; iter.next(&addr);) { |
|
158 ::new (addr) T(value); |
|
159 } |
|
160 } |
|
161 |
91 |
162 // Not implemented |
92 const T& get(uint32_t value_id = S::id()) const; |
163 ZValue(const ZValue<S, T>& value); |
93 T& get(uint32_t value_id = S::id()); |
164 ZValue<S, T>& operator=(const ZValue<S, T>& value); |
|
165 |
94 |
166 const T* addr(uint32_t value_id = S::id()) const { |
95 void set(const T& value, uint32_t value_id = S::id()); |
167 return reinterpret_cast<const T*>(value_addr(value_id)); |
96 void set_all(const T& value); |
168 } |
|
169 |
|
170 T* addr(uint32_t value_id = S::id()) { |
|
171 return reinterpret_cast<T*>(value_addr(value_id)); |
|
172 } |
|
173 |
|
174 const T& get(uint32_t value_id = S::id()) const { |
|
175 return *addr(value_id); |
|
176 } |
|
177 |
|
178 T& get(uint32_t value_id = S::id()) { |
|
179 return *addr(value_id); |
|
180 } |
|
181 |
|
182 void set(const T& value, uint32_t value_id = S::id()) { |
|
183 get(value_id) = value; |
|
184 } |
|
185 |
|
186 void set_all(const T& value) { |
|
187 ZValueIterator<S, T> iter(this); |
|
188 for (T* addr; iter.next(&addr);) { |
|
189 *addr = value; |
|
190 } |
|
191 } |
|
192 }; |
97 }; |
193 |
98 |
194 template <typename T> |
99 template <typename T> |
195 class ZContended : public ZValue<ZContendedStorage, T> { |
100 class ZContended : public ZValue<ZContendedStorage, T> { |
196 public: |
101 public: |
197 ZContended() : |
102 ZContended(); |
198 ZValue<ZContendedStorage, T>() {} |
103 ZContended(const T& value); |
199 |
|
200 ZContended(const T& value) : |
|
201 ZValue<ZContendedStorage, T>(value) {} |
|
202 |
|
203 using ZValue<ZContendedStorage, T>::operator=; |
|
204 }; |
104 }; |
205 |
105 |
206 template <typename T> |
106 template <typename T> |
207 class ZPerCPU : public ZValue<ZPerCPUStorage, T> { |
107 class ZPerCPU : public ZValue<ZPerCPUStorage, T> { |
208 public: |
108 public: |
209 ZPerCPU() : |
109 ZPerCPU(); |
210 ZValue<ZPerCPUStorage, T>() {} |
110 ZPerCPU(const T& value); |
211 |
|
212 ZPerCPU(const T& value) : |
|
213 ZValue<ZPerCPUStorage, T>(value) {} |
|
214 |
|
215 using ZValue<ZPerCPUStorage, T>::operator=; |
|
216 }; |
111 }; |
217 |
112 |
218 template <typename T> |
113 template <typename T> |
219 class ZPerNUMA : public ZValue<ZPerNUMAStorage, T> { |
114 class ZPerNUMA : public ZValue<ZPerNUMAStorage, T> { |
220 public: |
115 public: |
221 ZPerNUMA() : |
116 ZPerNUMA(); |
222 ZValue<ZPerNUMAStorage, T>() {} |
117 ZPerNUMA(const T& value); |
223 |
|
224 ZPerNUMA(const T& value) : |
|
225 ZValue<ZPerNUMAStorage, T>(value) {} |
|
226 |
|
227 using ZValue<ZPerNUMAStorage, T>::operator=; |
|
228 }; |
118 }; |
229 |
119 |
230 template <typename T> |
120 template <typename T> |
231 class ZPerWorker : public ZValue<ZPerWorkerStorage, T> { |
121 class ZPerWorker : public ZValue<ZPerWorkerStorage, T> { |
232 public: |
122 public: |
233 ZPerWorker() : |
123 ZPerWorker(); |
234 ZValue<ZPerWorkerStorage, T>() {} |
124 ZPerWorker(const T& value); |
|
125 }; |
235 |
126 |
236 ZPerWorker(const T& value) : |
127 // |
237 ZValue<ZPerWorkerStorage, T>(value) {} |
128 // Iterator |
238 |
129 // |
239 using ZValue<ZPerWorkerStorage, T>::operator=; |
|
240 }; |
|
241 |
130 |
242 template <typename S, typename T> |
131 template <typename S, typename T> |
243 class ZValueIterator { |
132 class ZValueIterator { |
244 private: |
133 private: |
245 ZValue<S, T>* const _value; |
134 ZValue<S, T>* const _value; |
246 uint32_t _value_id; |
135 uint32_t _value_id; |
247 |
136 |
248 public: |
137 public: |
249 ZValueIterator(ZValue<S, T>* value) : |
138 ZValueIterator(ZValue<S, T>* value); |
250 _value(value), |
|
251 _value_id(0) {} |
|
252 |
139 |
253 bool next(T** value) { |
140 bool next(T** value); |
254 if (_value_id < S::count()) { |
|
255 *value = _value->addr(_value_id++); |
|
256 return true; |
|
257 } |
|
258 return false; |
|
259 } |
|
260 }; |
141 }; |
261 |
142 |
262 template <typename T> |
143 template <typename T> |
263 class ZPerCPUIterator : public ZValueIterator<ZPerCPUStorage, T> { |
144 class ZPerCPUIterator : public ZValueIterator<ZPerCPUStorage, T> { |
264 public: |
145 public: |
265 ZPerCPUIterator(ZPerCPU<T>* value) : |
146 ZPerCPUIterator(ZPerCPU<T>* value); |
266 ZValueIterator<ZPerCPUStorage, T>(value) {} |
|
267 }; |
147 }; |
268 |
148 |
269 template <typename T> |
149 template <typename T> |
270 class ZPerNUMAIterator : public ZValueIterator<ZPerNUMAStorage, T> { |
150 class ZPerNUMAIterator : public ZValueIterator<ZPerNUMAStorage, T> { |
271 public: |
151 public: |
272 ZPerNUMAIterator(ZPerNUMA<T>* value) : |
152 ZPerNUMAIterator(ZPerNUMA<T>* value); |
273 ZValueIterator<ZPerNUMAStorage, T>(value) {} |
|
274 }; |
153 }; |
275 |
154 |
276 template <typename T> |
155 template <typename T> |
277 class ZPerWorkerIterator : public ZValueIterator<ZPerWorkerStorage, T> { |
156 class ZPerWorkerIterator : public ZValueIterator<ZPerWorkerStorage, T> { |
278 public: |
157 public: |
279 ZPerWorkerIterator(ZPerWorker<T>* value) : |
158 ZPerWorkerIterator(ZPerWorker<T>* value); |
280 ZValueIterator<ZPerWorkerStorage, T>(value) {} |
|
281 }; |
159 }; |
282 |
160 |
283 template <typename S, typename T> |
161 template <typename S, typename T> |
284 class ZValueConstIterator { |
162 class ZValueConstIterator { |
285 private: |
163 private: |
286 const ZValue<S, T>* const _value; |
164 const ZValue<S, T>* const _value; |
287 uint32_t _value_id; |
165 uint32_t _value_id; |
288 |
166 |
289 public: |
167 public: |
290 ZValueConstIterator(const ZValue<S, T>* value) : |
168 ZValueConstIterator(const ZValue<S, T>* value); |
291 _value(value), |
|
292 _value_id(0) {} |
|
293 |
169 |
294 bool next(const T** value) { |
170 bool next(const T** value); |
295 if (_value_id < S::count()) { |
|
296 *value = _value->addr(_value_id++); |
|
297 return true; |
|
298 } |
|
299 return false; |
|
300 } |
|
301 }; |
171 }; |
302 |
172 |
303 template <typename T> |
173 template <typename T> |
304 class ZPerCPUConstIterator : public ZValueConstIterator<ZPerCPUStorage, T> { |
174 class ZPerCPUConstIterator : public ZValueConstIterator<ZPerCPUStorage, T> { |
305 public: |
175 public: |
306 ZPerCPUConstIterator(const ZPerCPU<T>* value) : |
176 ZPerCPUConstIterator(const ZPerCPU<T>* value); |
307 ZValueConstIterator<ZPerCPUStorage, T>(value) {} |
|
308 }; |
177 }; |
309 |
178 |
310 template <typename T> |
179 template <typename T> |
311 class ZPerNUMAConstIterator : public ZValueConstIterator<ZPerNUMAStorage, T> { |
180 class ZPerNUMAConstIterator : public ZValueConstIterator<ZPerNUMAStorage, T> { |
312 public: |
181 public: |
313 ZPerNUMAConstIterator(const ZPerNUMA<T>* value) : |
182 ZPerNUMAConstIterator(const ZPerNUMA<T>* value); |
314 ZValueConstIterator<ZPerNUMAStorage, T>(value) {} |
|
315 }; |
183 }; |
316 |
184 |
317 template <typename T> |
185 template <typename T> |
318 class ZPerWorkerConstIterator : public ZValueConstIterator<ZPerWorkerStorage, T> { |
186 class ZPerWorkerConstIterator : public ZValueConstIterator<ZPerWorkerStorage, T> { |
319 public: |
187 public: |
320 ZPerWorkerConstIterator(const ZPerWorker<T>* value) : |
188 ZPerWorkerConstIterator(const ZPerWorker<T>* value); |
321 ZValueConstIterator<ZPerWorkerStorage, T>(value) {} |
|
322 }; |
189 }; |
323 |
190 |
324 #endif // SHARE_GC_Z_ZVALUE_HPP |
191 #endif // SHARE_GC_Z_ZVALUE_HPP |