< prev index next >

src/share/vm/gc/shared/cardTableRS.cpp

Print this page
rev 12906 : [mq]: gc_interface

@@ -72,45 +72,10 @@
 void KlassRemSet::clear_mod_union() {
   ClearKlassModUnionClosure closure;
   ClassLoaderDataGraph::classes_do(&closure);
 }
 
-CardTableRS::CardTableRS(MemRegion whole_heap) :
-  _bs(NULL),
-  _cur_youngergen_card_val(youngergenP1_card)
-{
-  _ct_bs = new CardTableModRefBSForCTRS(whole_heap);
-  _ct_bs->initialize();
-  set_bs(_ct_bs);
-  // max_gens is really GenCollectedHeap::heap()->gen_policy()->number_of_generations()
-  // (which is always 2, young & old), but GenCollectedHeap has not been initialized yet.
-  uint max_gens = 2;
-  _last_cur_val_in_gen = NEW_C_HEAP_ARRAY3(jbyte, max_gens + 1,
-                         mtGC, CURRENT_PC, AllocFailStrategy::RETURN_NULL);
-  if (_last_cur_val_in_gen == NULL) {
-    vm_exit_during_initialization("Could not create last_cur_val_in_gen array.");
-  }
-  for (uint i = 0; i < max_gens + 1; i++) {
-    _last_cur_val_in_gen[i] = clean_card_val();
-  }
-  _ct_bs->set_CTRS(this);
-}
-
-CardTableRS::~CardTableRS() {
-  if (_ct_bs) {
-    delete _ct_bs;
-    _ct_bs = NULL;
-  }
-  if (_last_cur_val_in_gen) {
-    FREE_C_HEAP_ARRAY(jbyte, _last_cur_val_in_gen);
-  }
-}
-
-void CardTableRS::resize_covered_region(MemRegion new_region) {
-  _ct_bs->resize_covered_region(new_region);
-}
-
 jbyte CardTableRS::find_unused_youngergenP_card_value() {
   for (jbyte v = youngergenP1_card;
        v < cur_youngergen_and_prev_nonclean_card;
        v++) {
     bool seen = false;

@@ -244,11 +209,11 @@
       }
 
       // fast forward through potential continuous whole-word range of clean cards beginning at a word-boundary
       if (is_word_aligned(cur_entry)) {
         jbyte* cur_row = cur_entry - BytesPerWord;
-        while (cur_row >= limit && *((intptr_t*)cur_row) ==  CardTableRS::clean_card_row()) {
+        while (cur_row >= limit && *((intptr_t*)cur_row) ==  CardTableRS::clean_card_row_val()) {
           cur_row -= BytesPerWord;
         }
         cur_entry = cur_row + BytesPerWord;
         cur_hw = _ct->addr_for(cur_entry);
       }

@@ -280,11 +245,11 @@
 // precleaned                     ==> cur_youngergen_and_prev_nonclean_card
 // prev-younger-gen               ==> cur_youngergen_and_prev_nonclean_card
 // cur-younger-gen                ==> cur_younger_gen
 // cur_youngergen_and_prev_nonclean_card ==> no change.
 void CardTableRS::write_ref_field_gc_par(void* field, oop new_val) {
-  volatile jbyte* entry = _ct_bs->byte_for(field);
+  volatile jbyte* entry = byte_for(field);
   do {
     jbyte entry_val = *entry;
     // We put this first because it's probably the most common case.
     if (entry_val == clean_card_val()) {
       // No threat of contention with cleaning threads.

@@ -338,11 +303,11 @@
       log_warning(gc)("CMS+ParNew: Flickering used_region_at_save_marks()!!");
     }
     ShouldNotReachHere();
   }
 #endif
-  _ct_bs->non_clean_card_iterate_possibly_parallel(sp, urasm, cl, this, n_threads);
+  non_clean_card_iterate_possibly_parallel(sp, urasm, cl, this, n_threads);
 }
 
 void CardTableRS::clear_into_younger(Generation* old_gen) {
   assert(GenCollectedHeap::heap()->is_old_gen(old_gen),
          "Should only be called for the old generation");

@@ -639,7 +604,116 @@
 void CardTableRS::verify() {
   // At present, we only know how to verify the card table RS for
   // generational heaps.
   VerifyCTGenClosure blk(this);
   GenCollectedHeap::heap()->generation_iterate(&blk, false);
-  _ct_bs->verify();
+  CardTable::verify();
+}
+
+CardTableRS::CardTableRS(MemRegion whole_heap) :
+  CardTable(whole_heap, /* scanned concurrently */ UseConcMarkSweepGC),
+  _cur_youngergen_card_val(youngergenP1_card),
+  // LNC functionality
+  _lowest_non_clean(NULL),
+  _lowest_non_clean_chunk_size(NULL),
+  _lowest_non_clean_base_chunk_index(NULL),
+  _last_LNC_resizing_collection(NULL)
+{
+  // max_gens is really GenCollectedHeap::heap()->gen_policy()->number_of_generations()
+  // (which is always 2, young & old), but GenCollectedHeap has not been initialized yet.
+  uint max_gens = 2;
+  _last_cur_val_in_gen = NEW_C_HEAP_ARRAY3(jbyte, max_gens + 1,
+                         mtGC, CURRENT_PC, AllocFailStrategy::RETURN_NULL);
+  if (_last_cur_val_in_gen == NULL) {
+    vm_exit_during_initialization("Could not create last_cur_val_in_gen array.");
+  }
+  for (uint i = 0; i < max_gens + 1; i++) {
+    _last_cur_val_in_gen[i] = clean_card_val();
+  }
+}
+
+CardTableRS::~CardTableRS() {
+  if (_last_cur_val_in_gen) {
+    FREE_C_HEAP_ARRAY(jbyte, _last_cur_val_in_gen);
+  }
+  if (_lowest_non_clean) {
+    FREE_C_HEAP_ARRAY(CardArr, _lowest_non_clean);
+    _lowest_non_clean = NULL;
+  }
+  if (_lowest_non_clean_chunk_size) {
+    FREE_C_HEAP_ARRAY(size_t, _lowest_non_clean_chunk_size);
+    _lowest_non_clean_chunk_size = NULL;
+  }
+  if (_lowest_non_clean_base_chunk_index) {
+    FREE_C_HEAP_ARRAY(uintptr_t, _lowest_non_clean_base_chunk_index);
+    _lowest_non_clean_base_chunk_index = NULL;
+  }
+  if (_last_LNC_resizing_collection) {
+    FREE_C_HEAP_ARRAY(int, _last_LNC_resizing_collection);
+    _last_LNC_resizing_collection = NULL;
+  }
+}
+
+void CardTableRS::initialize() {
+  CardTable::initialize();
+  _lowest_non_clean =
+    NEW_C_HEAP_ARRAY(CardArr, _max_covered_regions, mtGC);
+  _lowest_non_clean_chunk_size =
+    NEW_C_HEAP_ARRAY(size_t, _max_covered_regions, mtGC);
+  _lowest_non_clean_base_chunk_index =
+    NEW_C_HEAP_ARRAY(uintptr_t, _max_covered_regions, mtGC);
+  _last_LNC_resizing_collection =
+    NEW_C_HEAP_ARRAY(int, _max_covered_regions, mtGC);
+  if (_lowest_non_clean == NULL
+      || _lowest_non_clean_chunk_size == NULL
+      || _lowest_non_clean_base_chunk_index == NULL
+      || _last_LNC_resizing_collection == NULL)
+    vm_exit_during_initialization("couldn't allocate an LNC array.");
+  for (int i = 0; i < _max_covered_regions; i++) {
+    _lowest_non_clean[i] = NULL;
+    _lowest_non_clean_chunk_size[i] = 0;
+    _last_LNC_resizing_collection[i] = -1;
+  }
+}
+
+bool CardTableRS::card_will_be_scanned(jbyte cv) {
+  return card_is_dirty_wrt_gen_iter(cv) || is_prev_nonclean_card_val(cv);
+}
+
+bool CardTableRS::card_may_have_been_dirty(jbyte cv) {
+  return
+    cv != clean_card &&
+    (card_is_dirty_wrt_gen_iter(cv) ||
+     CardTableRS::youngergen_may_have_been_dirty(cv));
+}
+
+void CardTableRS::non_clean_card_iterate_possibly_parallel(
+  Space* sp,
+  MemRegion mr,
+  OopsInGenClosure* cl,
+  CardTableRS* ct,
+  uint n_threads)
+{
+  if (!mr.is_empty()) {
+    if (n_threads > 0) {
+#if INCLUDE_ALL_GCS
+      non_clean_card_iterate_parallel_work(sp, mr, cl, ct, n_threads);
+#else  // INCLUDE_ALL_GCS
+      fatal("Parallel gc not supported here.");
+#endif // INCLUDE_ALL_GCS
+    } else {
+      // clear_cl finds contiguous dirty ranges of cards to process and clear.
+
+      // This is the single-threaded version used by DefNew.
+      const bool parallel = false;
+
+      DirtyCardToOopClosure* dcto_cl = sp->new_dcto_cl(cl, precision(), cl->gen_boundary(), parallel);
+      ClearNoncleanCardWrapper clear_cl(dcto_cl, ct, parallel);
+
+      clear_cl.do_MemRegion(mr);
+    }
+  }
+}
+
+bool CardTableRS::is_in_young(void* addr) const {
+  return GenCollectedHeap::heap()->is_in_young((oop)addr);
 }
< prev index next >