From 5f3262530107cc5a86a840e7c9466e13b2d3c792 Mon Sep 17 00:00:00 2001 From: Rodrigo Kumpera Date: Tue, 17 Jul 2012 13:23:03 -0300 Subject: [PATCH] When calculating allowance, don't blindly cast from double to uint as it might not saturate the result. * sgen-gc.c (try_calculate_minor_collection_allowance): For workloads with very high survival rates the calculated allowance_target can overflow a mword on 32bits systems. Given this behavior is unspecified and we've been bitten by it, let's take the safe side and manually saturate it. --- mono/metadata/sgen-gc.c | 10 +++++++++- mono/metadata/sgen-gc.h | 4 +++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/mono/metadata/sgen-gc.c b/mono/metadata/sgen-gc.c index 81625f0b2ed..bac056b91bd 100644 --- a/mono/metadata/sgen-gc.c +++ b/mono/metadata/sgen-gc.c @@ -3013,6 +3013,14 @@ reset_minor_collection_allowance (void) need_calculate_minor_collection_allowance = TRUE; } +static mword +double_to_mword_with_saturation (double value) +{ + if (value >= (double)MWORD_MAX_VALUE) + return MWORD_MAX_VALUE; + return (mword)value; +} + static void try_calculate_minor_collection_allowance (gboolean overwrite) { @@ -3062,7 +3070,7 @@ try_calculate_minor_collection_allowance (gboolean overwrite) * * hence: */ - allowance_target = (mword)((double)save_target * (double)(minor_collection_sections_alloced * major_collector.section_size + last_collection_los_memory_alloced) / (double)(num_major_sections_saved * major_collector.section_size + los_memory_saved)); + allowance_target = double_to_mword_with_saturation ((double)save_target * (double)(minor_collection_sections_alloced * major_collector.section_size + last_collection_los_memory_alloced) / (double)(num_major_sections_saved * major_collector.section_size + los_memory_saved)); minor_collection_allowance = MAX (MIN (allowance_target, num_major_sections * major_collector.section_size + los_memory_usage), MIN_MINOR_COLLECTION_ALLOWANCE); diff --git a/mono/metadata/sgen-gc.h b/mono/metadata/sgen-gc.h index bb62f2feb13..67af84c6787 100644 --- a/mono/metadata/sgen-gc.h +++ b/mono/metadata/sgen-gc.h @@ -68,8 +68,10 @@ #if SIZEOF_VOID_P == 4 typedef guint32 mword; +#define MWORD_MAX_VALUE ((uint32_t) 0xffffffff) #else -typedef guint64 mword; +typedef guint64 mword; +#define MWORD_MAX_VALUE (G_MAXUINT64) #endif #define SGEN_TV_DECLARE(name) gint64 name -- 2.11.4.GIT