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