3 * domain.c: MonoDomain functions
6 * Dietmar Maurer (dietmar@ximian.com)
9 * (C) 2001 Ximian, Inc.
16 #include <mono/os/gc_wrapper.h>
18 #include <mono/metadata/object.h>
19 #include <mono/metadata/appdomain.h>
20 #include <mono/metadata/assembly.h>
21 #include <mono/metadata/exception.h>
22 #include <mono/metadata/cil-coff.h>
24 static guint32 appdomain_thread_id = 0;
25 static guint32 context_thread_id = 0;
27 static gint32 appdomain_id_counter = 0;
29 MonoGHashTable * appdomains_list = NULL;
31 MonoDomain *mono_root_domain = NULL;
33 static MonoJitInfoTable *
34 mono_jit_info_table_new (void)
36 return g_array_new (FALSE, FALSE, sizeof (gpointer));
40 mono_jit_info_table_free (MonoJitInfoTable *table)
42 g_array_free (table, TRUE);
46 mono_jit_info_table_index (MonoJitInfoTable *table, char *addr)
48 int left = 0, right = table->len;
50 while (left < right) {
51 int pos = (left + right) / 2;
52 MonoJitInfo *ji = g_array_index (table, gpointer, pos);
53 char *start = ji->code_start;
54 char *end = start + ji->code_size;
68 mono_jit_info_table_find (MonoDomain *domain, char *addr)
70 MonoJitInfoTable *table = domain->jit_info_table;
71 int left = 0, right = table->len;
73 while (left < right) {
74 int pos = (left + right) / 2;
75 MonoJitInfo *ji = g_array_index (table, gpointer, pos);
76 char *start = ji->code_start;
77 char *end = start + ji->code_size;
87 /* maybe irt is shared code, so we also search in the root domain */
88 if (domain != mono_root_domain)
89 return mono_jit_info_table_find (mono_root_domain, addr);
95 mono_jit_info_table_add (MonoDomain *domain, MonoJitInfo *ji)
97 MonoJitInfoTable *table = domain->jit_info_table;
98 gpointer start = ji->code_start;
99 int pos = mono_jit_info_table_index (table, start);
101 g_array_insert_val (table, pos, ji);
105 ldstr_hash (const char* str)
109 len = mono_metadata_decode_blob_size (str, &str) - 1;
111 /* if len == 0 *str will point to the mark byte */
114 * FIXME: The distribution may not be so nice with lots of
115 * null chars in the string.
117 for (str += 1; str < end; str++)
118 h = (h << 5) - h + *str;
123 ldstr_equal (const char *str1, const char *str2) {
125 len = mono_metadata_decode_blob_size (str1, NULL) - 1;
126 len2 = mono_metadata_decode_blob_size (str2, NULL) - 1;
129 return memcmp (str1, str2, len) == 0;
133 mono_string_equal (MonoString *s1, MonoString *s2)
135 int l1 = mono_string_length (s1);
136 int l2 = mono_string_length (s2);
141 return memcmp (mono_string_chars (s1), mono_string_chars (s2), l1) == 0;
145 mono_string_hash (MonoString *s)
147 const guint16 *p = mono_string_chars (s);
148 int i, len = mono_string_length (s);
151 for (i = 0; i < len; i++) {
152 h = (h << 5) - h + *p;
161 domain_finalizer (void *obj, void *data) {
162 g_print ("domain finalized\n");
167 mono_domain_create (void)
172 domain = GC_MALLOC (sizeof (MonoDomain));
173 GC_REGISTER_FINALIZER (domain, domain_finalizer, NULL, NULL, NULL);
175 domain = g_new0 (MonoDomain, 1);
177 domain->domain = NULL;
178 domain->setup = NULL;
179 domain->friendly_name = NULL;
180 domain->search_path = NULL;
182 domain->mp = mono_mempool_new ();
183 domain->code_mp = mono_mempool_new ();
184 domain->env = mono_g_hash_table_new ((GHashFunc)mono_string_hash, (GCompareFunc)mono_string_equal);
185 domain->assemblies = g_hash_table_new (g_str_hash, g_str_equal);
186 domain->class_vtable_hash = mono_g_hash_table_new (NULL, NULL);
187 domain->proxy_vtable_hash = mono_g_hash_table_new (NULL, NULL);
188 domain->static_data_hash = mono_g_hash_table_new (NULL, NULL);
189 domain->jit_code_hash = g_hash_table_new (NULL, NULL);
190 domain->ldstr_table = mono_g_hash_table_new ((GHashFunc)ldstr_hash, (GCompareFunc)ldstr_equal);
191 domain->jit_info_table = mono_jit_info_table_new ();
192 domain->domain_id = InterlockedIncrement (&appdomain_id_counter);
194 InitializeCriticalSection (&domain->lock);
196 mono_g_hash_table_insert(appdomains_list, GINT_TO_POINTER(domain->domain_id), domain);
204 * Creates the initial application domain and initializes the mono_defaults
206 * This function is guaranteed to not run any IL code.
208 * Returns: the initial domain.
211 mono_init (const char *filename)
213 static MonoDomain *domain = NULL;
215 MonoImageOpenStatus status = MONO_IMAGE_OK;
216 MonoAssemblyName corlib_aname;
219 g_assert_not_reached ();
221 appdomain_thread_id = TlsAlloc ();
222 context_thread_id = TlsAlloc ();
224 // FIXME: When should we release this memory?
225 appdomains_list = mono_g_hash_table_new (g_direct_hash, g_direct_equal);
227 domain = mono_domain_create ();
228 mono_root_domain = domain;
230 TlsSetValue (appdomain_thread_id, domain);
232 /* find the corlib */
233 corlib_aname.name = "corlib";
234 ass = mono_assembly_load (&corlib_aname, NULL, &status);
235 if ((status != MONO_IMAGE_OK) || (ass == NULL)) {
237 case MONO_IMAGE_ERROR_ERRNO:
238 g_print ("The assembly corlib.dll was not found or could not be loaded.\n");
239 g_print ("It should have been installed in the `%s' directory.\n", MONO_ASSEMBLIES);
241 case MONO_IMAGE_IMAGE_INVALID:
242 g_print ("The file %s/corlib.dll is an invalid CIL image\n", MONO_ASSEMBLIES);
244 case MONO_IMAGE_MISSING_ASSEMBLYREF:
245 g_print ("Minning assembly reference in %s/corlib.dll\n", MONO_ASSEMBLIES);
248 /* to suppress compiler warning */
254 mono_defaults.corlib = ass->image;
256 mono_defaults.object_class = mono_class_from_name (
257 mono_defaults.corlib, "System", "Object");
258 g_assert (mono_defaults.object_class != 0);
260 mono_defaults.void_class = mono_class_from_name (
261 mono_defaults.corlib, "System", "Void");
262 g_assert (mono_defaults.void_class != 0);
264 mono_defaults.boolean_class = mono_class_from_name (
265 mono_defaults.corlib, "System", "Boolean");
266 g_assert (mono_defaults.boolean_class != 0);
268 mono_defaults.byte_class = mono_class_from_name (
269 mono_defaults.corlib, "System", "Byte");
270 g_assert (mono_defaults.byte_class != 0);
272 mono_defaults.sbyte_class = mono_class_from_name (
273 mono_defaults.corlib, "System", "SByte");
274 g_assert (mono_defaults.sbyte_class != 0);
276 mono_defaults.int16_class = mono_class_from_name (
277 mono_defaults.corlib, "System", "Int16");
278 g_assert (mono_defaults.int16_class != 0);
280 mono_defaults.uint16_class = mono_class_from_name (
281 mono_defaults.corlib, "System", "UInt16");
282 g_assert (mono_defaults.uint16_class != 0);
284 mono_defaults.int32_class = mono_class_from_name (
285 mono_defaults.corlib, "System", "Int32");
286 g_assert (mono_defaults.int32_class != 0);
288 mono_defaults.uint32_class = mono_class_from_name (
289 mono_defaults.corlib, "System", "UInt32");
290 g_assert (mono_defaults.uint32_class != 0);
292 mono_defaults.uint_class = mono_class_from_name (
293 mono_defaults.corlib, "System", "UIntPtr");
294 g_assert (mono_defaults.uint_class != 0);
296 mono_defaults.int_class = mono_class_from_name (
297 mono_defaults.corlib, "System", "IntPtr");
298 g_assert (mono_defaults.int_class != 0);
300 mono_defaults.int64_class = mono_class_from_name (
301 mono_defaults.corlib, "System", "Int64");
302 g_assert (mono_defaults.int64_class != 0);
304 mono_defaults.uint64_class = mono_class_from_name (
305 mono_defaults.corlib, "System", "UInt64");
306 g_assert (mono_defaults.uint64_class != 0);
308 mono_defaults.single_class = mono_class_from_name (
309 mono_defaults.corlib, "System", "Single");
310 g_assert (mono_defaults.single_class != 0);
312 mono_defaults.double_class = mono_class_from_name (
313 mono_defaults.corlib, "System", "Double");
314 g_assert (mono_defaults.double_class != 0);
316 mono_defaults.char_class = mono_class_from_name (
317 mono_defaults.corlib, "System", "Char");
318 g_assert (mono_defaults.char_class != 0);
320 mono_defaults.string_class = mono_class_from_name (
321 mono_defaults.corlib, "System", "String");
322 g_assert (mono_defaults.string_class != 0);
324 mono_defaults.enum_class = mono_class_from_name (
325 mono_defaults.corlib, "System", "Enum");
326 g_assert (mono_defaults.enum_class != 0);
328 mono_defaults.array_class = mono_class_from_name (
329 mono_defaults.corlib, "System", "Array");
330 g_assert (mono_defaults.array_class != 0);
332 mono_defaults.multicastdelegate_class = mono_class_from_name (
333 mono_defaults.corlib, "System", "MulticastDelegate");
334 g_assert (mono_defaults.multicastdelegate_class != 0 );
336 mono_defaults.asyncresult_class = mono_class_from_name (
337 mono_defaults.corlib, "System.Runtime.Remoting.Messaging",
339 g_assert (mono_defaults.asyncresult_class != 0 );
341 mono_defaults.waithandle_class = mono_class_from_name (
342 mono_defaults.corlib, "System.Threading", "WaitHandle");
343 g_assert (mono_defaults.waithandle_class != 0 );
345 mono_defaults.typehandle_class = mono_class_from_name (
346 mono_defaults.corlib, "System", "RuntimeTypeHandle");
347 g_assert (mono_defaults.typehandle_class != 0);
349 mono_defaults.methodhandle_class = mono_class_from_name (
350 mono_defaults.corlib, "System", "RuntimeMethodHandle");
351 g_assert (mono_defaults.methodhandle_class != 0);
353 mono_defaults.fieldhandle_class = mono_class_from_name (
354 mono_defaults.corlib, "System", "RuntimeFieldHandle");
355 g_assert (mono_defaults.fieldhandle_class != 0);
357 mono_defaults.monotype_class = mono_class_from_name (
358 mono_defaults.corlib, "System", "MonoType");
359 g_assert (mono_defaults.monotype_class != 0);
361 mono_defaults.exception_class = mono_class_from_name (
362 mono_defaults.corlib, "System", "Exception");
363 g_assert (mono_defaults.exception_class != 0);
365 mono_defaults.threadabortexception_class = mono_class_from_name (
366 mono_defaults.corlib, "System.Threading", "ThreadAbortException");
367 g_assert (mono_defaults.threadabortexception_class != 0);
369 mono_defaults.thread_class = mono_class_from_name (
370 mono_defaults.corlib, "System.Threading", "Thread");
371 g_assert (mono_defaults.thread_class != 0);
373 mono_defaults.appdomain_class = mono_class_from_name (
374 mono_defaults.corlib, "System", "AppDomain");
375 g_assert (mono_defaults.appdomain_class != 0);
377 mono_defaults.transparent_proxy_class = mono_class_from_name (
378 mono_defaults.corlib, "System.Runtime.Remoting.Proxies", "TransparentProxy");
379 g_assert (mono_defaults.transparent_proxy_class != 0);
381 mono_defaults.real_proxy_class = mono_class_from_name (
382 mono_defaults.corlib, "System.Runtime.Remoting.Proxies", "RealProxy");
383 g_assert (mono_defaults.real_proxy_class != 0);
385 mono_defaults.mono_method_message_class = mono_class_from_name (
386 mono_defaults.corlib, "System.Runtime.Remoting.Messaging", "MonoMethodMessage");
387 g_assert (mono_defaults.mono_method_message_class != 0);
389 mono_defaults.field_info_class = mono_class_from_name (
390 mono_defaults.corlib, "System.Reflection", "FieldInfo");
391 g_assert (mono_defaults.field_info_class != 0);
393 mono_defaults.method_info_class = mono_class_from_name (
394 mono_defaults.corlib, "System.Reflection", "MethodInfo");
395 g_assert (mono_defaults.method_info_class != 0);
397 mono_defaults.stringbuilder_class = mono_class_from_name (
398 mono_defaults.corlib, "System.Text", "StringBuilder");
399 g_assert (mono_defaults.stringbuilder_class != 0);
401 mono_defaults.math_class = mono_class_from_name (
402 mono_defaults.corlib, "System", "Math");
403 g_assert (mono_defaults.math_class != 0);
405 mono_defaults.stack_frame_class = mono_class_from_name (
406 mono_defaults.corlib, "System.Diagnostics", "StackFrame");
407 g_assert (mono_defaults.stack_frame_class != 0);
409 mono_defaults.stack_trace_class = mono_class_from_name (
410 mono_defaults.corlib, "System.Diagnostics", "StackTrace");
411 g_assert (mono_defaults.stack_trace_class != 0);
413 mono_defaults.marshal_class = mono_class_from_name (
414 mono_defaults.corlib, "System.Runtime.InteropServices", "Marshal");
415 g_assert (mono_defaults.marshal_class != 0);
417 mono_defaults.iserializeable_class = mono_class_from_name (
418 mono_defaults.corlib, "System.Runtime.Serialization", "ISerializable");
419 g_assert (mono_defaults.iserializeable_class != 0);
421 mono_defaults.serializationinfo_class = mono_class_from_name (
422 mono_defaults.corlib, "System.Runtime.Serialization", "SerializationInfo");
423 g_assert (mono_defaults.serializationinfo_class != 0);
425 mono_defaults.streamingcontext_class = mono_class_from_name (
426 mono_defaults.corlib, "System.Runtime.Serialization", "StreamingContext");
427 g_assert (mono_defaults.streamingcontext_class != 0);
429 mono_defaults.typed_reference_class = mono_class_from_name (
430 mono_defaults.corlib, "System", "TypedReference");
431 g_assert (mono_defaults.typed_reference_class != 0);
433 domain->friendly_name = g_path_get_basename (filename);
441 * Returns the current domain.
446 return ((MonoDomain *)TlsGetValue (appdomain_thread_id));
451 * @domain: the new domain
453 * Sets the current domain to @domain.
456 mono_domain_set (MonoDomain *domain)
458 TlsSetValue (appdomain_thread_id, domain);
459 TlsSetValue (context_thread_id, domain->default_context);
463 * mono_domain_assembly_open:
464 * @domain: the application domain
465 * @name: file name of the assembly
467 * fixme: maybe we should integrate this with mono_assembly_open ??
470 mono_domain_assembly_open (MonoDomain *domain, const char *name)
474 if ((ass = g_hash_table_lookup (domain->assemblies, name)))
477 if (!(ass = mono_assembly_open (name, NULL)))
484 remove_assembly (gpointer key, gpointer value, gpointer user_data)
486 mono_assembly_close ((MonoAssembly *)value);
490 mono_domain_unload (MonoDomain *domain, gboolean force)
492 if ((domain == mono_root_domain) && !force) {
493 g_warning ("cant unload root domain");
497 mono_g_hash_table_remove(appdomains_list, GINT_TO_POINTER(domain->domain_id));
499 g_free (domain->friendly_name);
500 g_hash_table_foreach (domain->assemblies, remove_assembly, NULL);
502 mono_g_hash_table_destroy (domain->env);
503 g_hash_table_destroy (domain->assemblies);
504 mono_g_hash_table_destroy (domain->class_vtable_hash);
505 mono_g_hash_table_destroy (domain->proxy_vtable_hash);
506 mono_g_hash_table_destroy (domain->static_data_hash);
507 g_hash_table_destroy (domain->jit_code_hash);
508 mono_g_hash_table_destroy (domain->ldstr_table);
509 mono_jit_info_table_free (domain->jit_info_table);
510 mono_mempool_destroy (domain->mp);
511 mono_mempool_destroy (domain->code_mp);
512 DeleteCriticalSection (&domain->lock);
513 domain->setup = NULL;
515 /* FIXME: anything else required ? */
522 if ((domain == mono_root_domain))
523 mono_root_domain = NULL;
527 * mono_domain_get_id:
529 * Returns the a domain for a specific domain id.
532 mono_domain_get_by_id (gint32 domainid)
536 if ((domain = mono_g_hash_table_lookup(appdomains_list, GINT_TO_POINTER(domainid))))
543 mono_context_set (MonoAppContext * new_context)
545 TlsSetValue (context_thread_id, new_context);
551 return ((MonoAppContext *)TlsGetValue (context_thread_id));