Move the heap limits code to the memgov file.
authorRodrigo Kumpera <kumpera@gmail.com>
Thu, 21 Jun 2012 13:45:31 +0000 (10:45 -0300)
committerRodrigo Kumpera <kumpera@gmail.com>
Mon, 2 Jul 2012 20:53:07 +0000 (17:53 -0300)
mono/metadata/sgen-conf.h
mono/metadata/sgen-gc.c
mono/metadata/sgen-gc.h
mono/metadata/sgen-los.c
mono/metadata/sgen-marksweep.c
mono/metadata/sgen-memory-governor.c
mono/metadata/sgen-memory-governor.h

index 1ad7b10f6bf55ff7450d576bed1d5a551ef03213..716aba8006a47d6ca67f45e8836adf6f4aec52ad 100644 (file)
@@ -140,4 +140,16 @@ typedef guint64 mword;
  */
 #define DEFAULT_REMSET_SIZE 1024
 
+
+/*
+ * Minimum allowance for nursery allocations, as a multiple of the size of nursery.
+ *
+ * We allow at least this much allocation to happen to the major heap from multiple
+ * minor collections before triggering a major collection.
+ *
+ * Bigger values increases throughput by allowing more garbage to sit in the major heap.
+ * Smaller values leads to better memory effiency but more frequent major collections.
+ */
+#define SGEN_MIN_ALLOWANCE_NURSERY_SIZE_RATIO 4
+
 #endif
index 5019f6e479fcfc7d43f61aad61841c29e09c28c4..463b86e0f1a253df0b43da05d48e1ca134a3a44e 100644 (file)
 #include "metadata/sgen-protocol.h"
 #include "metadata/sgen-archdep.h"
 #include "metadata/sgen-bridge.h"
+#include "metadata/sgen-memory-governor.h"
 #include "metadata/mono-gc.h"
 #include "metadata/method-builder.h"
 #include "metadata/profiler-private.h"
@@ -411,8 +412,6 @@ static int gc_disabled = 0;
 
 static gboolean use_cardtable;
 
-#define MIN_MINOR_COLLECTION_ALLOWANCE (DEFAULT_NURSERY_SIZE * 4)
-
 #define SCAN_START_SIZE        SGEN_SCAN_START_SIZE
 
 static mword pagesize = 4096;
@@ -563,63 +562,9 @@ static MonoVTable *array_fill_vtable;
 MonoNativeThreadId main_gc_thread = NULL;
 #endif
 
-/*
- * ######################################################################
- * ########  Heap size accounting
- * ######################################################################
- */
-/*heap limits*/
-static mword max_heap_size = ((mword)0)- ((mword)1);
-static mword soft_heap_limit = ((mword)0) - ((mword)1);
-static mword allocated_heap;
-
 /*Object was pinned during the current collection*/
 static mword objects_pinned;
 
-void
-sgen_release_space (mword size, int space)
-{
-       allocated_heap -= size;
-}
-
-static size_t
-available_free_space (void)
-{
-       return max_heap_size - MIN (allocated_heap, max_heap_size);
-}
-
-gboolean
-sgen_try_alloc_space (mword size, int space)
-{
-       if (available_free_space () < size)
-               return FALSE;
-
-       allocated_heap += size;
-       mono_runtime_resource_check_limit (MONO_RESOURCE_GC_HEAP, allocated_heap);
-       return TRUE;
-}
-
-static void
-init_heap_size_limits (glong max_heap, glong soft_limit)
-{
-       if (soft_limit)
-               soft_heap_limit = soft_limit;
-
-       if (max_heap == 0)
-               return;
-
-       if (max_heap < soft_limit) {
-               fprintf (stderr, "max-heap-size must be at least as large as soft-heap-limit.\n");
-               exit (1);
-       }
-
-       if (max_heap < sgen_nursery_size * 4) {
-               fprintf (stderr, "max-heap-size must be at least 4 times larger than nursery size.\n");
-               exit (1);
-       }
-       max_heap_size = max_heap - sgen_nursery_size;
-}
-
 /*
  * ######################################################################
  * ########  Macros and function declarations.
@@ -2324,7 +2269,7 @@ try_calculate_minor_collection_allowance (gboolean overwrite)
 
        if (!*major_collector.have_swept) {
                if (overwrite)
-                       minor_collection_allowance = MIN_MINOR_COLLECTION_ALLOWANCE;
+                       minor_collection_allowance = sgen_memgov_min_allowance ();
                return;
        }
 
@@ -2361,14 +2306,9 @@ try_calculate_minor_collection_allowance (gboolean overwrite)
         */
        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));
 
-       minor_collection_allowance = MAX (MIN (allowance_target, num_major_sections * major_collector.section_size + los_memory_usage), MIN_MINOR_COLLECTION_ALLOWANCE);
+       minor_collection_allowance = MAX (MIN (allowance_target, num_major_sections * major_collector.section_size + los_memory_usage), sgen_memgov_min_allowance ());
 
