Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add a few variants of the MONO_GC_REGISTER_ROOT () to make most roots…

… precisely tracked and to avoid registering locations pointing to memory allocated by mono_gc_alloc_fixed () as roots under SGEN.
  • Loading branch information...
commit 9f96b7fad1135548019340be1264068d4094a81e 1 parent 1b126f7
@vargaz vargaz authored
View
6 mono/metadata/boehm-gc.c
@@ -454,6 +454,12 @@ mono_gc_make_descr_from_bitmap (gsize *bitmap, int numbits)
}
void*
+mono_gc_make_root_descr_all_refs (int numbits)
+{
+ return NULL;
+}
+
+void*
mono_gc_alloc_fixed (size_t size, void *descr)
{
/* To help track down typed allocation bugs */
View
7 mono/metadata/domain.c
@@ -1297,7 +1297,7 @@ mono_init_internal (const char *filename, const char *exe_filename, const char *
mono_reflection_init ();
/* FIXME: When should we release this memory? */
- MONO_GC_REGISTER_ROOT (appdomains_list);
+ MONO_GC_REGISTER_ROOT_FIXED (appdomains_list);
domain = mono_domain_create ();
mono_root_domain = domain;
@@ -2247,7 +2247,8 @@ mono_domain_add_class_static_data (MonoDomain *domain, MonoClass *klass, gpointe
int size = GPOINTER_TO_INT (domain->static_data_array [1]);
next = GPOINTER_TO_INT (domain->static_data_array [0]);
if (next >= size) {
- gpointer *new_array = mono_gc_alloc_fixed (sizeof (gpointer) * (size * 2), NULL);
+ /* 'data' is allocated by alloc_fixed */
+ gpointer *new_array = mono_gc_alloc_fixed (sizeof (gpointer) * (size * 2), MONO_GC_ROOT_DESCR_FOR_FIXED (size * 2));
memcpy (new_array, domain->static_data_array, sizeof (gpointer) * size);
size *= 2;
new_array [1] = GINT_TO_POINTER (size);
@@ -2256,7 +2257,7 @@ mono_domain_add_class_static_data (MonoDomain *domain, MonoClass *klass, gpointe
}
} else {
int size = 32;
- gpointer *new_array = mono_gc_alloc_fixed (sizeof (gpointer) * size, NULL);
+ gpointer *new_array = mono_gc_alloc_fixed (sizeof (gpointer) * size, MONO_GC_ROOT_DESCR_FOR_FIXED (size));
next = 2;
new_array [0] = GINT_TO_POINTER (next);
new_array [1] = GINT_TO_POINTER (size);
View
35 mono/metadata/gc-internal.h
@@ -17,10 +17,40 @@
#define mono_domain_finalizers_lock(domain) EnterCriticalSection (&(domain)->finalizable_objects_hash_lock);
#define mono_domain_finalizers_unlock(domain) LeaveCriticalSection (&(domain)->finalizable_objects_hash_lock);
+/* Register a memory area as a conservatively scanned GC root */
#define MONO_GC_REGISTER_ROOT(x) mono_gc_register_root ((char*)&(x), sizeof(x), NULL)
#define MONO_GC_UNREGISTER_ROOT(x) mono_gc_deregister_root ((char*)&(x))
+/*
+ * Register a memory location as a root pointing to memory allocated using
+ * mono_gc_alloc_fixed (). This includes MonoGHashTable.
+ */
+#ifdef HAVE_SGEN_GC
+/* The result of alloc_fixed () is not GC tracked memory */
+#define MONO_GC_REGISTER_ROOT_FIXED(x)
+#else
+#define MONO_GC_REGISTER_ROOT_FIXED(x) MONO_GC_REGISTER_ROOT ((x))
+#endif
+
+/*
+ * Return a GC descriptor for an array containing N pointers to memory allocated
+ * by mono_gc_alloc_fixed ().
+ */
+#ifdef HAVE_SGEN_GC
+/* The result of alloc_fixed () is not GC tracked memory */
+#define MONO_GC_ROOT_DESCR_FOR_FIXED(n) mono_gc_make_root_descr_all_refs (0)
+#else
+/* The result of alloc_fixed () is GC tracked memory */
+#define MONO_GC_ROOT_DESCR_FOR_FIXED(n) NULL
+#endif
+
+/* Register a memory location holding a single object reference as a GC root */
+#define MONO_GC_REGISTER_ROOT_SINGLE(x) do { \
+ g_assert (sizeof (x) == sizeof (MonoObject*)); \
+ mono_gc_register_root ((char*)&(x), sizeof(MonoObject*), mono_gc_make_root_descr_all_refs (1)); \
+ } while (0)
+
void mono_object_register_finalizer (MonoObject *obj) MONO_INTERNAL;
void ves_icall_System_GC_InternalCollect (int generation) MONO_INTERNAL;
gint64 ves_icall_System_GC_GetTotalMemory (MonoBoolean forceCollection) MONO_INTERNAL;
@@ -86,6 +116,9 @@ GCHandle_CheckCurrentDomain (guint32 gchandle) MONO_INTERNAL;
/* simple interface for data structures needed in the runtime */
void* mono_gc_make_descr_from_bitmap (gsize *bitmap, int numbits) MONO_INTERNAL;
+/* Return a root descriptor for a root with all refs */
+void* mono_gc_make_root_descr_all_refs (int numbits) MONO_INTERNAL;
+
/* User defined marking function */
/* It should work like this:
* foreach (ref in GC references in the are structure pointed to by ADDR)
@@ -102,6 +135,8 @@ void *mono_gc_make_root_descr_user (MonoGCRootMarkFunc marker);
* The memory is non-moving and it will be explicitly deallocated.
* size bytes will be available from the returned address (ie, descr
* must not be stored in the returned memory)
+ * NOTE: Under Boehm, this returns memory allocated using GC_malloc, so the result should
+ * be stored into a location registered using MONO_GC_REGISTER_ROOT_FIXED ().
*/
void* mono_gc_alloc_fixed (size_t size, void *descr) MONO_INTERNAL;
void mono_gc_free_fixed (void* addr) MONO_INTERNAL;
View
18 mono/metadata/gc.c
@@ -72,7 +72,7 @@ add_thread_to_finalize (MonoInternalThread *thread)
{
mono_finalizer_lock ();
if (!threads_to_finalize)
- MONO_GC_REGISTER_ROOT (threads_to_finalize);
+ MONO_GC_REGISTER_ROOT_SINGLE (threads_to_finalize);
threads_to_finalize = mono_mlist_append (threads_to_finalize, (MonoObject*)thread);
mono_finalizer_unlock ();
}
@@ -605,7 +605,7 @@ alloc_handle (HandleData *handles, MonoObject *obj, gboolean track)
if (!handles->size) {
handles->size = 32;
if (handles->type > HANDLE_WEAK_TRACK) {
- handles->entries = mono_gc_alloc_fixed (sizeof (gpointer) * handles->size, NULL);
+ handles->entries = mono_gc_alloc_fixed (sizeof (gpointer) * handles->size, mono_gc_make_root_descr_all_refs (handles->size));
} else {
handles->entries = g_malloc0 (sizeof (gpointer) * handles->size);
handles->domain_ids = g_malloc0 (sizeof (guint16) * handles->size);
@@ -641,17 +641,9 @@ alloc_handle (HandleData *handles, MonoObject *obj, gboolean track)
/* resize and copy the entries */
if (handles->type > HANDLE_WEAK_TRACK) {
- gsize *gc_bitmap;
gpointer *entries;
- void *descr;
- /* Create a GC descriptor */
- gc_bitmap = g_malloc (new_size / 8);
- memset (gc_bitmap, 0xff, new_size / 8);
- descr = mono_gc_make_descr_from_bitmap (gc_bitmap, new_size);
- g_free (gc_bitmap);
-
- entries = mono_gc_alloc_fixed (sizeof (gpointer) * new_size, descr);
+ entries = mono_gc_alloc_fixed (sizeof (gpointer) * new_size, mono_gc_make_root_descr_all_refs (new_size));
memcpy (entries, handles->entries, sizeof (gpointer) * handles->size);
mono_gc_free_fixed (handles->entries);
@@ -1088,8 +1080,8 @@ mono_gc_init (void)
InitializeCriticalSection (&finalizer_mutex);
- MONO_GC_REGISTER_ROOT (gc_handles [HANDLE_NORMAL].entries);
- MONO_GC_REGISTER_ROOT (gc_handles [HANDLE_PINNED].entries);
+ MONO_GC_REGISTER_ROOT_FIXED (gc_handles [HANDLE_NORMAL].entries);
+ MONO_GC_REGISTER_ROOT_FIXED (gc_handles [HANDLE_PINNED].entries);
mono_gc_base_init ();
View
2  mono/metadata/marshal.c
@@ -4119,7 +4119,7 @@ emit_invoke_call (MonoMethodBuilder *mb, MonoMethod *method,
/* to make it work with our special string constructors */
if (!string_dummy) {
- MONO_GC_REGISTER_ROOT (string_dummy);
+ MONO_GC_REGISTER_ROOT_SINGLE (string_dummy);
string_dummy = mono_string_new_wrapper ("dummy");
}
View
2  mono/metadata/mono-debug-debugger.c
@@ -81,7 +81,7 @@ mono_debugger_unlock (void)
void
mono_debugger_initialize (gboolean use_debugger)
{
- MONO_GC_REGISTER_ROOT (last_exception);
+ MONO_GC_REGISTER_ROOT_SINGLE (last_exception);
g_assert (!mono_debugger_use_debugger);
View
5 mono/metadata/mono-ptr-array.h
@@ -17,6 +17,7 @@
/* This is an implementation of a growable pointer array that avoids doing memory allocations for small sizes.
* It works by allocating an initial small array on stack and only going to gc tracked memory if needed.
+ * The array elements are assumed to be object references.
*/
typedef struct {
void **data;
@@ -29,7 +30,7 @@ typedef struct {
#define mono_ptr_array_init(ARRAY, INITIAL_SIZE) do {\
(ARRAY).size = 0; \
(ARRAY).capacity = MAX (INITIAL_SIZE, MONO_PTR_ARRAY_MAX_ON_STACK); \
- (ARRAY).data = INITIAL_SIZE > MONO_PTR_ARRAY_MAX_ON_STACK ? mono_gc_alloc_fixed (sizeof (void*) * INITIAL_SIZE, NULL) : g_newa (void*, MONO_PTR_ARRAY_MAX_ON_STACK); \
+ (ARRAY).data = INITIAL_SIZE > MONO_PTR_ARRAY_MAX_ON_STACK ? mono_gc_alloc_fixed (sizeof (void*) * INITIAL_SIZE, mono_gc_make_root_descr_all_refs (INITIAL_SIZE)) : g_newa (void*, MONO_PTR_ARRAY_MAX_ON_STACK); \
} while (0)
#define mono_ptr_array_destroy(ARRAY) do {\
@@ -39,7 +40,7 @@ typedef struct {
#define mono_ptr_array_append(ARRAY, VALUE) do { \
if ((ARRAY).size >= (ARRAY).capacity) {\
- void *__tmp = mono_gc_alloc_fixed (sizeof (void*) * (ARRAY).capacity * 2, NULL); \
+ void *__tmp = mono_gc_alloc_fixed (sizeof (void*) * (ARRAY).capacity * 2, mono_gc_make_root_descr_all_refs ((ARRAY).capacity * 2)); \
memcpy (__tmp, (ARRAY).data, (ARRAY).capacity * sizeof (void*)); \
if ((ARRAY).capacity > MONO_PTR_ARRAY_MAX_ON_STACK) \
mono_gc_free_fixed ((ARRAY).data); \
View
2  mono/metadata/mono-wsq.c
@@ -53,7 +53,7 @@ mono_wsq_create ()
wsq = g_new0 (MonoWSQ, 1);
wsq->mask = INITIAL_LENGTH - 1;
- MONO_GC_REGISTER_ROOT (wsq->queue);
+ MONO_GC_REGISTER_ROOT_SINGLE (wsq->queue);
root = mono_get_root_domain ();
wsq->queue = mono_array_new_cached (root, mono_defaults.object_class, INITIAL_LENGTH);
MONO_SEM_INIT (&wsq->lock, 1);
View
6 mono/metadata/null-gc.c
@@ -145,6 +145,12 @@ mono_gc_make_descr_from_bitmap (gsize *bitmap, int numbits)
}
void*
+mono_gc_make_root_descr_all_refs (int numbits)
+{
+ return NULL;
+}
+
+void*
mono_gc_alloc_fixed (size_t size, void *descr)
{
return g_malloc0 (size);
View
28 mono/metadata/sgen-gc.c
@@ -6273,7 +6273,9 @@ mono_gc_ephemeron_array_add (MonoObject *obj)
void*
mono_gc_make_descr_from_bitmap (gsize *bitmap, int numbits)
{
- if (numbits < ((sizeof (*bitmap) * 8) - ROOT_DESC_TYPE_SHIFT)) {
+ if (numbits == 0) {
+ return (void*)MAKE_ROOT_DESC (ROOT_DESC_BITMAP, 0);
+ } else if (numbits < ((sizeof (*bitmap) * 8) - ROOT_DESC_TYPE_SHIFT)) {
return (void*)MAKE_ROOT_DESC (ROOT_DESC_BITMAP, bitmap [0]);
} else {
mword complex = alloc_complex_descriptor (bitmap, numbits);
@@ -6281,6 +6283,30 @@ mono_gc_make_descr_from_bitmap (gsize *bitmap, int numbits)
}
}
+ static void *all_ref_root_descrs [32];
+
+void*
+mono_gc_make_root_descr_all_refs (int numbits)
+{
+ gsize *gc_bitmap;
+ void *descr;
+
+ if (numbits < 32 && all_ref_root_descrs [numbits])
+ return all_ref_root_descrs [numbits];
+
+ gc_bitmap = g_malloc (ALIGN_TO (numbits, 8) + 1);
+ memset (gc_bitmap, 0xff, numbits / 8);
+ if (numbits % 8)
+ gc_bitmap [numbits / 8] = (1 << (numbits % 8)) - 1;
+ descr = mono_gc_make_descr_from_bitmap (gc_bitmap, numbits);
+ g_free (gc_bitmap);
+
+ if (numbits < 32)
+ all_ref_root_descrs [numbits] = descr;
+
+ return descr;
+}
+
void*
mono_gc_make_root_descr_user (MonoGCRootMarkFunc marker)
{
View
2  mono/metadata/sgen-pinning.c
@@ -80,6 +80,8 @@ evacuate_pin_staging_area (void)
g_assert (next_pin_slot <= pin_queue_size);
pin_staging_area_index = 0;
+
+ printf ("%d\n", next_pin_slot);
}
static void
View
16 mono/metadata/threadpool.c
@@ -1200,14 +1200,14 @@ mono_thread_pool_init ()
}
}
- MONO_GC_REGISTER_ROOT (async_tp.first);
- MONO_GC_REGISTER_ROOT (async_tp.last);
- MONO_GC_REGISTER_ROOT (async_tp.unused);
- MONO_GC_REGISTER_ROOT (async_io_tp.first);
- MONO_GC_REGISTER_ROOT (async_io_tp.unused);
- MONO_GC_REGISTER_ROOT (async_io_tp.last);
-
- MONO_GC_REGISTER_ROOT (socket_io_data.sock_to_state);
+ MONO_GC_REGISTER_ROOT_SINGLE (async_tp.first);
+ MONO_GC_REGISTER_ROOT_SINGLE (async_tp.last);
+ MONO_GC_REGISTER_ROOT_SINGLE (async_tp.unused);
+ MONO_GC_REGISTER_ROOT_SINGLE (async_io_tp.first);
+ MONO_GC_REGISTER_ROOT_SINGLE (async_io_tp.unused);
+ MONO_GC_REGISTER_ROOT_SINGLE (async_io_tp.last);
+
+ MONO_GC_REGISTER_ROOT_FIXED (socket_io_data.sock_to_state);
InitializeCriticalSection (&socket_io_data.io_lock);
if (g_getenv ("MONO_THREADS_PER_CPU") != NULL) {
threads_per_cpu = atoi (g_getenv ("MONO_THREADS_PER_CPU"));
View
14 mono/metadata/threads.c
@@ -256,7 +256,7 @@ static gboolean handle_store(MonoThread *thread)
}
if(threads==NULL) {
- MONO_GC_REGISTER_ROOT (threads);
+ MONO_GC_REGISTER_ROOT_FIXED (threads);
threads=mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC);
}
@@ -331,7 +331,7 @@ small_id_alloc (MonoInternalThread *thread)
if (!small_id_table) {
small_id_table_size = 2;
- small_id_table = mono_gc_alloc_fixed (small_id_table_size * sizeof (MonoInternalThread*), NULL);
+ small_id_table = mono_gc_alloc_fixed (small_id_table_size * sizeof (MonoInternalThread*), mono_gc_make_root_descr_all_refs (small_id_table_size));
}
for (i = small_id_next; i < small_id_table_size; ++i) {
if (!small_id_table [i]) {
@@ -353,7 +353,7 @@ small_id_alloc (MonoInternalThread *thread)
if (new_size >= (1 << 16))
g_assert_not_reached ();
id = small_id_table_size;
- new_table = mono_gc_alloc_fixed (new_size * sizeof (MonoInternalThread*), NULL);
+ new_table = mono_gc_alloc_fixed (new_size * sizeof (MonoInternalThread*), mono_gc_make_root_descr_all_refs (new_size));
memcpy (new_table, small_id_table, small_id_table_size * sizeof (void*));
mono_gc_free_fixed (small_id_table);
small_id_table = new_table;
@@ -834,7 +834,7 @@ static void
register_thread_start_argument (MonoThread *thread, struct StartInfo *start_info)
{
if (thread_start_args == NULL) {
- MONO_GC_REGISTER_ROOT (thread_start_args);
+ MONO_GC_REGISTER_ROOT_FIXED (thread_start_args);
thread_start_args = mono_g_hash_table_new (NULL, NULL);
}
mono_g_hash_table_insert (thread_start_args, thread, start_info->start_arg);
@@ -866,7 +866,7 @@ MonoInternalThread* mono_thread_create_internal (MonoDomain *domain, gpointer fu
return NULL;
}
if (threads_starting_up == NULL) {
- MONO_GC_REGISTER_ROOT (threads_starting_up);
+ MONO_GC_REGISTER_ROOT_FIXED (threads_starting_up);
threads_starting_up = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_VALUE_GC);
}
@@ -1154,7 +1154,7 @@ HANDLE ves_icall_System_Threading_Thread_Thread_internal(MonoThread *this,
mono_threads_lock ();
register_thread_start_argument (this, start_info);
if (threads_starting_up == NULL) {
- MONO_GC_REGISTER_ROOT (threads_starting_up);
+ MONO_GC_REGISTER_ROOT_FIXED (threads_starting_up);
threads_starting_up = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_VALUE_GC);
}
mono_g_hash_table_insert (threads_starting_up, this, this);
@@ -2648,7 +2648,7 @@ ves_icall_System_Threading_Thread_VolatileWriteObject (void *ptr, void *value)
void mono_thread_init (MonoThreadStartCB start_cb,
MonoThreadAttachCB attach_cb)
{
- MONO_GC_REGISTER_ROOT (small_id_table);
+ MONO_GC_REGISTER_ROOT_FIXED (small_id_table);
InitializeCriticalSection(&threads_mutex);
InitializeCriticalSection(&interlocked_mutex);
InitializeCriticalSection(&contexts_mutex);
View
8 mono/mini/debugger-agent.c
@@ -784,13 +784,13 @@ mono_debugger_agent_init (void)
debugger_tls_id = TlsAlloc ();
thread_to_tls = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_GC);
- MONO_GC_REGISTER_ROOT (thread_to_tls);
+ MONO_GC_REGISTER_ROOT_FIXED (thread_to_tls);
tid_to_thread = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC);
- MONO_GC_REGISTER_ROOT (tid_to_thread);
+ MONO_GC_REGISTER_ROOT_FIXED (tid_to_thread);
tid_to_thread_obj = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC);
- MONO_GC_REGISTER_ROOT (tid_to_thread_obj);
+ MONO_GC_REGISTER_ROOT_FIXED (tid_to_thread_obj);
loaded_classes = g_hash_table_new (mono_aligned_addr_hash, NULL);
pending_assembly_loads = g_ptr_array_new ();
@@ -2881,7 +2881,7 @@ thread_startup (MonoProfiler *prof, uintptr_t tid)
// FIXME: Free this somewhere
tls = g_new0 (DebuggerTlsData, 1);
tls->resume_event = CreateEvent (NULL, FALSE, FALSE, NULL);
- MONO_GC_REGISTER_ROOT (tls->thread);
+ MONO_GC_REGISTER_ROOT_SINGLE (tls->thread);
tls->thread = thread;
TlsSetValue (debugger_tls_id, tls);
View
2  mono/mini/method-to-ir.c
@@ -5260,7 +5260,7 @@ static void
set_exception_object (MonoCompile *cfg, MonoException *exception)
{
cfg->exception_type = MONO_EXCEPTION_OBJECT_SUPPLIED;
- MONO_GC_REGISTER_ROOT (cfg->exception_ptr);
+ MONO_GC_REGISTER_ROOT_SINGLE (cfg->exception_ptr);
cfg->exception_ptr = exception;
}
Please sign in to comment.
Something went wrong with that request. Please try again.