Merge pull request #3059 from lateralusX/jlorenss/win-x64-dyncall-gsharedvt-support
[mono.git] / mono / mini / mini.h
index 6954a7639ac771732aab96445870b50923a4eaea..a10818df3991a22551b79f753a322128c9b629ee 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright 2002-2003 Ximian Inc
  * Copyright 2003-2011 Novell Inc
  * Copyright 2011 Xamarin Inc
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 #ifndef __MONO_MINI_H__
 #define __MONO_MINI_H__
@@ -39,6 +40,7 @@
 #include "regalloc.h"
 #include "mini-unwind.h"
 #include "jit.h"
+#include "cfgdump.h"
 
 #include "mono/metadata/class-internals.h"
 #include "mono/metadata/domain-internals.h"
 #endif
 
 /* Version number of the AOT file format */
-#define MONO_AOT_FILE_VERSION 132
+#define MONO_AOT_FILE_VERSION 133
 
 //TODO: This is x86/amd64 specific.
 #define mono_simd_shuffle_mask(a,b,c,d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6))
@@ -354,6 +356,8 @@ typedef struct
        gpointer *memcpy_addr [17];
        gpointer *bzero_addr [17];
        gpointer llvm_module;
+       /* Maps MonoMethod -> GSlist of addresses */
+       GHashTable *llvm_jit_callees;
 } MonoJitDomainInfo;
 
 typedef struct {
@@ -480,7 +484,8 @@ enum {
 #define MONO_IS_STORE_MEMBASE(ins) (((ins)->opcode >= OP_STORE_MEMBASE_REG && (ins)->opcode <= OP_STOREV_MEMBASE) || ((ins)->opcode >= OP_ATOMIC_STORE_I1 && (ins)->opcode <= OP_ATOMIC_STORE_R8))
 #define MONO_IS_STORE_MEMINDEX(ins) (((ins)->opcode >= OP_STORE_MEMINDEX) && ((ins)->opcode <= OP_STORER8_MEMINDEX))
 
-#define MONO_IS_CALL(ins) (((ins->opcode >= OP_VOIDCALL) && (ins->opcode <= OP_VOIDCALL_MEMBASE)) || ((ins->opcode >= OP_FCALL) && (ins->opcode <= OP_FCALL_MEMBASE)) || ((ins->opcode >= OP_LCALL) && (ins->opcode <= OP_LCALL_MEMBASE)) || ((ins->opcode >= OP_VCALL) && (ins->opcode <= OP_VCALL_MEMBASE)) || ((ins->opcode >= OP_CALL) && (ins->opcode <= OP_CALL_MEMBASE)) || ((ins->opcode >= OP_VCALL2) && (ins->opcode <= OP_VCALL2_MEMBASE)) || (ins->opcode == OP_TAILCALL) || ((ins->opcode >= OP_RCALL) && (ins->opcode <= OP_RCALL_MEMBASE)))
+// OP_DYN_CALL is not a MonoCallInst
+#define MONO_IS_CALL(ins) (((ins->opcode >= OP_VOIDCALL) && (ins->opcode <= OP_VCALL2_MEMBASE)) || (ins->opcode == OP_TAILCALL))
 
 #define MONO_IS_JUMP_TABLE(ins) (((ins)->opcode == OP_JUMP_TABLE) ? TRUE : ((((ins)->opcode == OP_AOTCONST) && (ins->inst_i1 == (gpointer)MONO_PATCH_INFO_SWITCH)) ? TRUE : ((ins)->opcode == OP_SWITCH) ? TRUE : ((((ins)->opcode == OP_GOT_ENTRY) && ((ins)->inst_right->inst_i1 == (gpointer)MONO_PATCH_INFO_SWITCH)) ? TRUE : FALSE)))
 
@@ -783,11 +788,7 @@ typedef enum {
        LLVMArgFpStruct,
        LLVMArgVtypeByRef,
        /* Vtype returned as an int */
-       LLVMArgVtypeAsScalar,
-       /* Scalar returned by ref using an additional argument */
-       LLVMArgScalarRetAddr,
-       /* Scalar passed by ref */
-       LLVMArgScalarByRef
+       LLVMArgVtypeAsScalar
 } LLVMArgStorage;
 
 typedef struct {
@@ -1605,7 +1606,7 @@ typedef struct {
        /* Points to a MonoGSharedVtMethodRuntimeInfo at runtime */
        MonoInst *gsharedvt_info_var;
 
-       /* For native-to-managed wrappers, the saved old domain */
+       /* For native-to-managed wrappers, CEE_MONO_JIT_(AT|DE)TACH opcodes */
        MonoInst *orig_domain_var;
 
        MonoInst *lmf_var;
@@ -1660,6 +1661,7 @@ typedef struct {
        guint            disable_deadce_vars : 1;
        guint            disable_out_of_line_bblocks : 1;
        guint            disable_direct_icalls : 1;
+       guint            disable_gc_safe_points : 1;
        guint            create_lmf_var : 1;
        /*
         * When this is set, the code to push/pop the LMF from the LMF stack is generated as IR
@@ -1843,6 +1845,9 @@ typedef struct {
        /* Error handling */
        MonoError error;
 
+       /* pointer to context datastructure used for graph dumping */
+       MonoGraphDumper *gdump_ctx;
+
        /* Stats */
        int stat_allocate_var;
        int stat_locals_stack_size;
@@ -1893,6 +1898,43 @@ typedef struct {
        int methods_without_llvm;
        char *max_ratio_method;
        char *biggest_method;
+       double jit_method_to_ir;
+       double jit_liveness_handle_exception_clauses;
+       double jit_handle_out_of_line_bblock;
+       double jit_decompose_long_opts;
+       double jit_local_cprop;
+       double jit_local_emulate_ops;
+       double jit_optimize_branches;
+       double jit_handle_global_vregs;
+       double jit_local_deadce;
+       double jit_local_alias_analysis;
+       double jit_if_conversion;
+       double jit_bb_ordering;
+       double jit_compile_dominator_info;
+       double jit_compute_natural_loops;
+       double jit_insert_safepoints;
+       double jit_ssa_compute;
+       double jit_ssa_cprop;
+       double jit_ssa_deadce;
+       double jit_perform_abc_removal;
+       double jit_ssa_remove;
+       double jit_local_cprop2;
+       double jit_handle_global_vregs2;
+       double jit_local_deadce2;
+       double jit_optimize_branches2;
+       double jit_decompose_vtype_opts;
+       double jit_decompose_array_access_opts;
+       double jit_liveness_handle_exception_clauses2;
+       double jit_analyze_liveness;
+       double jit_linear_scan;
+       double jit_arch_allocate_vars;
+       double jit_spill_global_vars;
+       double jit_local_cprop3;
+       double jit_local_deadce3;
+       double jit_codegen;
+       double jit_create_jit_info;
+       double jit_gc_create_gc_map;
+       double jit_save_seq_point_info;
        double jit_time;
        gboolean enabled;
 } MonoJitStats;
@@ -2097,6 +2139,11 @@ typedef struct {
         * Translate Debugger.Break () into a native breakpoint signal
         */
        gboolean native_debugger_break;
+       /*
+        * Disabling the frame pointer emit optimization can allow debuggers to more easily
+        * identify the stack on some platforms
+        */
+       gboolean disable_omit_fp;
 } MonoDebugOptions;
 
 enum {
@@ -2240,11 +2287,19 @@ mono_bb_last_inst (MonoBasicBlock *bb, int filter)
 MONO_API int         mono_main                      (int argc, char* argv[]);
 MONO_API void        mono_set_defaults              (int verbose_level, guint32 opts);
 MONO_API void        mono_parse_env_options         (int *ref_argc, char **ref_argv []);
+MONO_API char       *mono_parse_options_from        (const char *options, int *ref_argc, char **ref_argv []);
+
 MonoDomain* mini_init                      (const char *filename, const char *runtime_version);
 void        mini_cleanup                   (MonoDomain *domain);
 MONO_API MonoDebugOptions *mini_get_debug_options   (void);
 MONO_API gboolean    mini_parse_debug_option (const char *option);
 
+/* graph dumping */
+void mono_cfg_dump_create_context (MonoCompile *cfg);
+void mono_cfg_dump_begin_group (MonoCompile *cfg);
+void mono_cfg_dump_close_group (MonoCompile *cfg);
+void mono_cfg_dump_ir (MonoCompile *cfg, const char *phase_name);
+
 /* helper methods */
 void      mini_jit_init                    (void);
 void      mini_jit_cleanup                 (void);
@@ -2300,6 +2355,7 @@ void      mono_blockset_print               (MonoCompile *cfg, MonoBitSet *set,
 const char*mono_ji_type_to_string           (MonoJumpInfoType type);
 void      mono_print_ji                     (const MonoJumpInfo *ji);
 void      mono_print_ins_index              (int i, MonoInst *ins);
+GString  *mono_print_ins_index_strbuf       (int i, MonoInst *ins);
 void      mono_print_ins                    (MonoInst *ins);
 void      mono_print_bb                     (MonoBasicBlock *bb, const char *msg);
 void      mono_print_code                   (MonoCompile *cfg, const char *msg);
@@ -2332,8 +2388,8 @@ MonoLMF * mono_get_lmf                      (void);
 MonoLMF** mono_get_lmf_addr                 (void);
 void      mono_set_lmf                      (MonoLMF *lmf);
 MonoJitTlsData* mono_get_jit_tls            (void);
-MONO_API MonoDomain *mono_jit_thread_attach          (MonoDomain *domain);
-MONO_API void      mono_jit_set_domain               (MonoDomain *domain);
+MONO_API MonoDomain* mono_jit_thread_attach (MonoDomain *domain);
+MONO_API void      mono_jit_set_domain      (MonoDomain *domain);
 gint32    mono_get_jit_tls_offset           (void);
 gint32    mono_get_lmf_tls_offset           (void);
 gint32    mono_get_lmf_addr_tls_offset      (void);
@@ -2363,7 +2419,7 @@ MonoInst *mono_get_got_var (MonoCompile *cfg);
 void      mono_add_seq_point (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins, int native_offset);
 void      mono_add_var_location (MonoCompile *cfg, MonoInst *var, gboolean is_reg, int reg, int offset, int from, int to);
 MonoInst* mono_emit_jit_icall (MonoCompile *cfg, gconstpointer func, MonoInst **args);
-MonoInst* mono_emit_jit_icall_by_info (MonoCompile *cfg, MonoJitICallInfo *info, MonoInst **args);
+MonoInst* mono_emit_jit_icall_by_info (MonoCompile *cfg, int il_offset, MonoJitICallInfo *info, MonoInst **args);
 MonoInst* mono_emit_method_call (MonoCompile *cfg, MonoMethod *method, MonoInst **args, MonoInst *this_ins);
 void      mono_create_helper_signatures (void);
 
@@ -2382,29 +2438,6 @@ void      mono_liveness_handle_exception_clauses (MonoCompile *cfg);
 
 /* Native Client functions */
 gpointer mono_realloc_native_code(MonoCompile *cfg);
-#ifdef __native_client_codegen__
-void mono_nacl_align_inst(guint8 **pcode, int instlen);
-void mono_nacl_align_call(guint8 **start, guint8 **pcode);
-guint8 *mono_nacl_pad_call(guint8 *code, guint8 ilength);
-guint8 *mono_nacl_align(guint8 *code);
-void mono_nacl_fix_patches(const guint8 *code, MonoJumpInfo *ji);
-/* Defined for each arch */
-guint8 *mono_arch_nacl_pad(guint8 *code, int pad);
-guint8 *mono_arch_nacl_skip_nops(guint8 *code);
-
-#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__)
 extern volatile int __nacl_thread_suspension_needed;
@@ -2412,12 +2445,6 @@ void __nacl_suspend_thread_if_needed(void);
 void mono_nacl_gc(void);
 #endif
 
-#if defined(__native_client_codegen__) || defined(__native_client__)
-#define NACL_SIZE(a, b) (b)
-#else
-#define NACL_SIZE(a, b) (a)
-#endif
-
 extern MonoDebugOptions debug_options;
 
 static inline MonoMethod*
@@ -2429,9 +2456,9 @@ jinfo_get_method (MonoJitInfo *ji)
 /* AOT */
 void      mono_aot_init                     (void);
 void      mono_aot_cleanup                  (void);
-gpointer  mono_aot_get_method               (MonoDomain *domain,
-                                                                                        MonoMethod *method);
-gpointer  mono_aot_get_method_from_token    (MonoDomain *domain, MonoImage *image, guint32 token);
+gpointer  mono_aot_get_method_checked       (MonoDomain *domain,
+                                                                                        MonoMethod *method, MonoError *error);
+gpointer  mono_aot_get_method_from_token    (MonoDomain *domain, MonoImage *image, guint32 token, MonoError *error);
 gboolean  mono_aot_is_got_entry             (guint8 *code, guint8 *addr);
 guint8*   mono_aot_get_plt_entry            (guint8 *code);
 guint32   mono_aot_get_plt_info_offset      (mgreg_t *regs, guint8 *code);
@@ -2440,7 +2467,7 @@ gboolean  mono_aot_get_class_from_name      (MonoImage *image, const char *name_
 MonoJitInfo* mono_aot_find_jit_info         (MonoDomain *domain, MonoImage *image, gpointer addr);
 gpointer mono_aot_plt_resolve               (gpointer aot_module, guint32 plt_info_offset, guint8 *code, MonoError *error);
 void     mono_aot_patch_plt_entry           (guint8 *code, guint8 *plt_entry, gpointer *got, mgreg_t *regs, guint8 *addr);
-gpointer mono_aot_get_method_from_vt_slot   (MonoDomain *domain, MonoVTable *vtable, int slot);
+gpointer mono_aot_get_method_from_vt_slot   (MonoDomain *domain, MonoVTable *vtable, int slot, MonoError *error);
 gpointer mono_aot_create_specific_trampoline   (MonoImage *image, gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len);
 gpointer mono_aot_get_trampoline            (const char *name);
 gpointer mono_aot_get_trampoline_full       (const char *name, MonoTrampInfo **out_tinfo);
@@ -2503,11 +2530,11 @@ guint8 *          mono_get_trampoline_code (MonoTrampolineType tramp_type);
 gpointer          mono_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len);
 gpointer          mono_create_jump_trampoline (MonoDomain *domain, 
                                                                                           MonoMethod *method, 
-                                                                                          gboolean add_sync_wrapper);
+                                                                                          gboolean add_sync_wrapper,
+                                                                                          MonoError *error);
 gpointer          mono_create_class_init_trampoline (MonoVTable *vtable);
-gpointer          mono_create_jit_trampoline (MonoMethod *method);
+gpointer          mono_create_jit_trampoline (MonoDomain *domain, MonoMethod *method, MonoError *error) MONO_LLVM_INTERNAL;
 gpointer          mono_create_jit_trampoline_from_token (MonoImage *image, guint32 token);
-gpointer          mono_create_jit_trampoline_in_domain (MonoDomain *domain, MonoMethod *method) MONO_LLVM_INTERNAL;
 gpointer          mono_create_delegate_trampoline (MonoDomain *domain, MonoClass *klass);
 MonoDelegateTrampInfo* mono_create_delegate_trampoline_info (MonoDomain *domain, MonoClass *klass, MonoMethod *method);
 gpointer          mono_create_delegate_virtual_trampoline (MonoDomain *domain, MonoClass *klass, MonoMethod *method);
@@ -2549,9 +2576,6 @@ MonoFtnDesc      *mini_create_llvmonly_ftndesc (MonoDomain *domain, gpointer add
 
 gboolean          mono_running_on_valgrind (void);
 void*             mono_global_codeman_reserve (int size);
-void*             nacl_global_codeman_get_dest(void *data);
-void              mono_global_codeman_commit(void *data, int size, int newsize);
-void              nacl_global_codeman_validate(guint8 **buf_base, int buf_size, guint8 **code_end);
 const char       *mono_regname_full (int reg, int bank);
 gint32*           mono_allocate_stack_slots (MonoCompile *cfg, gboolean backward, guint32 *stack_size, guint32 *stack_align);
 void              mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb);
@@ -2629,7 +2653,7 @@ GList    *mono_arch_get_global_fp_regs          (MonoCompile *cfg);
 GList    *mono_arch_get_iregs_clobbered_by_call (MonoCallInst *call);
 GList    *mono_arch_get_fregs_clobbered_by_call (MonoCallInst *call);
 guint32   mono_arch_regalloc_cost               (MonoCompile *cfg, MonoMethodVar *vmv);
-void      mono_arch_patch_code                  (MonoCompile *cfg, MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *ji, gboolean run_cctors);
+void      mono_arch_patch_code                  (MonoCompile *cfg, MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *ji, gboolean run_cctors, MonoError *error);
 void      mono_arch_patch_code_new              (MonoCompile *cfg, MonoDomain *domain, guint8 *code, MonoJumpInfo *ji, gpointer target);
 void      mono_arch_flush_icache                (guint8 *code, gint size);
 int       mono_arch_max_epilog_size             (MonoCompile *cfg);
@@ -2694,21 +2718,6 @@ gpointer mono_arch_get_seq_point_info           (MonoDomain *domain, guint8 *cod
 void     mono_arch_init_lmf_ext                 (MonoLMFExt *ext, gpointer prev_lmf);
 #endif
 
-#ifdef USE_JUMP_TABLES
-void
-mono_jumptable_init  (void);
-gpointer*
-mono_jumptable_add_entry (void);
-gpointer*
-mono_jumptable_add_entries (guint32 entries);
-void
-mono_jumptable_cleanup  (void);
-gpointer*
-mono_arch_jumptable_entry_from_code (guint8 *code);
-gpointer*
-mono_jumptable_get_entry (guint8 *code);
-#endif
-
 gboolean
 mono_arch_unwind_frame (MonoDomain *domain, MonoJitTlsData *jit_tls, 
                                                MonoJitInfo *ji, MonoContext *ctx, 
@@ -2968,6 +2977,10 @@ mono_method_is_generic_sharable_full (MonoMethod *method, gboolean allow_type_va
 gboolean
 mini_class_is_generic_sharable (MonoClass *klass);
 
+
+gboolean
+mini_generic_inst_is_sharable (MonoGenericInst *inst, gboolean allow_type_vars, gboolean allow_partial);
+
 gboolean
 mono_is_partially_sharable_inst (MonoGenericInst *inst);
 
@@ -3008,6 +3021,18 @@ void mono_cfg_add_try_hole (MonoCompile *cfg, MonoExceptionClause *clause, guint
 void mono_cfg_set_exception (MonoCompile *cfg, int type);
 void mono_cfg_set_exception_invalid_program (MonoCompile *cfg, char *msg);
 
+#define MONO_TIME_TRACK(a, phase) \
+       { \
+               GTimer *timer = mono_time_track_start (); \
+               (phase) ; \
+               mono_time_track_end (&(a), timer); \
+       }
+
+GTimer *mono_time_track_start (void);
+void mono_time_track_end (double *time, GTimer *timer);
+
+void mono_update_jit_stats (MonoCompile *cfg);
+
 gboolean mini_type_is_reference (MonoType *type);
 gboolean mini_type_is_vtype (MonoType *t) MONO_LLVM_INTERNAL;
 gboolean mini_type_var_is_vt (MonoType *type) MONO_LLVM_INTERNAL;
@@ -3115,6 +3140,11 @@ void mono_cross_helpers_run (void);
  * Signal handling
  */
 
+#if defined(DISABLE_HW_TRAPS) || defined(MONO_ARCH_DISABLE_HW_TRAPS)
+ // Signal handlers not available
+#define MONO_ARCH_NEED_DIV_CHECK 1
+#endif
+
 void MONO_SIG_HANDLER_SIGNATURE (mono_sigfpe_signal_handler) ;
 void MONO_SIG_HANDLER_SIGNATURE (mono_sigill_signal_handler) ;
 void MONO_SIG_HANDLER_SIGNATURE (mono_sigsegv_signal_handler);
@@ -3131,4 +3161,14 @@ gboolean MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal);
 #define ARCH_VARARG_ICALLS 0
 #endif
 
+/*
+ * Native unwinder integration
+ */
+void mono_exception_native_unwind (void *ctx, MONO_SIG_HANDLER_INFO_TYPE *info);
+
+/*
+ * Coop support for trampolines
+ */
+void mono_interruption_checkpoint_from_trampoline (void);
+
 #endif /* __MONO_MINI_H__ */