7 *
8 * This code is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
25 #define SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
26
27 #include "memory/space.hpp"
28 #include "gc_implementation/shenandoah/shenandoahAllocRequest.hpp"
29 #include "gc_implementation/shenandoah/shenandoahAsserts.hpp"
30 #include "gc_implementation/shenandoah/shenandoahHeap.hpp"
31 #include "gc_implementation/shenandoah/shenandoahPacer.hpp"
32
33 class VMStructs;
34
35 class ShenandoahHeapRegion : public ContiguousSpace {
36 friend class VMStructs;
37 private:
38 /*
39 Region state is described by a state machine. Transitions are guarded by
40 heap lock, which allows changing the state of several regions atomically.
41 Region states can be logically aggregated in groups.
42
43 "Empty":
44 .................................................................
45 . .
46 . .
47 . Uncommitted <------- Committed <------------------------\
48 . | | . |
49 . \---------v-----------/ . |
50 . | . |
51 .........................|....................................... |
52 | |
53 "Active": | |
54 .........................|....................................... |
55 . | . |
195 RegionState state() const { return _state; }
196 int state_ordinal() const { return region_state_to_ordinal(_state); }
197
198 void record_pin();
199 void record_unpin();
200 size_t pin_count() const;
201
202 private:
203 static size_t RegionCount;
204 static size_t RegionSizeBytes;
205 static size_t RegionSizeWords;
206 static size_t RegionSizeBytesShift;
207 static size_t RegionSizeWordsShift;
208 static size_t RegionSizeBytesMask;
209 static size_t RegionSizeWordsMask;
210 static size_t HumongousThresholdBytes;
211 static size_t HumongousThresholdWords;
212 static size_t MaxTLABSizeBytes;
213 static size_t MaxTLABSizeWords;
214
215 // Global allocation counter, increased for each allocation under Shenandoah heap lock.
216 // Padded to avoid false sharing with the read-only fields above.
217 struct PaddedAllocSeqNum {
218 char _pad0[DEFAULT_CACHE_LINE_SIZE];
219 uint64_t value;
220 char _pad1[DEFAULT_CACHE_LINE_SIZE];
221
222 PaddedAllocSeqNum() {
223 // start with 1, reserve 0 for uninitialized value
224 value = 1;
225 }
226 };
227
228 static PaddedAllocSeqNum _alloc_seq_num;
229
230 // Never updated fields
231 ShenandoahHeap* _heap;
232 MemRegion _reserved;
233 size_t _region_number;
234
235 // Rarely updated fields
236 HeapWord* _new_top;
237 double _empty_time;
238
239 // Seldom updated fields
240 RegionState _state;
241
242 // Frequently updated fields
243 size_t _tlab_allocs;
244 size_t _gclab_allocs;
245 size_t _shared_allocs;
246
247 uint64_t _seqnum_first_alloc_mutator;
248 uint64_t _seqnum_first_alloc_gc;
249 uint64_t _seqnum_last_alloc_mutator;
250 uint64_t _seqnum_last_alloc_gc;
251
252 volatile jint _live_data;
253 volatile jint _critical_pins;
254
255 // Claim some space at the end to protect next region
256 char _pad0[DEFAULT_CACHE_LINE_SIZE];
257
258 public:
259 ShenandoahHeapRegion(ShenandoahHeap* heap, HeapWord* start, size_t size_words, size_t index, bool committed);
260
261 static const size_t MIN_NUM_REGIONS = 10;
262
263 static void setup_sizes(size_t max_heap_size);
264
265 double empty_time() {
266 return _empty_time;
267 }
268
269 inline static size_t required_regions(size_t bytes) {
270 return (bytes + ShenandoahHeapRegion::region_size_bytes() - 1) >> ShenandoahHeapRegion::region_size_bytes_shift();
271 }
272
273 inline static size_t region_count() {
274 return ShenandoahHeapRegion::RegionCount;
275 }
276
277 inline static size_t region_size_bytes() {
278 return ShenandoahHeapRegion::RegionSizeBytes;
279 }
321 assert (ShenandoahHeapRegion::RegionSizeWordsShift <= (size_t)max_jint, "sanity");
322 return (jint)ShenandoahHeapRegion::RegionSizeWordsShift;
323 }
324
325 inline static size_t humongous_threshold_bytes() {
326 return ShenandoahHeapRegion::HumongousThresholdBytes;
327 }
328
329 inline static size_t humongous_threshold_words() {
330 return ShenandoahHeapRegion::HumongousThresholdWords;
331 }
332
333 inline static size_t max_tlab_size_bytes() {
334 return ShenandoahHeapRegion::MaxTLABSizeBytes;
335 }
336
337 inline static size_t max_tlab_size_words() {
338 return ShenandoahHeapRegion::MaxTLABSizeWords;
339 }
340
341 static uint64_t seqnum_current_alloc() {
342 // Last used seq number
343 return _alloc_seq_num.value - 1;
344 }
345
346 size_t region_number() const;
347
348 // Allocation (return NULL if full)
349 inline HeapWord* allocate(size_t word_size, ShenandoahAllocRequest::Type type);
350
351 HeapWord* allocate(size_t word_size) shenandoah_not_implemented_return(NULL)
352
353 void clear_live_data();
354 void set_live_data(size_t s);
355
356 // Increase live data for newly allocated region
357 inline void increase_live_data_alloc_words(size_t s);
358
359 // Increase live data for region scanned with GC
360 inline void increase_live_data_gc_words(size_t s);
361
362 bool has_live() const;
363 size_t get_live_data_bytes() const;
364 size_t get_live_data_words() const;
365
366 void print_on(outputStream* st) const;
367
368 size_t garbage() const;
369
370 void recycle();
371
372 void oop_iterate_skip_unreachable(ExtendedOopClosure* cl, bool skip_unreachable_objects) shenandoah_not_implemented;
373 HeapWord* object_iterate_careful(ObjectClosureCareful* cl) shenandoah_not_implemented_return(NULL);
374
375 HeapWord* block_start_const(const void* p) const;
376
377 bool in_collection_set() const;
378
379 // Find humongous start region that this region belongs to
380 ShenandoahHeapRegion* humongous_start_region() const;
381
382 void set_new_top(HeapWord* new_top) { _new_top = new_top; }
383 HeapWord* new_top() const { return _new_top; }
384
385 inline void adjust_alloc_metadata(ShenandoahAllocRequest::Type type, size_t);
386 void reset_alloc_metadata_to_shared();
387 void reset_alloc_metadata();
388 size_t get_shared_allocs() const;
389 size_t get_tlab_allocs() const;
390 size_t get_gclab_allocs() const;
391
392 uint64_t seqnum_first_alloc() const {
393 if (_seqnum_first_alloc_mutator == 0) return _seqnum_first_alloc_gc;
394 if (_seqnum_first_alloc_gc == 0) return _seqnum_first_alloc_mutator;
395 return MIN2(_seqnum_first_alloc_mutator, _seqnum_first_alloc_gc);
396 }
397
398 uint64_t seqnum_last_alloc() const {
399 return MAX2(_seqnum_last_alloc_mutator, _seqnum_last_alloc_gc);
400 }
401
402 uint64_t seqnum_first_alloc_mutator() const {
403 return _seqnum_first_alloc_mutator;
404 }
405
406 uint64_t seqnum_last_alloc_mutator() const {
407 return _seqnum_last_alloc_mutator;
408 }
409
410 uint64_t seqnum_first_alloc_gc() const {
411 return _seqnum_first_alloc_gc;
412 }
413
414 uint64_t seqnum_last_alloc_gc() const {
415 return _seqnum_last_alloc_gc;
416 }
417
418 private:
419 void do_commit();
420 void do_uncommit();
421
422 inline void internal_increase_live_data(size_t s);
423 };
424
425 #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
|
7 *
8 * This code is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
25 #define SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
26
27 #include "gc_implementation/shenandoah/shenandoahAllocRequest.hpp"
28 #include "gc_implementation/shenandoah/shenandoahAsserts.hpp"
29 #include "gc_implementation/shenandoah/shenandoahHeap.hpp"
30 #include "gc_implementation/shenandoah/shenandoahPacer.hpp"
31 #include "gc_implementation/shenandoah/shenandoahPadding.hpp"
32
33 class VMStructs;
34
35 class ShenandoahHeapRegion {
36 friend class VMStructs;
37 private:
38 /*
39 Region state is described by a state machine. Transitions are guarded by
40 heap lock, which allows changing the state of several regions atomically.
41 Region states can be logically aggregated in groups.
42
43 "Empty":
44 .................................................................
45 . .
46 . .
47 . Uncommitted <------- Committed <------------------------\
48 . | | . |
49 . \---------v-----------/ . |
50 . | . |
51 .........................|....................................... |
52 | |
53 "Active": | |
54 .........................|....................................... |
55 . | . |
195 RegionState state() const { return _state; }
196 int state_ordinal() const { return region_state_to_ordinal(_state); }
197
198 void record_pin();
199 void record_unpin();
200 size_t pin_count() const;
201
202 private:
203 static size_t RegionCount;
204 static size_t RegionSizeBytes;
205 static size_t RegionSizeWords;
206 static size_t RegionSizeBytesShift;
207 static size_t RegionSizeWordsShift;
208 static size_t RegionSizeBytesMask;
209 static size_t RegionSizeWordsMask;
210 static size_t HumongousThresholdBytes;
211 static size_t HumongousThresholdWords;
212 static size_t MaxTLABSizeBytes;
213 static size_t MaxTLABSizeWords;
214
215 // Never updated fields
216 size_t const _index;
217 HeapWord* const _bottom;
218 HeapWord* const _end;
219
220 // Rarely updated fields
221 HeapWord* _new_top;
222 double _empty_time;
223
224 // Seldom updated fields
225 RegionState _state;
226
227 // Frequently updated fields
228 HeapWord* _top;
229
230 size_t _tlab_allocs;
231 size_t _gclab_allocs;
232
233 volatile jint _live_data;
234 volatile jint _critical_pins;
235
236 HeapWord* volatile _update_watermark;
237
238 public:
239 ShenandoahHeapRegion(HeapWord* start, size_t index, bool committed);
240
241 static const size_t MIN_NUM_REGIONS = 10;
242
243 static void setup_sizes(size_t max_heap_size);
244
245 double empty_time() {
246 return _empty_time;
247 }
248
249 inline static size_t required_regions(size_t bytes) {
250 return (bytes + ShenandoahHeapRegion::region_size_bytes() - 1) >> ShenandoahHeapRegion::region_size_bytes_shift();
251 }
252
253 inline static size_t region_count() {
254 return ShenandoahHeapRegion::RegionCount;
255 }
256
257 inline static size_t region_size_bytes() {
258 return ShenandoahHeapRegion::RegionSizeBytes;
259 }
301 assert (ShenandoahHeapRegion::RegionSizeWordsShift <= (size_t)max_jint, "sanity");
302 return (jint)ShenandoahHeapRegion::RegionSizeWordsShift;
303 }
304
305 inline static size_t humongous_threshold_bytes() {
306 return ShenandoahHeapRegion::HumongousThresholdBytes;
307 }
308
309 inline static size_t humongous_threshold_words() {
310 return ShenandoahHeapRegion::HumongousThresholdWords;
311 }
312
313 inline static size_t max_tlab_size_bytes() {
314 return ShenandoahHeapRegion::MaxTLABSizeBytes;
315 }
316
317 inline static size_t max_tlab_size_words() {
318 return ShenandoahHeapRegion::MaxTLABSizeWords;
319 }
320
321 inline size_t index() const {
322 return _index;
323 }
324
325 // Allocation (return NULL if full)
326 inline HeapWord* allocate(size_t word_size, ShenandoahAllocRequest::Type type);
327
328 inline void clear_live_data();
329 void set_live_data(size_t s);
330
331 // Increase live data for newly allocated region
332 inline void increase_live_data_alloc_words(size_t s);
333
334 // Increase live data for region scanned with GC
335 inline void increase_live_data_gc_words(size_t s);
336
337 inline bool has_live() const;
338 inline size_t get_live_data_bytes() const;
339 inline size_t get_live_data_words() const;
340
341 inline size_t garbage() const;
342
343 void print_on(outputStream* st) const;
344
345 void recycle();
346
347 HeapWord* block_start(const void* p) const;
348 size_t block_size(const HeapWord* p) const;
349 bool block_is_obj(const HeapWord* p) const { return p < top(); }
350
351 // Find humongous start region that this region belongs to
352 ShenandoahHeapRegion* humongous_start_region() const;
353
354 HeapWord* top() const { return _top; }
355 void set_top(HeapWord* v) { _top = v; }
356
357 HeapWord* new_top() const { return _new_top; }
358 void set_new_top(HeapWord* v) { _new_top = v; }
359
360 HeapWord* bottom() const { return _bottom; }
361 HeapWord* end() const { return _end; }
362
363 size_t capacity() const { return byte_size(bottom(), end()); }
364 size_t used() const { return byte_size(bottom(), top()); }
365 size_t free() const { return byte_size(top(), end()); }
366
367 inline void adjust_alloc_metadata(ShenandoahAllocRequest::Type type, size_t);
368 void reset_alloc_metadata();
369 size_t get_shared_allocs() const;
370 size_t get_tlab_allocs() const;
371 size_t get_gclab_allocs() const;
372
373 inline HeapWord* get_update_watermark() const;
374 inline void set_update_watermark(HeapWord* w);
375 inline void set_update_watermark_at_safepoint(HeapWord* w);
376
377 private:
378 void do_commit();
379 void do_uncommit();
380
381 inline void internal_increase_live_data(size_t s);
382 };
383
384 #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
|