#define SGEN_DEFAULT_NURSERY_SIZE (1 << 22)
#define SGEN_DEFAULT_NURSERY_MAX_SIZE (1 << 25)
+/*
+ * We are trying to keep pauses lower than this (ms). We use it for dynamic nursery
+ * sizing heuristics. We are keeping leeway in order to be prepared for work-load
+ * variations.
+ */
+#define SGEN_MAX_PAUSE_TIME 30
+#define SGEN_MAX_PAUSE_MARGIN 0.66f
+
#endif
static guint64 time_max = 0;
+static int sgen_max_pause_time = SGEN_MAX_PAUSE_TIME;
+static float sgen_max_pause_margin = SGEN_MAX_PAUSE_MARGIN;
+
static SGEN_TV_DECLARE (time_major_conc_collection_start);
static SGEN_TV_DECLARE (time_major_conc_collection_end);
SgenGrayQueue gc_thread_gray_queue;
SgenObjectOperations *object_ops_nopar, *object_ops_par = NULL;
ScanCopyContext ctx;
+ int duration;
TV_DECLARE (atv);
TV_DECLARE (btv);
SGEN_TV_DECLARE (last_minor_collection_start_tv);
if (remset_consistency_checks)
sgen_check_remset_consistency ();
- sgen_resize_nursery ();
+
+ TV_GETTIME (btv);
+ duration = (int)(TV_ELAPSED (last_minor_collection_start_tv, btv) / 10000);
+ if (duration > (sgen_max_pause_time * sgen_max_pause_margin))
+ sgen_resize_nursery (TRUE);
+ else
+ sgen_resize_nursery (FALSE);
/* walk the pin_queue, build up the fragment list of free memory, unmark
* pinned objects as we go, memzero() the empty fragments so they are ready for the
void sgen_clear_nursery_fragments (void);
void sgen_nursery_allocator_prepare_for_pinning (void);
void sgen_nursery_allocator_set_nursery_bounds (char *nursery_start, size_t min_size, size_t max_size);
-void sgen_resize_nursery (void);
+void sgen_resize_nursery (gboolean need_shrink);
mword sgen_build_nursery_fragments (GCMemSection *nursery_section, SgenGrayQueue *unpin_queue);
void sgen_init_nursery_allocator (void);
void sgen_nursery_allocator_init_heavy_stats (void);
}
void
-sgen_resize_nursery (void)
+sgen_resize_nursery (gboolean need_shrink)
{
size_t major_size;
* section).
*/
if ((sgen_nursery_size * 2) < (major_size / SGEN_DEFAULT_ALLOWANCE_NURSERY_SIZE_RATIO) &&
- (sgen_nursery_size * 2) <= sgen_nursery_max_size) {
+ (sgen_nursery_size * 2) <= sgen_nursery_max_size && !need_shrink) {
if ((nursery_section->end_data - nursery_section->data) == sgen_nursery_size)
nursery_section->end_data += sgen_nursery_size;
sgen_nursery_size *= 2;
- } else if (sgen_nursery_size > (major_size / SGEN_DEFAULT_ALLOWANCE_NURSERY_SIZE_RATIO) &&
+ } else if ((sgen_nursery_size > (major_size / SGEN_DEFAULT_ALLOWANCE_NURSERY_SIZE_RATIO) || need_shrink) &&
(sgen_nursery_size / 2) >= sgen_nursery_min_size) {
sgen_nursery_size /= 2;
}