--- old/src/share/vm/gc/cms/parNewGeneration.cpp 2015-07-01 17:50:54.488069535 -0400 +++ new/src/share/vm/gc/cms/parNewGeneration.cpp 2015-07-01 17:50:54.376070258 -0400 @@ -879,6 +879,53 @@ 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, @@ -924,6 +971,7 @@ age_table()->clear(); to()->clear(SpaceDecorator::Mangle); + adjust_cards_per_stride(*_old_gen); gch->save_marks();