< prev index next >

src/share/vm/gc/cms/parNewGeneration.cpp

Print this page
rev 8612 : 8086056: ParNew: auto-tune ParGCCardsPerStrideChunk
Summary: Automatically calculate ParGCCardsPerStrideChunk based on the old gen capacity.
Reviewed-by:
rev 8613 : imported patch TonyCMSChunksAuto2
rev 8614 : imported patch TonyCMSChunksAuto3
rev 8615 : imported patch TonyCMSChunksAuto4
rev 8616 : [mq]: TonyCMSChunksAuto5

@@ -877,10 +877,57 @@
   }
   // Reset the PromotionFailureALot counters.
   NOT_PRODUCT(gch->reset_promotion_should_fail();)
 }
 
+void ParNewGeneration::adjust_cards_per_stride(const Generation& old_gen) {
+  if (!UseDynamicParGCStrides) return;
+
+  const size_t min_old_gen_capacity = DynamicParGCStridesMinOldGenCapacity;
+  const size_t max_old_gen_capacity = DynamicParGCStridesMaxOldGenCapacity;
+  assert(min_old_gen_capacity <= max_old_gen_capacity,
+         "should be enforced by cmd line arg constraints");
+
+  const size_t min_stride_size = DynamicParGCStridesMinSize;
+  const size_t max_stride_size = DynamicParGCStridesMaxSize;
+  assert(min_stride_size <= max_stride_size,
+         "should be enforced by cmd line arg constraints");
+
+  const size_t capacity = old_gen.capacity();
+  size_t res = 0;
+  if (capacity < min_old_gen_capacity) {
+    res = min_stride_size;
+  } else if (capacity > max_old_gen_capacity) {
+    res = max_stride_size;
+  } else {
+    const size_t capacity_diff = max_old_gen_capacity - min_old_gen_capacity;
+    const size_t capacity_offset = capacity - min_old_gen_capacity;
+    const double r = (double) capacity_offset / (double) capacity_diff;
+
+    const size_t stride_size_diff = max_stride_size - min_stride_size;
+    const size_t stride_size_offset = (size_t) (r * (double) stride_size_diff);
+    const size_t stride_size = min_stride_size + stride_size_offset;
+    assert(min_stride_size <= stride_size && stride_size <= max_stride_size,
+           "sanity");
+
+    const int stride_size_log = log2_long((jlong) stride_size);
+    res = (size_t) 1 << stride_size_log;
+  }
+
+  if (PrintGCDetails && PrintDynamicParGCStrides) {
+    gclog_or_tty->print(" [ParGCCardsPerStrideChunk: "SIZE_FORMAT" "
+                        "old_capacity: "SIZE_FORMAT"K "
+                        "old_capacity_bounds: "SIZE_FORMAT"K-"SIZE_FORMAT"K "
+                        "stride_size_bounds: "SIZE_FORMAT"-"SIZE_FORMAT"] ",
+                        res, capacity / K,
+                        min_old_gen_capacity / K, max_old_gen_capacity / K,
+                        min_stride_size, max_stride_size);
+  }
+
+  FLAG_SET_ERGO(intx, ParGCCardsPerStrideChunk, (intx) res);
+}
+
 void ParNewGeneration::collect(bool   full,
                                bool   clear_all_soft_refs,
                                size_t size,
                                bool   is_tlab) {
   assert(full || size > 0, "otherwise we don't want to collect");

@@ -922,10 +969,11 @@
   // Capture heap used before collection (for printing).
   size_t gch_prev_used = gch->used();
 
   age_table()->clear();
   to()->clear(SpaceDecorator::Mangle);
+  adjust_cards_per_stride(*_old_gen);
 
   gch->save_marks();
 
   // Set the correct parallelism (number of queues) in the reference processor
   ref_processor()->set_active_mt_degree(active_workers);
< prev index next >