2009-12-02 Mark Probst <mark.probst@gmail.com>
authorMark Probst <mark.probst@gmail.com>
Wed, 2 Dec 2009 02:03:03 +0000 (02:03 -0000)
committerMark Probst <mark.probst@gmail.com>
Wed, 2 Dec 2009 02:03:03 +0000 (02:03 -0000)
        * appdomain.c: When unloading a domain, zero its static data and
        perform a minor collection when using SGen.  That will get rid of
        all the remsets pointing into that domain's static data.

        * sgen-gc.c: Allow remsets into static data.  By doing this we
        need less checks so we're more efficient.

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

mono/metadata/ChangeLog
mono/metadata/appdomain.c
mono/metadata/sgen-gc.c

index eadf02512cf91094fba68cb30bddafcc23f9ffdb..ab564cf34f9cf1d65b585d856125bc4dbe62ab7c 100644 (file)
@@ -1,3 +1,12 @@
+2009-12-02  Mark Probst  <mark.probst@gmail.com>
+
+       * appdomain.c: When unloading a domain, zero its static data and
+       perform a minor collection when using SGen.  That will get rid of
+       all the remsets pointing into that domain's static data.
+
+       * sgen-gc.c: Allow remsets into static data.  By doing this we
+       need less checks so we're more efficient.
+
 2009-12-01  Rodrigo Kumpera  <rkumpera@novell.com>
 
        * verify.c (mono_method_verify): Check for catch clauses with broken
index 0ca1607f1bd34b3599394b785946c63b83f43719..24a1f2bbb037684ffe19eb5551f7008a9cdf9db3 100644 (file)
@@ -2099,6 +2099,16 @@ clear_cached_vtable (gpointer key, gpointer value, gpointer user_data)
                mono_gc_free_fixed (vtable->data);
 }
 
+static void
+zero_static_data (gpointer key, gpointer value, gpointer user_data)
+{
+       MonoClass *klass = (MonoClass*)key;
+       MonoVTable *vtable = value;
+
+       if (vtable->data && klass->has_static_refs)
+               memset (vtable->data, 0, mono_class_data_size (klass));
+}
+
 typedef struct unload_data {
        MonoDomain *domain;
        char *failure_reason;
@@ -2208,6 +2218,19 @@ unload_thread_main (void *arg)
 
        mono_loader_lock ();
        mono_domain_lock (domain);
+#ifdef HAVE_SGEN_GC
+       /*
+        * We need to make sure that we don't have any remsets
+        * pointing into static data of the to-be-freed domain because
+        * at the next collections they would be invalid.  So what we
+        * do is we first zero all static data and then do a minor
+        * collection.  Because all references in the static data will
+        * now be null we won't do any unnecessary copies and after
+        * the collection there won't be any more remsets.
+        */
+       g_hash_table_foreach (domain->class_vtable_hash, zero_static_data, domain);
+       mono_gc_collect (0);
+#endif
        g_hash_table_foreach (domain->class_vtable_hash, clear_cached_vtable, domain);
 #ifdef HAVE_SGEN_GC
        deregister_reflection_info_roots (domain);
index 70a0f83ee5589794bd87a84d97297145c60865b8..08f86a4c68aaad447d2187c852bd7ac4cc9199fe 100644 (file)
@@ -5321,7 +5321,7 @@ handle_remset (mword *p, void *start_nursery, void *end_nursery, gboolean global
        case REMSET_LOCATION:
                ptr = (void**)(*p);
                //__builtin_prefetch (ptr);
-               if (((void*)ptr < start_nursery || (void*)ptr >= end_nursery) && ptr_in_heap (ptr)) {
+               if (((void*)ptr < start_nursery || (void*)ptr >= end_nursery)) {
                        *ptr = copy_object (*ptr, start_nursery, end_nursery);
                        DEBUG (9, fprintf (gc_debug_file, "Overwrote remset at %p with %p\n", ptr, *ptr));
                        if (!global && *ptr >= start_nursery && *ptr < end_nursery) {
@@ -5338,7 +5338,7 @@ handle_remset (mword *p, void *start_nursery, void *end_nursery, gboolean global
                return p + 1;
        case REMSET_RANGE:
                ptr = (void**)(*p & ~REMSET_TYPE_MASK);
-               if (((void*)ptr >= start_nursery && (void*)ptr < end_nursery) || !ptr_in_heap (ptr))
+               if (((void*)ptr >= start_nursery && (void*)ptr < end_nursery))
                        return p + 2;
                count = p [1];
                while (count-- > 0) {
@@ -5351,7 +5351,7 @@ handle_remset (mword *p, void *start_nursery, void *end_nursery, gboolean global
                return p + 2;
        case REMSET_OBJECT:
                ptr = (void**)(*p & ~REMSET_TYPE_MASK);
-               if (((void*)ptr >= start_nursery && (void*)ptr < end_nursery) || !ptr_in_heap (ptr))
+               if (((void*)ptr >= start_nursery && (void*)ptr < end_nursery))
                        return p + 1;
                scan_object ((char*)ptr, start_nursery, end_nursery);
                return p + 1;
@@ -5360,7 +5360,7 @@ handle_remset (mword *p, void *start_nursery, void *end_nursery, gboolean global
 
                switch (p [1]) {
                case REMSET_VTYPE:
-                       if (((void*)ptr >= start_nursery && (void*)ptr < end_nursery) || !ptr_in_heap (ptr))
+                       if (((void*)ptr >= start_nursery && (void*)ptr < end_nursery))
                                return p + 4;
                        desc = p [2];
                        count = p [3];
@@ -5964,7 +5964,7 @@ mono_gc_wbarrier_generic_nostore (gpointer ptr)
 #endif
 
        LOCK_GC;
-       if (ptr_in_nursery (ptr) || !ptr_in_heap (ptr)) {
+       if (ptr_in_nursery (ptr) || ptr_on_stack (ptr)) {
                DEBUG (8, fprintf (gc_debug_file, "Skipping remset at %p\n", ptr));
                UNLOCK_GC;
                return;
@@ -6031,7 +6031,7 @@ mono_gc_wbarrier_value_copy (gpointer dest, gpointer src, int count, MonoClass *
        LOCK_GC;
        memmove (dest, src, count * mono_class_value_size (klass, NULL));
        rs = REMEMBERED_SET;
-       if (ptr_in_nursery (dest) || !ptr_in_heap (dest)) {
+       if (ptr_in_nursery (dest) || ptr_on_stack (dest)) {
                UNLOCK_GC;
                return;
        }
@@ -6078,7 +6078,7 @@ mono_gc_wbarrier_object_copy (MonoObject* obj, MonoObject *src)
        /* do not copy the sync state */
        memcpy ((char*)obj + sizeof (MonoObject), (char*)src + sizeof (MonoObject),
                        size - sizeof (MonoObject));
-       if (ptr_in_nursery (obj) || !ptr_in_heap (obj)) {
+       if (ptr_in_nursery (obj) || ptr_on_stack (obj)) {
                UNLOCK_GC;
                return;
        }