3 * domain.c: MonoDomain functions
6 * Dietmar Maurer (dietmar@ximian.com)
8 * (C) 2001 Ximian, Inc.
19 #include <mono/metadata/object.h>
20 #include <mono/metadata/appdomain.h>
21 #include <mono/metadata/assembly.h>
22 #include <mono/metadata/exception.h>
23 #include <mono/metadata/cil-coff.h>
25 static guint32 appdomain_thread_id = 0;
27 MonoDomain *mono_root_domain = NULL;
29 static MonoJitInfoTable *
30 mono_jit_info_table_new (void)
32 return g_array_new (FALSE, FALSE, sizeof (gpointer));
36 mono_jit_info_table_free (MonoJitInfoTable *table)
38 g_array_free (table, TRUE);
42 mono_jit_info_table_index (MonoJitInfoTable *table, char *addr)
44 int left = 0, right = table->len;
46 while (left < right) {
47 int pos = (left + right) / 2;
48 MonoJitInfo *ji = g_array_index (table, gpointer, pos);
49 char *start = ji->code_start;
50 char *end = start + ji->code_size;
64 mono_jit_info_table_find (MonoDomain *domain, char *addr)
66 MonoJitInfoTable *table = domain->jit_info_table;
67 int left = 0, right = table->len;
69 while (left < right) {
70 int pos = (left + right) / 2;
71 MonoJitInfo *ji = g_array_index (table, gpointer, pos);
72 char *start = ji->code_start;
73 char *end = start + ji->code_size;
83 /* maybe irt is shared code, so we also search in the root domain */
84 if (domain != mono_root_domain)
85 return mono_jit_info_table_find (mono_root_domain, addr);
91 mono_jit_info_table_add (MonoDomain *domain, MonoJitInfo *ji)
93 MonoJitInfoTable *table = domain->jit_info_table;
94 gpointer start = ji->code_start;
95 int pos = mono_jit_info_table_index (table, start);
97 g_array_insert_val (table, pos, ji);
101 ldstr_hash (const char* str)
105 len = mono_metadata_decode_blob_size (str, &str) - 1;
107 /* if len == 0 *str will point to the mark byte */
110 * FIXME: The distribution may not be so nice with lots of
111 * null chars in the string.
113 for (str += 1; str < end; str++)
114 h = (h << 5) - h + *str;
119 ldstr_equal (const char *str1, const char *str2) {
121 len = mono_metadata_decode_blob_size (str1, NULL) - 1;
122 len2 = mono_metadata_decode_blob_size (str2, NULL) - 1;
125 return memcmp (str1, str2, len) == 0;
130 domain_finalizer (void *obj, void *data) {
131 g_print ("domain finalized\n");
136 mono_domain_create (void)
141 domain = GC_malloc (sizeof (MonoDomain));
142 GC_register_finalizer (domain, domain_finalizer, NULL, NULL, NULL);
144 domain = g_new0 (MonoDomain, 1);
146 domain->domain = NULL;
147 domain->setup = NULL;
148 domain->friendly_name = NULL;
150 domain->mp = mono_mempool_new ();
151 domain->env = g_hash_table_new (g_str_hash, g_str_equal);
152 domain->assemblies = g_hash_table_new (g_str_hash, g_str_equal);
153 domain->class_vtable_hash = mono_g_hash_table_new (NULL, NULL);
154 domain->proxy_vtable_hash = mono_g_hash_table_new (NULL, NULL);
155 domain->static_data_hash = mono_g_hash_table_new (NULL, NULL);
156 domain->jit_code_hash = g_hash_table_new (NULL, NULL);
157 domain->ldstr_table = mono_g_hash_table_new ((GHashFunc)ldstr_hash, (GCompareFunc)ldstr_equal);
158 domain->jit_info_table = mono_jit_info_table_new ();
160 InitializeCriticalSection (&domain->lock);
167 * Creates the initial application domain and initializes the mono_defaults
169 * This function is guaranteed to not run any IL code.
171 * Returns: the initial domain.
174 mono_init (const char *filename)
176 static MonoDomain *domain = NULL;
178 MonoImageOpenStatus status = MONO_IMAGE_OK;
179 MonoAssemblyName corlib_aname;
182 g_assert_not_reached ();
184 appdomain_thread_id = TlsAlloc ();
186 domain = mono_domain_create ();
187 mono_root_domain = domain;
189 TlsSetValue (appdomain_thread_id, domain);
191 /* find the corlib */
192 corlib_aname.name = "corlib";
193 ass = mono_assembly_load (&corlib_aname, NULL, &status);
194 if ((status != MONO_IMAGE_OK) || (ass == NULL)) {
196 case MONO_IMAGE_ERROR_ERRNO:
197 g_print ("The assembly corlib.dll was not found or could not be loaded.\n");
198 g_print ("It should have been installed in the `%s' directory.\n", MONO_ASSEMBLIES);
200 case MONO_IMAGE_IMAGE_INVALID:
201 g_print ("The file %s/corlib.dll is an invalid CIL image\n", MONO_ASSEMBLIES);
203 case MONO_IMAGE_MISSING_ASSEMBLYREF:
204 g_print ("Minning assembly reference in %s/corlib.dll\n", MONO_ASSEMBLIES);
207 /* to suppress compiler warning */
213 mono_defaults.corlib = ass->image;
215 mono_defaults.object_class = mono_class_from_name (
216 mono_defaults.corlib, "System", "Object");
217 g_assert (mono_defaults.object_class != 0);
219 mono_defaults.void_class = mono_class_from_name (
220 mono_defaults.corlib, "System", "Void");
221 g_assert (mono_defaults.void_class != 0);
223 mono_defaults.boolean_class = mono_class_from_name (
224 mono_defaults.corlib, "System", "Boolean");
225 g_assert (mono_defaults.boolean_class != 0);
227 mono_defaults.byte_class = mono_class_from_name (
228 mono_defaults.corlib, "System", "Byte");
229 g_assert (mono_defaults.byte_class != 0);
231 mono_defaults.sbyte_class = mono_class_from_name (
232 mono_defaults.corlib, "System", "SByte");
233 g_assert (mono_defaults.sbyte_class != 0);
235 mono_defaults.int16_class = mono_class_from_name (
236 mono_defaults.corlib, "System", "Int16");
237 g_assert (mono_defaults.int16_class != 0);
239 mono_defaults.uint16_class = mono_class_from_name (
240 mono_defaults.corlib, "System", "UInt16");
241 g_assert (mono_defaults.uint16_class != 0);
243 mono_defaults.int32_class = mono_class_from_name (
244 mono_defaults.corlib, "System", "Int32");
245 g_assert (mono_defaults.int32_class != 0);
247 mono_defaults.uint32_class = mono_class_from_name (
248 mono_defaults.corlib, "System", "UInt32");
249 g_assert (mono_defaults.uint32_class != 0);
251 mono_defaults.uint_class = mono_class_from_name (
252 mono_defaults.corlib, "System", "UIntPtr");
253 g_assert (mono_defaults.uint_class != 0);
255 mono_defaults.int_class = mono_class_from_name (
256 mono_defaults.corlib, "System", "IntPtr");
257 g_assert (mono_defaults.int_class != 0);
259 mono_defaults.int64_class = mono_class_from_name (
260 mono_defaults.corlib, "System", "Int64");
261 g_assert (mono_defaults.int64_class != 0);
263 mono_defaults.uint64_class = mono_class_from_name (
264 mono_defaults.corlib, "System", "UInt64");
265 g_assert (mono_defaults.uint64_class != 0);
267 mono_defaults.single_class = mono_class_from_name (
268 mono_defaults.corlib, "System", "Single");
269 g_assert (mono_defaults.single_class != 0);
271 mono_defaults.double_class = mono_class_from_name (
272 mono_defaults.corlib, "System", "Double");
273 g_assert (mono_defaults.double_class != 0);
275 mono_defaults.char_class = mono_class_from_name (
276 mono_defaults.corlib, "System", "Char");
277 g_assert (mono_defaults.char_class != 0);
279 mono_defaults.string_class = mono_class_from_name (
280 mono_defaults.corlib, "System", "String");
281 g_assert (mono_defaults.string_class != 0);
283 mono_defaults.enum_class = mono_class_from_name (
284 mono_defaults.corlib, "System", "Enum");
285 g_assert (mono_defaults.enum_class != 0);
287 mono_defaults.array_class = mono_class_from_name (
288 mono_defaults.corlib, "System", "Array");
289 g_assert (mono_defaults.array_class != 0);
291 mono_defaults.multicastdelegate_class = mono_class_from_name (
292 mono_defaults.corlib, "System", "MulticastDelegate");
293 g_assert (mono_defaults.multicastdelegate_class != 0 );
295 mono_defaults.asyncresult_class = mono_class_from_name (
296 mono_defaults.corlib, "System.Runtime.Remoting.Messaging",
298 g_assert (mono_defaults.asyncresult_class != 0 );
300 mono_defaults.waithandle_class = mono_class_from_name (
301 mono_defaults.corlib, "System.Threading", "WaitHandle");
302 g_assert (mono_defaults.waithandle_class != 0 );
304 mono_defaults.typehandle_class = mono_class_from_name (
305 mono_defaults.corlib, "System", "RuntimeTypeHandle");
306 g_assert (mono_defaults.typehandle_class != 0);
308 mono_defaults.methodhandle_class = mono_class_from_name (
309 mono_defaults.corlib, "System", "RuntimeMethodHandle");
310 g_assert (mono_defaults.methodhandle_class != 0);
312 mono_defaults.fieldhandle_class = mono_class_from_name (
313 mono_defaults.corlib, "System", "RuntimeFieldHandle");
314 g_assert (mono_defaults.fieldhandle_class != 0);
316 mono_defaults.monotype_class = mono_class_from_name (
317 mono_defaults.corlib, "System", "MonoType");
318 g_assert (mono_defaults.monotype_class != 0);
320 mono_defaults.exception_class = mono_class_from_name (
321 mono_defaults.corlib, "System", "Exception");
322 g_assert (mono_defaults.exception_class != 0);
324 mono_defaults.thread_class = mono_class_from_name (
325 mono_defaults.corlib, "System.Threading", "Thread");
326 g_assert (mono_defaults.thread_class != 0);
328 mono_defaults.appdomain_class = mono_class_from_name (
329 mono_defaults.corlib, "System", "AppDomain");
330 g_assert (mono_defaults.appdomain_class != 0);
332 mono_defaults.transparent_proxy_class = mono_class_from_name (
333 mono_defaults.corlib, "System.Runtime.Remoting.Proxies", "TransparentProxy");
334 g_assert (mono_defaults.transparent_proxy_class != 0);
336 mono_defaults.real_proxy_class = mono_class_from_name (
337 mono_defaults.corlib, "System.Runtime.Remoting.Proxies", "RealProxy");
338 g_assert (mono_defaults.real_proxy_class != 0);
340 mono_defaults.mono_method_message_class = mono_class_from_name (
341 mono_defaults.corlib, "System.Runtime.Remoting.Messaging", "MonoMethodMessage");
342 g_assert (mono_defaults.mono_method_message_class != 0);
344 mono_defaults.field_info_class = mono_class_from_name (
345 mono_defaults.corlib, "System.Reflection", "FieldInfo");
346 g_assert (mono_defaults.field_info_class != 0);
348 mono_defaults.stringbuilder_class = mono_class_from_name (
349 mono_defaults.corlib, "System.Text", "StringBuilder");
350 g_assert (mono_defaults.stringbuilder_class != 0);
352 mono_defaults.math_class = mono_class_from_name (
353 mono_defaults.corlib, "System", "Math");
354 g_assert (mono_defaults.math_class != 0);
356 mono_defaults.stack_frame_class = mono_class_from_name (
357 mono_defaults.corlib, "System.Diagnostics", "StackFrame");
358 g_assert (mono_defaults.stack_frame_class != 0);
360 mono_defaults.stack_trace_class = mono_class_from_name (
361 mono_defaults.corlib, "System.Diagnostics", "StackTrace");
362 g_assert (mono_defaults.stack_trace_class != 0);
364 mono_defaults.marshal_class = mono_class_from_name (
365 mono_defaults.corlib, "System.Runtime.InteropServices", "Marshal");
366 g_assert (mono_defaults.marshal_class != 0);
368 domain->friendly_name = g_path_get_basename (filename);
376 * Returns the current domain.
381 return ((MonoDomain *)TlsGetValue (appdomain_thread_id));
386 * @domain: the new domain
388 * Sets the current domain to @domain.
391 mono_domain_set (MonoDomain *domain)
393 TlsSetValue (appdomain_thread_id, domain);
397 * mono_domain_assembly_open:
398 * @domain: the application domain
399 * @name: file name of the assembly
401 * fixme: maybe we should integrate this with mono_assembly_open ??
404 mono_domain_assembly_open (MonoDomain *domain, char *name)
406 MonoAssembly *ass, *tmp;
409 if ((ass = g_hash_table_lookup (domain->assemblies, name)))
412 if (!(ass = mono_assembly_open (name, NULL)))
415 mono_domain_lock (domain);
416 g_hash_table_insert (domain->assemblies, ass->aname.name, ass);
417 mono_domain_unlock (domain);
419 /* FIXME: maybe this must be recursive ? */
420 for (i = 0; (tmp = ass->image->references [i]) != NULL; i++) {
421 if (!g_hash_table_lookup (domain->assemblies, tmp->aname.name))
422 g_hash_table_insert (domain->assemblies, tmp->aname.name, tmp);
429 remove_assembly (gpointer key, gpointer value, gpointer user_data)
431 mono_assembly_close ((MonoAssembly *)value);
435 mono_domain_unload (MonoDomain *domain, gboolean force)
437 if ((domain == mono_root_domain) && !force) {
438 g_warning ("cant unload root domain");
442 g_free (domain->friendly_name);
443 g_hash_table_foreach (domain->assemblies, remove_assembly, NULL);
445 g_hash_table_destroy (domain->env);
446 g_hash_table_destroy (domain->assemblies);
447 mono_g_hash_table_destroy (domain->class_vtable_hash);
448 mono_g_hash_table_destroy (domain->proxy_vtable_hash);
449 mono_g_hash_table_destroy (domain->static_data_hash);
450 g_hash_table_destroy (domain->jit_code_hash);
451 mono_g_hash_table_destroy (domain->ldstr_table);
452 mono_jit_info_table_free (domain->jit_info_table);
453 mono_mempool_destroy (domain->mp);
454 DeleteCriticalSection (&domain->lock);
456 /* FIXME: anything else required ? */
463 if ((domain == mono_root_domain))
464 mono_root_domain = NULL;