2008-01-05 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Sat, 5 Jan 2008 14:21:51 +0000 (14:21 -0000)
committerZoltan Varga <vargaz@gmail.com>
Sat, 5 Jan 2008 14:21:51 +0000 (14:21 -0000)
* object.c (mono_array_full_copy): Fix detection of whenever to use a write
barrier.
(mono_array_clone_in_domain): Ditto.
(mono_array_clone_in_domain): Ditto.

* threads.c (start_wrapper): Register the thread start argument as a GC root.
(cache_culture): Use a write barrier.

* icall.c (ves_icall_System_Array_SetValueImpl): Call a write barrier.
(ves_icall_get_property_info): Ditto.

* object.h (MONO_STRUCT_SETREF): New macro.

* class-internals.h (MonoStats): Add some GC statistics.

* boehm-gc.c null-gc.c: Define mono_gc_deregister_root ().

svn path=/trunk/mono/; revision=92280

mono/metadata/ChangeLog
mono/metadata/boehm-gc.c
mono/metadata/class-internals.h
mono/metadata/icall.c
mono/metadata/null-gc.c
mono/metadata/object.c
mono/metadata/object.h
mono/metadata/threads.c

index 6b426b2ff5606a530ab85d3efa51936acb63fbb1..b8e30357bb38e03a045ca037ed22a9e9dada66ca 100644 (file)
@@ -1,3 +1,22 @@
+2008-01-05  Zoltan Varga  <vargaz@gmail.com>
+
+       * object.c (mono_array_full_copy): Fix detection of whenever to use a write
+       barrier.
+       (mono_array_clone_in_domain): Ditto.
+       (mono_array_clone_in_domain): Ditto.
+
+       * threads.c (start_wrapper): Register the thread start argument as a GC root.
+       (cache_culture): Use a write barrier.
+
+       * icall.c (ves_icall_System_Array_SetValueImpl): Call a write barrier.
+       (ves_icall_get_property_info): Ditto.
+
+       * object.h (MONO_STRUCT_SETREF): New macro.
+
+       * class-internals.h (MonoStats): Add some GC statistics.
+
+       * boehm-gc.c null-gc.c: Define mono_gc_deregister_root ().
+
 2008-01-04  Andreas Faerber  <andreas.faerber@web.de>
 
        * exception.c (mono_exception_from_name_two_strings):
index c1e727eba22e6735985f8865e157caaded9013b6..6f9f48f133b02d99eababc09d6283bf6da3a0191 100644 (file)
@@ -259,6 +259,13 @@ mono_gc_register_root (char *start, size_t size, void *descr)
        return TRUE;
 }
 
+void
+mono_gc_deregister_root (char* addr)
+{
+       /* FIXME: No size info */
+       GC_remove_roots (addr, addr + sizeof (gpointer));
+}
+
 void
 mono_gc_weak_link_add (void **link_addr, MonoObject *obj)
 {
index 57c32e3d747896d95a09a93bc4fad7af89810421..59299e00a6cd90a032fde0d011eb4e09c652bc96 100644 (file)
@@ -555,6 +555,10 @@ typedef struct {
        gulong generics_sharable_methods;
        gulong generics_unsharable_methods;
        gulong generics_shared_methods;
+       gulong minor_gc_count;
+       gulong major_gc_count;
+       gulong minor_gc_time_usecs;
+       gulong major_gc_time_usecs;
        gboolean enabled;
 } MonoStats;
 
index a7c6fca9680ec73b2cc386ead526873459490aba..828e7f996aa9fcd3557f3e1ab0cad1c6d55e1d67 100644 (file)
@@ -269,11 +269,12 @@ ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32
        if (!ec->valuetype) {
                if (!mono_object_isinst (value, ec))
                        INVALID_CAST;
-               *ea = (gpointer)value;
+               mono_gc_wbarrier_set_arrayref (this, ea, (MonoObject*)value);
                return;
        }
 
        if (mono_object_isinst (value, ec)) {
+               // FIXME: Add membarrier
                memcpy (ea, (char *)value + sizeof (MonoObject), esize);
                return;
        }
@@ -1778,23 +1779,23 @@ ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo
        MONO_ARCH_SAVE_REGS;
 
        if ((req_info & PInfo_ReflectedType) != 0)
-               info->parent = mono_type_get_object (domain, &property->klass->byval_arg);
+               MONO_STRUCT_SETREF (info, parent, mono_type_get_object (domain, &property->klass->byval_arg));
        else if ((req_info & PInfo_DeclaringType) != 0)
-               info->parent = mono_type_get_object (domain, &property->property->parent->byval_arg);
+               MONO_STRUCT_SETREF (info, parent, mono_type_get_object (domain, &property->property->parent->byval_arg));
 
        if ((req_info & PInfo_Name) != 0)
-               info->name = mono_string_new (domain, property->property->name);
+               MONO_STRUCT_SETREF (info, name, mono_string_new (domain, property->property->name));
 
        if ((req_info & PInfo_Attributes) != 0)
                info->attrs = property->property->attrs;
 
        if ((req_info & PInfo_GetMethod) != 0)
-               info->get = property->property->get ?
-                           mono_method_get_object (domain, property->property->get, property->klass): NULL;
+               MONO_STRUCT_SETREF (info, get, property->property->get ?
+                                                       mono_method_get_object (domain, property->property->get, property->klass): NULL);
        
        if ((req_info & PInfo_SetMethod) != 0)
-               info->set = property->property->set ?
-                           mono_method_get_object (domain, property->property->set, property->klass): NULL;
+               MONO_STRUCT_SETREF (info, set, property->property->set ?
+                                                       mono_method_get_object (domain, property->property->set, property->klass): NULL);
        /* 
         * There may be other methods defined for properties, though, it seems they are not exposed 
         * in the reflection API 
index 079ad43df002c13109c8671cfe394cfc5619625e..cc33c3b2321a92ee064cf30aff6631fe3d9bc7a1 100644 (file)
@@ -95,6 +95,11 @@ mono_gc_register_root (char *start, size_t size, void *descr)
        return TRUE;
 }
 
+void
+mono_gc_deregister_root (char* addr)
+{
+}
+
 void
 mono_gc_weak_link_add (void **link_addr, MonoObject *obj)
 {
index 80db6588b2a933d0e8431a4f1156480cfb1f8694..b2d39deaee12321350f85da969efe630012067be 100644 (file)
@@ -3440,8 +3440,8 @@ mono_array_full_copy (MonoArray *src, MonoArray *dest)
        g_assert (size == mono_array_length (dest));
        size *= mono_array_element_size (klass);
 #ifdef HAVE_SGEN_GC
-       if (klass->valuetype) {
-               if (klass->has_references)
+       if (klass->element_class->valuetype) {
+               if (klass->element_class->has_references)
                        mono_value_copy_array (dest, 0, src, mono_array_length (src));
                else
                        memcpy (&dest->vector, &src->vector, size);
@@ -3477,8 +3477,8 @@ mono_array_clone_in_domain (MonoDomain *domain, MonoArray *array)
 
                size *= mono_array_element_size (klass);
 #ifdef HAVE_SGEN_GC
-               if (klass->valuetype) {
-                       if (klass->has_references)
+               if (klass->element_class->valuetype) {
+                       if (klass->element_class->has_references)
                                mono_value_copy_array (o, 0, array, mono_array_length (array));
                        else
                                memcpy (&o->vector, &array->vector, size);
@@ -3500,8 +3500,8 @@ mono_array_clone_in_domain (MonoDomain *domain, MonoArray *array)
        }
        o = mono_array_new_full (domain, klass, sizes, sizes + klass->rank);
 #ifdef HAVE_SGEN_GC
-       if (klass->valuetype) {
-               if (klass->has_references)
+       if (klass->element_class->valuetype) {
+               if (klass->element_class->has_references)
                        mono_value_copy_array (o, 0, array, mono_array_length (array));
                else
                        memcpy (&o->vector, &array->vector, size);
index 91c42a955f709e4b30a7945b672f982dae9d2c9d..1a93d7c179ca769e5f0051f08dee88fb6ca4222b 100644 (file)
@@ -61,6 +61,11 @@ typedef void     (*MonoMainThreadFunc)    (gpointer user_data);
                /*(obj)->fieldname = (value);*/ \
        } while (0)
 
