#include <mono/metadata/metadata-internals.h>
#include <mono/metadata/marshal.h>
#include <mono/metadata/runtime.h>
+#include <mono/metadata/handle.h>
#include <mono/metadata/sgen-toggleref.h>
#include <mono/utils/atomic.h>
#include <mono/utils/mono-logger-internals.h>
static void
boehm_thread_unregister (MonoThreadInfo *p);
static void
+boehm_thread_detach (MonoThreadInfo *p);
+static void
register_test_toggleref_callback (void);
#define BOEHM_GC_BIT_FINALIZER_AWARE 1
mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_GC, msg, (unsigned long)arg);
}
+static void on_gc_notification (GC_EventType event);
+static void on_gc_heap_resize (size_t new_size);
+
void
mono_gc_base_init (void)
{
mono_counters_init ();
+#ifndef HOST_WIN32
+ mono_w32handle_init ();
+#endif
+
/*
* Handle the case when we are called from a thread different from the main thread,
* confusing libgc.
memset (&cb, 0, sizeof (cb));
cb.thread_register = boehm_thread_register;
cb.thread_unregister = boehm_thread_unregister;
+ cb.thread_detach = boehm_thread_detach;
cb.mono_method_is_critical = (gboolean (*)(void *))mono_runtime_is_critical_method;
mono_threads_init (&cb, sizeof (MonoThreadInfo));
mono_thread_info_attach (&dummy);
- mono_gc_enable_events ();
+ GC_set_on_collection_event (on_gc_notification);
+ GC_on_heap_resize = on_gc_heap_resize;
MONO_GC_REGISTER_ROOT_FIXED (gc_handles [HANDLE_NORMAL].entries, MONO_ROOT_SOURCE_GC_HANDLE, "gc handles table");
MONO_GC_REGISTER_ROOT_FIXED (gc_handles [HANDLE_PINNED].entries, MONO_ROOT_SOURCE_GC_HANDLE, "gc handles table");
res = GC_register_my_thread (&sb);
if (res == GC_UNIMPLEMENTED)
return NULL; /* Cannot happen with GC v7+. */
+
+ info->handle_stack = mono_handle_stack_alloc ();
+
return info;
}
mono_threads_add_joinable_thread ((gpointer)tid);
}
+static void
+boehm_thread_detach (MonoThreadInfo *p)
+{
+ if (mono_thread_internal_current_is_attached ())
+ mono_thread_detach_internal (mono_thread_internal_current ());
+}
+
gboolean
mono_object_is_alive (MonoObject* o)
{
switch (e) {
case MONO_GC_EVENT_PRE_STOP_WORLD:
MONO_GC_WORLD_STOP_BEGIN ();
- mono_thread_info_suspend_lock ();
break;
case MONO_GC_EVENT_POST_STOP_WORLD:
case MONO_GC_EVENT_POST_START_WORLD:
MONO_GC_WORLD_RESTART_END (1);
- mono_thread_info_suspend_unlock ();
break;
case MONO_GC_EVENT_START:
}
mono_profiler_gc_event (e, 0);
+
+ switch (e) {
+ case MONO_GC_EVENT_PRE_STOP_WORLD:
+ mono_thread_info_suspend_lock ();
+ mono_profiler_gc_event (MONO_GC_EVENT_PRE_STOP_WORLD_LOCKED, 0);
+ break;
+ case MONO_GC_EVENT_POST_START_WORLD:
+ mono_thread_info_suspend_unlock ();
+ mono_profiler_gc_event (MONO_GC_EVENT_POST_START_WORLD_UNLOCKED, 0);
+ break;
+ default:
+ break;
+ }
}
+
static void
on_gc_heap_resize (size_t new_size)
mono_profiler_gc_heap_resize (new_size);
}
-void
-mono_gc_enable_events (void)
-{
- GC_set_on_collection_event (on_gc_notification);
- GC_on_heap_resize = on_gc_heap_resize;
-}
-
-static gboolean alloc_events = FALSE;
-
-void
-mono_gc_enable_alloc_events (void)
-{
- alloc_events = TRUE;
-}
-
int
mono_gc_register_root (char *start, size_t size, void *descr, MonoGCRootSource source, const char *msg)
{
obj->vtable = vtable;
}
- if (G_UNLIKELY (alloc_events))
+ if (G_UNLIKELY (mono_profiler_events & MONO_PROFILE_ALLOCATIONS))
mono_profiler_allocation (obj);
return obj;
obj->max_length = max_length;
- if (G_UNLIKELY (alloc_events))
+ if (G_UNLIKELY (mono_profiler_events & MONO_PROFILE_ALLOCATIONS))
mono_profiler_allocation (&obj->obj);
return obj;
if (bounds_size)
obj->bounds = (MonoArrayBounds *) ((char *) obj + size - bounds_size);
- if (G_UNLIKELY (alloc_events))
+ if (G_UNLIKELY (mono_profiler_events & MONO_PROFILE_ALLOCATIONS))
mono_profiler_allocation (&obj->obj);
return obj;
obj->length = len;
obj->chars [len] = 0;
- if (G_UNLIKELY (alloc_events))
+ if (G_UNLIKELY (mono_profiler_events & MONO_PROFILE_ALLOCATIONS))
mono_profiler_allocation (&obj->object);
return obj;
return 0;
}
-gboolean
+MonoBoolean
mono_gc_pending_finalizers (void)
{
return GC_should_invoke_finalizers ();
{
}
+void
+mono_gc_suspend_finalizers (void)
+{
+}
+
int
mono_gc_get_suspend_signal (void)
{
return NULL;
if (!SMALL_ENOUGH (klass->instance_size))
return NULL;
- if (mono_class_has_finalizer (klass) || mono_class_is_marshalbyref (klass) || (mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS))
+ if (mono_class_has_finalizer (klass) || mono_class_is_marshalbyref (klass))
+ return NULL;
+ if (mono_profiler_get_events () & (MONO_PROFILE_ALLOCATIONS | MONO_PROFILE_STATISTICAL))
return NULL;
if (klass->rank)
return NULL;
atype = ATYPE_NORMAL;
*/
}
- return mono_gc_get_managed_allocator_by_type (atype, FALSE);
+ return mono_gc_get_managed_allocator_by_type (atype, MANAGED_ALLOCATOR_REGULAR);
}
MonoMethod*
* Return a managed allocator method corresponding to allocator type ATYPE.
*/
MonoMethod*
-mono_gc_get_managed_allocator_by_type (int atype, gboolean slowpath)
+mono_gc_get_managed_allocator_by_type (int atype, ManagedAllocatorVariant variant)
{
int offset = -1;
MonoMethod *res;
+ gboolean slowpath = variant != MANAGED_ALLOCATOR_REGULAR;
MonoMethod **cache = slowpath ? slowpath_alloc_method_cache : alloc_method_cache;
MONO_THREAD_VAR_OFFSET (GC_thread_tls, offset);
}
MonoMethod*
-mono_gc_get_managed_allocator_by_type (int atype, gboolean slowpath)
+mono_gc_get_managed_allocator_by_type (int atype, ManagedAllocatorVariant variant)
{
return NULL;
}
return NULL;
}
-void
-mono_gc_set_current_thread_appdomain (MonoDomain *domain)
-{
-}
-
gboolean
mono_gc_precise_stack_mark_enabled (void)
{
return NULL;
}
+void
+mono_gc_params_set (const char* options)
+{
+}
+
+void
+mono_gc_debug_set (const char* options)
+{
+}
+
void
mono_gc_conservatively_scan_area (void *start, void *end)
{
}
}
+#else
+#ifdef _MSC_VER
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+void __mono_win32_boehm_gc_quiet_lnk4221(void) {}
+#endif
#endif /* no Boehm GC */