20 * questions.
21 *
22 */
23
24 #include "precompiled.hpp"
25
26 #include "memory/allocation.hpp"
27 #include "gc_implementation/shared/spaceDecorator.hpp"
28 #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp"
29 #include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp"
30 #include "gc_implementation/shenandoah/shenandoahMarkingContext.inline.hpp"
31 #include "jfr/jfrEvents.hpp"
32 #include "memory/space.inline.hpp"
33 #include "memory/resourceArea.hpp"
34 #include "memory/universe.hpp"
35 #include "oops/oop.inline.hpp"
36 #include "runtime/java.hpp"
37 #include "runtime/mutexLocker.hpp"
38 #include "runtime/os.hpp"
39 #include "runtime/safepoint.hpp"
40
41 size_t ShenandoahHeapRegion::RegionCount = 0;
42 size_t ShenandoahHeapRegion::RegionSizeBytes = 0;
43 size_t ShenandoahHeapRegion::RegionSizeWords = 0;
44 size_t ShenandoahHeapRegion::RegionSizeBytesShift = 0;
45 size_t ShenandoahHeapRegion::RegionSizeWordsShift = 0;
46 size_t ShenandoahHeapRegion::RegionSizeBytesMask = 0;
47 size_t ShenandoahHeapRegion::RegionSizeWordsMask = 0;
48 size_t ShenandoahHeapRegion::HumongousThresholdBytes = 0;
49 size_t ShenandoahHeapRegion::HumongousThresholdWords = 0;
50 size_t ShenandoahHeapRegion::MaxTLABSizeBytes = 0;
51 size_t ShenandoahHeapRegion::MaxTLABSizeWords = 0;
52
53 ShenandoahHeapRegion::ShenandoahHeapRegion(HeapWord* start, size_t index, bool committed) :
54 _index(index),
55 _bottom(start),
56 _end(start + RegionSizeWords),
57 _new_top(NULL),
58 _empty_time(os::elapsedTime()),
59 _state(committed ? _empty_committed : _empty_uncommitted),
503 byte_size_in_proper_unit<size_t>(ShenandoahMinRegionSize),
504 proper_unit_for_byte_size(ShenandoahMinRegionSize));
505 vm_exit_during_initialization("Invalid -XX:ShenandoahRegionSize option", message);
506 }
507 if (ShenandoahRegionSize > ShenandoahMaxRegionSize) {
508 err_msg message("Heap region size (" SIZE_FORMAT "%s) should be lower than max region size (" SIZE_FORMAT "%s).",
509 byte_size_in_proper_unit<size_t>(ShenandoahRegionSize),
510 proper_unit_for_byte_size(ShenandoahRegionSize),
511 byte_size_in_proper_unit<size_t>(ShenandoahMaxRegionSize),
512 proper_unit_for_byte_size(ShenandoahMaxRegionSize));
513 vm_exit_during_initialization("Invalid -XX:ShenandoahRegionSize option", message);
514 }
515 region_size = ShenandoahRegionSize;
516 }
517
518 if (1 > ShenandoahHumongousThreshold || ShenandoahHumongousThreshold > 100) {
519 vm_exit_during_initialization("Invalid -XX:ShenandoahHumongousThreshold option, should be within [1..100]");
520 }
521
522 // Make sure region size is at least one large page, if enabled.
523 // Otherwise, uncommitting one region may falsely uncommit the adjacent
524 // regions too.
525 // Also see shenandoahArguments.cpp, where it handles UseLargePages.
526 if (UseLargePages && ShenandoahUncommit) {
527 region_size = MAX2(region_size, os::large_page_size());
528 }
529
530 int region_size_log = log2_long((jlong) region_size);
531 // Recalculate the region size to make sure it's a power of
532 // 2. This means that region_size is the largest power of 2 that's
533 // <= what we've calculated so far.
534 region_size = size_t(1) << region_size_log;
535
536 // Now, set up the globals.
537 guarantee(RegionSizeBytesShift == 0, "we should only set it once");
538 RegionSizeBytesShift = (size_t)region_size_log;
539
540 guarantee(RegionSizeWordsShift == 0, "we should only set it once");
541 RegionSizeWordsShift = RegionSizeBytesShift - LogHeapWordSize;
542
543 guarantee(RegionSizeBytes == 0, "we should only set it once");
544 RegionSizeBytes = region_size;
545 RegionSizeWords = RegionSizeBytes >> LogHeapWordSize;
546 assert (RegionSizeWords*HeapWordSize == RegionSizeBytes, "sanity");
547
548 guarantee(RegionSizeWordsMask == 0, "we should only set it once");
549 RegionSizeWordsMask = RegionSizeWords - 1;
550
551 guarantee(RegionSizeBytesMask == 0, "we should only set it once");
552 RegionSizeBytesMask = RegionSizeBytes - 1;
553
554 guarantee(RegionCount == 0, "we should only set it once");
555 RegionCount = max_heap_size / RegionSizeBytes;
556
557 guarantee(HumongousThresholdWords == 0, "we should only set it once");
558 HumongousThresholdWords = RegionSizeWords * ShenandoahHumongousThreshold / 100;
559 HumongousThresholdWords = (size_t)align_size_down(HumongousThresholdWords, MinObjAlignment);
560 assert (HumongousThresholdWords <= RegionSizeWords, "sanity");
561
562 guarantee(HumongousThresholdBytes == 0, "we should only set it once");
563 HumongousThresholdBytes = HumongousThresholdWords * HeapWordSize;
564 assert (HumongousThresholdBytes <= RegionSizeBytes, "sanity");
565
566 // The rationale for trimming the TLAB sizes has to do with the raciness in
567 // TLAB allocation machinery. It may happen that TLAB sizing policy polls Shenandoah
568 // about next free size, gets the answer for region #N, goes away for a while, then
569 // tries to allocate in region #N, and fail because some other thread have claimed part
570 // of the region #N, and then the freeset allocation code has to retire the region #N,
571 // before moving the allocation to region #N+1.
572 //
573 // The worst case realizes when "answer" is "region size", which means it could
574 // prematurely retire an entire region. Having smaller TLABs does not fix that
575 // completely, but reduces the probability of too wasteful region retirement.
|
20 * questions.
21 *
22 */
23
24 #include "precompiled.hpp"
25
26 #include "memory/allocation.hpp"
27 #include "gc_implementation/shared/spaceDecorator.hpp"
28 #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp"
29 #include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp"
30 #include "gc_implementation/shenandoah/shenandoahMarkingContext.inline.hpp"
31 #include "jfr/jfrEvents.hpp"
32 #include "memory/space.inline.hpp"
33 #include "memory/resourceArea.hpp"
34 #include "memory/universe.hpp"
35 #include "oops/oop.inline.hpp"
36 #include "runtime/java.hpp"
37 #include "runtime/mutexLocker.hpp"
38 #include "runtime/os.hpp"
39 #include "runtime/safepoint.hpp"
40 #include "utilities/align.hpp"
41
42 size_t ShenandoahHeapRegion::RegionCount = 0;
43 size_t ShenandoahHeapRegion::RegionSizeBytes = 0;
44 size_t ShenandoahHeapRegion::RegionSizeWords = 0;
45 size_t ShenandoahHeapRegion::RegionSizeBytesShift = 0;
46 size_t ShenandoahHeapRegion::RegionSizeWordsShift = 0;
47 size_t ShenandoahHeapRegion::RegionSizeBytesMask = 0;
48 size_t ShenandoahHeapRegion::RegionSizeWordsMask = 0;
49 size_t ShenandoahHeapRegion::HumongousThresholdBytes = 0;
50 size_t ShenandoahHeapRegion::HumongousThresholdWords = 0;
51 size_t ShenandoahHeapRegion::MaxTLABSizeBytes = 0;
52 size_t ShenandoahHeapRegion::MaxTLABSizeWords = 0;
53
54 ShenandoahHeapRegion::ShenandoahHeapRegion(HeapWord* start, size_t index, bool committed) :
55 _index(index),
56 _bottom(start),
57 _end(start + RegionSizeWords),
58 _new_top(NULL),
59 _empty_time(os::elapsedTime()),
60 _state(committed ? _empty_committed : _empty_uncommitted),
504 byte_size_in_proper_unit<size_t>(ShenandoahMinRegionSize),
505 proper_unit_for_byte_size(ShenandoahMinRegionSize));
506 vm_exit_during_initialization("Invalid -XX:ShenandoahRegionSize option", message);
507 }
508 if (ShenandoahRegionSize > ShenandoahMaxRegionSize) {
509 err_msg message("Heap region size (" SIZE_FORMAT "%s) should be lower than max region size (" SIZE_FORMAT "%s).",
510 byte_size_in_proper_unit<size_t>(ShenandoahRegionSize),
511 proper_unit_for_byte_size(ShenandoahRegionSize),
512 byte_size_in_proper_unit<size_t>(ShenandoahMaxRegionSize),
513 proper_unit_for_byte_size(ShenandoahMaxRegionSize));
514 vm_exit_during_initialization("Invalid -XX:ShenandoahRegionSize option", message);
515 }
516 region_size = ShenandoahRegionSize;
517 }
518
519 if (1 > ShenandoahHumongousThreshold || ShenandoahHumongousThreshold > 100) {
520 vm_exit_during_initialization("Invalid -XX:ShenandoahHumongousThreshold option, should be within [1..100]");
521 }
522
523 // Make sure region size is at least one large page, if enabled.
524 // The heap sizes would be rounded by heap initialization code by
525 // page size, so we need to round up the region size too, to cover
526 // the heap exactly.
527 if (UseLargePages) {
528 region_size = MAX2(region_size, os::large_page_size());
529 }
530
531 int region_size_log = log2_long((jlong) region_size);
532 // Recalculate the region size to make sure it's a power of
533 // 2. This means that region_size is the largest power of 2 that's
534 // <= what we've calculated so far.
535 region_size = size_t(1) << region_size_log;
536
537 // Now, set up the globals.
538 guarantee(RegionSizeBytesShift == 0, "we should only set it once");
539 RegionSizeBytesShift = (size_t)region_size_log;
540
541 guarantee(RegionSizeWordsShift == 0, "we should only set it once");
542 RegionSizeWordsShift = RegionSizeBytesShift - LogHeapWordSize;
543
544 guarantee(RegionSizeBytes == 0, "we should only set it once");
545 RegionSizeBytes = region_size;
546 RegionSizeWords = RegionSizeBytes >> LogHeapWordSize;
547 assert (RegionSizeWords*HeapWordSize == RegionSizeBytes, "sanity");
548
549 guarantee(RegionSizeWordsMask == 0, "we should only set it once");
550 RegionSizeWordsMask = RegionSizeWords - 1;
551
552 guarantee(RegionSizeBytesMask == 0, "we should only set it once");
553 RegionSizeBytesMask = RegionSizeBytes - 1;
554
555 guarantee(RegionCount == 0, "we should only set it once");
556 RegionCount = align_up(max_heap_size, RegionSizeBytes) / RegionSizeBytes;
557
558 guarantee(HumongousThresholdWords == 0, "we should only set it once");
559 HumongousThresholdWords = RegionSizeWords * ShenandoahHumongousThreshold / 100;
560 HumongousThresholdWords = (size_t)align_size_down(HumongousThresholdWords, MinObjAlignment);
561 assert (HumongousThresholdWords <= RegionSizeWords, "sanity");
562
563 guarantee(HumongousThresholdBytes == 0, "we should only set it once");
564 HumongousThresholdBytes = HumongousThresholdWords * HeapWordSize;
565 assert (HumongousThresholdBytes <= RegionSizeBytes, "sanity");
566
567 // The rationale for trimming the TLAB sizes has to do with the raciness in
568 // TLAB allocation machinery. It may happen that TLAB sizing policy polls Shenandoah
569 // about next free size, gets the answer for region #N, goes away for a while, then
570 // tries to allocate in region #N, and fail because some other thread have claimed part
571 // of the region #N, and then the freeset allocation code has to retire the region #N,
572 // before moving the allocation to region #N+1.
573 //
574 // The worst case realizes when "answer" is "region size", which means it could
575 // prematurely retire an entire region. Having smaller TLABs does not fix that
576 // completely, but reduces the probability of too wasteful region retirement.
|