Merge pull request #669 from LogosBible/Uri_TryCreate
[mono.git] / mono / mini / mini.h
index 946bf44995fa51fd382480ee900eb92fab1b7644..3e028ada899eaf049b2dbda1de027dd6d3354e2a 100644 (file)
@@ -29,6 +29,7 @@
 #include <mono/utils/mono-stack-unwinding.h>
 #include <mono/utils/mono-threads.h>
 #include <mono/utils/mono-tls.h>
+#include <mono/utils/atomic.h>
 
 #define MONO_BREAKPOINT_ARRAY_SIZE 64
 
 #include "mini-unwind.h"
 #include "jit.h"
 
+#ifdef __native_client_codegen__
+#include <nacl/nacl_dyncode.h>
+#endif
+
+
 /*
  * The mini code should not have any compile time dependencies on the GC being used, so the same object file from mini/
  * can be linked into both mono and mono-sgen.
 #endif
 
 /* Version number of the AOT file format */
-#define MONO_AOT_FILE_VERSION 87
+#define MONO_AOT_FILE_VERSION 90
 
 //TODO: This is x86/amd64 specific.
 #define mono_simd_shuffle_mask(a,b,c,d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6))
 
+/* Remap printf to g_print (we use a mix of these in the mini code) */
+#ifdef PLATFORM_ANDROID
+#define printf g_print
+#endif
+
 /* Constants used to encode different types of methods in AOT */
 enum {
        MONO_AOT_METHODREF_MIN = 240,
@@ -207,9 +218,7 @@ typedef struct MonoAotFileInfo
        gpointer method_info_offsets;
        gpointer ex_info_offsets;
        gpointer code_offsets;
-#ifdef MONOTOUCH
        gpointer method_addresses;
-#endif
        gpointer extra_method_info_offsets;
        gpointer extra_method_table;
        gpointer got_info_offsets;
@@ -301,6 +310,9 @@ typedef struct
        GHashTable *arch_seq_points;
        /* Maps a GSharedVtTrampInfo structure to a trampoline address */
        GHashTable *gsharedvt_arg_tramp_hash;
+       /* memcpy/bzero methods specialized for small constant sizes */
+       gpointer *memcpy_addr [17];
+       gpointer *bzero_addr [17];
 } MonoJitDomainInfo;
 
 typedef struct {
@@ -516,7 +528,12 @@ extern gboolean mono_use_llvm;
 extern const char ins_info[];
 extern const gint8 ins_sreg_counts [];
 
+#ifndef DISABLE_JIT
 #define mono_inst_get_num_src_registers(ins) (ins_sreg_counts [(ins)->opcode - OP_START - 1])
+#else
+#define mono_inst_get_num_src_registers(ins) 0
+#endif
+
 #define mono_inst_get_src_registers(ins, regs) (((regs) [0] = (ins)->sreg1), ((regs) [1] = (ins)->sreg2), ((regs) [2] = (ins)->sreg3), mono_inst_get_num_src_registers ((ins)))
 
 #define MONO_BB_FOR_EACH_INS(bb, ins) for ((ins) = (bb)->code; (ins); (ins) = (ins)->next)
@@ -706,7 +723,8 @@ typedef enum {
        LLVMArgInFPReg,
        LLVMArgVtypeInReg,
        LLVMArgVtypeByVal,
-       LLVMArgVtypeRetAddr /* On on cinfo->ret */
+       LLVMArgVtypeRetAddr, /* On on cinfo->ret */
+       LLVMArgGSharedVt,
 } LLVMArgStorage;
 
 typedef struct {
@@ -1028,6 +1046,16 @@ typedef struct {
        gboolean orig_ex_ctx_set;
 } MonoJitTlsData;
 
+/* TLS entries used by JITted code */
+typedef enum {
+       /* mono_thread_internal_current () */
+       TLS_KEY_THREAD = 0,
+       TLS_KEY_JIT_TLS = 1,
+       /* mono_domain_get () */
+       TLS_KEY_DOMAIN = 2,
+       TLS_KEY_LMF = 3
+} MonoJitTlsKey;
+
 /*
  * This structure is an extension of MonoLMF and contains extra information.
  */
@@ -1061,7 +1089,20 @@ typedef enum {
        MONO_RGCTX_INFO_METHOD_GSHAREDVT_OUT_TRAMPOLINE_VIRT,
        /* Same for calli, associated with a signature */
        MONO_RGCTX_INFO_SIG_GSHAREDVT_OUT_TRAMPOLINE_CALLI,
-       MONO_RGCTX_INFO_CLASS_IS_REF
+       /*
+        * 0 - vtype
+        * 1 - ref
+        * 2 - gsharedvt type
+        */
+       MONO_RGCTX_INFO_CLASS_BOX_TYPE,
+       /* Resolves to a MonoGSharedVtMethodRuntimeInfo */
+       MONO_RGCTX_INFO_METHOD_GSHAREDVT_INFO,
+       MONO_RGCTX_INFO_LOCAL_OFFSET,
+       MONO_RGCTX_INFO_MEMCPY,
+       MONO_RGCTX_INFO_BZERO,
+       /* The address of Nullable<T>.Box () */
+       MONO_RGCTX_INFO_NULLABLE_CLASS_BOX,
+       MONO_RGCTX_INFO_NULLABLE_CLASS_UNBOX,
 } MonoRgctxInfoType;
 
 typedef struct _MonoRuntimeGenericContextInfoTemplate {
@@ -1089,6 +1130,25 @@ typedef struct {
 #define MONO_RGCTX_SLOT_INDEX(s)       ((s) & 0x7fffffff)
 #define MONO_RGCTX_SLOT_IS_MRGCTX(s)   (((s) & 0x80000000) ? TRUE : FALSE)
 
+#define MONO_GSHAREDVT_DEL_INVOKE_VT_OFFSET -2
+
+typedef struct {
+       MonoMethod *method;
+       /* Array of MonoRuntimeGenericContextInfoTemplate* entries */
+       GPtrArray *entries;
+} MonoGSharedVtMethodInfo;
+
+/* This is used by gsharedvt methods to allocate locals and compute local offsets */
+typedef struct {
+       int locals_size;
+       /*
+        * The results of resolving the entries in MOonGSharedVtMethodInfo->entries.
+        * We use this instead of rgctx slots since these can be loaded using a load instead
+        * of a call to an rgctx fetch trampoline.
+        */
+       gpointer entries [MONO_ZERO_LEN_ARRAY];
+} MonoGSharedVtMethodRuntimeInfo;
+
 typedef enum {
 #define PATCH_INFO(a,b) MONO_PATCH_INFO_ ## a,
 #include "patch-info.h"
@@ -1153,6 +1213,7 @@ struct MonoJumpInfo {
                MonoJumpInfoRgctxEntry *rgctx_entry;
                MonoJumpInfoImtTramp *imt_tramp;
                MonoJumpInfoGSharedVtCall *gsharedvt;
+               MonoGSharedVtMethodInfo *gsharedvt_method;
                MonoMethodSignature *sig;
        } data;
 };
@@ -1183,7 +1244,9 @@ typedef enum {
        MONO_TRAMPOLINE_AOT_PLT,
        MONO_TRAMPOLINE_DELEGATE,
        MONO_TRAMPOLINE_RESTORE_STACK_PROT,
+#ifndef DISABLE_REMOTING
        MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING,
+#endif
        MONO_TRAMPOLINE_MONITOR_ENTER,
        MONO_TRAMPOLINE_MONITOR_EXIT,
        MONO_TRAMPOLINE_VCALL,
@@ -1309,6 +1372,17 @@ typedef struct {
 
        gboolean gsharedvt;
 
+       MonoGSharedVtMethodInfo *gsharedvt_info;
+
+       /* Points to the gsharedvt locals area at runtime */
+       MonoInst *gsharedvt_locals_var;
+
+       /* The localloc instruction used to initialize gsharedvt_locals_var */
+       MonoInst *gsharedvt_locals_var_ins;
+
+       /* Points to a MonoGSharedVtMethodRuntimeInfo at runtime */
+       MonoInst *gsharedvt_info_var;
+
        /* For native-to-managed wrappers, the saved old domain */
        MonoInst *orig_domain_var;
 
@@ -1457,7 +1531,7 @@ typedef struct {
        GSList *headers_to_free;
 
        /* Used by AOT */
-       guint32 got_offset, ex_info_offset, method_info_offset;
+       guint32 got_offset, ex_info_offset, method_info_offset, method_index;
        /* Symbol used to refer to this method in generated assembly */
        char *asm_symbol;
        char *llvm_method_name;
@@ -1854,6 +1928,7 @@ void      mono_merge_basic_blocks           (MonoCompile *cfg, MonoBasicBlock *b
 void      mono_optimize_branches            (MonoCompile *cfg) MONO_INTERNAL;
 
 void      mono_blockset_print               (MonoCompile *cfg, MonoBitSet *set, const char *name, guint idom) MONO_INTERNAL;
+void      mono_print_ji                     (const MonoJumpInfo *ji) MONO_INTERNAL;
 void      mono_print_ins_index              (int i, MonoInst *ins) MONO_INTERNAL;
 void      mono_print_ins                    (MonoInst *ins) MONO_INTERNAL;
 void      mono_print_bb                     (MonoBasicBlock *bb, const char *msg) MONO_INTERNAL;
@@ -1890,6 +1965,7 @@ MonoNativeTlsKey mono_get_jit_tls_key       (void) MONO_INTERNAL;
 gint32    mono_get_jit_tls_offset           (void) MONO_INTERNAL;
 gint32    mono_get_lmf_tls_offset           (void) MONO_INTERNAL;
 gint32    mono_get_lmf_addr_tls_offset      (void) MONO_INTERNAL;
+int       mini_get_tls_offset               (MonoJitTlsKey key) MONO_INTERNAL;
 MonoInst* mono_get_jit_tls_intrinsic        (MonoCompile *cfg) MONO_INTERNAL;
 MonoInst* mono_get_domain_intrinsic         (MonoCompile* cfg) MONO_INTERNAL;
 MonoInst* mono_get_thread_intrinsic         (MonoCompile* cfg) MONO_INTERNAL;
@@ -1941,12 +2017,24 @@ void mono_nacl_fix_patches(const guint8 *code, MonoJumpInfo *ji);
 guint8 *mono_arch_nacl_pad(guint8 *code, int pad);
 guint8 *mono_arch_nacl_skip_nops(guint8 *code);
 
-extern const guint kNaClAlignment;
-extern const guint kNaClAlignmentMask;
+#if defined(TARGET_X86)
+#define kNaClAlignment kNaClAlignmentX86
+#define kNaClAlignmentMask kNaClAlignmentMaskX86
+#elif defined(TARGET_AMD64)
+#define kNaClAlignment kNaClAlignmentAMD64
+#define kNaClAlignmentMask kNaClAlignmentMaskAMD64
+#elif defined(TARGET_ARM)
+#define kNaClAlignment kNaClAlignmentARM
+#define kNaClAlignmentMask kNaClAlignmentMaskARM
+#endif
+
+#define NACL_BUNDLE_ALIGN_UP(p) ((((p)+kNaClAlignmentMask)) & ~kNaClAlignmentMask)
 #endif
 
 #if defined(__native_client__) || defined(__native_client_codegen__)
-void mono_nacl_gc();
+extern volatile int __nacl_thread_suspension_needed;
+void __nacl_suspend_thread_if_needed(void);
+void mono_nacl_gc(void);
 #endif
 
 #if defined(__native_client_codegen__) || defined(__native_client__)
@@ -1984,6 +2072,7 @@ MonoMethod* mono_aot_get_array_helper_from_wrapper (MonoMethod *method) MONO_INT
 guint32  mono_aot_get_got_offset            (MonoJumpInfo *ji) MONO_LLVM_INTERNAL;
 char*    mono_aot_get_method_name           (MonoCompile *cfg) MONO_LLVM_INTERNAL;
 char*    mono_aot_get_plt_symbol            (MonoJumpInfoType type, gconstpointer data) MONO_LLVM_INTERNAL;
+int      mono_aot_get_method_index          (MonoMethod *method) MONO_LLVM_INTERNAL;
 MonoJumpInfo* mono_aot_patch_info_dup       (MonoJumpInfo* ji) MONO_LLVM_INTERNAL;
 void     mono_aot_set_make_unreadable       (gboolean unreadable) MONO_INTERNAL;
 gboolean mono_aot_is_pagefault              (void *ptr) MONO_INTERNAL;
@@ -2046,7 +2135,9 @@ gpointer          mono_create_llvm_imt_trampoline (MonoDomain *domain, MonoMetho
 MonoVTable*       mono_find_class_init_trampoline_by_addr (gconstpointer addr) MONO_INTERNAL;
 guint32           mono_find_rgctx_lazy_fetch_trampoline_by_addr (gconstpointer addr) MONO_INTERNAL;
 gpointer          mono_magic_trampoline (mgreg_t *regs, guint8 *code, gpointer arg, guint8* tramp) MONO_INTERNAL;
+#ifndef DISABLE_REMOTING
 gpointer          mono_generic_virtual_remoting_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, guint8 *tramp) MONO_INTERNAL;
+#endif
 gpointer          mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *tramp_data, guint8* tramp) MONO_INTERNAL;
 gpointer          mono_aot_trampoline (mgreg_t *regs, guint8 *code, guint8 *token_info, 
                                                                           guint8* tramp) MONO_INTERNAL;
@@ -2060,7 +2151,8 @@ gconstpointer     mono_get_trampoline_func (MonoTrampolineType tramp_type);
 gpointer          mini_get_vtable_trampoline (int slot_index) MONO_INTERNAL;
 char*             mono_get_generic_trampoline_name (MonoTrampolineType tramp_type) MONO_INTERNAL;
 char*             mono_get_rgctx_fetch_trampoline_name (int slot) MONO_INTERNAL;
-gpointer          mini_add_method_trampoline (MonoMethod *orig_method, MonoMethod *m, gpointer compiled_method, MonoJitInfo *caller_ji, gboolean add_static_rgctx_tramp) MONO_INTERNAL;
+gpointer          mini_add_method_trampoline (MonoMethod *orig_method, MonoMethod *m, gpointer compiled_method, gboolean add_static_rgctx_tramp, gboolean add_unbox_tramp) MONO_INTERNAL;
+gboolean          mini_jit_info_is_gsharedvt (MonoJitInfo *ji) MONO_INTERNAL;
 
 gboolean          mono_running_on_valgrind (void) MONO_INTERNAL;
 void*             mono_global_codeman_reserve (int size) MONO_INTERNAL;
@@ -2168,6 +2260,7 @@ void      mono_arch_set_target                  (char *mtriple) MONO_INTERNAL;
 gboolean  mono_arch_gsharedvt_sig_supported     (MonoMethodSignature *sig) MONO_INTERNAL;
 gpointer  mono_arch_get_gsharedvt_trampoline    (MonoTrampInfo **info, gboolean aot) MONO_INTERNAL;
 gpointer  mono_arch_get_gsharedvt_call_info     (gpointer addr, MonoMethodSignature *normal_sig, MonoMethodSignature *gsharedvt_sig, MonoGenericSharingContext *gsctx, gboolean gsharedvt_in, gint32 vcall_offset, gboolean calli) MONO_INTERNAL;
+gboolean  mono_arch_opcode_needs_emulation      (MonoCompile *cfg, int opcode) MONO_INTERNAL;
 
 /* Soft Debug support */
 #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
@@ -2183,6 +2276,21 @@ gpointer mono_arch_get_seq_point_info           (MonoDomain *domain, guint8 *cod
 void     mono_arch_setup_resume_sighandler_ctx  (MonoContext *ctx, gpointer func) MONO_INTERNAL;
 #endif
 
+#ifdef USE_JUMP_TABLES
+void
+mono_jumptable_init  (void) MONO_INTERNAL;
+gpointer*
+mono_jumptable_add_entry (void) MONO_INTERNAL;
+gpointer*
+mono_jumptable_add_entries (guint32 entries) MONO_INTERNAL;
+void
+mono_jumptable_cleanup  (void) MONO_INTERNAL;
+gpointer*
+mono_arch_jumptable_entry_from_code (guint8 *code);
+gpointer*
+mono_jumptable_get_entry (guint8 *code);
+#endif
+
 gboolean
 mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, 
                                                 MonoJitInfo *ji, MonoContext *ctx, 
@@ -2385,6 +2493,9 @@ mono_set_generic_sharing_supported (gboolean supported) MONO_INTERNAL;
 void
 mono_set_generic_sharing_vt_supported (gboolean supported) MONO_INTERNAL;
 
+void
+mono_set_partial_sharing_supported (gboolean supported) MONO_INTERNAL;
+
 gboolean
 mono_class_generic_sharing_enabled (MonoClass *class) MONO_INTERNAL;
 
@@ -2400,6 +2511,9 @@ mono_method_lookup_rgctx (MonoVTable *class_vtable, MonoGenericInst *method_inst
 const char*
 mono_rgctx_info_type_to_str (MonoRgctxInfoType type) MONO_INTERNAL;
 
+MonoJumpInfoType
+mini_rgctx_info_type_to_patch_info_type (MonoRgctxInfoType info_type) MONO_INTERNAL;
+
 gboolean
 mono_method_needs_static_rgctx_invoke (MonoMethod *method, gboolean allow_type_vars) MONO_INTERNAL;
 
@@ -2432,10 +2546,13 @@ gboolean
 mono_method_is_generic_impl (MonoMethod *method) MONO_INTERNAL;
 
 gboolean
-mono_method_is_generic_sharable_impl (MonoMethod *method, gboolean allow_type_vars) MONO_INTERNAL;
+mono_method_is_generic_sharable (MonoMethod *method, gboolean allow_type_vars) MONO_INTERNAL;
 
 gboolean
-mono_method_is_generic_sharable_impl_full (MonoMethod *method, gboolean allow_type_vars, gboolean allow_partial, gboolean allow_gsharedvt) MONO_INTERNAL;
+mono_method_is_generic_sharable_full (MonoMethod *method, gboolean allow_type_vars, gboolean allow_partial, gboolean allow_gsharedvt) MONO_INTERNAL;
+
+gboolean
+mini_class_is_generic_sharable (MonoClass *klass) MONO_INTERNAL;
 
 gboolean
 mono_is_partially_sharable_inst (MonoGenericInst *inst) MONO_INTERNAL;
@@ -2473,16 +2590,16 @@ void mono_cfg_add_try_hole (MonoCompile *cfg, MonoExceptionClause *clause, guint
 
 void mono_cfg_set_exception (MonoCompile *cfg, int type) MONO_INTERNAL;
 gboolean mini_type_is_reference (MonoCompile *cfg, MonoType *type) MONO_INTERNAL;
-gboolean mini_type_is_vtype (MonoCompile *cfg, MonoType *t) MONO_INTERNAL;
-gboolean mini_type_var_is_vt (MonoCompile *cfg, MonoType *type) MONO_INTERNAL;
-gboolean mini_is_gsharedvt_klass (MonoCompile *cfg, MonoClass *klass) MONO_INTERNAL;
+gboolean mini_type_is_vtype (MonoCompile *cfg, MonoType *t); /* should be internal but it's used by llvm */
+gboolean mini_type_var_is_vt (MonoCompile *cfg, MonoType *type); /* should be internal but it's used by llvm */
+gboolean mini_is_gsharedvt_klass (MonoCompile *cfg, MonoClass *klass); /* should be internal but it's used by llvm */
 gboolean mini_is_gsharedvt_type (MonoCompile *cfg, MonoType *t) MONO_INTERNAL;
 gboolean mini_is_gsharedvt_signature (MonoCompile *cfg, MonoMethodSignature *sig) MONO_INTERNAL;
 gboolean mini_is_gsharedvt_type_gsctx (MonoGenericSharingContext *gsctx, MonoType *t) MONO_INTERNAL;
 gboolean mini_is_gsharedvt_variable_type (MonoCompile *cfg, MonoType *t) MONO_INTERNAL;
-MonoType* mini_get_gsharedvt_alloc_type_for_type (MonoCompile *cfg, MonoType *t) MONO_INTERNAL;
 gboolean mini_is_gsharedvt_sharable_method (MonoMethod *method) MONO_INTERNAL;
 gboolean mini_is_gsharedvt_variable_signature (MonoMethodSignature *sig) MONO_INTERNAL;
+gboolean mini_is_gsharedvt_sharable_inst (MonoGenericInst *inst) MONO_INTERNAL;
 gpointer mini_method_get_rgctx (MonoMethod *m) MONO_INTERNAL;
 void mini_init_gsctx (MonoGenericContext *context, MonoGenericSharingContext *gsctx) MONO_INTERNAL;
 
@@ -2617,4 +2734,26 @@ void SIG_HANDLER_SIGNATURE (mono_sigsegv_signal_handler) MONO_INTERNAL;
 void SIG_HANDLER_SIGNATURE (mono_sigint_signal_handler)  MONO_INTERNAL;
 gboolean SIG_HANDLER_SIGNATURE (mono_chain_signal) MONO_INTERNAL;
 
+#ifdef MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE
+#define ARCH_HAVE_DELEGATE_TRAMPOLINES 1
+#else
+#define ARCH_HAVE_DELEGATE_TRAMPOLINES 0
+#endif
+
+#ifdef MONO_ARCH_USE_OP_TAIL_CALL
+#define ARCH_USE_OP_TAIL_CALL 1
+#else
+#define ARCH_USE_OP_TAIL_CALL 0
+#endif
+
+#ifndef MONO_ARCH_HAVE_TLS_GET
+#define MONO_ARCH_HAVE_TLS_GET 0
+#endif
+
+#ifdef MONO_ARCH_HAVE_TLS_GET_REG
+#define ARCH_HAVE_TLS_GET_REG 1
+#else
+#define ARCH_HAVE_TLS_GET_REG 0
+#endif
+
 #endif /* __MONO_MINI_H__ */