static void
major_free_swept_blocks (void)
{
- size_t section_reserve = sgen_get_minor_collection_allowance () / MS_BLOCK_SIZE;
+ /* FIXME: use something sensible here. */
+ size_t section_reserve = DEFAULT_NURSERY_SIZE * 2 / MS_BLOCK_SIZE;
SGEN_ASSERT (0, sweep_state == SWEEP_STATE_SWEPT, "Sweeping must have finished before freeing blocks");
return size;
}
+/* FIXME: return number of bytes, not of sections */
static size_t
get_num_major_sections (void)
{
}
/*
- * Returns the number of major sections that were present when the last sweep was initiated,
- * and were not freed during the sweep. They are the basis for calculating the allowance.
+ * Returns the number of bytes in blocks that were present when the last sweep was
+ * initiated, and were not freed during the sweep. They are the basis for calculating the
+ * allowance.
*/
static size_t
-get_num_major_unswept_old_sections (void)
+get_bytes_survived_last_sweep (void)
{
SGEN_ASSERT (0, sweep_state == SWEEP_STATE_SWEPT, "Can only query unswept sections after sweep");
- return num_major_sections_before_sweep - num_major_sections_freed_in_sweep;
+ return (num_major_sections_before_sweep - num_major_sections_freed_in_sweep) * MS_BLOCK_SIZE;
}
static gboolean
collector->obj_is_from_pinned_alloc = obj_is_from_pinned_alloc;
collector->report_pinned_memory_usage = major_report_pinned_memory_usage;
collector->get_num_major_sections = get_num_major_sections;
- collector->get_num_major_unswept_old_sections = get_num_major_unswept_old_sections;
+ collector->get_bytes_survived_last_sweep = get_bytes_survived_last_sweep;
collector->handle_gc_param = major_handle_gc_param;
collector->print_gc_param_usage = major_print_gc_param_usage;
collector->post_param_init = post_param_init;
/* use this to tune when to do a major/minor collection */
static mword memory_pressure = 0;
-static mword minor_collection_allowance;
+static mword major_collection_trigger_size;
static mword last_major_num_sections = 0;
static mword last_los_memory_usage = 0;
static gboolean need_calculate_minor_collection_allowance;
-static mword last_collection_old_num_major_sections;
+/* The size of the LOS after the last major collection, after sweeping. */
static mword last_collection_los_memory_usage = 0;
-static mword last_collection_old_los_memory_usage;
-static mword last_collection_los_memory_alloced;
static mword sgen_memgov_available_free_space (void);
static void
sgen_memgov_calculate_minor_collection_allowance (void)
{
- size_t num_major_sections;
- mword new_major, new_heap_size, allowance_target;
+ size_t new_major, new_heap_size, allowance_target, allowance;
if (!need_calculate_minor_collection_allowance)
return;
SGEN_ASSERT (0, major_collector.have_swept (), "Can only calculate allowance if heap is swept");
- num_major_sections = major_collector.get_num_major_unswept_old_sections ();
-
- new_major = num_major_sections * major_collector.section_size;
- /* FIXME: We're using the current major heap size, but the previous LOS size. */
+ new_major = major_collector.get_bytes_survived_last_sweep ();
new_heap_size = new_major + last_collection_los_memory_usage;
/*
*/
allowance_target = new_heap_size / 3;
- minor_collection_allowance = MAX (allowance_target, MIN_MINOR_COLLECTION_ALLOWANCE);
+ allowance = MAX (allowance_target, MIN_MINOR_COLLECTION_ALLOWANCE);
- if (new_heap_size + minor_collection_allowance > soft_heap_limit) {
+ if (new_heap_size + allowance > soft_heap_limit) {
if (new_heap_size > soft_heap_limit)
- minor_collection_allowance = MIN_MINOR_COLLECTION_ALLOWANCE;
+ allowance = MIN_MINOR_COLLECTION_ALLOWANCE;
else
- minor_collection_allowance = MAX (soft_heap_limit - new_heap_size, MIN_MINOR_COLLECTION_ALLOWANCE);
- }
-
- if (debug_print_allowance) {
- mword old_major = last_collection_old_num_major_sections * major_collector.section_size;
-
- SGEN_LOG (1, "Before collection: %ld bytes (%ld major, %ld LOS)",
- (long)(old_major + last_collection_old_los_memory_usage), (long)old_major, (long)last_collection_old_los_memory_usage);
- SGEN_LOG (1, "After collection: %ld bytes (%ld major, %ld LOS)",
- (long)new_heap_size, (long)new_major, (long)last_collection_los_memory_usage);
- SGEN_LOG (1, "Allowance: %ld bytes", (long)minor_collection_allowance);
+ allowance = MAX (soft_heap_limit - new_heap_size, MIN_MINOR_COLLECTION_ALLOWANCE);
}
+ /* FIXME: Why is this here? */
if (major_collector.free_swept_blocks)
major_collector.free_swept_blocks ();
+ major_collection_trigger_size = new_heap_size + allowance;
+
need_calculate_minor_collection_allowance = FALSE;
-}
+ if (debug_print_allowance) {
+ SGEN_LOG (0, "Surviving sweep: %ld bytes (%ld major, %ld LOS)", (long)new_heap_size, (long)new_major, (long)last_collection_los_memory_usage);
+ SGEN_LOG (0, "Allowance: %ld bytes", (long)allowance);
+ SGEN_LOG (0, "Trigger size: %ld bytes", (long)major_collection_trigger_size);
+ }
+}
gboolean
sgen_need_major_collection (mword space_needed)
{
- size_t los_alloced;
- size_t num_sections;
- size_t num_unswept_old_sections;
- size_t minor_collection_sections_alloced;
+ size_t heap_size;
if (sgen_concurrent_collection_in_progress ())
return FALSE;
if (!major_collector.have_swept ())
return FALSE;
- num_sections = major_collector.get_num_major_sections ();
- num_unswept_old_sections = major_collector.get_num_major_unswept_old_sections ();
- SGEN_ASSERT (0, num_sections >= num_unswept_old_sections, "Number of sections should not shrink after sweep");
- minor_collection_sections_alloced = num_sections - num_unswept_old_sections;
+ if (space_needed > sgen_memgov_available_free_space ())
+ return TRUE;
- if (need_calculate_minor_collection_allowance)
- sgen_memgov_calculate_minor_collection_allowance ();
+ sgen_memgov_calculate_minor_collection_allowance ();
+
+ heap_size = major_collector.get_num_major_sections () * major_collector.section_size + los_memory_usage;
- los_alloced = los_memory_usage - MIN (last_collection_los_memory_usage, los_memory_usage);
- return (space_needed > sgen_memgov_available_free_space ()) ||
- minor_collection_sections_alloced * major_collector.section_size + los_alloced > minor_collection_allowance;
+ return heap_size > major_collection_trigger_size;
}
void
void
sgen_memgov_major_collection_start (void)
{
- last_collection_old_num_major_sections = sgen_get_major_collector ()->get_num_major_sections ();
-
- /*
- * A domain could have been freed, resulting in
- * los_memory_usage being less than last_collection_los_memory_usage.
- */
- last_collection_los_memory_alloced = los_memory_usage - MIN (last_collection_los_memory_usage, los_memory_usage);
- last_collection_old_los_memory_usage = los_memory_usage;
-
need_calculate_minor_collection_allowance = TRUE;
+
+ if (debug_print_allowance) {
+ SGEN_LOG (0, "Starting collection with heap size %ld bytes", (long)(major_collector.get_num_major_sections () * major_collector.section_size + los_memory_usage));
+ }
}
void
}
}
-void
-sgen_memgov_collection_start (int generation)
-{
- last_major_num_sections = major_collector.get_num_major_sections ();
- last_los_memory_usage = los_memory_usage;
-}
-
static void
log_timming (GGTimingInfo *info)
{
los_memory_usage / 1024);
}
+/* FIXME: Remove either these or the specialized ones above. */
+void
+sgen_memgov_collection_start (int generation)
+{
+}
+
void
sgen_memgov_collection_end (int generation, GGTimingInfo* info, int info_count)
{
}
}
-mword
-sgen_get_minor_collection_allowance (void)
-{
- return minor_collection_allowance;
-}
-
/* Memory pressure API */
/* Negative value to remove */
soft_heap_limit = soft_limit;
debug_print_allowance = debug_allowance;
- minor_collection_allowance = MIN_MINOR_COLLECTION_ALLOWANCE;
+ major_collection_trigger_size = MIN_MINOR_COLLECTION_ALLOWANCE;
mono_counters_register ("Memgov alloc", MONO_COUNTER_GC | MONO_COUNTER_WORD | MONO_COUNTER_BYTES | MONO_COUNTER_VARIABLE, &total_alloc);
mono_counters_register ("Memgov max alloc", MONO_COUNTER_GC | MONO_COUNTER_WORD | MONO_COUNTER_BYTES | MONO_COUNTER_MONOTONIC, &total_alloc_max);
if (save_target)
save_target_ratio = save_target;
- minor_collection_allowance = MIN_MINOR_COLLECTION_ALLOWANCE;
}
#endif