Merge pull request #5014 from vkargov/vk-kasha
[mono.git] / mono / metadata / domain-internals.h
1 /**
2  * \file
3  * Appdomain-related internal data structures and functions.
4  * Copyright 2012 Xamarin Inc (http://www.xamarin.com)
5  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
6  */
7 #ifndef __MONO_METADATA_DOMAIN_INTERNALS_H__
8 #define __MONO_METADATA_DOMAIN_INTERNALS_H__
9
10 #include <mono/metadata/appdomain.h>
11 #include <mono/metadata/mempool.h>
12 #include <mono/metadata/lock-tracer.h>
13 #include <mono/utils/mono-codeman.h>
14 #include <mono/metadata/mono-hash.h>
15 #include <mono/metadata/mono-conc-hash.h>
16 #include <mono/utils/mono-compiler.h>
17 #include <mono/utils/mono-internal-hash.h>
18 #include <mono/metadata/mempool-internals.h>
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 *next_tombstone;
66         MonoJitInfo * volatile data [MONO_JIT_INFO_TABLE_CHUNK_SIZE];
67 };
68
69 struct _MonoJitInfoTable
70 {
71         MonoDomain             *domain;
72         int                     num_chunks;
73         int                     num_valid;
74         MonoJitInfoTableChunk  *chunks [MONO_ZERO_LEN_ARRAY];
75 };
76
77 #define MONO_SIZEOF_JIT_INFO_TABLE (sizeof (struct _MonoJitInfoTable) - MONO_ZERO_LEN_ARRAY * SIZEOF_VOID_P)
78
79 typedef GArray MonoAotModuleInfoTable;
80
81 typedef struct {
82         guint32  flags;
83         gint32   exvar_offset;
84         gpointer try_start;
85         gpointer try_end;
86         gpointer handler_start;
87         /*
88          * For LLVM compiled code, this is the index of the il clause
89          * associated with this handler.
90          */
91         int clause_index;
92         uint32_t try_offset;
93         uint32_t try_len;
94         uint32_t handler_offset;
95         uint32_t handler_len;
96         union {
97                 MonoClass *catch_class;
98                 gpointer filter;
99                 gpointer handler_end;
100         } data;
101 } MonoJitExceptionInfo;
102
103 /*
104  * Contains information about the type arguments for generic shared methods.
105  */
106 typedef struct {
107         gboolean is_gsharedvt;
108 } MonoGenericSharingContext;
109
110 /* Simplified DWARF location list entry */
111 typedef struct {
112         /* Whenever the value is in a register */
113         gboolean is_reg;
114         /*
115          * If is_reg is TRUE, the register which contains the value. Otherwise
116          * the base register.
117          */
118         int reg;
119         /*
120          * If is_reg is FALSE, the offset of the stack location relative to 'reg'.
121          * Otherwise, 0.
122          */
123         int offset;
124         /*
125          * Offsets of the PC interval where the value is in this location.
126          */
127         int from, to;
128 } MonoDwarfLocListEntry;
129
130 typedef struct
131 {
132         MonoGenericSharingContext *generic_sharing_context;
133         int nlocs;
134         MonoDwarfLocListEntry *locations;
135         gint32 this_offset;
136         guint8 this_reg;
137         gboolean has_this:1;
138         gboolean this_in_reg:1;
139 } MonoGenericJitInfo;
140
141 /*
142 A try block hole is used to represent a non-contiguous part of
143 of a segment of native code protected by a given .try block.
144 Usually, a try block is defined as a contiguous segment of code.
145 But in some cases it's needed to have some parts of it to not be protected.
146 For example, given "try {} finally {}", the code in the .try block to call
147 the finally part looks like:
148
149 try {
150     ...
151         call finally_block
152         adjust stack
153         jump outside try block
154         ...
155 } finally {
156         ...
157 }
158
159 The instructions between the call and the jump should not be under the try block since they happen
160 after the finally block executes, which means if an async exceptions happens at that point we would
161 execute the finally clause twice. So, to avoid this, we introduce a hole in the try block to signal
162 that those instructions are not protected.
163 */
164 typedef struct
165 {
166         guint32 offset;
167         guint16 clause;
168         guint16 length;
169 } MonoTryBlockHoleJitInfo;
170
171 typedef struct
172 {
173         guint16 num_holes;
174         MonoTryBlockHoleJitInfo holes [MONO_ZERO_LEN_ARRAY];
175 } MonoTryBlockHoleTableJitInfo;
176
177 typedef struct
178 {
179         guint32 stack_size;
180         guint32 epilog_size;
181 } MonoArchEHJitInfo;
182
183 typedef struct {
184         /* Relative to code_start */
185         int thunks_offset;
186         int thunks_size;
187 } MonoThunkJitInfo;
188
189 typedef struct {
190         guint8 *unw_info;
191         int unw_info_len;
192 } MonoUnwindJitInfo;
193
194 typedef enum {
195         JIT_INFO_NONE = 0,
196         JIT_INFO_HAS_GENERIC_JIT_INFO = (1 << 0),
197         JIT_INFO_HAS_TRY_BLOCK_HOLES = (1 << 1),
198         JIT_INFO_HAS_ARCH_EH_INFO = (1 << 2),
199         JIT_INFO_HAS_THUNK_INFO = (1 << 3),
200         /*
201          * If this is set, the unwind info is stored in the structure, instead of being pointed to by the
202          * 'unwind_info' field.
203          */
204         JIT_INFO_HAS_UNWIND_INFO = (1 << 4)
205 } MonoJitInfoFlags;
206
207 struct _MonoJitInfo {
208         /* NOTE: These first two elements (method and
209            next_jit_code_hash) must be in the same order and at the
210            same offset as in RuntimeMethod, because of the jit_code_hash
211            internal hash table in MonoDomain. */
212         union {
213                 MonoMethod *method;
214                 MonoImage *image;
215                 gpointer aot_info;
216                 gpointer tramp_info;
217         } d;
218         union {
219                 struct _MonoJitInfo *next_jit_code_hash;
220                 struct _MonoJitInfo *next_tombstone;
221         } n;
222         gpointer    code_start;
223         guint32     unwind_info;
224         int         code_size;
225         guint32     num_clauses:15;
226         /* Whenever the code is domain neutral or 'shared' */
227         gboolean    domain_neutral:1;
228         gboolean    has_generic_jit_info:1;
229         gboolean    has_try_block_holes:1;
230         gboolean    has_arch_eh_info:1;
231         gboolean    has_thunk_info:1;
232         gboolean    has_unwind_info:1;
233         gboolean    from_aot:1;
234         gboolean    from_llvm:1;
235         gboolean    dbg_attrs_inited:1;
236         gboolean    dbg_hidden:1;
237         /* Whenever this jit info was loaded in async context */
238         gboolean    async:1;
239         gboolean    dbg_step_through:1;
240         gboolean    dbg_non_user_code:1;
241         /*
242          * Whenever this jit info refers to a trampoline.
243          * d.tramp_info contains additional data in this case.
244          */
245         gboolean    is_trampoline:1;
246         /* Whenever this jit info refers to an interpreter method */
247         gboolean    is_interp:1;
248
249         /* FIXME: Embed this after the structure later*/
250         gpointer    gc_info; /* Currently only used by SGen */
251         
252         MonoJitExceptionInfo clauses [MONO_ZERO_LEN_ARRAY];
253         /* There is an optional MonoGenericJitInfo after the clauses */
254         /* There is an optional MonoTryBlockHoleTableJitInfo after MonoGenericJitInfo clauses*/
255         /* There is an optional MonoArchEHJitInfo after MonoTryBlockHoleTableJitInfo */
256         /* There is an optional MonoThunkJitInfo after MonoArchEHJitInfo */
257 };
258
259 #define MONO_SIZEOF_JIT_INFO (offsetof (struct _MonoJitInfo, clauses))
260
261 typedef struct {
262         gpointer *static_data; /* Used to free the static data without going through the MonoAppContext object itself. */
263         uint32_t gc_handle;
264 } ContextStaticData;
265
266 struct _MonoAppContext {
267         MonoObject obj;
268         gint32 domain_id;
269         gint32 context_id;
270         gpointer *static_data;
271         ContextStaticData *data;
272 };
273
274 /* Lock-free allocator */
275 typedef struct {
276         guint8 *mem;
277         gpointer prev;
278         int size, pos;
279 } LockFreeMempoolChunk;
280
281 typedef struct {
282         LockFreeMempoolChunk *current, *chunks;
283 } LockFreeMempool;
284
285 /*
286  * We have two unloading states because the domain
287  * must remain fully functional while AppDomain::DomainUnload is
288  * processed.
289  * After that unloading began and all domain facilities are teared down
290  * such as execution of new threadpool jobs.  
291  */
292 typedef enum {
293         MONO_APPDOMAIN_CREATED,
294         MONO_APPDOMAIN_UNLOADING_START,
295         MONO_APPDOMAIN_UNLOADING,
296         MONO_APPDOMAIN_UNLOADED
297 } MonoAppDomainState;
298
299 typedef struct _MonoThunkFreeList {
300         guint32 size;
301         int length;             /* only valid for the wait list */
302         struct _MonoThunkFreeList *next;
303 } MonoThunkFreeList;
304
305 typedef struct _MonoJitCodeHash MonoJitCodeHash;
306
307 struct _MonoDomain {
308         /*
309          * This lock must never be taken before the loader lock,
310          * i.e. if both are taken by the same thread, the loader lock
311          * must taken first.
312          */
313         MonoCoopMutex    lock;
314         MonoMemPool        *mp;
315         MonoCodeManager    *code_mp;
316         /*
317          * keep all the managed objects close to each other for the precise GC
318          * For the Boehm GC we additionally keep close also other GC-tracked pointers.
319          */
320 #define MONO_DOMAIN_FIRST_OBJECT setup
321         MonoAppDomainSetup *setup;
322         MonoAppDomain      *domain;
323         MonoAppContext     *default_context;
324         MonoException      *out_of_memory_ex;
325         MonoException      *null_reference_ex;
326         MonoException      *stack_overflow_ex;
327         /* typeof (void) */
328         MonoObject         *typeof_void;
329         /* Ephemeron Tombstone*/
330         MonoObject         *ephemeron_tombstone;
331         /* new MonoType [0] */
332         MonoArray          *empty_types;
333         MonoString         *empty_string;
334         /* 
335          * The fields between FIRST_GC_TRACKED and LAST_GC_TRACKED are roots, but
336          * not object references.
337          */
338 #define MONO_DOMAIN_FIRST_GC_TRACKED env
339         MonoGHashTable     *env;
340         MonoGHashTable     *ldstr_table;
341         /* hashtables for Reflection handles */
342         MonoGHashTable     *type_hash;
343         MonoConcGHashTable     *refobject_hash;
344         /* maps class -> type initialization exception object */
345         MonoGHashTable    *type_init_exception_hash;
346         /* maps delegate trampoline addr -> delegate object */
347         MonoGHashTable     *delegate_hash_table;
348 #define MONO_DOMAIN_LAST_GC_TRACKED delegate_hash_table
349         guint32            state;
350         /* Needed by Thread:GetDomainID() */
351         gint32             domain_id;
352         gint32             shadow_serial;
353         GSList             *domain_assemblies;
354         MonoAssembly       *entry_assembly;
355         char               *friendly_name;
356         GPtrArray          *class_vtable_array;
357         /* maps remote class key -> MonoRemoteClass */
358         GHashTable         *proxy_vtable_hash;
359         /* Protected by 'jit_code_hash_lock' */
360         MonoInternalHashTable jit_code_hash;
361         mono_mutex_t    jit_code_hash_lock;
362         int                 num_jit_info_tables;
363         MonoJitInfoTable * 
364           volatile          jit_info_table;
365         /*
366          * Contains information about AOT loaded code.
367          * Only used in the root domain.
368          */
369         MonoJitInfoTable *
370           volatile          aot_modules;
371         GSList             *jit_info_free_queue;
372         /* Used when loading assemblies */
373         gchar **search_path;
374         gchar *private_bin_path;
375         LockFreeMempool *lock_free_mp;
376         
377         /* Used by remoting proxies */
378         MonoMethod         *create_proxy_for_type_method;
379         MonoMethod         *private_invoke_method;
380         /* Used to store offsets of thread and context static fields */
381         GHashTable         *special_static_fields;
382         /* 
383          * This must be a GHashTable, since these objects can't be finalized
384          * if the hashtable contains a GC visible reference to them.
385          */
386         GHashTable         *finalizable_objects_hash;
387
388         /* Protects the three hashes above */
389         mono_mutex_t   finalizable_objects_hash_lock;
390         /* Used when accessing 'domain_assemblies' */
391         mono_mutex_t    assemblies_lock;
392
393         GHashTable         *method_rgctx_hash;
394
395         GHashTable         *generic_virtual_cases;
396
397         /* Information maintained by the JIT engine */
398         gpointer runtime_info;
399         
400         /* Contains the compiled runtime invoke wrapper used by finalizers */
401         gpointer            finalize_runtime_invoke;
402
403         /* Contains the compiled runtime invoke wrapper used by async resylt creation to capture thread context*/
404         gpointer            capture_context_runtime_invoke;
405
406         /* Contains the compiled method used by async resylt creation to capture thread context*/
407         gpointer            capture_context_method;
408
409         /* Assembly bindings, the per-domain part */
410         GSList *assembly_bindings;
411         gboolean assembly_bindings_parsed;
412
413         /* Used by socket-io.c */
414         /* These are domain specific, since the assembly can be unloaded */
415         MonoImage *socket_assembly;
416         MonoClass *sockaddr_class;
417         MonoClassField *sockaddr_data_field;
418         MonoClassField *sockaddr_data_length_field;
419
420         /* Cache function pointers for architectures  */
421         /* that require wrappers */
422         GHashTable *ftnptrs_hash;
423
424         /* Maps MonoMethod* to weak links to DynamicMethod objects */
425         GHashTable *method_to_dyn_method;
426
427         /* <ThrowUnobservedTaskExceptions /> support */
428         gboolean throw_unobserved_task_exceptions;
429
430         guint32 execution_context_field_offset;
431 };
432
433 typedef struct  {
434         guint16 major, minor, build, revision;
435 } AssemblyVersionSet;
436
437 /* MonoRuntimeInfo: Contains information about versions supported by this runtime */
438 typedef struct  {
439         const char runtime_version [12];
440         const char framework_version [4];
441         const AssemblyVersionSet version_sets [5];
442 } MonoRuntimeInfo;
443
444 #define mono_domain_assemblies_lock(domain) mono_locks_os_acquire(&(domain)->assemblies_lock, DomainAssembliesLock)
445 #define mono_domain_assemblies_unlock(domain) mono_locks_os_release(&(domain)->assemblies_lock, DomainAssembliesLock)
446 #define mono_domain_jit_code_hash_lock(domain) mono_locks_os_acquire(&(domain)->jit_code_hash_lock, DomainJitCodeHashLock)
447 #define mono_domain_jit_code_hash_unlock(domain) mono_locks_os_release(&(domain)->jit_code_hash_lock, DomainJitCodeHashLock)
448
449 typedef MonoDomain* (*MonoLoadFunc) (const char *filename, const char *runtime_version);
450
451 void mono_domain_lock (MonoDomain *domain) MONO_LLVM_INTERNAL;
452 void mono_domain_unlock (MonoDomain *domain) MONO_LLVM_INTERNAL;
453
454 void
455 mono_install_runtime_load  (MonoLoadFunc func);
456
457 MonoDomain*
458 mono_runtime_load (const char *filename, const char *runtime_version);
459
460 typedef void (*MonoCreateDomainFunc) (MonoDomain *domain);
461
462 void
463 mono_install_create_domain_hook (MonoCreateDomainFunc func);
464
465 typedef void (*MonoFreeDomainFunc) (MonoDomain *domain);
466
467 void
468 mono_install_free_domain_hook (MonoFreeDomainFunc func);
469
470 void 
471 mono_cleanup (void);
472
473 void
474 mono_close_exe_image (void);
475
476 int
477 mono_jit_info_size (MonoJitInfoFlags flags, int num_clauses, int num_holes);
478
479 void
480 mono_jit_info_init (MonoJitInfo *ji, MonoMethod *method, guint8 *code, int code_size,
481                                         MonoJitInfoFlags flags, int num_clauses, int num_holes);
482
483 MonoJitInfoTable *
484 mono_jit_info_table_new (MonoDomain *domain);
485
486 void
487 mono_jit_info_table_free (MonoJitInfoTable *table);
488
489 void
490 mono_jit_info_table_add    (MonoDomain *domain, MonoJitInfo *ji);
491
492 void
493 mono_jit_info_table_remove (MonoDomain *domain, MonoJitInfo *ji);
494
495 void
496 mono_jit_info_add_aot_module (MonoImage *image, gpointer start, gpointer end);
497
498 MonoGenericJitInfo*
499 mono_jit_info_get_generic_jit_info (MonoJitInfo *ji);
500
501 MonoGenericSharingContext*
502 mono_jit_info_get_generic_sharing_context (MonoJitInfo *ji);
503
504 void
505 mono_jit_info_set_generic_sharing_context (MonoJitInfo *ji, MonoGenericSharingContext *gsctx);
506
507 char *
508 mono_make_shadow_copy (const char *filename, MonoError *error);
509
510 gboolean
511 mono_is_shadow_copy_enabled (MonoDomain *domain, const gchar *dir_name);
512
513 gpointer
514 mono_domain_alloc  (MonoDomain *domain, guint size);
515
516 gpointer
517 mono_domain_alloc0 (MonoDomain *domain, guint size);
518
519 gpointer
520 mono_domain_alloc0_lock_free (MonoDomain *domain, guint size);
521
522 void*
523 mono_domain_code_reserve (MonoDomain *domain, int size) MONO_LLVM_INTERNAL;
524
525 void*
526 mono_domain_code_reserve_align (MonoDomain *domain, int size, int alignment);
527
528 void
529 mono_domain_code_commit (MonoDomain *domain, void *data, int size, int newsize);
530
531 void
532 mono_domain_code_foreach (MonoDomain *domain, MonoCodeManagerFunc func, void *user_data);
533
534 void
535 mono_domain_unset (void);
536
537 void
538 mono_domain_set_internal_with_options (MonoDomain *domain, gboolean migrate_exception);
539
540 gboolean
541 mono_domain_set_config_checked (MonoDomain *domain, const char *base_dir, const char *config_file_name, MonoError *error);
542
543 MonoTryBlockHoleTableJitInfo*
544 mono_jit_info_get_try_block_hole_table_info (MonoJitInfo *ji);
545
546 MonoArchEHJitInfo*
547 mono_jit_info_get_arch_eh_info (MonoJitInfo *ji);
548
549 MonoThunkJitInfo*
550 mono_jit_info_get_thunk_info (MonoJitInfo *ji);
551
552 MonoUnwindJitInfo*
553 mono_jit_info_get_unwind_info (MonoJitInfo *ji);
554
555 /* 
556  * Installs a new function which is used to return a MonoJitInfo for a method inside
557  * an AOT module.
558  */
559 typedef MonoJitInfo *(*MonoJitInfoFindInAot)         (MonoDomain *domain, MonoImage *image, gpointer addr);
560 void          mono_install_jit_info_find_in_aot (MonoJitInfoFindInAot func);
561
562 void
563 mono_jit_code_hash_init (MonoInternalHashTable *jit_code_hash);
564
565 MonoAssembly *
566 mono_assembly_load_corlib (const MonoRuntimeInfo *runtime, MonoImageOpenStatus *status);
567
568 const MonoRuntimeInfo*
569 mono_get_runtime_info (void);
570
571 void
572 mono_runtime_set_no_exec (gboolean val);
573
574 gboolean
575 mono_runtime_get_no_exec (void);
576
577 void
578 mono_domain_parse_assembly_bindings (MonoDomain *domain, int amajor, int aminor, gchar *domain_config_file_name);
579
580 gboolean
581 mono_assembly_name_parse (const char *name, MonoAssemblyName *aname);
582
583 MonoImage *mono_assembly_open_from_bundle (const char *filename,
584                                            MonoImageOpenStatus *status,
585                                            gboolean refonly);
586
587 MonoAssembly *
588 mono_try_assembly_resolve (MonoDomain *domain, const char *fname, MonoAssembly *requesting, gboolean refonly, MonoError *error);
589
590 MonoAssembly *
591 mono_domain_assembly_postload_search (MonoAssemblyName *aname, MonoAssembly *requesting, gboolean refonly);
592
593 MonoAssembly* mono_assembly_load_full_nosearch (MonoAssemblyName *aname, 
594                                                 const char       *basedir, 
595                                                 MonoImageOpenStatus *status,
596                                                 gboolean refonly);
597
598 void mono_domain_set_options_from_config (MonoDomain *domain);
599
600 int mono_framework_version (void);
601
602 void mono_reflection_cleanup_domain (MonoDomain *domain);
603
604 void mono_assembly_cleanup_domain_bindings (guint32 domain_id);
605
606 MonoJitInfo* mono_jit_info_table_find_internal (MonoDomain *domain, char *addr, gboolean try_aot, gboolean allow_trampolines);
607
608 void mono_enable_debug_domain_unload (gboolean enable);
609
610 MonoReflectionAssembly *
611 mono_domain_try_type_resolve_checked (MonoDomain *domain, char *name, MonoObject *tb, MonoError *error);
612
613 void
614 mono_runtime_init_checked (MonoDomain *domain, MonoThreadStartCB start_cb, MonoThreadAttachCB attach_cb, MonoError *error);
615
616 void
617 mono_context_init_checked (MonoDomain *domain, MonoError *error);
618
619 gboolean
620 mono_assembly_has_reference_assembly_attribute (MonoAssembly *assembly, MonoError *error);
621
622 GPtrArray*
623 mono_domain_get_assemblies (MonoDomain *domain, gboolean refonly);
624
625 #endif /* __MONO_METADATA_DOMAIN_INTERNALS_H__ */