< prev index next >

src/share/vm/gc/g1/g1CardLiveData.cpp

Print this page




 114     // For small ranges use a simple loop; otherwise use set_range.
 115     // The range is made up of the cards that are spanned by an object/mem
 116     // region so 8 cards will allow up to object sizes up to 4K to be handled
 117     // using the loop.
 118     if ((end_idx - start_idx) <= 8) {
 119       for (BitMap::idx_t i = start_idx; i < end_idx; i += 1) {
 120         _card_bm.set_bit(i);
 121       }
 122     } else {
 123       _card_bm.set_range(start_idx, end_idx);
 124     }
 125   }
 126 
 127   // We cache the last mark set. This avoids setting the same bit multiple times.
 128   // This is particularly interesting for dense bitmaps, as this avoids doing
 129   // lots of work most of the time.
 130   BitMap::idx_t _last_marked_bit_idx;
 131 
 132   void clear_card_bitmap_range(HeapWord* start, HeapWord* end) {
 133     BitMap::idx_t start_idx = card_live_bitmap_index_for(start);
 134     BitMap::idx_t end_idx = card_live_bitmap_index_for(align_ptr_up(end, CardTableModRefBS::card_size));
 135 
 136     _card_bm.clear_range(start_idx, end_idx);
 137   }
 138 
 139   // Mark the card liveness bitmap for the object spanning from start to end.
 140   void mark_card_bitmap_range(HeapWord* start, HeapWord* end) {
 141     BitMap::idx_t start_idx = card_live_bitmap_index_for(start);
 142     BitMap::idx_t end_idx = card_live_bitmap_index_for(align_ptr_up(end, CardTableModRefBS::card_size));
 143 
 144     assert((end_idx - start_idx) > 0, "Trying to mark zero sized range.");
 145 
 146     if (start_idx == _last_marked_bit_idx) {
 147       start_idx++;
 148     }
 149     if (start_idx == end_idx) {
 150       return;
 151     }
 152 
 153     // Set the bits in the card bitmap for the cards spanned by this object.
 154     set_card_bitmap_range(start_idx, end_idx);
 155     _last_marked_bit_idx = end_idx - 1;
 156   }
 157 
 158   void reset_mark_cache() {
 159     _last_marked_bit_idx = (BitMap::idx_t)-1;
 160   }
 161 
 162 public:


 406 
 407   static size_t chunk_size() { return M; }
 408 
 409   virtual void work(uint worker_id) {
 410     while (true) {
 411       size_t to_process = Atomic::add(1, &_cur_chunk) - 1;
 412       if (to_process >= _num_chunks) {
 413         break;
 414       }
 415 
 416       BitMap::idx_t start = M * BitsPerByte * to_process;
 417       BitMap::idx_t end = MIN2(start + M * BitsPerByte, _bitmap.size());
 418       _bitmap.clear_range(start, end);
 419     }
 420   }
 421 };
 422 
 423 void G1CardLiveData::clear(WorkGang* workers) {
 424   guarantee(Universe::is_fully_initialized(), "Should not call this during initialization.");
 425 
 426   size_t const num_chunks = align_size_up(live_cards_bm().size_in_bytes(), G1ClearCardLiveDataTask::chunk_size()) / G1ClearCardLiveDataTask::chunk_size();
 427   uint const num_workers = (uint)MIN2(num_chunks, (size_t)workers->active_workers());
 428 
 429   G1ClearCardLiveDataTask cl(live_cards_bm(), num_chunks);
 430 
 431   log_debug(gc, ergo)("Running %s using %u workers for " SIZE_FORMAT " work units.", cl.name(), num_workers, num_chunks);
 432   workers->run_task(&cl, num_workers);
 433 
 434   // The region live bitmap is always very small, even for huge heaps. Clear
 435   // directly.
 436   live_regions_bm().clear();
 437 }
 438 
 439 class G1VerifyCardLiveDataTask: public AbstractGangTask {
 440   // Heap region closure used for verifying the live count data
 441   // that was created concurrently and finalized during
 442   // the remark pause. This closure is applied to the heap
 443   // regions during the STW cleanup pause.
 444   class G1VerifyCardLiveDataClosure: public HeapRegionClosure {
 445   private:
 446     G1CollectedHeap* _g1h;




 114     // For small ranges use a simple loop; otherwise use set_range.
 115     // The range is made up of the cards that are spanned by an object/mem
 116     // region so 8 cards will allow up to object sizes up to 4K to be handled
 117     // using the loop.
 118     if ((end_idx - start_idx) <= 8) {
 119       for (BitMap::idx_t i = start_idx; i < end_idx; i += 1) {
 120         _card_bm.set_bit(i);
 121       }
 122     } else {
 123       _card_bm.set_range(start_idx, end_idx);
 124     }
 125   }
 126 
 127   // We cache the last mark set. This avoids setting the same bit multiple times.
 128   // This is particularly interesting for dense bitmaps, as this avoids doing
 129   // lots of work most of the time.
 130   BitMap::idx_t _last_marked_bit_idx;
 131 
 132   void clear_card_bitmap_range(HeapWord* start, HeapWord* end) {
 133     BitMap::idx_t start_idx = card_live_bitmap_index_for(start);
 134     BitMap::idx_t end_idx = card_live_bitmap_index_for(align_up(end, CardTableModRefBS::card_size));
 135 
 136     _card_bm.clear_range(start_idx, end_idx);
 137   }
 138 
 139   // Mark the card liveness bitmap for the object spanning from start to end.
 140   void mark_card_bitmap_range(HeapWord* start, HeapWord* end) {
 141     BitMap::idx_t start_idx = card_live_bitmap_index_for(start);
 142     BitMap::idx_t end_idx = card_live_bitmap_index_for(align_up(end, CardTableModRefBS::card_size));
 143 
 144     assert((end_idx - start_idx) > 0, "Trying to mark zero sized range.");
 145 
 146     if (start_idx == _last_marked_bit_idx) {
 147       start_idx++;
 148     }
 149     if (start_idx == end_idx) {
 150       return;
 151     }
 152 
 153     // Set the bits in the card bitmap for the cards spanned by this object.
 154     set_card_bitmap_range(start_idx, end_idx);
 155     _last_marked_bit_idx = end_idx - 1;
 156   }
 157 
 158   void reset_mark_cache() {
 159     _last_marked_bit_idx = (BitMap::idx_t)-1;
 160   }
 161 
 162 public:


 406 
 407   static size_t chunk_size() { return M; }
 408 
 409   virtual void work(uint worker_id) {
 410     while (true) {
 411       size_t to_process = Atomic::add(1, &_cur_chunk) - 1;
 412       if (to_process >= _num_chunks) {
 413         break;
 414       }
 415 
 416       BitMap::idx_t start = M * BitsPerByte * to_process;
 417       BitMap::idx_t end = MIN2(start + M * BitsPerByte, _bitmap.size());
 418       _bitmap.clear_range(start, end);
 419     }
 420   }
 421 };
 422 
 423 void G1CardLiveData::clear(WorkGang* workers) {
 424   guarantee(Universe::is_fully_initialized(), "Should not call this during initialization.");
 425 
 426   size_t const num_chunks = align_up(live_cards_bm().size_in_bytes(), G1ClearCardLiveDataTask::chunk_size()) / G1ClearCardLiveDataTask::chunk_size();
 427   uint const num_workers = (uint)MIN2(num_chunks, (size_t)workers->active_workers());
 428 
 429   G1ClearCardLiveDataTask cl(live_cards_bm(), num_chunks);
 430 
 431   log_debug(gc, ergo)("Running %s using %u workers for " SIZE_FORMAT " work units.", cl.name(), num_workers, num_chunks);
 432   workers->run_task(&cl, num_workers);
 433 
 434   // The region live bitmap is always very small, even for huge heaps. Clear
 435   // directly.
 436   live_regions_bm().clear();
 437 }
 438 
 439 class G1VerifyCardLiveDataTask: public AbstractGangTask {
 440   // Heap region closure used for verifying the live count data
 441   // that was created concurrently and finalized during
 442   // the remark pause. This closure is applied to the heap
 443   // regions during the STW cleanup pause.
 444   class G1VerifyCardLiveDataClosure: public HeapRegionClosure {
 445   private:
 446     G1CollectedHeap* _g1h;


< prev index next >