#define MAX_PTR ((uint8_t*)(~(ptrdiff_t)0))
#define commit_min_th (16*OS_PAGE_SIZE)
+#define MIN_SOH_CROSS_GEN_REFS (400)
+#define MIN_LOH_CROSS_GEN_REFS (800)
+
static size_t smoothed_desired_per_heap = 0;
#ifdef SERVER_GC
double gc_heap::short_plugs_pad_ratio = 0;
#endif //SHORT_PLUGS
+int gc_heap::generation_skip_ratio_threshold = 0;
+
uint64_t gc_heap::suspended_start_time = 0;
uint64_t gc_heap::end_gc_time = 0;
uint64_t gc_heap::total_suspended_time = 0;
size_t gc_heap::fgn_last_alloc = 0;
int gc_heap::generation_skip_ratio = 100;
+#ifdef FEATURE_CARD_MARKING_STEALING
+VOLATILE(size_t) gc_heap::n_eph_soh = 0;
+VOLATILE(size_t) gc_heap::n_gen_soh = 0;
+VOLATILE(size_t) gc_heap::n_eph_loh = 0;
+VOLATILE(size_t) gc_heap::n_gen_loh = 0;
+#endif //FEATURE_CARD_MARKING_STEALING
uint64_t gc_heap::loh_alloc_since_cg = 0;
/* promote into max-generation if the card table has too many
* generation faults besides the n -> 0
*/
- ret = (generation_skip_ratio < 30);
+ ret = (generation_skip_ratio < generation_skip_ratio_threshold);
break;
}
short_plugs_pad_ratio = (double)DESIRED_PLUG_LENGTH / (double)(DESIRED_PLUG_LENGTH - Align (min_obj_size));
#endif //SHORT_PLUGS
+ generation_skip_ratio_threshold = (int)GCConfig::GetGCLowSkipRatio();
+
ret = 1;
cleanup:
generation_skip_ratio = 100;
+#ifdef FEATURE_CARD_MARKING_STEALING
+ n_eph_soh = 0;
+ n_gen_soh = 0;
+ n_eph_loh = 0;
+ n_gen_loh = 0;
+#endif //FEATURE_CARD_MARKING_STEALING
mark_stack_tos = 0;
mark_stack_bos = 0;
if (!full_p)
{
+#ifdef FEATURE_CARD_MARKING_STEALING
+ n_eph_soh = 0;
+ n_gen_soh = 0;
+ n_eph_loh = 0;
+ n_gen_loh = 0;
+#endif //FEATURE_CARD_MARKING_STEALING
+
#ifdef CARD_BUNDLE
#ifdef MULTIPLE_HEAPS
if (gc_t_join.r_join(this, gc_r_join_update_card_bundle))
#ifdef FEATURE_CARD_MARKING_STEALING
reset_card_marking_enumerators();
+
+ if (!full_p)
+ {
+ int generation_skip_ratio_soh = ((n_eph_soh > MIN_SOH_CROSS_GEN_REFS) ?
+ (int)(((float)n_gen_soh / (float)n_eph_soh) * 100) : 100);
+ int generation_skip_ratio_loh = ((n_eph_loh > MIN_LOH_CROSS_GEN_REFS) ?
+ (int)(((float)n_gen_loh / (float)n_eph_loh) * 100) : 100);
+
+ generation_skip_ratio = min (generation_skip_ratio_soh, generation_skip_ratio_loh);
+ dprintf (2, ("h%d skip ratio soh: %d, loh: %d", heap_number,
+ generation_skip_ratio_soh, generation_skip_ratio_loh));
+ }
#endif // FEATURE_CARD_MARKING_STEALING
// null out the target of short weakref that were not promoted.
assert (gen_number > settings.condemned_generation);
return generation_allocation_start (generation_of (gen_number - 1 ));
}
-
}
inline void
cg_pointers_found ++;
dprintf (4, ("cg pointer %Ix found, %Id so far",
(size_t)*poo, cg_pointers_found ));
-
}
}
// compute the efficiency ratio of the card table
if (!relocating)
{
- generation_skip_ratio = ((n_eph > 400)? (int)(((float)n_gen / (float)n_eph) * 100) : 100);
- dprintf (3, ("Msoh: cross: %Id, useful: %Id, cards set: %Id, cards cleared: %Id, ratio: %d",
- n_eph, n_gen , n_card_set, total_cards_cleared, generation_skip_ratio));
+#ifdef FEATURE_CARD_MARKING_STEALING
+ Interlocked::ExchangeAddPtr(&n_eph_soh, n_eph);
+ Interlocked::ExchangeAddPtr(&n_gen_soh, n_gen);
+ dprintf (3, ("h%d marking h%d Msoh: cross: %Id, useful: %Id, cards set: %Id, cards cleared: %Id, ratio: %d",
+ hpt->heap_number, heap_number, n_eph, n_gen, n_card_set, total_cards_cleared,
+ (n_eph ? (int)(((float)n_gen / (float)n_eph) * 100) : 0)));
+ dprintf (3, ("h%d marking h%d Msoh: total cross %Id, useful: %Id, running ratio: %d",
+ hpt->heap_number, heap_number, n_eph_soh, n_gen_soh,
+ (n_eph_soh ? (int)(((float)n_gen_soh / (float)n_eph_soh) * 100) : 0)));
+#else
+ generation_skip_ratio = ((n_eph > MIN_SOH_CROSS_GEN_REFS) ? (int)(((float)n_gen / (float)n_eph) * 100) : 100);
+ dprintf (3, ("marking h%d Msoh: cross: %Id, useful: %Id, cards set: %Id, cards cleared: %Id, ratio: %d",
+ heap_number, n_eph, n_gen, n_card_set, total_cards_cleared, generation_skip_ratio));
+#endif //FEATURE_CARD_MARKING_STEALING
}
else
{
// compute the efficiency ratio of the card table
if (!relocating)
{
- generation_skip_ratio = min (((n_eph > 800) ?
- (int)(((float)n_gen / (float)n_eph) * 100) : 100),
- generation_skip_ratio);
-
- dprintf (3, ("Mloh: cross: %Id, useful: %Id, cards cleared: %Id, cards set: %Id, ratio: %d",
- n_eph, n_gen, total_cards_cleared, n_card_set, generation_skip_ratio));
+#ifdef FEATURE_CARD_MARKING_STEALING
+ Interlocked::ExchangeAddPtr(&n_eph_loh, n_eph);
+ Interlocked::ExchangeAddPtr(&n_gen_loh, n_gen);
+ dprintf (3, ("h%d marking h%d Mloh: cross: %Id, useful: %Id, cards set: %Id, cards cleared: %Id, ratio: %d",
+ hpt->heap_number, heap_number, n_eph, n_gen, n_card_set, total_cards_cleared,
+ (n_eph ? (int)(((float)n_gen / (float)n_eph) * 100) : 0)));
+ dprintf (3, ("h%d marking h%d Mloh: total cross %Id, useful: %Id, running ratio: %d",
+ hpt->heap_number, heap_number, n_eph_loh, n_gen_loh,
+ (n_eph_loh ? (int)(((float)n_gen_loh / (float)n_eph_loh) * 100) : 0)));
+#else
+ generation_skip_ratio = min (((n_eph > MIN_LOH_CROSS_GEN_REFS) ?
+ (int)(((float)n_gen / (float)n_eph) * 100) : 100),
+ generation_skip_ratio);
+ dprintf (3, ("marking h%d Mloh: cross: %Id, useful: %Id, cards cleared: %Id, cards set: %Id, ratio: %d",
+ heap_number, n_eph, n_gen, total_cards_cleared, n_card_set, generation_skip_ratio));
+#endif //FEATURE_CARD_MARKING_STEALING
}
else
{
INT_CONFIG (BGCSpinCount, "BGCSpinCount", NULL, 140, "Specifies the bgc spin count") \
INT_CONFIG (BGCSpin, "BGCSpin", NULL, 2, "Specifies the bgc spin time") \
INT_CONFIG (HeapCount, "GCHeapCount", "System.GC.HeapCount", 0, "Specifies the number of server GC heaps") \
- INT_CONFIG (Gen0Size, "GCgen0size", NULL, 0, "Specifies the smallest gen0 size") \
+ INT_CONFIG (Gen0Size, "GCgen0size", NULL, 0, "Specifies the smallest gen0 budget") \
INT_CONFIG (SegmentSize, "GCSegmentSize", NULL, 0, "Specifies the managed heap segment size") \
INT_CONFIG (LatencyMode, "GCLatencyMode", NULL, -1, "Specifies the GC latency mode - batch, interactive or low latency (note that the same " \
"thing can be specified via API which is the supported way") \
INT_CONFIG (GCHighMemPercent, "GCHighMemPercent", "System.GC.HighMemoryPercent", 0, "The percent for GC to consider as high memory") \
INT_CONFIG (GCProvModeStress, "GCProvModeStress", NULL, 0, "Stress the provisional modes") \
INT_CONFIG (GCGen0MaxBudget, "GCGen0MaxBudget", NULL, 0, "Specifies the largest gen0 allocation budget") \
+ INT_CONFIG (GCLowSkipRatio, "GCLowSkipRatio", NULL, 30, "Specifies the low generation skip ratio") \
INT_CONFIG (GCHeapHardLimit, "GCHeapHardLimit", "System.GC.HeapHardLimit", 0, "Specifies a hard limit for the GC heap") \
INT_CONFIG (GCHeapHardLimitPercent, "GCHeapHardLimitPercent", "System.GC.HeapHardLimitPercent", 0, "Specifies the GC heap usage as a percentage of the total memory") \
INT_CONFIG (GCTotalPhysicalMemory, "GCTotalPhysicalMemory", NULL, 0, "Specifies what the GC should consider to be total physical memory") \