Patch for bug #62532 implemention of a kqueue/kevent based FileSystemWatcher.
[mono.git] / mono / metadata / gc.c
index 45c12f8d7ab238d3a60ff4c405096666a2bd0807..f5ed4c1a938bc2752fa1c9c72fd6edce2334b8fa 100644 (file)
@@ -16,6 +16,7 @@
 #include <mono/metadata/exception.h>
 #include <mono/metadata/domain-internals.h>
 #include <mono/metadata/class-internals.h>
+#include <mono/utils/mono-logger.h>
 #define GC_I_HIDE_POINTERS
 #include <mono/os/gc_wrapper.h>
 
@@ -347,13 +348,17 @@ ves_icall_System_GCHandle_GetTargetHandle (MonoObject *obj, guint32 handle, gint
        /* Indexes start from 1 since 0 means the handle is not allocated */
        idx = ++next_handle;
        if (idx >= array_size) {
-#if HAVE_BOEHM_GC
                gpointer *new_array;
                guint8 *new_type_array;
                if (!array_size)
                        array_size = 16;
+#if HAVE_BOEHM_GC
                new_array = GC_MALLOC (sizeof (gpointer) * (array_size * 2));
                new_type_array = GC_MALLOC (sizeof (guint8) * (array_size * 2));
+#else
+               new_array = g_malloc0 (sizeof (gpointer) * (array_size * 2));
+               new_type_array = g_malloc0 (sizeof (guint8) * (array_size * 2));
+#endif
                if (gc_handles) {
                        int i;
                        memcpy (new_array, gc_handles, sizeof (gpointer) * array_size);
@@ -370,20 +375,22 @@ ves_icall_System_GCHandle_GetTargetHandle (MonoObject *obj, guint32 handle, gint
 #else
                                if (((gulong)new_array [i]) & 0x1) {
 #endif
+#if HAVE_BOEHM_GC
                                        if (gc_handles [i] != (gpointer)-1)
                                                GC_unregister_disappearing_link (&(gc_handles [i]));
                                        if (new_array [i] != (gpointer)-1)
                                                GC_GENERAL_REGISTER_DISAPPEARING_LINK (&(new_array [i]), REVEAL_POINTER (new_array [i]));
+#endif
                                }
                        }
                }
                array_size *= 2;
+#ifndef HAVE_BOEHM_GC
+               g_free (gc_handles);
+               g_free (gc_handle_types);
+#endif
                gc_handles = new_array;
                gc_handle_types = new_type_array;
-#else
-               LeaveCriticalSection (&handle_section);
-               mono_raise_exception (mono_get_exception_execution_engine ("No GCHandle support built-in"));
-#endif
        }
 
        /* resuse the type from the old target */
@@ -399,9 +406,6 @@ ves_icall_System_GCHandle_GetTargetHandle (MonoObject *obj, guint32 handle, gint
 #if HAVE_BOEHM_GC
                if (gc_handles [idx] != (gpointer)-1)
                        GC_GENERAL_REGISTER_DISAPPEARING_LINK (&(gc_handles [idx]), obj);
-#else
-               LeaveCriticalSection (&handle_section);
-               mono_raise_exception (mono_get_exception_execution_engine ("No weakref support"));
 #endif
                break;
        default:
@@ -429,9 +433,6 @@ ves_icall_System_GCHandle_FreeHandle (guint32 handle)
                if (gc_handles [idx] != (gpointer)-1)
                        GC_unregister_disappearing_link (&(gc_handles [idx]));
        }
-#else
-       LeaveCriticalSection (&handle_section);
-       mono_raise_exception (mono_get_exception_execution_engine ("No GCHandle support"));
 #endif
 
        gc_handles [idx] = (gpointer)-1;
@@ -457,7 +458,20 @@ ves_icall_System_GCHandle_GetAddrOfPinnedObject (guint32 handle)
                        if (obj == (MonoObject *) -1)
                                return NULL;
                }
-               return obj;
+               if (obj) {
+                       MonoClass *klass = mono_object_class (obj);
+                       if (klass == mono_defaults.string_class) {
+                               return mono_string_chars ((MonoString*)obj);
+                       } else if (klass->rank) {
+                               return mono_array_addr ((MonoArray*)obj, char, 0);
+                       } else {
+                               /* the C# code will check and throw the exception */
+                               /* FIXME: missing !klass->blittable test, see bug #61134 */
+                               if ((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT)
+                                       return (gpointer)-1;
+                               return (char*)obj + sizeof (MonoObject);
+                       }
+               }
        }
        return NULL;
 }
@@ -631,6 +645,12 @@ static GCThreadFunctions mono_gc_thread_vtable = {
 };
 #endif /* WITH_INCLUDED_LIBGC */
 
+static void
+mono_gc_warning (char *msg, GC_word arg)
+{
+       mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_GC, msg, (unsigned long)arg);
+}
+
 void mono_gc_init (void)
 {
        InitializeCriticalSection (&handle_section);
@@ -641,6 +661,12 @@ void mono_gc_init (void)
 #ifdef WITH_INCLUDED_LIBGC
        gc_thread_vtable = &mono_gc_thread_vtable;
 #endif
+       
+       MONO_GC_REGISTER_ROOT (gc_handles);
+       MONO_GC_REGISTER_ROOT (gc_handle_types);
+       GC_no_dls = TRUE;
+
+       GC_set_warn_proc (mono_gc_warning);
 
 #ifdef ENABLE_FINALIZER_THREAD