Mon Mar 25 13:04:56 CET 2002 Paolo Molaro <lupus@ximian.com>
[mono.git] / mono / metadata / appdomain.c
index 0d84e08356d06df87457b865281d45779d2bf2e2..c2623daad31b2d1a8ac3b8ab884d7095e25daf0c 100644 (file)
 #include <glib.h>
 #include <string.h>
 
+#if HAVE_BOEHM_GC
+#include <gc/gc.h>
+#endif
+
 #include <mono/metadata/object.h>
 #include <mono/metadata/appdomain.h>
 #include <mono/metadata/assembly.h>
 
 static guint32 appdomain_thread_id = 0;
 
+static MonoJitInfoTable *
+mono_jit_info_table_new ()
+{
+       return g_array_new (FALSE, FALSE, sizeof (gpointer));
+}
+
+static void
+mono_jit_info_table_free (MonoJitInfoTable *table)
+{
+       g_array_free (table, TRUE);
+}
+
+static int
+mono_jit_info_table_index (MonoJitInfoTable *table, gpointer addr)
+{
+       int left = 0, right = table->len;
+
+       while (left < right) {
+               int pos = (left + right) / 2;
+               MonoJitInfo *ji = g_array_index (table, gpointer, pos);
+               gpointer start = ji->code_start;
+               gpointer end = start + ji->code_size;
+
+               if (addr < start)
+                       right = pos;
+               else if (addr >= end) 
+                       left = pos + 1;
+               else
+                       return pos;
+       }
+
+       return left;
+}
+
+MonoJitInfo *
+mono_jit_info_table_find (MonoDomain *domain, gpointer addr)
+{
+       MonoJitInfoTable *table = domain->jit_info_table;
+       int left = 0, right = table->len;
+
+       while (left < right) {
+               int pos = (left + right) / 2;
+               MonoJitInfo *ji = g_array_index (table, gpointer, pos);
+               gpointer start = ji->code_start;
+               gpointer end = start + ji->code_size;
+
+               if (addr < start)
+                       right = pos;
+               else if (addr >= end) 
+                       left = pos + 1;
+               else
+                       return ji;
+       }
+
+       /* maybe irt is shared code, so we also search in the root domain */
+       if (domain != mono_root_domain)
+               return mono_jit_info_table_find (domain, addr);
+
+       return NULL;
+}
+
+void
+mono_jit_info_table_add (MonoDomain *domain, MonoJitInfo *ji)
+{
+       MonoJitInfoTable *table = domain->jit_info_table;
+       gpointer start = ji->code_start;
+       int pos = mono_jit_info_table_index (table, start);
+
+       g_array_insert_val (table, pos, ji);
+}
+
 static int
 ldstr_hash (const char* str)
 {
@@ -46,12 +121,24 @@ ldstr_equal (const char *str1, const char *str2) {
        return memcmp (str1, str2, len) == 0;
 }
 
+#if HAVE_BOEHM_GC
+static void
+domain_finalizer (void *obj, void *data) {
+       g_print ("domain finalized\n");
+}
+#endif
+
 static MonoDomain *
 mono_create_domain ()
 {
        MonoDomain *domain;
 
+#if HAVE_BOEHM_GC
+       domain = GC_malloc (sizeof (MonoDomain));
+       GC_register_finalizer (domain, domain_finalizer, NULL, NULL, NULL);
+#else
        domain = g_new0 (MonoDomain, 1);
+#endif
        domain->domain = NULL;
        domain->setup = NULL;
        domain->friendly_name = NULL;
@@ -59,10 +146,10 @@ mono_create_domain ()
        domain->mp = mono_mempool_new ();
        domain->env = g_hash_table_new (g_str_hash, g_str_equal);
        domain->assemblies = g_hash_table_new (g_str_hash, g_str_equal);
-       domain->class_vtable_hash = g_hash_table_new (NULL, NULL);
+       domain->class_vtable_hash = mono_g_hash_table_new (NULL, NULL);
        domain->jit_code_hash = g_hash_table_new (NULL, NULL);
-       domain->ldstr_table = g_hash_table_new ((GHashFunc)ldstr_hash, (GCompareFunc)ldstr_equal);
-
+       domain->ldstr_table = mono_g_hash_table_new ((GHashFunc)ldstr_hash, (GCompareFunc)ldstr_equal);
+       domain->jit_info_table = mono_jit_info_table_new ();
        return domain;
 }
 
@@ -100,9 +187,22 @@ mono_init (const char *filename)
        /* find the corlib */
        ass = mono_assembly_open (CORLIB_NAME, NULL, &status);
        if ((status != MONO_IMAGE_OK) || (ass == NULL)) {
-               g_print ("The assembly corlib.dll was not found or could not be loaded.\n");
-               g_print ("It should have been installed in the `%s' directory.\n", MONO_ASSEMBLIES);
-               exit (0);
+               switch (status){
+               case MONO_IMAGE_ERROR_ERRNO:
+                       g_print ("The assembly corlib.dll was not found or could not be loaded.\n");
+                       g_print ("It should have been installed in the `%s' directory.\n", MONO_ASSEMBLIES);
+                       break;
+               case MONO_IMAGE_IMAGE_INVALID:
+                       g_print ("The file %s/corlib.dll is an invalid CIL image\n", MONO_ASSEMBLIES);
+                       break;
+               case MONO_IMAGE_MISSING_ASSEMBLYREF:
+                       g_print ("Minning assembly reference in %s/corlib.dll\n", MONO_ASSEMBLIES);
+                       break;
+               case MONO_IMAGE_OK:
+                       /* to suppress compiler warning */
+               }
+               
+               exit (1);
        }
        mono_defaults.corlib = ass->image;
 
@@ -182,9 +282,18 @@ mono_init (const char *filename)
                 mono_defaults.corlib, "System", "Array");
        g_assert (mono_defaults.array_class != 0);
 
