2009-08-10 Gonzalo Paniagua Javier <gonzalo@novell.com>
[mono.git] / mono / metadata / domain.c
index ec40d1dbac6a04088cd2e504129e9f8aa085f2cd..ebe13ad5568b4122f417702af92ce394563b8917 100644 (file)
@@ -132,6 +132,7 @@ static const MonoRuntimeInfo supported_runtimes[] = {
        {"v1.1.4322", "1.0", { {1,0,5000,0}, {7,0,5000,0} }     },
        {"v2.0.50215","2.0", { {2,0,0,0},    {8,0,0,0} }        },
        {"v2.0.50727","2.0", { {2,0,0,0},    {8,0,0,0} }        },
+       {"v4.0.20506","4.0", { {4,0,0,0},    {10,0,0,0} }   },
        {"moonlight", "2.1", { {2,0,5,0},    {9,0,0,0} }    },
 };
 
@@ -1199,7 +1200,9 @@ mono_domain_create (void)
        domain->jit_info_table = jit_info_table_new (domain);
        domain->jit_info_free_queue = NULL;
        domain->finalizable_objects_hash = g_hash_table_new (mono_aligned_addr_hash, NULL);
+#ifndef HAVE_SGEN_GC
        domain->track_resurrection_handles_hash = g_hash_table_new (mono_aligned_addr_hash, NULL);
+#endif
 
        InitializeCriticalSection (&domain->lock);
        InitializeCriticalSection (&domain->assemblies_lock);
@@ -1563,6 +1566,9 @@ mono_init_internal (const char *filename, const char *exe_filename, const char *
        mono_defaults.internals_visible_class = mono_class_from_name (
                mono_defaults.corlib, "System.Runtime.CompilerServices", "InternalsVisibleToAttribute");
 
+       mono_defaults.critical_finalizer_object = mono_class_from_name (
+               mono_defaults.corlib, "System.Runtime.ConstrainedExecution", "CriticalFinalizerObject");
+
        /*
         * mscorlib needs a little help, only now it can load its friends list (after we have
         * loaded the InternalsVisibleToAttribute), load it now
@@ -1751,6 +1757,28 @@ mono_domain_get ()
        return GET_APPDOMAIN ();
 }
 
+void
+mono_domain_set_internal_with_options (MonoDomain *domain, gboolean migrate_exception)
+{
+       MonoThread *thread;
+
+       if (mono_domain_get () == domain)
+               return;
+
+       SET_APPDOMAIN (domain);
+       SET_APPCONTEXT (domain->default_context);
+
+       if (migrate_exception) {
+               thread = mono_thread_current ();
+               if (!thread->abort_exc)
+                       return;
+
+               g_assert (thread->abort_exc->object.vtable->domain != domain);
+               MONO_OBJECT_SETREF (thread, abort_exc, mono_get_exception_thread_abort ());
+               g_assert (thread->abort_exc->object.vtable->domain == domain);
+       }
+}
+
 /**
  * mono_domain_set_internal:
  * @domain: the new domain
@@ -1760,8 +1788,7 @@ mono_domain_get ()
 void
 mono_domain_set_internal (MonoDomain *domain)
 {
-       SET_APPDOMAIN (domain);
-       SET_APPCONTEXT (domain->default_context);
+       mono_domain_set_internal_with_options (domain, TRUE);
 }
 
 void
@@ -1799,6 +1826,7 @@ mono_domain_foreach (MonoDomainFunc func, gpointer user_data)
 MonoAssembly *
 mono_domain_assembly_open (MonoDomain *domain, const char *name)
 {
+       MonoDomain *current;
        MonoAssembly *ass;
        GSList *tmp;
 
@@ -1812,8 +1840,15 @@ mono_domain_assembly_open (MonoDomain *domain, const char *name)
        }
        mono_domain_assemblies_unlock (domain);
 
-       if (!(ass = mono_assembly_open (name, NULL)))
-               return NULL;
+       if (domain != mono_domain_get ()) {
+               current = mono_domain_get ();
+
+               mono_domain_set (domain, FALSE);
+               ass = mono_assembly_open (name, NULL);
+               mono_domain_set (current, FALSE);
+       } else {
+               ass = mono_assembly_open (name, NULL);
+       }
 
        return ass;
 }
@@ -1844,6 +1879,8 @@ mono_domain_free (MonoDomain *domain, gboolean force)
 
        mono_debug_domain_unload (domain);
 
+       mono_gc_clear_domain (domain);
+
        mono_appdomains_lock ();
        appdomains_list [domain->domain_id] = NULL;
        mono_appdomains_unlock ();
@@ -1917,26 +1954,27 @@ mono_domain_free (MonoDomain *domain, gboolean force)
        mono_code_manager_destroy (domain->code_mp);
        domain->code_mp = NULL;
 #endif 
+
+       mono_reflection_cleanup_domain (domain);
+       
        if (domain->type_hash) {
                mono_g_hash_table_destroy (domain->type_hash);
                domain->type_hash = NULL;
        }
-       if (domain->refobject_hash) {
-               mono_g_hash_table_destroy (domain->refobject_hash);
-               domain->refobject_hash = NULL;
-       }
        if (domain->type_init_exception_hash) {
                mono_g_hash_table_destroy (domain->type_init_exception_hash);
                domain->type_init_exception_hash = NULL;
        }
        g_hash_table_destroy (domain->finalizable_objects_hash);
        domain->finalizable_objects_hash = NULL;
+#ifndef HAVE_SGEN_GC
        if (domain->track_resurrection_objects_hash) {
                g_hash_table_foreach (domain->track_resurrection_objects_hash, free_slist, NULL);
                g_hash_table_destroy (domain->track_resurrection_objects_hash);
        }
        if (domain->track_resurrection_handles_hash)
                g_hash_table_destroy (domain->track_resurrection_handles_hash);
+#endif
        if (domain->method_rgctx_hash) {
                g_hash_table_destroy (domain->method_rgctx_hash);
                domain->method_rgctx_hash = NULL;