+/* This should be used if 's' can reside on the heap */
+#define MONO_STRUCT_SETREF(s,field,value) do { \
+        mono_gc_wbarrier_generic_store (&((s)->field), (MonoObject*)(value)); \
+    } while (0)
+
 #define mono_array_length(array) ((array)->max_length)
 #define mono_array_addr(array,type,index) ((type*)(gpointer) mono_array_addr_with_size (array, sizeof (type), index))
 #define mono_array_addr_with_size(array,size,index) ( ((char*)(array)->vector) + (size) * (index) )
index 8d013c1f7374dda7f0351ca901e0423e035960a7..2622709e0dbd44fff6f72d492d359d992e7c50c0 100644 (file)
@@ -571,7 +571,8 @@ static guint32 WINAPI start_wrapper(void *data)
                 */
                ReleaseSemaphore (thread->start_notify, 1, NULL);
        }
-       
+
+       MONO_GC_UNREGISTER_ROOT (start_info->start_arg);
        g_free (start_info);
 
        thread_adjust_static_data (thread);
@@ -652,6 +653,12 @@ void mono_thread_create_internal (MonoDomain *domain, gpointer func, gpointer ar
        start_info->obj = thread;
        start_info->domain = domain;
        start_info->start_arg = arg;
+
+       /* 
+        * The argument may be an object reference, and there is no ref to keep it alive
+        * when the new thread is started but not yet registered with the collector.
+        */
+       MONO_GC_REGISTER_ROOT (start_info->start_arg);
        
        /* Create suspended, so we can do some housekeeping before the thread
         * starts
@@ -661,6 +668,8 @@ void mono_thread_create_internal (MonoDomain *domain, gpointer func, gpointer ar
        THREAD_DEBUG (g_message ("%s: Started thread ID %"G_GSIZE_FORMAT" (handle %p)", __func__, tid, thread_handle));
        if (thread_handle == NULL) {
                /* The thread couldn't be created, so throw an exception */
+               MONO_GC_UNREGISTER_ROOT (start_info->start_arg);
+               g_free (start_info);
                mono_raise_exception (mono_get_exception_execution_engine ("Couldn't create thread"));
                return;
        }
@@ -1100,7 +1109,7 @@ cache_culture (MonoThread *this, MonoObject *culture, int start_idx)
        EnterCriticalSection (this->synch_cs);
        
        if (!this->cached_culture_info)
-               this->cached_culture_info = mono_array_new (mono_object_domain (this), mono_defaults.object_class, NUM_CACHED_CULTURES * 2);
+               MONO_OBJECT_SETREF (this, cached_culture_info, mono_array_new (mono_object_domain (this), mono_defaults.object_class, NUM_CACHED_CULTURES * 2));
 
        for (i = start_idx; i < start_idx + NUM_CACHED_CULTURES; ++i) {
                obj = mono_array_get (this->cached_culture_info, MonoObject*, i);