-       mono_defaults.delegate_class = mono_class_from_name (
-                mono_defaults.corlib, "System", "Delegate");
-       g_assert (mono_defaults.delegate_class != 0);
+       mono_defaults.multicastdelegate_class = mono_class_from_name (
+               mono_defaults.corlib, "System", "MulticastDelegate");
+       g_assert (mono_defaults.multicastdelegate_class != 0 );
+
+       mono_defaults.asyncresult_class = mono_class_from_name (
+               mono_defaults.corlib, "System.Runtime.Remoting.Messaging", 
+               "AsyncResult");
+       g_assert (mono_defaults.asyncresult_class != 0 );
+
+       mono_defaults.waithandle_class = mono_class_from_name (
+               mono_defaults.corlib, "System.Threading", "WaitHandle");
+       g_assert (mono_defaults.waithandle_class != 0 );
 
        mono_defaults.typehandle_class = mono_class_from_name (
                 mono_defaults.corlib, "System", "RuntimeTypeHandle");
@@ -206,6 +315,9 @@ mono_init (const char *filename)
                 mono_defaults.corlib, "System", "Exception");
        g_assert (mono_defaults.exception_class != 0);
 
+       mono_defaults.thread_class = mono_class_from_name (
+                mono_defaults.corlib, "System.Threading", "Thread");
+       g_assert (mono_defaults.thread_class != 0);
 
        class = mono_class_from_name (mono_defaults.corlib, "System", "AppDomainSetup");
        setup = (MonoAppDomainSetup *) mono_object_new (domain, class);
@@ -543,14 +655,18 @@ mono_domain_unload (MonoDomain *domain, gboolean force)
 
        g_hash_table_destroy (domain->env);
        g_hash_table_destroy (domain->assemblies);
-       g_hash_table_destroy (domain->class_vtable_hash);
+       mono_g_hash_table_destroy (domain->class_vtable_hash);
        g_hash_table_destroy (domain->jit_code_hash);
-       g_hash_table_destroy (domain->ldstr_table);
+       mono_g_hash_table_destroy (domain->ldstr_table);
+       mono_jit_info_table_free (domain->jit_info_table);
        mono_mempool_destroy (domain->mp);
        
        // fixme: anything else required ? */
 
+#if HAVE_BOEHM_GC
+#else
        g_free (domain);
+#endif
 
        if ((domain == mono_root_domain))
                mono_root_domain = NULL;
@@ -594,3 +710,4 @@ ves_icall_System_AppDomain_ExecuteAssembly (MonoAppDomain *ad, MonoString *file,
 
        return res;
 }
+