src/hotspot/share/gc/g1/heapRegionRemSet.hpp
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 54623 1126f0607c70
child 58679 9c3209ff7550
equal deleted inserted replaced
58677:13588c901957 58678:9cf78a70fa4f
    26 #define SHARE_GC_G1_HEAPREGIONREMSET_HPP
    26 #define SHARE_GC_G1_HEAPREGIONREMSET_HPP
    27 
    27 
    28 #include "gc/g1/g1CodeCacheRemSet.hpp"
    28 #include "gc/g1/g1CodeCacheRemSet.hpp"
    29 #include "gc/g1/g1FromCardCache.hpp"
    29 #include "gc/g1/g1FromCardCache.hpp"
    30 #include "gc/g1/sparsePRT.hpp"
    30 #include "gc/g1/sparsePRT.hpp"
       
    31 #include "utilities/bitMap.hpp"
    31 
    32 
    32 // Remembered set for a heap region.  Represent a set of "cards" that
    33 // Remembered set for a heap region.  Represent a set of "cards" that
    33 // contain pointers into the owner heap region.  Cards are defined somewhat
    34 // contain pointers into the owner heap region.  Cards are defined somewhat
    34 // abstractly, in terms of what the "BlockOffsetTable" in use can parse.
    35 // abstractly, in terms of what the "BlockOffsetTable" in use can parse.
    35 
    36 
    36 class G1CollectedHeap;
    37 class G1CollectedHeap;
    37 class G1BlockOffsetTable;
    38 class G1BlockOffsetTable;
    38 class G1CardLiveData;
    39 class G1CardLiveData;
    39 class HeapRegion;
    40 class HeapRegion;
    40 class HeapRegionRemSetIterator;
       
    41 class PerRegionTable;
    41 class PerRegionTable;
    42 class SparsePRT;
    42 class SparsePRT;
    43 class nmethod;
    43 class nmethod;
    44 
    44 
    45 // The "_coarse_map" is a bitmap with one bit for each region, where set
    45 // The "_coarse_map" is a bitmap with one bit for each region, where set
    65 //      it's _coarse_map bit is set, so the that we were attempting to add
    65 //      it's _coarse_map bit is set, so the that we were attempting to add
    66 //      is represented.  If a deleted PRT is re-used, a thread adding a bit,
    66 //      is represented.  If a deleted PRT is re-used, a thread adding a bit,
    67 //      thinking the PRT is for a different region, does no harm.
    67 //      thinking the PRT is for a different region, does no harm.
    68 
    68 
    69 class OtherRegionsTable {
    69 class OtherRegionsTable {
    70   friend class HeapRegionRemSetIterator;
       
    71 
       
    72   G1CollectedHeap* _g1h;
    70   G1CollectedHeap* _g1h;
    73   Mutex*           _m;
    71   Mutex*           _m;
    74 
    72 
    75   // These are protected by "_m".
    73   // These are protected by "_m".
    76   CHeapBitMap _coarse_map;
    74   CHeapBitMap _coarse_map;
   123 
   121 
   124 public:
   122 public:
   125   // Create a new remembered set. The given mutex is used to ensure consistency.
   123   // Create a new remembered set. The given mutex is used to ensure consistency.
   126   OtherRegionsTable(Mutex* m);
   124   OtherRegionsTable(Mutex* m);
   127 
   125 
       
   126   template <class Closure>
       
   127   void iterate(Closure& v);
       
   128 
   128   // Returns the card index of the given within_region pointer relative to the bottom
   129   // Returns the card index of the given within_region pointer relative to the bottom
   129   // of the given heap region.
   130   // of the given heap region.
   130   static CardIdx_t card_within_region(OopOrNarrowOopStar within_region, HeapRegion* hr);
   131   static CardIdx_t card_within_region(OopOrNarrowOopStar within_region, HeapRegion* hr);
   131   // Adds the reference from "from to this remembered set.
   132   // Adds the reference from "from to this remembered set.
   132   void add_reference(OopOrNarrowOopStar from, uint tid);
   133   void add_reference(OopOrNarrowOopStar from, uint tid);
   155 
   156 
   156   // Clear the entire contents of this remembered set.
   157   // Clear the entire contents of this remembered set.
   157   void clear();
   158   void clear();
   158 };
   159 };
   159 
   160 
       
   161 class PerRegionTable: public CHeapObj<mtGC> {
       
   162   friend class OtherRegionsTable;
       
   163 
       
   164   HeapRegion*     _hr;
       
   165   CHeapBitMap     _bm;
       
   166   jint            _occupied;
       
   167 
       
   168   // next pointer for free/allocated 'all' list
       
   169   PerRegionTable* _next;
       
   170 
       
   171   // prev pointer for the allocated 'all' list
       
   172   PerRegionTable* _prev;
       
   173 
       
   174   // next pointer in collision list
       
   175   PerRegionTable * _collision_list_next;
       
   176 
       
   177   // Global free list of PRTs
       
   178   static PerRegionTable* volatile _free_list;
       
   179 
       
   180 protected:
       
   181   PerRegionTable(HeapRegion* hr) :
       
   182     _hr(hr),
       
   183     _bm(HeapRegion::CardsPerRegion, mtGC),
       
   184     _occupied(0),
       
   185     _next(NULL), _prev(NULL),
       
   186     _collision_list_next(NULL)
       
   187   {}
       
   188 
       
   189 public:
       
   190   // We need access in order to union things into the base table.
       
   191   BitMap* bm() { return &_bm; }
       
   192 
       
   193   HeapRegion* hr() const { return OrderAccess::load_acquire(&_hr); }
       
   194 
       
   195   jint occupied() const {
       
   196     // Overkill, but if we ever need it...
       
   197     // guarantee(_occupied == _bm.count_one_bits(), "Check");
       
   198     return _occupied;
       
   199   }
       
   200 
       
   201   void init(HeapRegion* hr, bool clear_links_to_all_list);
       
   202 
       
   203   inline void add_reference(OopOrNarrowOopStar from);
       
   204 
       
   205   inline void add_card(CardIdx_t from_card_index);
       
   206 
       
   207   // (Destructively) union the bitmap of the current table into the given
       
   208   // bitmap (which is assumed to be of the same size.)
       
   209   void union_bitmap_into(BitMap* bm) {
       
   210     bm->set_union(_bm);
       
   211   }
       
   212 
       
   213   // Mem size in bytes.
       
   214   size_t mem_size() const {
       
   215     return sizeof(PerRegionTable) + _bm.size_in_words() * HeapWordSize;
       
   216   }
       
   217 
       
   218   // Requires "from" to be in "hr()".
       
   219   bool contains_reference(OopOrNarrowOopStar from) const {
       
   220     assert(hr()->is_in_reserved(from), "Precondition.");
       
   221     size_t card_ind = pointer_delta(from, hr()->bottom(),
       
   222                                     G1CardTable::card_size);
       
   223     return _bm.at(card_ind);
       
   224   }
       
   225 
       
   226   // Bulk-free the PRTs from prt to last, assumes that they are
       
   227   // linked together using their _next field.
       
   228   static void bulk_free(PerRegionTable* prt, PerRegionTable* last) {
       
   229     while (true) {
       
   230       PerRegionTable* fl = _free_list;
       
   231       last->set_next(fl);
       
   232       PerRegionTable* res = Atomic::cmpxchg(prt, &_free_list, fl);
       
   233       if (res == fl) {
       
   234         return;
       
   235       }
       
   236     }
       
   237     ShouldNotReachHere();
       
   238   }
       
   239 
       
   240   static void free(PerRegionTable* prt) {
       
   241     bulk_free(prt, prt);
       
   242   }
       
   243 
       
   244   // Returns an initialized PerRegionTable instance.
       
   245   static PerRegionTable* alloc(HeapRegion* hr);
       
   246 
       
   247   PerRegionTable* next() const { return _next; }
       
   248   void set_next(PerRegionTable* next) { _next = next; }
       
   249   PerRegionTable* prev() const { return _prev; }
       
   250   void set_prev(PerRegionTable* prev) { _prev = prev; }
       
   251 
       
   252   // Accessor and Modification routines for the pointer for the
       
   253   // singly linked collision list that links the PRTs within the
       
   254   // OtherRegionsTable::_fine_grain_regions hash table.
       
   255   //
       
   256   // It might be useful to also make the collision list doubly linked
       
   257   // to avoid iteration over the collisions list during scrubbing/deletion.
       
   258   // OTOH there might not be many collisions.
       
   259 
       
   260   PerRegionTable* collision_list_next() const {
       
   261     return _collision_list_next;
       
   262   }
       
   263 
       
   264   void set_collision_list_next(PerRegionTable* next) {
       
   265     _collision_list_next = next;
       
   266   }
       
   267 
       
   268   PerRegionTable** collision_list_next_addr() {
       
   269     return &_collision_list_next;
       
   270   }
       
   271 
       
   272   static size_t fl_mem_size() {
       
   273     PerRegionTable* cur = _free_list;
       
   274     size_t res = 0;
       
   275     while (cur != NULL) {
       
   276       res += cur->mem_size();
       
   277       cur = cur->next();
       
   278     }
       
   279     return res;
       
   280   }
       
   281 
       
   282   static void test_fl_mem_size();
       
   283 };
       
   284 
   160 class HeapRegionRemSet : public CHeapObj<mtGC> {
   285 class HeapRegionRemSet : public CHeapObj<mtGC> {
   161   friend class VMStructs;
   286   friend class VMStructs;
   162   friend class HeapRegionRemSetIterator;
       
   163 
   287 
   164 private:
   288 private:
   165   G1BlockOffsetTable* _bot;
   289   G1BlockOffsetTable* _bot;
   166 
   290 
   167   // A set of code blobs (nmethods) whose code contains pointers into
   291   // A set of code blobs (nmethods) whose code contains pointers into
   177   void clear_fcc();
   301   void clear_fcc();
   178 
   302 
   179 public:
   303 public:
   180   HeapRegionRemSet(G1BlockOffsetTable* bot, HeapRegion* hr);
   304   HeapRegionRemSet(G1BlockOffsetTable* bot, HeapRegion* hr);
   181 
   305 
       
   306   // Setup sparse and fine-grain tables sizes.
   182   static void setup_remset_size();
   307   static void setup_remset_size();
   183 
   308 
   184   bool cardset_is_empty() const {
       
   185     return _other_regions.is_empty();
       
   186   }
       
   187 
       
   188   bool is_empty() const {
   309   bool is_empty() const {
   189     return (strong_code_roots_list_length() == 0) && cardset_is_empty();
   310     return (strong_code_roots_list_length() == 0) && _other_regions.is_empty();
   190   }
   311   }
   191 
   312 
   192   bool occupancy_less_or_equal_than(size_t occ) const {
   313   bool occupancy_less_or_equal_than(size_t occ) const {
   193     return (strong_code_roots_list_length() == 0) && _other_regions.occupancy_less_or_equal_than(occ);
   314     return (strong_code_roots_list_length() == 0) && _other_regions.occupancy_less_or_equal_than(occ);
   194   }
   315   }
       
   316 
       
   317   // For each PRT in the card (remembered) set call one of the following methods
       
   318   // of the given closure:
       
   319   //
       
   320   // set_full_region_dirty(uint region_idx) - pass the region index for coarse PRTs
       
   321   // set_bitmap_dirty(uint region_idx, BitMap* bitmap) - pass the region index and bitmap for fine PRTs
       
   322   // set_cards_dirty(uint region_idx, elem_t* cards, uint num_cards) - pass region index and cards for sparse PRTs
       
   323   template <class Closure>
       
   324   inline void iterate_prts(Closure& cl);
   195 
   325 
   196   size_t occupied() {
   326   size_t occupied() {
   197     MutexLocker x(&_m, Mutex::_no_safepoint_check_flag);
   327     MutexLocker x(&_m, Mutex::_no_safepoint_check_flag);
   198     return occupied_locked();
   328     return occupied_locked();
   199   }
   329   }
   241   void set_state_complete() {
   371   void set_state_complete() {
   242     clear_fcc();
   372     clear_fcc();
   243     _state = Complete;
   373     _state = Complete;
   244   }
   374   }
   245 
   375 
   246   // Used in the sequential case.
       
   247   void add_reference(OopOrNarrowOopStar from) {
       
   248     add_reference(from, 0);
       
   249   }
       
   250 
       
   251   // Used in the parallel case.
       
   252   void add_reference(OopOrNarrowOopStar from, uint tid) {
   376   void add_reference(OopOrNarrowOopStar from, uint tid) {
   253     RemSetState state = _state;
   377     RemSetState state = _state;
   254     if (state == Untracked) {
   378     if (state == Untracked) {
   255       return;
   379       return;
   256     }
   380     }
   336 
   460 
   337   static void test();
   461   static void test();
   338 #endif
   462 #endif
   339 };
   463 };
   340 
   464 
   341 class HeapRegionRemSetIterator : public StackObj {
       
   342 private:
       
   343   // The region RSet over which we are iterating.
       
   344   HeapRegionRemSet* _hrrs;
       
   345 
       
   346   // Local caching of HRRS fields.
       
   347   const BitMap*             _coarse_map;
       
   348 
       
   349   G1BlockOffsetTable*       _bot;
       
   350   G1CollectedHeap*          _g1h;
       
   351 
       
   352   // The number of cards yielded since initialization.
       
   353   size_t _n_yielded_fine;
       
   354   size_t _n_yielded_coarse;
       
   355   size_t _n_yielded_sparse;
       
   356 
       
   357   // Indicates what granularity of table that we are currently iterating over.
       
   358   // We start iterating over the sparse table, progress to the fine grain
       
   359   // table, and then finish with the coarse table.
       
   360   enum IterState {
       
   361     Sparse,
       
   362     Fine,
       
   363     Coarse
       
   364   };
       
   365   IterState _is;
       
   366 
       
   367   // For both Coarse and Fine remembered set iteration this contains the
       
   368   // first card number of the heap region we currently iterate over.
       
   369   size_t _cur_region_card_offset;
       
   370 
       
   371   // Current region index for the Coarse remembered set iteration.
       
   372   int    _coarse_cur_region_index;
       
   373   size_t _coarse_cur_region_cur_card;
       
   374 
       
   375   bool coarse_has_next(size_t& card_index);
       
   376 
       
   377   // The PRT we are currently iterating over.
       
   378   PerRegionTable* _fine_cur_prt;
       
   379   // Card offset within the current PRT.
       
   380   size_t _cur_card_in_prt;
       
   381 
       
   382   // Update internal variables when switching to the given PRT.
       
   383   void switch_to_prt(PerRegionTable* prt);
       
   384   bool fine_has_next();
       
   385   bool fine_has_next(size_t& card_index);
       
   386 
       
   387   // The Sparse remembered set iterator.
       
   388   SparsePRTIter _sparse_iter;
       
   389 
       
   390 public:
       
   391   HeapRegionRemSetIterator(HeapRegionRemSet* hrrs);
       
   392 
       
   393   // If there remains one or more cards to be yielded, returns true and
       
   394   // sets "card_index" to one of those cards (which is then considered
       
   395   // yielded.)   Otherwise, returns false (and leaves "card_index"
       
   396   // undefined.)
       
   397   bool has_next(size_t& card_index);
       
   398 
       
   399   size_t n_yielded_fine() { return _n_yielded_fine; }
       
   400   size_t n_yielded_coarse() { return _n_yielded_coarse; }
       
   401   size_t n_yielded_sparse() { return _n_yielded_sparse; }
       
   402   size_t n_yielded() {
       
   403     return n_yielded_fine() + n_yielded_coarse() + n_yielded_sparse();
       
   404   }
       
   405 };
       
   406 
       
   407 #endif // SHARE_GC_G1_HEAPREGIONREMSET_HPP
   465 #endif // SHARE_GC_G1_HEAPREGIONREMSET_HPP