< prev index next >

src/hotspot/share/gc/z/zRelocationSetSelector.cpp

Print this page




  49     _page_type(page_type),
  50     _page_size(page_size),
  51     _object_size_limit(object_size_limit),
  52     _fragmentation_limit(page_size * (ZFragmentationLimit / 100)),
  53     _registered_pages(),
  54     _sorted_pages(NULL),
  55     _nselected(0),
  56     _stats() {}
  57 
  58 ZRelocationSetSelectorGroup::~ZRelocationSetSelectorGroup() {
  59   FREE_C_HEAP_ARRAY(ZPage*, _sorted_pages);
  60 }
  61 
  62 void ZRelocationSetSelectorGroup::register_live_page(ZPage* page) {
  63   const uint8_t type = page->type();
  64   const size_t size = page->size();
  65   const size_t live = page->live_bytes();
  66   const size_t garbage = size - live;
  67 
  68   if (garbage > _fragmentation_limit) {
  69     _registered_pages.add(page);
  70   }
  71 
  72   _stats._npages++;
  73   _stats._total += size;
  74   _stats._live += live;
  75   _stats._garbage += garbage;
  76 }
  77 
  78 void ZRelocationSetSelectorGroup::register_garbage_page(ZPage* page) {
  79   const size_t size = page->size();
  80 
  81   _stats._npages++;
  82   _stats._total += size;
  83   _stats._garbage += size;
  84   _stats._empty += size;
  85 }
  86 
  87 bool ZRelocationSetSelectorGroup::is_disabled() {
  88   // Medium pages are disabled when their page size is zero
  89   return _page_type == ZPageTypeMedium && _page_size == 0;
  90 }
  91 
  92 bool ZRelocationSetSelectorGroup::is_selectable() {
  93   // Large pages are not selectable
  94   return _page_type != ZPageTypeLarge;
  95 }
  96 
  97 void ZRelocationSetSelectorGroup::semi_sort() {
  98   // Semi-sort registered pages by live bytes in ascending order
  99   const size_t npartitions_shift = 11;
 100   const size_t npartitions = (size_t)1 << npartitions_shift;
 101   const size_t partition_size = _page_size >> npartitions_shift;
 102   const size_t partition_size_shift = exact_log2(partition_size);
 103   const size_t npages = _registered_pages.size();
 104 
 105   // Partition slots/fingers
 106   size_t partitions[npartitions];
 107 
 108   // Allocate destination array
 109   assert(_sorted_pages == NULL, "Already initialized");
 110   _sorted_pages = NEW_C_HEAP_ARRAY(ZPage*, npages, mtGC);
 111   debug_only(memset(_sorted_pages, 0, npages * sizeof(ZPage*)));
 112 
 113   // Calculate partition slots
 114   memset(partitions, 0, sizeof(partitions));
 115   ZArrayIterator<ZPage*> iter1(&_registered_pages);
 116   for (ZPage* page; iter1.next(&page);) {
 117     const size_t index = page->live_bytes() >> partition_size_shift;
 118     partitions[index]++;
 119   }
 120 
 121   // Calculate partition fingers
 122   size_t finger = 0;
 123   for (size_t i = 0; i < npartitions; i++) {
 124     const size_t slots = partitions[i];
 125     partitions[i] = finger;
 126     finger += slots;
 127   }
 128 
 129   // Sort pages into partitions
 130   ZArrayIterator<ZPage*> iter2(&_registered_pages);
 131   for (ZPage* page; iter2.next(&page);) {
 132     const size_t index = page->live_bytes() >> partition_size_shift;
 133     const size_t finger = partitions[index]++;
 134     assert(_sorted_pages[finger] == NULL, "Invalid finger");
 135     _sorted_pages[finger] = page;
 136   }
 137 }
 138 
 139 void ZRelocationSetSelectorGroup::select_inner() {
 140   // Calculate the number of pages to relocate by successively including pages in
 141   // a candidate relocation set and calculate the maximum space requirement for
 142   // their live objects.
 143   const size_t npages = _registered_pages.size();
 144   size_t selected_from = 0;
 145   size_t selected_to = 0;
 146   size_t from_size = 0;
 147 
 148   semi_sort();
 149 
 150   for (size_t from = 1; from <= npages; from++) {
 151     // Add page to the candidate relocation set
 152     from_size += _sorted_pages[from - 1]->live_bytes();
 153 
 154     // Calculate the maximum number of pages needed by the candidate relocation set.
 155     // By subtracting the object size limit from the pages size we get the maximum
 156     // number of pages that the relocation set is guaranteed to fit in, regardless
 157     // of in which order the objects are relocated.
 158     const size_t to = ceil((double)(from_size) / (double)(_page_size - _object_size_limit));
 159 
 160     // Calculate the relative difference in reclaimable space compared to our
 161     // currently selected final relocation set. If this number is larger than the
 162     // acceptable fragmentation limit, then the current candidate relocation set
 163     // becomes our new final relocation set.




  49     _page_type(page_type),
  50     _page_size(page_size),
  51     _object_size_limit(object_size_limit),
  52     _fragmentation_limit(page_size * (ZFragmentationLimit / 100)),
  53     _registered_pages(),
  54     _sorted_pages(NULL),
  55     _nselected(0),
  56     _stats() {}
  57 
  58 ZRelocationSetSelectorGroup::~ZRelocationSetSelectorGroup() {
  59   FREE_C_HEAP_ARRAY(ZPage*, _sorted_pages);
  60 }
  61 
  62 void ZRelocationSetSelectorGroup::register_live_page(ZPage* page) {
  63   const uint8_t type = page->type();
  64   const size_t size = page->size();
  65   const size_t live = page->live_bytes();
  66   const size_t garbage = size - live;
  67 
  68   if (garbage > _fragmentation_limit) {
  69     _registered_pages.append(page);
  70   }
  71 
  72   _stats._npages++;
  73   _stats._total += size;
  74   _stats._live += live;
  75   _stats._garbage += garbage;
  76 }
  77 
  78 void ZRelocationSetSelectorGroup::register_garbage_page(ZPage* page) {
  79   const size_t size = page->size();
  80 
  81   _stats._npages++;
  82   _stats._total += size;
  83   _stats._garbage += size;
  84   _stats._empty += size;
  85 }
  86 
  87 bool ZRelocationSetSelectorGroup::is_disabled() {
  88   // Medium pages are disabled when their page size is zero
  89   return _page_type == ZPageTypeMedium && _page_size == 0;
  90 }
  91 
  92 bool ZRelocationSetSelectorGroup::is_selectable() {
  93   // Large pages are not selectable
  94   return _page_type != ZPageTypeLarge;
  95 }
  96 
  97 void ZRelocationSetSelectorGroup::semi_sort() {
  98   // Semi-sort registered pages by live bytes in ascending order
  99   const size_t npartitions_shift = 11;
 100   const size_t npartitions = (size_t)1 << npartitions_shift;
 101   const size_t partition_size = _page_size >> npartitions_shift;
 102   const size_t partition_size_shift = exact_log2(partition_size);
 103   const size_t npages = _registered_pages.length();
 104 
 105   // Partition slots/fingers
 106   size_t partitions[npartitions];
 107 
 108   // Allocate destination array
 109   assert(_sorted_pages == NULL, "Already initialized");
 110   _sorted_pages = NEW_C_HEAP_ARRAY(ZPage*, npages, mtGC);
 111   debug_only(memset(_sorted_pages, 0, npages * sizeof(ZPage*)));
 112 
 113   // Calculate partition slots
 114   memset(partitions, 0, sizeof(partitions));
 115   ZArrayIterator<ZPage*> iter1(&_registered_pages);
 116   for (ZPage* page; iter1.next(&page);) {
 117     const size_t index = page->live_bytes() >> partition_size_shift;
 118     partitions[index]++;
 119   }
 120 
 121   // Calculate partition fingers
 122   size_t finger = 0;
 123   for (size_t i = 0; i < npartitions; i++) {
 124     const size_t slots = partitions[i];
 125     partitions[i] = finger;
 126     finger += slots;
 127   }
 128 
 129   // Sort pages into partitions
 130   ZArrayIterator<ZPage*> iter2(&_registered_pages);
 131   for (ZPage* page; iter2.next(&page);) {
 132     const size_t index = page->live_bytes() >> partition_size_shift;
 133     const size_t finger = partitions[index]++;
 134     assert(_sorted_pages[finger] == NULL, "Invalid finger");
 135     _sorted_pages[finger] = page;
 136   }
 137 }
 138 
 139 void ZRelocationSetSelectorGroup::select_inner() {
 140   // Calculate the number of pages to relocate by successively including pages in
 141   // a candidate relocation set and calculate the maximum space requirement for
 142   // their live objects.
 143   const size_t npages = _registered_pages.length();
 144   size_t selected_from = 0;
 145   size_t selected_to = 0;
 146   size_t from_size = 0;
 147 
 148   semi_sort();
 149 
 150   for (size_t from = 1; from <= npages; from++) {
 151     // Add page to the candidate relocation set
 152     from_size += _sorted_pages[from - 1]->live_bytes();
 153 
 154     // Calculate the maximum number of pages needed by the candidate relocation set.
 155     // By subtracting the object size limit from the pages size we get the maximum
 156     // number of pages that the relocation set is guaranteed to fit in, regardless
 157     // of in which order the objects are relocated.
 158     const size_t to = ceil((double)(from_size) / (double)(_page_size - _object_size_limit));
 159 
 160     // Calculate the relative difference in reclaimable space compared to our
 161     // currently selected final relocation set. If this number is larger than the
 162     // acceptable fragmentation limit, then the current candidate relocation set
 163     // becomes our new final relocation set.


< prev index next >