[MethodImplAttribute (MethodImplOptions.InternalCall)]
public static extern string GetNativeStackTrace (Exception exception);
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ public static extern bool SetGCAllowSynchronousMajor (bool flag);
}
}
* 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)]
* 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
{
return NULL;
}
+gboolean
+mono_gc_set_allow_synchronous_major (gboolean flag)
+{
+ return flag;
+}
+
#endif /* no Boehm GC */
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;
/*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;
return NULL;
}
+MonoBoolean
+ves_icall_Mono_Runtime_SetGCAllowSynchronousMajor (MonoBoolean flag)
+{
+ return mono_gc_set_allow_synchronous_major (flag);
+}
+
typedef struct {
guint32 *bitmap;
gpointer *entries;
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)
{
}
+gboolean
+mono_gc_set_allow_synchronous_major (gboolean flag)
+{
+ return TRUE;
+}
+
#endif
/* 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;
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;
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)
{
}
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;
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)
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) \
--- /dev/null
+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;
+ }
+}