[gc] Mono.Runtime method for enabling/disabling synchronous collections.
authorMark Probst <mark.probst@gmail.com>
Tue, 19 Feb 2013 18:25:50 +0000 (10:25 -0800)
committerMark Probst <mark.probst@gmail.com>
Sat, 23 Feb 2013 00:26:54 +0000 (16:26 -0800)
mcs/class/corlib/Mono/Runtime.cs
mcs/class/corlib/System/Environment.cs
mono/metadata/appdomain.c
mono/metadata/boehm-gc.c
mono/metadata/gc-internal.h
mono/metadata/gc.c
mono/metadata/icall-def.h
mono/metadata/null-gc.c
mono/metadata/sgen-gc.c
mono/tests/Makefile.am
mono/tests/allow-synchronous-major.cs [new file with mode: 0644]

index b036daba679dddb14a94bdb347b15cd51f5cd73a..454a14b7484c78369f3ed991b4db6c96c36a5af0 100644 (file)
@@ -51,6 +51,8 @@ namespace Mono {
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                public static extern string GetNativeStackTrace (Exception exception);
 
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               public static extern bool SetGCAllowSynchronousMajor (bool flag);
        }
        
 }
index f2972eceb8bbfc226a3f6921a9ef34ef198a790d..a254006c6988558dabadfddcf33d54fd47577807 100644 (file)
@@ -56,7 +56,7 @@ namespace System {
                 * of icalls, do not require an increment.
                 */
 #pragma warning disable 169
-               private const int mono_corlib_version = 109;
+               private const int mono_corlib_version = 110;
 #pragma warning restore 169
 
                [ComVisible (true)]
index 7f1ede48a64fa53bf045f6935c125084d97e806b..a5acdb14639c061746e00721648f0856c9af6935 100644 (file)
@@ -75,7 +75,7 @@
  * Changes which are already detected at runtime, like the addition
  * of icalls, do not require an increment.
  */
-#define MONO_CORLIB_VERSION 109
+#define MONO_CORLIB_VERSION 110
 
 typedef struct
 {
index 7611ebd1403dba182b4dce1a88c9a13e2eafdec8..e8ff58a98ca020adbdf5c9782d7ce0f32da4504a 100644 (file)
@@ -1227,4 +1227,10 @@ mono_gc_make_root_descr_user (MonoGCRootMarkFunc marker)
        return NULL;
 }
 
+gboolean
+mono_gc_set_allow_synchronous_major (gboolean flag)
+{
+       return flag;
+}
+
 #endif /* no Boehm GC */
index 3d94bc1f8d1374d571000d9d8ee16ab3a9d1c8c9..c63ecb1ea507dee0eb547006917701a21449a5f8 100644 (file)
@@ -87,6 +87,8 @@ gpointer    ves_icall_System_GCHandle_GetAddrOfPinnedObject (guint32 handle) MON
 void        ves_icall_System_GC_register_ephemeron_array (MonoObject *array) MONO_INTERNAL;
 MonoObject  *ves_icall_System_GC_get_ephemeron_tombstone (void) MONO_INTERNAL;
 
+MonoBoolean ves_icall_Mono_Runtime_SetGCAllowSynchronousMajor (MonoBoolean flag) MONO_INTERNAL;
+
 extern void mono_gc_init (void) MONO_INTERNAL;
 extern void mono_gc_base_init (void) MONO_INTERNAL;
 extern void mono_gc_cleanup (void) MONO_INTERNAL;
@@ -123,6 +125,8 @@ MonoObject *mono_gc_weak_link_get    (void **link_addr) MONO_INTERNAL;
 /*Ephemeron functionality. Sgen only*/
 gboolean    mono_gc_ephemeron_array_add (MonoObject *obj) MONO_INTERNAL;
 
+/* To disable synchronous, evacuating collections - concurrent SGen only */
+gboolean    mono_gc_set_allow_synchronous_major (gboolean flag) MONO_INTERNAL;
 
 MonoBoolean
 GCHandle_CheckCurrentDomain (guint32 gchandle) MONO_INTERNAL;
index 6a41811ec83274a9929ebc8b520e880584568a52..77498a63cc39b7ae3bbdf52dc8b0a89448c9fe3f 100644 (file)
@@ -581,6 +581,12 @@ ves_icall_System_GCHandle_GetAddrOfPinnedObject (guint32 handle)
        return NULL;
 }
 
