< prev index next >

src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.cpp

Print this page
rev 12241 : [backport] 8265239: Shenandoah: Shenandoah heap region count could be off by 1
Reviewed-by: shade
rev 12242 : [backport] 8266802: Shenandoah: Round up region size to page size unconditionally
Reviewed-by: zgu

  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.


< prev index next >