src/share/vm/gc_implementation/g1/sparsePRT.cpp

Print this page
rev 6582 : 8047330: Remove unrolled card loops in G1 SparsePRTEntry
Summary: Removed unrolled card loops in sparsePRT.cpp
Reviewed-by:
Contributed-by: andreas.sjoberg@oracle.com
rev 6583 : 8047328: Change typedef CardIdx_t from int to uint16_t
Summary: Changed the typedef and made the necessary changes to code interacting with the SparsePRTEntry class.
Reviewed-by:
Contributed-by: andreas.sjoberg@oracle.com


  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "gc_implementation/g1/heapRegion.hpp"
  27 #include "gc_implementation/g1/heapRegionRemSet.hpp"
  28 #include "gc_implementation/g1/sparsePRT.hpp"
  29 #include "memory/allocation.inline.hpp"
  30 #include "memory/cardTableModRefBS.hpp"
  31 #include "memory/space.inline.hpp"
  32 #include "runtime/mutexLocker.hpp"
  33 
  34 #define SPARSE_PRT_VERBOSE 0
  35 
  36 void SparsePRTEntry::init(RegionIdx_t region_ind) {
  37   _region_ind = region_ind;
  38   _next_index = NullEntry;

  39 
  40   for (int i = 0; i < cards_num(); i++) {
  41     _cards[i] = NullEntry;
  42   }
  43 }
  44 
  45 bool SparsePRTEntry::contains_card(CardIdx_t card_index) const {
  46   for (int i = 0; i < cards_num(); i++) {
  47     if (_cards[i] == card_index) return true;
  48   }
  49   return false;
  50 }
  51 
  52 int SparsePRTEntry::num_valid_cards() const {
  53   int sum = 0;
  54   for (int i = 0; i < cards_num(); i++) {
  55     sum += (_cards[i] != NullEntry);
  56   }
  57   return sum;
  58 }
  59 
  60 SparsePRTEntry::AddCardResult SparsePRTEntry::add_card(CardIdx_t card_index) {
  61   for (int i = 0; i < cards_num(); i++) {
  62     CardIdx_t c = _cards[i];
  63     if (c == card_index) return found;
  64     if (c == NullEntry) { _cards[i] = card_index; return added; }






  65   }
  66   // Otherwise, we're full.
  67   return overflow;
  68 }
  69 
  70 void SparsePRTEntry::copy_cards(CardIdx_t* cards) const {
  71   memcpy(cards, _cards, cards_num() * sizeof(CardIdx_t));
  72 }
  73 
  74 void SparsePRTEntry::copy_cards(SparsePRTEntry* e) const {
  75   copy_cards(&e->_cards[0]);



  76 }
  77 
  78 // ----------------------------------------------------------------------
  79 
  80 RSHashTable::RSHashTable(size_t capacity) :
  81   _capacity(capacity), _capacity_mask(capacity-1),
  82   _occupied_entries(0), _occupied_cards(0),
  83   _entries((SparsePRTEntry*)NEW_C_HEAP_ARRAY(char, SparsePRTEntry::size() * capacity, mtGC)),
  84   _buckets(NEW_C_HEAP_ARRAY(int, capacity, mtGC)),
  85   _free_list(NullEntry), _free_region(0)
  86 {
  87   clear();
  88 }
  89 
  90 RSHashTable::~RSHashTable() {
  91   if (_entries != NULL) {
  92     FREE_C_HEAP_ARRAY(SparsePRTEntry, _entries, mtGC);
  93     _entries = NULL;
  94   }
  95   if (_buckets != NULL) {


 203     _free_region++;
 204     return res;
 205   } else {
 206     return NullEntry;
 207   }
 208 }
 209 
 210 void RSHashTable::free_entry(int fi) {
 211   entry(fi)->set_next_index(_free_list);
 212   _free_list = fi;
 213 }
 214 
 215 void RSHashTable::add_entry(SparsePRTEntry* e) {
 216   assert(e->num_valid_cards() > 0, "Precondition.");
 217   SparsePRTEntry* e2 = entry_for_region_ind_create(e->r_ind());
 218   e->copy_cards(e2);
 219   _occupied_cards += e2->num_valid_cards();
 220   assert(e2->num_valid_cards() > 0, "Postcondition.");
 221 }
 222 
 223 CardIdx_t RSHashTableIter::find_first_card_in_list() {
 224   CardIdx_t res;
 225   while (_bl_ind != RSHashTable::NullEntry) {
 226     res = _rsht->entry(_bl_ind)->card(0);
 227     if (res != SparsePRTEntry::NullEntry) {
 228       return res;

 229     } else {
 230       _bl_ind = _rsht->entry(_bl_ind)->next_index();
 231     }
 232   }
 233   // Otherwise, none found:
 234   return SparsePRTEntry::NullEntry;
 235 }
 236 
 237 size_t RSHashTableIter::compute_card_ind(CardIdx_t ci) {
 238   return (_rsht->entry(_bl_ind)->r_ind() * HeapRegion::CardsPerRegion) + ci;
 239 }
 240 
 241 bool RSHashTableIter::has_next(size_t& card_index) {
 242   _card_ind++;
 243   CardIdx_t ci;
 244   if (_card_ind < SparsePRTEntry::cards_num() &&
 245       ((ci = _rsht->entry(_bl_ind)->card(_card_ind)) !=
 246        SparsePRTEntry::NullEntry)) {

 247     card_index = compute_card_ind(ci);
 248     return true;
 249   }


 250   // Otherwise, must find the next valid entry.
 251   _card_ind = 0;
 252 
 253   if (_bl_ind != RSHashTable::NullEntry) {
 254       _bl_ind = _rsht->entry(_bl_ind)->next_index();
 255       ci = find_first_card_in_list();
 256       if (ci != SparsePRTEntry::NullEntry) {
 257         card_index = compute_card_ind(ci);
 258         return true;
 259       }
 260   }
 261   // If we didn't return above, must go to the next non-null table index.
 262   _tbl_ind++;
 263   while ((size_t)_tbl_ind < _rsht->capacity()) {
 264     _bl_ind = _rsht->_buckets[_tbl_ind];
 265     ci = find_first_card_in_list();
 266     if (ci != SparsePRTEntry::NullEntry) {
 267       card_index = compute_card_ind(ci);
 268       return true;
 269     }
 270     // Otherwise, try next entry.
 271     _tbl_ind++;
 272   }
 273   // Otherwise, there were no entry.
 274   return false;
 275 }
 276 
 277 bool RSHashTable::contains_card(RegionIdx_t region_index, CardIdx_t card_index) const {
 278   SparsePRTEntry* e = get_entry(region_index);
 279   return (e != NULL && e->contains_card(card_index));
 280 }
 281 
 282 size_t RSHashTable::mem_size() const {
 283   return sizeof(RSHashTable) +
 284     capacity() * (SparsePRTEntry::size() + sizeof(int));
 285 }
 286 




  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "gc_implementation/g1/heapRegion.hpp"
  27 #include "gc_implementation/g1/heapRegionRemSet.hpp"
  28 #include "gc_implementation/g1/sparsePRT.hpp"
  29 #include "memory/allocation.inline.hpp"
  30 #include "memory/cardTableModRefBS.hpp"
  31 #include "memory/space.inline.hpp"
  32 #include "runtime/mutexLocker.hpp"
  33 
  34 #define SPARSE_PRT_VERBOSE 0
  35 
  36 void SparsePRTEntry::init(RegionIdx_t region_ind) {
  37   _region_ind = region_ind;
  38   _next_index = RSHashTable::NullEntry;
  39   _next_null = 0;
  40 



  41 }
  42 
  43 bool SparsePRTEntry::contains_card(CardIdx_t card_index) const {
  44   for (int i = 0; i < _next_null; i++) {
  45     if (_cards[i] == card_index) return true;
  46   }
  47   return false;
  48 }
  49 







  50 
  51 SparsePRTEntry::AddCardResult SparsePRTEntry::add_card(CardIdx_t card_index) {
  52   for (int i = 0; i < _next_null; i++) {
  53     CardIdx_t c = card(i);
  54     if (c == card_index) {
  55       return found;
  56     }
  57   }
  58   if (_next_null < cards_num() -1) {
  59     _cards[_next_null] = card_index;
  60     _next_null++;
  61     return added;
  62    }
  63   // Otherwise, we're full.
  64   return overflow;
  65 }
  66 
  67 void SparsePRTEntry::copy_cards(CardIdx_t* cards) const {
  68   memcpy(cards, _cards, _next_null * sizeof(CardIdx_t));
  69 }
  70 
  71 void SparsePRTEntry::copy_cards(SparsePRTEntry* e) const {
  72   copy_cards(e->_cards);
  73   assert(_next_null >= 0, "invariant");
  74   assert(_next_null <= cards_num(), "invariant");
  75   e->_next_null = _next_null;
  76 }
  77 
  78 // ----------------------------------------------------------------------
  79 
  80 RSHashTable::RSHashTable(size_t capacity) :
  81   _capacity(capacity), _capacity_mask(capacity-1),
  82   _occupied_entries(0), _occupied_cards(0),
  83   _entries((SparsePRTEntry*)NEW_C_HEAP_ARRAY(char, SparsePRTEntry::size() * capacity, mtGC)),
  84   _buckets(NEW_C_HEAP_ARRAY(int, capacity, mtGC)),
  85   _free_list(NullEntry), _free_region(0)
  86 {
  87   clear();
  88 }
  89 
  90 RSHashTable::~RSHashTable() {
  91   if (_entries != NULL) {
  92     FREE_C_HEAP_ARRAY(SparsePRTEntry, _entries, mtGC);
  93     _entries = NULL;
  94   }
  95   if (_buckets != NULL) {


 203     _free_region++;
 204     return res;
 205   } else {
 206     return NullEntry;
 207   }
 208 }
 209 
 210 void RSHashTable::free_entry(int fi) {
 211   entry(fi)->set_next_index(_free_list);
 212   _free_list = fi;
 213 }
 214 
 215 void RSHashTable::add_entry(SparsePRTEntry* e) {
 216   assert(e->num_valid_cards() > 0, "Precondition.");
 217   SparsePRTEntry* e2 = entry_for_region_ind_create(e->r_ind());
 218   e->copy_cards(e2);
 219   _occupied_cards += e2->num_valid_cards();
 220   assert(e2->num_valid_cards() > 0, "Postcondition.");
 221 }
 222 
 223 bool RSHashTableIter::find_first_card_in_list(CardIdx_t & res) {

 224   while (_bl_ind != RSHashTable::NullEntry) {
 225     SparsePRTEntry * sparse_entry = _rsht->entry(_bl_ind);
 226     if (sparse_entry->num_valid_cards() > 0) {
 227       res = sparse_entry->card(0);
 228       return true;
 229     } else {
 230       _bl_ind = sparse_entry->next_index();
 231     }
 232   }
 233   // Otherwise, none found:
 234   return false;
 235 }
 236 
 237 size_t RSHashTableIter::compute_card_ind(CardIdx_t ci) {
 238   return (_rsht->entry(_bl_ind)->r_ind() * HeapRegion::CardsPerRegion) + ci;
 239 }
 240 
 241 bool RSHashTableIter::has_next(size_t& card_index) {
 242   _card_ind++;
 243   CardIdx_t ci;
 244   if (_bl_ind >= 0) {
 245     SparsePRTEntry * e = _rsht->entry(_bl_ind);
 246     if (_card_ind < e->num_valid_cards()) {
 247       ci = e->card(_card_ind);
 248       card_index = compute_card_ind(ci);
 249       return true;
 250     }
 251   }
 252   
 253   // Otherwise, must find the next valid entry.
 254   _card_ind = 0;
 255 
 256   if (_bl_ind != RSHashTable::NullEntry) {
 257       _bl_ind = _rsht->entry(_bl_ind)->next_index();
 258       bool found = find_first_card_in_list(ci);
 259       if (found) {
 260         card_index = compute_card_ind(ci);
 261         return true;
 262       }
 263   }
 264   // If we didn't return above, must go to the next non-null table index.
 265   _tbl_ind++;
 266   while ((size_t)_tbl_ind < _rsht->capacity()) {
 267     _bl_ind = _rsht->_buckets[_tbl_ind];
 268     bool found = find_first_card_in_list(ci);
 269     if (found) {
 270       card_index = compute_card_ind(ci);
 271       return true;
 272     }
 273     // Otherwise, try next entry.
 274     _tbl_ind++;
 275   }
 276   // Otherwise, there were no entry.
 277   return false;
 278 }
 279 
 280 bool RSHashTable::contains_card(RegionIdx_t region_index, CardIdx_t card_index) const {
 281   SparsePRTEntry* e = get_entry(region_index);
 282   return (e != NULL && e->contains_card(card_index));
 283 }
 284 
 285 size_t RSHashTable::mem_size() const {
 286   return sizeof(RSHashTable) +
 287     capacity() * (SparsePRTEntry::size() + sizeof(int));
 288 }
 289