New tests.
[mono.git] / mono / metadata / domain-internals.h
1 /*
2  * Appdomain-related internal data structures and functions.
3  */
4 #ifndef __MONO_METADATA_DOMAIN_INTERNALS_H__
5 #define __MONO_METADATA_DOMAIN_INTERNALS_H__
6
7 #include <mono/metadata/appdomain.h>
8 #include <mono/metadata/mempool.h>
9 #include <mono/metadata/lock-tracer.h>
10 #include <mono/utils/mono-codeman.h>
11 #include <mono/utils/mono-hash.h>
12 #include <mono/utils/mono-compiler.h>
13 #include <mono/utils/mono-internal-hash.h>
14 #include <mono/io-layer/io-layer.h>
15 #include <mono/metadata/mempool-internals.h>
16
17 extern CRITICAL_SECTION mono_delegate_section;
18 extern CRITICAL_SECTION mono_strtod_mutex;
19
20 /*
21  * If this is set, the memory belonging to appdomains is not freed when a domain is
22  * unloaded, and assemblies loaded by the appdomain are not unloaded either. This
23  * allows us to use typed gc in non-default appdomains too, leading to increased
24  * performance.
25  */ 
26 extern gboolean mono_dont_free_domains;
27
28 /* This is a copy of System.AppDomainSetup */
29 typedef struct {
30         MonoObject object;
31         MonoString *application_base;
32         MonoString *application_name;
33         MonoString *cache_path;
34         MonoString *configuration_file;
35         MonoString *dynamic_base;
36         MonoString *license_file;
37         MonoString *private_bin_path;
38         MonoString *private_bin_path_probe;
39         MonoString *shadow_copy_directories;
40         MonoString *shadow_copy_files;
41         MonoBoolean publisher_policy;
42         MonoBoolean path_changed;
43         int loader_optimization;
44         MonoBoolean disallow_binding_redirects;
45         MonoBoolean disallow_code_downloads;
46         MonoObject *activation_arguments; /* it is System.Object in 1.x, ActivationArguments in 2.0 */
47         MonoObject *domain_initializer;
48         MonoObject *application_trust; /* it is System.Object in 1.x, ApplicationTrust in 2.0 */
49         MonoArray *domain_initializer_args;
50         MonoBoolean disallow_appbase_probe;
51         MonoArray *configuration_bytes;
52         MonoArray *serialized_non_primitives;
53 } MonoAppDomainSetup;
54
55 typedef struct _MonoJitInfoTable MonoJitInfoTable;
56 typedef struct _MonoJitInfoTableChunk MonoJitInfoTableChunk;
57
58 #define MONO_JIT_INFO_TABLE_CHUNK_SIZE          64
59
60 struct _MonoJitInfoTableChunk
61 {
62         int                    refcount;
63         volatile int           num_elements;
64         volatile gint8        *last_code_end;
65         MonoJitInfo * volatile data [MONO_JIT_INFO_TABLE_CHUNK_SIZE];
66 };
67
68 struct _MonoJitInfoTable
69 {
70         MonoDomain             *domain;
71         int                     num_chunks;
72         MonoJitInfoTableChunk  *chunks [MONO_ZERO_LEN_ARRAY];
73 };
74
75 #define MONO_SIZEOF_JIT_INFO_TABLE (sizeof (struct _MonoJitInfoTable) - MONO_ZERO_LEN_ARRAY * SIZEOF_VOID_P)
76
77 typedef GArray MonoAotModuleInfoTable;
78
79 typedef struct {
80         guint32  flags;
81         gint32   exvar_offset;
82         gpointer try_start;
83         gpointer try_end;
84         gpointer handler_start;
85         union {
86                 MonoClass *catch_class;
87                 gpointer filter;
88                 gpointer handler_end;
89         } data;
90 } MonoJitExceptionInfo;
91
92 /*
93  * Will contain information on the generic type arguments in the
94  * future.  For now, all arguments are always reference types.
95  */
96 typedef struct {
97         int dummy;
98 } MonoGenericSharingContext;
99
100 typedef struct
101 {
102         MonoGenericSharingContext *generic_sharing_context;
103         gint32 this_offset;
104         guint8 this_reg;
105         gboolean has_this:1;
106         gboolean this_in_reg:1;
107 } MonoGenericJitInfo;
108
109 /*
110 A try block hole is used to represent a non-contiguous part of
111 of a segment of native code protected by a given .try block.
112 Usually, a try block is defined as a contiguous segment of code.
113 But in some cases it's needed to have some parts of it to not be protected.
114 For example, given "try {} finally {}", the code in the .try block to call
115 the finally part looks like:
116
117 try {
118     ...
119         call finally_block
120         adjust stack
121         jump outside try block
122         ...
123 } finally {
124         ...
125 }
126
127 The instructions between the call and the jump should not be under the try block since they happen
128 after the finally block executes, which means if an async exceptions happens at that point we would
129 execute the finally clause twice. So, to avoid this, we introduce a hole in the try block to signal
130 that those instructions are not protected.
131 */
132 typedef struct
133 {
134         guint32 offset;
135         guint16 clause;
136         guint16 length;
137 } MonoTryBlockHoleJitInfo;
138
139 typedef struct
140 {
141         guint16 num_holes;
142         MonoTryBlockHoleJitInfo holes [MONO_ZERO_LEN_ARRAY];
143 } MonoTryBlockHoleTableJitInfo;
144
145 struct _MonoJitInfo {
146         /* NOTE: These first two elements (method and
147            next_jit_code_hash) must be in the same order and at the
148            same offset as in RuntimeMethod, because of the jit_code_hash
149            internal hash table in MonoDomain. */
150         MonoMethod *method;
151         struct _MonoJitInfo *next_jit_code_hash;
152         gpointer    code_start;
153         /* This might contain an id for the unwind info instead of a register mask */
154         guint32     used_regs;
155         int         code_size;
156         guint32     num_clauses:15;
157         /* Whenever the code is domain neutral or 'shared' */
158         gboolean    domain_neutral:1;
159         gboolean    cas_inited:1;
160         gboolean    cas_class_assert:1;
161         gboolean    cas_class_deny:1;
162         gboolean    cas_class_permitonly:1;
163         gboolean    cas_method_assert:1;
164         gboolean    cas_method_deny:1;
165         gboolean    cas_method_permitonly:1;
166         gboolean    has_generic_jit_info:1;
167         gboolean    has_try_block_holes:1;
168         gboolean    from_aot:1;
169         gboolean    from_llvm:1;
170 #ifdef HAVE_SGEN_GC
171         /* FIXME: Embed this after the structure later */
172         gpointer    gc_info;
173 #endif
174         MonoJitExceptionInfo clauses [MONO_ZERO_LEN_ARRAY];
175         /* There is an optional MonoGenericJitInfo after the clauses */
176         /* There is an optional MonoTryBlockHoleTableJitInfo after MonoGenericJitInfo clauses*/
177 };
178
179 #define MONO_SIZEOF_JIT_INFO (offsetof (struct _MonoJitInfo, clauses))
180
181 struct _MonoAppContext {
182         MonoObject obj;
183         gint32 domain_id;
184         gint32 context_id;
185         gpointer *static_data;
186 };
187
188 /*
189  * We have two unloading states because the domain
190  * must remain fully functional while AppDomain::DomainUnload is
191  * processed.
192  * After that unloading began and all domain facilities are teared down
193  * such as execution of new threadpool jobs.  
194  */
195 typedef enum {
196         MONO_APPDOMAIN_CREATED,
197         MONO_APPDOMAIN_UNLOADING_START,
198         MONO_APPDOMAIN_UNLOADING,
199         MONO_APPDOMAIN_UNLOADED
200 } MonoAppDomainState;
201
202 typedef struct _MonoThunkFreeList {
203         guint32 size;
204         int length;             /* only valid for the wait list */
205         struct _MonoThunkFreeList *next;
206 } MonoThunkFreeList;
207
208 typedef struct _MonoJitCodeHash MonoJitCodeHash;
209
210 struct _MonoDomain {
211         /*
212          * This lock must never be taken before the loader lock,
213          * i.e. if both are taken by the same thread, the loader lock
214          * must taken first.
215          */
216         CRITICAL_SECTION    lock;
217         MonoMemPool        *mp;
218         MonoCodeManager    *code_mp;
219         /*
220          * keep all the managed objects close to each other for the precise GC
221          * For the Boehm GC we additionally keep close also other GC-tracked pointers.
222          */
223 #define MONO_DOMAIN_FIRST_OBJECT setup
224         MonoAppDomainSetup *setup;
225         MonoAppDomain      *domain;
226         MonoAppContext     *default_context;
227         MonoException      *out_of_memory_ex;
228         MonoException      *null_reference_ex;
229         MonoException      *stack_overflow_ex;
230         /* typeof (void) */
231         MonoObject         *typeof_void;
232         /* 
233          * The fields between FIRST_GC_TRACKED and LAST_GC_TRACKED are roots, but
234          * not object references.
235          */
236 #define MONO_DOMAIN_FIRST_GC_TRACKED env
237         MonoGHashTable     *env;
238         MonoGHashTable     *ldstr_table;
239         /* hashtables for Reflection handles */
240         MonoGHashTable     *type_hash;
241         MonoGHashTable     *refobject_hash;
242         /* a GC-tracked array to keep references to the static fields of types */
243         gpointer           *static_data_array;
244         /* maps class -> type initialization exception object */
245         MonoGHashTable    *type_init_exception_hash;
246         /* maps delegate trampoline addr -> delegate object */
247         MonoGHashTable     *delegate_hash_table;
248 #define MONO_DOMAIN_LAST_GC_TRACKED delegate_hash_table
249         guint32            state;
250         /* Needed by Thread:GetDomainID() */
251         gint32             domain_id;
252         gint32             shadow_serial;
253         unsigned char      inet_family_hint; // used in socket-io.c as a cache
254         GSList             *domain_assemblies;
255         MonoAssembly       *entry_assembly;
256         char               *friendly_name;
257         GPtrArray          *class_vtable_array;
258         /* maps remote class key -> MonoRemoteClass */
259         GHashTable         *proxy_vtable_hash;
260         /* Protected by 'jit_code_hash_lock' */
261         MonoInternalHashTable jit_code_hash;
262         CRITICAL_SECTION    jit_code_hash_lock;
263         int                 num_jit_info_tables;
264         MonoJitInfoTable * 
265           volatile          jit_info_table;
266         GSList             *jit_info_free_queue;
267         /* Used when loading assemblies */
268         gchar **search_path;
269         gchar *private_bin_path;
270         
271         /* Used by remoting proxies */
272         MonoMethod         *create_proxy_for_type_method;
273         MonoMethod         *private_invoke_method;
274         /* Used to store offsets of thread and context static fields */
275         GHashTable         *special_static_fields;
276         /* 
277          * This must be a GHashTable, since these objects can't be finalized
278          * if the hashtable contains a GC visible reference to them.
279          */
280         GHashTable         *finalizable_objects_hash;
281 #ifndef HAVE_SGEN_GC
282         /* Maps MonoObjects to a GSList of WeakTrackResurrection GCHandles pointing to them */
283         GHashTable         *track_resurrection_objects_hash;
284         /* Maps WeakTrackResurrection GCHandles to the MonoObjects they point to */
285         GHashTable         *track_resurrection_handles_hash;
286 #endif
287         /* Protects the three hashes above */
288         CRITICAL_SECTION   finalizable_objects_hash_lock;
289         /* Used when accessing 'domain_assemblies' */
290         CRITICAL_SECTION    assemblies_lock;
291
292         GHashTable         *method_rgctx_hash;
293
294         GHashTable         *generic_virtual_cases;
295         MonoThunkFreeList **thunk_free_lists;
296
297         /* Information maintained by the JIT engine */
298         gpointer runtime_info;
299
300         /*thread pool jobs, used to coordinate shutdown.*/
301         volatile int                    threadpool_jobs;
302         HANDLE                          cleanup_semaphore;
303         
304         /* Contains the compiled runtime invoke wrapper used by finalizers */
305         gpointer            finalize_runtime_invoke;
306
307         /* Contains the compiled runtime invoke wrapper used by async resylt creation to capture thread context*/
308         gpointer            capture_context_runtime_invoke;
309
310         /* Contains the compiled method used by async resylt creation to capture thread context*/
311         gpointer            capture_context_method;
312
313         /* Assembly bindings, the per-domain part */
314         GSList *assembly_bindings;
315         gboolean assembly_bindings_parsed;
316 };
317
318 typedef struct  {
319         guint16 major, minor, build, revision;
320 } AssemblyVersionSet;
321
322 /* MonoRuntimeInfo: Contains information about versions supported by this runtime */
323 typedef struct  {
324         const char runtime_version [12];
325         const char framework_version [4];
326         const AssemblyVersionSet version_sets [2];
327 } MonoRuntimeInfo;
328
329 #define mono_domain_lock(domain) mono_locks_acquire(&(domain)->lock, DomainLock)
330 #define mono_domain_unlock(domain) mono_locks_release(&(domain)->lock, DomainLock)
331 #define mono_domain_assemblies_lock(domain) mono_locks_acquire(&(domain)->assemblies_lock, DomainAssembliesLock)
332 #define mono_domain_assemblies_unlock(domain) mono_locks_release(&(domain)->assemblies_lock, DomainAssembliesLock)
333 #define mono_domain_jit_code_hash_lock(domain) mono_locks_acquire(&(domain)->jit_code_hash_lock, DomainJitCodeHashLock)
334 #define mono_domain_jit_code_hash_unlock(domain) mono_locks_release(&(domain)->jit_code_hash_lock, DomainJitCodeHashLock)
335
336 typedef MonoDomain* (*MonoLoadFunc) (const char *filename, const char *runtime_version);
337
338 void
339 mono_install_runtime_load  (MonoLoadFunc func) MONO_INTERNAL;
340
341 MonoDomain*
342 mono_runtime_load (const char *filename, const char *runtime_version) MONO_INTERNAL;
343
344 typedef void (*MonoCreateDomainFunc) (MonoDomain *domain);
345
346 void
347 mono_install_create_domain_hook (MonoCreateDomainFunc func) MONO_INTERNAL;
348
349 typedef void (*MonoFreeDomainFunc) (MonoDomain *domain);
350
351 void
352 mono_install_free_domain_hook (MonoFreeDomainFunc func) MONO_INTERNAL;
353
354 void 
355 mono_init_com_types (void) MONO_INTERNAL;
356
357 void 
358 mono_cleanup (void) MONO_INTERNAL;
359
360 void
361 mono_close_exe_image (void) MONO_INTERNAL;
362
363 void
364 mono_jit_info_table_add    (MonoDomain *domain, MonoJitInfo *ji) MONO_INTERNAL;
365
366 void
367 mono_jit_info_table_remove (MonoDomain *domain, MonoJitInfo *ji) MONO_INTERNAL;
368
369 void
370 mono_jit_info_add_aot_module (MonoImage *image, gpointer start, gpointer end) MONO_INTERNAL;
371
372 MonoGenericJitInfo*
373 mono_jit_info_get_generic_jit_info (MonoJitInfo *ji) MONO_INTERNAL;
374
375 MonoGenericSharingContext*
376 mono_jit_info_get_generic_sharing_context (MonoJitInfo *ji) MONO_INTERNAL;
377
378 void
379 mono_jit_info_set_generic_sharing_context (MonoJitInfo *ji, MonoGenericSharingContext *gsctx) MONO_INTERNAL;
380
381 MonoJitInfo*
382 mono_domain_lookup_shared_generic (MonoDomain *domain, MonoMethod *method) MONO_INTERNAL;
383
384 char *
385 mono_make_shadow_copy (const char *filename) MONO_INTERNAL;
386
387 gboolean
388 mono_is_shadow_copy_enabled (MonoDomain *domain, const gchar *dir_name) MONO_INTERNAL;
389
390 gpointer
391 mono_domain_alloc  (MonoDomain *domain, guint size) MONO_INTERNAL;
392
393 gpointer
394 mono_domain_alloc0 (MonoDomain *domain, guint size) MONO_INTERNAL;
395
396 void*
397 mono_domain_code_reserve (MonoDomain *domain, int size) MONO_INTERNAL;
398
399 void*
400 mono_domain_code_reserve_align (MonoDomain *domain, int size, int alignment) MONO_INTERNAL;
401
402 void
403 mono_domain_code_commit (MonoDomain *domain, void *data, int size, int newsize) MONO_INTERNAL;
404
405 void
406 mono_domain_code_foreach (MonoDomain *domain, MonoCodeManagerFunc func, void *user_data) MONO_INTERNAL;
407
408 void
409 mono_domain_unset (void) MONO_INTERNAL;
410
411 void
412 mono_domain_set_internal_with_options (MonoDomain *domain, gboolean migrate_exception) MONO_INTERNAL;
413
414 MonoTryBlockHoleTableJitInfo*
415 mono_jit_info_get_try_block_hole_table_info (MonoJitInfo *ji) MONO_INTERNAL;
416
417 /* 
418  * Installs a new function which is used to return a MonoJitInfo for a method inside
419  * an AOT module.
420  */
421 typedef MonoJitInfo *(*MonoJitInfoFindInAot)         (MonoDomain *domain, MonoImage *image, gpointer addr);
422 void          mono_install_jit_info_find_in_aot (MonoJitInfoFindInAot func) MONO_INTERNAL;
423
424 void
425 mono_jit_code_hash_init (MonoInternalHashTable *jit_code_hash) MONO_INTERNAL;
426
427 MonoAppDomain *
428 ves_icall_System_AppDomain_getCurDomain            (void) MONO_INTERNAL;
429
430 MonoAppDomain *
431 ves_icall_System_AppDomain_getRootDomain           (void) MONO_INTERNAL;
432
433 MonoAppDomain *
434 ves_icall_System_AppDomain_createDomain            (MonoString         *friendly_name,
435                                                     MonoAppDomainSetup *setup) MONO_INTERNAL;
436
437 MonoObject *
438 ves_icall_System_AppDomain_GetData                 (MonoAppDomain *ad, 
439                                                     MonoString    *name) MONO_INTERNAL;
440
441 MonoReflectionAssembly *
442 ves_icall_System_AppDomain_LoadAssemblyRaw         (MonoAppDomain *ad,
443                                                     MonoArray *raw_assembly, 
444                                                     MonoArray *raw_symbol_store,
445                                                     MonoObject *evidence,
446                                                     MonoBoolean refonly) MONO_INTERNAL;
447
448 void
449 ves_icall_System_AppDomain_SetData                 (MonoAppDomain *ad, 
450                                                     MonoString    *name, 
451                                                     MonoObject    *data) MONO_INTERNAL;
452
453 MonoAppDomainSetup *
454 ves_icall_System_AppDomain_getSetup                (MonoAppDomain *ad) MONO_INTERNAL;
455
456 MonoString *
457 ves_icall_System_AppDomain_getFriendlyName         (MonoAppDomain *ad) MONO_INTERNAL;
458
459 MonoArray *
460 ves_icall_System_AppDomain_GetAssemblies           (MonoAppDomain *ad,
461                                                     MonoBoolean refonly) MONO_INTERNAL;
462
463 MonoReflectionAssembly *
464 ves_icall_System_Reflection_Assembly_LoadFrom      (MonoString *fname,
465                                                     MonoBoolean refonly) MONO_INTERNAL;
466
467 MonoReflectionAssembly *
468 ves_icall_System_AppDomain_LoadAssembly            (MonoAppDomain *ad, 
469                                                     MonoString *assRef,
470                                                     MonoObject    *evidence,
471                                                     MonoBoolean refonly) MONO_INTERNAL;
472
473 gboolean
474 ves_icall_System_AppDomain_InternalIsFinalizingForUnload (gint32 domain_id) MONO_INTERNAL;
475
476 void
477 ves_icall_System_AppDomain_InternalUnload          (gint32 domain_id) MONO_INTERNAL;
478
479 gint32
480 ves_icall_System_AppDomain_ExecuteAssembly         (MonoAppDomain *ad, 
481                                                                                                         MonoReflectionAssembly *refass,
482                                                                                                         MonoArray     *args) MONO_INTERNAL;
483
484 MonoAppDomain * 
485 ves_icall_System_AppDomain_InternalSetDomain       (MonoAppDomain *ad) MONO_INTERNAL;
486
487 MonoAppDomain * 
488 ves_icall_System_AppDomain_InternalSetDomainByID   (gint32 domainid) MONO_INTERNAL;
489
490 void
491 ves_icall_System_AppDomain_InternalPushDomainRef (MonoAppDomain *ad) MONO_INTERNAL;
492
493 void
494 ves_icall_System_AppDomain_InternalPushDomainRefByID (gint32 domain_id) MONO_INTERNAL;
495
496 void
497 ves_icall_System_AppDomain_InternalPopDomainRef (void) MONO_INTERNAL;
498
499 MonoAppContext * 
500 ves_icall_System_AppDomain_InternalGetContext      (void) MONO_INTERNAL;
501
502 MonoAppContext * 
503 ves_icall_System_AppDomain_InternalGetDefaultContext      (void) MONO_INTERNAL;
504
505 MonoAppContext * 
506 ves_icall_System_AppDomain_InternalSetContext      (MonoAppContext *mc) MONO_INTERNAL;
507
508 gint32 
509 ves_icall_System_AppDomain_GetIDFromDomain (MonoAppDomain * ad) MONO_INTERNAL;
510
511 MonoString *
512 ves_icall_System_AppDomain_InternalGetProcessGuid (MonoString* newguid) MONO_INTERNAL;
513
514 MonoAssembly *
515 mono_assembly_load_corlib (const MonoRuntimeInfo *runtime, MonoImageOpenStatus *status) MONO_INTERNAL;
516
517 const MonoRuntimeInfo*
518 mono_get_runtime_info (void) MONO_INTERNAL;
519
520 void
521 mono_runtime_set_no_exec (gboolean val) MONO_INTERNAL;
522
523 gboolean
524 mono_runtime_get_no_exec (void) MONO_INTERNAL;
525
526 gboolean
527 mono_assembly_name_parse (const char *name, MonoAssemblyName *aname) MONO_INTERNAL;
528
529 MonoImage *mono_assembly_open_from_bundle (const char *filename,
530                                            MonoImageOpenStatus *status,
531                                            gboolean refonly) MONO_INTERNAL;
532
533 void
534 mono_domain_add_class_static_data (MonoDomain *domain, MonoClass *klass, gpointer data, guint32 *bitmap);
535
536 MonoReflectionAssembly *
537 mono_try_assembly_resolve (MonoDomain *domain, MonoString *fname, gboolean refonly) MONO_INTERNAL;
538
539 MonoAssembly* mono_assembly_load_full_nosearch (MonoAssemblyName *aname, 
540                                                 const char       *basedir, 
541                                                 MonoImageOpenStatus *status,
542                                                 gboolean refonly) MONO_INTERNAL;
543
544 void mono_set_private_bin_path_from_config (MonoDomain *domain) MONO_INTERNAL;
545
546 int mono_framework_version (void) MONO_INTERNAL;
547
548 void mono_reflection_cleanup_domain (MonoDomain *domain) MONO_INTERNAL;
549
550 #endif /* __MONO_METADATA_DOMAIN_INTERNALS_H__ */