-       if (new_heap_size + minor_collection_allowance > soft_heap_limit) {
-               if (new_heap_size > soft_heap_limit)
-                       minor_collection_allowance = MIN_MINOR_COLLECTION_ALLOWANCE;
-               else
-                       minor_collection_allowance = MAX (soft_heap_limit - new_heap_size, MIN_MINOR_COLLECTION_ALLOWANCE);
-       }
+       minor_collection_allowance = sgen_memgov_adjust_allowance (minor_collection_allowance, new_heap_size);
 
        if (debug_print_allowance) {
                mword old_major = last_collection_old_num_major_sections * major_collector.section_size;
@@ -2390,7 +2330,7 @@ static gboolean
 need_major_collection (mword space_needed)
 {
        mword los_alloced = los_memory_usage - MIN (last_collection_los_memory_usage, los_memory_usage);
-       return (space_needed > available_free_space ()) ||
+       return (space_needed > sgen_memgov_available_free_space ()) ||
                minor_collection_sections_alloced * major_collector.section_size + los_alloced > minor_collection_allowance;
 }
 
@@ -4840,7 +4780,7 @@ mono_gc_base_init (void)
        conservative_stack_mark = TRUE;
 
        sgen_nursery_size = DEFAULT_NURSERY_SIZE;
-       minor_collection_allowance = MIN_MINOR_COLLECTION_ALLOWANCE;
+       minor_collection_allowance = sgen_memgov_min_allowance ();
 
        if (opts) {
                for (ptr = opts; *ptr; ++ptr) {
@@ -4987,7 +4927,7 @@ mono_gc_base_init (void)
        if (minor_collector_opt)
                g_free (minor_collector_opt);
 
-       init_heap_size_limits (max_heap, soft_limit);
+       sgen_memgov_init (max_heap, soft_limit);
 
        alloc_nursery ();
 
index cb604409e5001c30401d0c092645051a025fcc4d..afe122364dab7042f1b4d7c2c832d600af2834b9 100644 (file)
@@ -790,8 +790,6 @@ enum {
        SPACE_LOS
 };
 
-gboolean sgen_try_alloc_space (mword size, int space) MONO_INTERNAL;
-void sgen_release_space (mword size, int space) MONO_INTERNAL;
 void sgen_pin_object (void *object, SgenGrayQueue *queue) MONO_INTERNAL;
 void sgen_parallel_pin_or_update (void **ptr, void *obj, MonoVTable *vt, SgenGrayQueue *queue) MONO_INTERNAL;
 void sgen_collect_major_no_lock (const char *reason) MONO_INTERNAL;
index 7c52b6bac55645b1f09e007d93c87cadbcc403b3..17fba9e4d41fdcd34b06cb35c0e0e2b23f50d139 100644 (file)
@@ -52,6 +52,7 @@
 #include "metadata/sgen-gc.h"
 #include "metadata/sgen-protocol.h"
 #include "metadata/sgen-cardtable.h"
+#include "metadata/sgen-memory-governor.h"
 #include "utils/mono-mmap.h"
 
 #define LOS_SECTION_SIZE       (1024 * 1024)
@@ -241,7 +242,7 @@ get_los_section_memory (size_t size)
        if (free_chunks)
                return (LOSObject*)free_chunks;
 
-       if (!sgen_try_alloc_space (LOS_SECTION_SIZE, SPACE_LOS))
+       if (!sgen_memgov_try_alloc_space (LOS_SECTION_SIZE, SPACE_LOS))
                return NULL;
 
        section = sgen_alloc_os_memory_aligned (LOS_SECTION_SIZE, LOS_SECTION_SIZE, TRUE);
@@ -324,7 +325,7 @@ sgen_los_free_object (LOSObject *obj)
                size += pagesize - 1;
                size &= ~(pagesize - 1);
                sgen_free_os_memory (obj, size);
-               sgen_release_space (size, SPACE_LOS);
+               sgen_memgov_release_space (size, SPACE_LOS);
        } else {
                free_los_section_memory (obj, size + sizeof (LOSObject));
 #ifdef LOS_CONSISTENCY_CHECKS
@@ -374,7 +375,7 @@ sgen_los_alloc_large_inner (MonoVTable *vtable, size_t size)
                alloc_size += sizeof (LOSObject);
                alloc_size += pagesize - 1;
                alloc_size &= ~(pagesize - 1);
-               if (sgen_try_alloc_space (alloc_size, SPACE_LOS)) {
+               if (sgen_memgov_try_alloc_space (alloc_size, SPACE_LOS)) {
                        obj = sgen_alloc_os_memory (alloc_size, TRUE);
                        if (obj)
                                obj->huge_object = TRUE;
@@ -427,7 +428,7 @@ sgen_los_sweep (void)
                        else
                                los_sections = next;
                        sgen_free_os_memory (section, LOS_SECTION_SIZE);
-                       sgen_release_space (LOS_SECTION_SIZE, SPACE_LOS);
+                       sgen_memgov_release_space (LOS_SECTION_SIZE, SPACE_LOS);
                        section = next;
                        --los_num_sections;
                        continue;
index 10600a0d085c2dfe9be8a652e8abdb4c57c4e863..0e6ff172abab3f0a2008442c226cb704be1fd900 100644 (file)
@@ -42,6 +42,7 @@
 #include "metadata/sgen-gc.h"
 #include "metadata/sgen-protocol.h"
 #include "metadata/sgen-cardtable.h"
+#include "metadata/sgen-memory-governor.h"
 #include "metadata/gc-internal.h"
 
 #define MS_BLOCK_SIZE  (16*1024)
@@ -376,7 +377,7 @@ ms_free_block (MSBlockInfo *block)
        empty_blocks = block;
        block->used = FALSE;
        block->zeroed = FALSE;
-       sgen_release_space (MS_BLOCK_SIZE, SPACE_MAJOR);
+       sgen_memgov_release_space (MS_BLOCK_SIZE, SPACE_MAJOR);
 }
 #else
 static void*
@@ -431,7 +432,7 @@ ms_free_block (void *block)
 {
        void *empty;
 
-       sgen_release_space (MS_BLOCK_SIZE, SPACE_MAJOR);
+       sgen_memgov_release_space (MS_BLOCK_SIZE, SPACE_MAJOR);
        memset (block, 0, MS_BLOCK_SIZE);
 
        do {
@@ -548,7 +549,7 @@ ms_alloc_block (int size_index, gboolean pinned, gboolean has_references)
        char *obj_start;
        int i;
 
-       if (!sgen_try_alloc_space (MS_BLOCK_SIZE, SPACE_MAJOR))
+       if (!sgen_memgov_try_alloc_space (MS_BLOCK_SIZE, SPACE_MAJOR))
                return FALSE;
 
 #ifdef FIXED_HEAP
index e90ded5de32de6dd8df1bb3dc8085442d5fd2a0b..47347b1f1276d5071c66f756a951245a0b235e84 100644 (file)
 
 #include "metadata/sgen-gc.h"
 #include "metadata/sgen-memory-governor.h"
+#include "utils/mono-counters.h"
+
+#define MIN_MINOR_COLLECTION_ALLOWANCE ((mword)(DEFAULT_NURSERY_SIZE * SGEN_MIN_ALLOWANCE_NURSERY_SIZE_RATIO))
+
+/*heap limits*/
+static mword max_heap_size = ((mword)0)- ((mword)1);
+static mword soft_heap_limit = ((mword)0) - ((mword)1);
+static mword allocated_heap;
+
+
+mword
+sgen_memgov_available_free_space (void)
+{
+       return max_heap_size - MIN (allocated_heap, max_heap_size);
+}
+
+mword
+sgen_memgov_min_allowance (void)
+{
+       return MIN_MINOR_COLLECTION_ALLOWANCE;
+}
+
+mword
+sgen_memgov_adjust_allowance (mword allowance_estimate, mword new_heap_size)
+{
+       if (new_heap_size + allowance_estimate > soft_heap_limit) {
+               if (new_heap_size > soft_heap_limit)
+                       return MIN_MINOR_COLLECTION_ALLOWANCE;
+               else
+                       return MAX (soft_heap_limit - new_heap_size, MIN_MINOR_COLLECTION_ALLOWANCE);
+       }
+       return allowance_estimate;
+}
+
+void
+sgen_memgov_release_space (mword size, int space)
+{
+       allocated_heap -= size;
+}
+
+gboolean
+sgen_memgov_try_alloc_space (mword size, int space)
+{
+       if (sgen_memgov_available_free_space () < size)
+               return FALSE;
+
+       allocated_heap += size;
+       mono_runtime_resource_check_limit (MONO_RESOURCE_GC_HEAP, allocated_heap);
+       return TRUE;
+}
+
+void
+sgen_memgov_init (glong max_heap, glong soft_limit)
+{
+       if (soft_limit)
+               soft_heap_limit = soft_limit;
+
+       if (max_heap == 0)
+               return;
+
+       if (max_heap < soft_limit) {
+               fprintf (stderr, "max-heap-size must be at least as large as soft-heap-limit.\n");
+               exit (1);
+       }
+
+       if (max_heap < sgen_nursery_size * 4) {
+               fprintf (stderr, "max-heap-size must be at least 4 times larger than nursery size.\n");
+               exit (1);
+       }
+       max_heap_size = max_heap - sgen_nursery_size;
+}
 
 #endif
index 0bd505b910b7bec61cb589d92e493ef50a386a06..72cc102d7d627d71677ed8c4f822230f9faff12f 100644 (file)
 #ifndef __MONO_SGEN_MEMORY_GOVERNOR_H__
 #define __MONO_SGEN_MEMORY_GOVERNOR_H__
 
+void sgen_memgov_init (glong max_heap, glong soft_limit) MONO_INTERNAL;
+void sgen_memgov_release_space (mword size, int space) MONO_INTERNAL;
+gboolean sgen_memgov_try_alloc_space (mword size, int space) MONO_INTERNAL;
+mword sgen_memgov_adjust_allowance (mword allowance_estimate, mword new_heap_size) MONO_INTERNAL;
+mword sgen_memgov_min_allowance (void) MONO_INTERNAL;
+mword sgen_memgov_available_free_space (void) MONO_INTERNAL;
 
 #endif