+MonoBoolean
+ves_icall_Mono_Runtime_SetGCAllowSynchronousMajor (MonoBoolean flag)
+{
+       return mono_gc_set_allow_synchronous_major (flag);
+}
+
 typedef struct {
        guint32  *bitmap;
        gpointer *entries;
index 4afee25245c6be2ee7301f43c6d1a37e50fb3ad3..3c25adf0fb6af9897dc877a4a2ef968369f56519 100644 (file)
@@ -48,6 +48,7 @@ ICALL(COMPROX_2, "FindProxy", ves_icall_Mono_Interop_ComInteropProxy_FindProxy)
 ICALL_TYPE(RUNTIME, "Mono.Runtime", RUNTIME_1)
 ICALL(RUNTIME_1, "GetDisplayName", ves_icall_Mono_Runtime_GetDisplayName)
 ICALL(RUNTIME_12, "GetNativeStackTrace", ves_icall_Mono_Runtime_GetNativeStackTrace)
+ICALL(RUNTIME_13, "SetGCAllowSynchronousMajor", ves_icall_Mono_Runtime_SetGCAllowSynchronousMajor)
 
 #ifndef PLATFORM_RO_FS
 ICALL_TYPE(KPAIR, "Mono.Security.Cryptography.KeyPairPersistence", KPAIR_1)
index 4297749f9c19a61a7fbfe3b587c239212d101fd3..4d48eb50adc2f72ede553b7a8d1518908fd1e073 100644 (file)
@@ -453,4 +453,10 @@ mono_gc_register_altstack (gpointer stack, gint32 stack_size, gpointer altstack,
 {
 }
 
+gboolean
+mono_gc_set_allow_synchronous_major (gboolean flag)
+{
+       return TRUE;
+}
+
 #endif
index b760150ac65a328939bb08a4267c3c6df8b7d09a..987e713d023624d46e93a8533dc4933360d5e851 100644 (file)
@@ -278,6 +278,12 @@ static gboolean conservative_stack_mark = FALSE;
 /* If set, do a plausibility check on the scan_starts before and after
    each collection */
 static gboolean do_scan_starts_check = FALSE;
+/*
+ * If the major collector is concurrent and this is FALSE, we will
+ * never initiate a synchronous major collection, unless requested via
+ * GC.Collect().
+ */
+static gboolean allow_synchronous_major = TRUE;
 static gboolean nursery_collection_is_parallel = FALSE;
 static gboolean disable_minor_collections = FALSE;
 static gboolean disable_major_collections = FALSE;
@@ -3411,6 +3417,7 @@ sgen_perform_collection (size_t requested_size, int generation_to_collect, const
                        goto done;
        } else {
                if (generation_to_collect == GENERATION_OLD &&
+                               allow_synchronous_major &&
                                major_collector.want_synchronous_collection &&
                                *major_collector.want_synchronous_collection) {
                        wait_to_finish = TRUE;
@@ -4741,6 +4748,16 @@ mono_gc_ephemeron_array_add (MonoObject *obj)
        return TRUE;
 }
 
+gboolean
+mono_gc_set_allow_synchronous_major (gboolean flag)
+{
+       if (!major_collector.is_concurrent)
+               return flag;
+
+       allow_synchronous_major = flag;
+       return TRUE;
+}
+
 void*
 mono_gc_invoke_with_gc_lock (MonoGCLockedCallbackFunc func, void *data)
 {
@@ -5058,6 +5075,23 @@ mono_gc_base_init (void)
                                }
                                continue;
                        }
+                       if (g_str_has_prefix (opt, "allow-synchronous-major=")) {
+                               if (!major_collector.is_concurrent) {
+                                       fprintf (stderr, "Warning: allow-synchronous-major has no effect because the major collector is not concurrent.\n");
+                                       continue;
+                               }
+
+                               opt = strchr (opt, '=') + 1;
+
+                               if (!strcmp (opt, "yes")) {
+                                       allow_synchronous_major = TRUE;
+                               } else if (!strcmp (opt, "no")) {
+                                       allow_synchronous_major = FALSE;
+                               } else {
+                                       fprintf (stderr, "allow-synchronous-major must be either `yes' or `no'.\n");
+                                       exit (1);
+                               }
+                       }
 
                        if (!strcmp (opt, "cementing")) {
                                cement_enabled = TRUE;
@@ -5083,6 +5117,8 @@ mono_gc_base_init (void)
                        fprintf (stderr, "  wbarrier=WBARRIER (where WBARRIER is `remset' or `cardtable')\n");
                        fprintf (stderr, "  stack-mark=MARK-METHOD (where MARK-METHOD is 'precise' or 'conservative')\n");
                        fprintf (stderr, "  [no-]cementing\n");
+                       if (major_collector.is_concurrent)
+                               fprintf (stderr, "  allow-synchronous-major=FLAG (where FLAG is `yes' or `no')\n");
                        if (major_collector.print_gc_param_usage)
                                major_collector.print_gc_param_usage ();
                        if (sgen_minor_collector.print_gc_param_usage)
index c36b99b58aa82fdf5ca4bce0c6c8b3b0f30f857b..a9d34462c0a25f18bce4b193e048a6c75141c887 100644 (file)
@@ -387,7 +387,8 @@ BASE_TEST_CS_SRC=           \
        appdomain-unload-doesnot-raise-pending-events.cs        \
        bug-6148.cs     \
        assembly_append_ordering.cs     \
-       bug-10127.cs
+       bug-10127.cs    \
+       allow-synchronous-major.cs
 
 TEST_CS_SRC_DIST=      \
        $(BASE_TEST_CS_SRC)     \
diff --git a/mono/tests/allow-synchronous-major.cs b/mono/tests/allow-synchronous-major.cs
new file mode 100644 (file)
index 0000000..914b6cc
--- /dev/null
@@ -0,0 +1,26 @@
+using System;
+using System.Reflection;
+
+public class Test
+{
+       public static int Main ()
+       {
+               var t = Type.GetType("Mono.Runtime");
+               if (t == null)
+                       return 1;
+               var setGCAllowSynchronousMajor = (Func<bool,bool>) Delegate.CreateDelegate(typeof(Func<bool,bool>),
+                                                                                          t,
+                                                                                          "SetGCAllowSynchronousMajor",
+                                                                                          ignoreCase:false,
+                                                                                          throwOnBindFailure:false);
+               if (setGCAllowSynchronousMajor == null)
+                       return 1;
+
+               if (!setGCAllowSynchronousMajor (false))
+                       Console.WriteLine ("could not disable synchronous major");
+               if (!setGCAllowSynchronousMajor (true))
+                       return 1;
+
+               return 0;
+       }
+}