Merge pull request #1412 from esdrubal/stackframe
[mono.git] / mono / mini / mini.h
index f989bc274162fe8eb07217769c3a3789cc6b81cd..2169a79423f1b5440e27fd30fd9736a56b807dc8 100755 (executable)
@@ -31,6 +31,7 @@
 #include <mono/utils/mono-tls.h>
 #include <mono/utils/atomic.h>
 #include <mono/utils/mono-conc-hashtable.h>
+#include <mono/utils/mono-signal-handler.h>
 
 #define MONO_BREAKPOINT_ARRAY_SIZE 64
 
 #error "The code in mini/ should not depend on these defines."
 #endif
 
-#ifndef G_LIKELY
-#define G_LIKELY(a) (a)
-#define G_UNLIKELY(a) (a)
-#endif
-
-#ifndef G_MAXINT32
-#define G_MAXINT32 2147483647
-#endif
-
-#ifndef G_MININT32
-#define G_MININT32 (-G_MAXINT32 - 1)
-#endif
-
 #ifndef __GNUC__
 /*#define __alignof__(a) sizeof(a)*/
 #define __alignof__(type) G_STRUCT_OFFSET(struct { char c; type x; }, x)
 #define COMPILE_SOFT_FLOAT(cfg) (0)
 #endif
 
-#ifdef ENABLE_LLVM
-#define LLVM_CHECK_VERSION(major,minor) \
-       ((LLVM_MAJOR_VERSION > (major)) ||                                                                      \
-        ((LLVM_MAJOR_VERSION == (major)) && (LLVM_MINOR_VERSION >= (minor))))
-#else
-#define LLVM_CHECK_VERSION(major,minor) 0
-#endif
-
 #define NOT_IMPLEMENTED do { g_assert_not_reached (); } while (0)
 
 /* for 32 bit systems */
 #endif
 
 /* Version number of the AOT file format */
-#define MONO_AOT_FILE_VERSION 103
+#define MONO_AOT_FILE_VERSION 104
 
 //TODO: This is x86/amd64 specific.
 #define mono_simd_shuffle_mask(a,b,c,d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6))
 #define printf g_print
 #endif
 
-#if !defined(HAVE_KW_THREAD) || !defined(MONO_ARCH_ENABLE_MONO_LMF_VAR)
-#define MONO_JIT_TLS_DATA_HAS_LMF
-#endif
-
 #define MONO_TYPE_IS_PRIMITIVE(t) ((!(t)->byref && ((((t)->type >= MONO_TYPE_BOOLEAN && (t)->type <= MONO_TYPE_R8) || ((t)->type >= MONO_TYPE_I && (t)->type <= MONO_TYPE_U)))))
 
 /* Constants used to encode different types of methods in AOT */
@@ -353,34 +329,13 @@ typedef struct {
  */
 typedef MonoStackFrameInfo StackFrameInfo;
 
-#define MONO_SEQ_POINT_FLAG_NONEMPTY_STACK 1
-
-typedef struct {
-       int il_offset, native_offset, flags;
-       /* Indexes of successor sequence points */
-       int *next;
-       /* Number of entries in next */
-       int next_len;
-} SeqPoint;
-
-typedef struct {
-       int len;
-       SeqPoint seq_points [MONO_ZERO_LEN_ARRAY];
-} MonoSeqPointInfo;
-
 #if 0
 #define mono_bitset_foreach_bit(set,b,n) \
        for (b = 0; b < n; b++)\
                if (mono_bitset_test_fast(set,b))
-#define mono_bitset_foreach_bit_rev(set,b,n) \
-       for (b = n - 1; b >= 0; b--)\
-               if (mono_bitset_test_fast(set,b))
 #else
 #define mono_bitset_foreach_bit(set,b,n) \
        for (b = mono_bitset_find_start (set); b < n && b >= 0; b = mono_bitset_find_first (set, b))
-#define mono_bitset_foreach_bit_rev(set,b,n) \
-       for (b = mono_bitset_find_last (set, n - 1); b >= 0; b = b ? mono_bitset_find_last (set, b) : -1)
 #endif
 
 /*
@@ -417,11 +372,6 @@ enum {
         (dest)->inst.cil_code = (cfg)->ip;  \
        } while (0)
 
-#define MONO_INST_NEW_CALL_ARG(cfg,dest,op) do {       \
-               (dest) = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoCallArgParm));        \
-               (dest)->ins.opcode = (op);      \
-       } while (0)
-
 #define MONO_ADD_INS(b,inst) do {      \
                if ((b)->last_ins) {    \
                        (b)->last_ins->next = (inst);   \
@@ -851,6 +801,8 @@ struct MonoCallInst {
         * calling convention as OP_CALL.
         */
        guint vret_in_reg : 1;
+       /* Whenever vret_in_reg returns fp values */
+       guint vret_in_reg_fp : 1;
        /* Whenever there is an IMT argument and it is dynamic */
        guint dynamic_imt_arg : 1;
        /* Whenever there is an RGCTX argument */
@@ -956,6 +908,14 @@ enum {
 #define inst_phi_args   data.op[1].phi_args
 #define inst_eh_block   data.op[1].exception_clause
 
+static inline void
+mono_inst_set_src_registers (MonoInst *ins, int *regs)
+{
+       ins->sreg1 = regs [0];
+       ins->sreg2 = regs [1];
+       ins->sreg3 = regs [2];
+}
+
 /* instruction description for use in regalloc/scheduling */
 enum {
        MONO_INST_DEST,
@@ -1426,8 +1386,6 @@ typedef struct {
        MonoGenericSharingContext gsctx;
        MonoGenericContext *gsctx_context;
 
-       gboolean gsharedvt;
-
        MonoGSharedVtMethodInfo *gsharedvt_info;
 
        /* Points to the gsharedvt locals area at runtime */
@@ -1458,6 +1416,7 @@ typedef struct {
        guint            code_len;
        guint            prolog_end;
        guint            epilog_begin;
+       guint            epilog_end;
        regmask_t        used_int_regs;
        guint32          opt;
        guint32          prof_options;
@@ -1514,6 +1473,7 @@ typedef struct {
        guint            uses_simd_intrinsics : 1;
        guint            keep_cil_nops : 1;
        guint            gen_seq_points : 1;
+       guint            gen_seq_points_debug_data : 1;
        guint            explicit_null_checks : 1;
        guint            compute_gc_maps : 1;
        guint            soft_breakpoints : 1;
@@ -1524,6 +1484,9 @@ typedef struct {
        guint            has_atomic_cas_i4 : 1;
        guint            check_pinvoke_callconv : 1;
        guint            has_unwind_info_for_epilog : 1;
+       guint            disable_inline : 1;
+       guint            gshared : 1;
+       guint            gsharedvt : 1;
        gpointer         debug_info;
        guint32          lmf_offset;
     guint16          *intvars;
@@ -1540,6 +1503,8 @@ typedef struct {
        guint32          encoded_unwind_ops_len;
        GSList*          unwind_ops;
 
+       GList*           dont_inline;
+
        /* Fields used by the local reg allocator */
        void*            reginfo;
        int              reginfo_len;
@@ -1604,7 +1569,7 @@ typedef struct {
        GPtrArray *seq_points;
 
        /* The encoded sequence point info */
-       MonoSeqPointInfo *seq_point_info;
+       struct MonoSeqPointInfo *seq_point_info;
 
        /* Method headers which need to be freed after compilation */
        GSList *headers_to_free;
@@ -1633,6 +1598,9 @@ typedef struct {
        /* The offsets of the locals area relative to the frame pointer */
        gint locals_min_stack_offset, locals_max_stack_offset;
 
+       /* The current CFA rule */
+       int cur_cfa_reg, cur_cfa_offset;
+
        /* The final CFA rule at the end of the prolog */
        int cfa_reg, cfa_offset;
 
@@ -1646,6 +1614,9 @@ typedef struct {
        guint8 *gc_map;
        guint32 gc_map_size;
 
+       /* Error handling */
+       MonoError error;
+
        /* Stats */
        int stat_allocate_var;
        int stat_locals_stack_size;
@@ -1681,6 +1652,7 @@ typedef struct {
        gint32 max_code_size_ratio;
        gint32 biggest_method_size;
        gint32 allocated_code_size;
+       gint32 allocated_seq_points_size;
        gint32 inlineable_methods;
        gint32 inlined_methods;
        gint32 basic_blocks;
@@ -1859,7 +1831,11 @@ typedef struct {
        gboolean suspend_on_unhandled;
        gboolean dyn_runtime_invoke;
        gboolean gdb;
-       gboolean gen_seq_points;
+       /*
+        * Whenever data such as next sequence points and flags is required.
+        * Next sequence points and flags are required by the debugger agent.
+        */
+       gboolean gen_seq_points_debug_data;
        gboolean explicit_null_checks;
        /*
         * Fill stack frames with 0x2a in method prologs. This helps with the
@@ -2030,7 +2006,6 @@ MONO_API void      mono_print_method_from_ip         (void *ip);
 MONO_API char     *mono_pmip                         (void *ip);
 gboolean  mono_debug_count                  (void) MONO_INTERNAL;
 MONO_API const char* mono_inst_name                  (int op);
-void      mono_inst_set_src_registers       (MonoInst *ins, int *regs) MONO_INTERNAL;
 int       mono_op_to_op_imm                 (int opcode) MONO_INTERNAL;
 int       mono_op_imm_to_op                 (int opcode) MONO_INTERNAL;
 int       mono_load_membase_to_load_mem     (int opcode) MONO_INTERNAL;
@@ -2174,6 +2149,8 @@ guint32  mono_aot_method_hash               (MonoMethod *method) MONO_INTERNAL;
 MonoMethod* mono_aot_get_array_helper_from_wrapper (MonoMethod *method) MONO_INTERNAL;
 guint32  mono_aot_get_got_offset            (MonoJumpInfo *ji) MONO_LLVM_INTERNAL;
 char*    mono_aot_get_method_name           (MonoCompile *cfg) MONO_LLVM_INTERNAL;
+gboolean mono_aot_is_direct_callable        (MonoJumpInfo *patch_info) MONO_LLVM_INTERNAL;
+void     mono_aot_mark_unused_llvm_plt_entry(MonoJumpInfo *patch_info) 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;
@@ -2200,7 +2177,7 @@ void     mono_llvm_cleanup                  (void) MONO_LLVM_INTERNAL;
 void     mono_llvm_emit_method              (MonoCompile *cfg) MONO_LLVM_INTERNAL;
 void     mono_llvm_emit_call                (MonoCompile *cfg, MonoCallInst *call) MONO_LLVM_INTERNAL;
 void     mono_llvm_create_aot_module        (const char *got_symbol) MONO_LLVM_INTERNAL;
-void     mono_llvm_emit_aot_module          (const char *filename, int got_size) MONO_LLVM_INTERNAL;
+void     mono_llvm_emit_aot_module          (const char *filename, const char *cu_name, int got_size) MONO_LLVM_INTERNAL;
 void     mono_llvm_check_method_supported   (MonoCompile *cfg) MONO_LLVM_INTERNAL;
 void     mono_llvm_free_domain_info         (MonoDomain *domain) MONO_LLVM_INTERNAL;
 
@@ -2295,7 +2272,7 @@ void              mono_tramp_info_register (MonoTrampInfo *info) MONO_INTERNAL;
 int               mini_exception_id_by_name (const char *name) MONO_INTERNAL;
 
 int               mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_bblock, MonoBasicBlock *end_bblock, 
-                                                                        MonoInst *return_var, GList *dont_inline, MonoInst **inline_args, 
+                                                                        MonoInst *return_var, MonoInst **inline_args,
                                                                         guint inline_offset, gboolean is_virtual_call) MONO_INTERNAL;
 
 MonoInst         *mono_decompose_opcode (MonoCompile *cfg, MonoInst *ins) MONO_INTERNAL;
@@ -2438,8 +2415,6 @@ void     mono_arch_handle_altstack_exception    (void *sigctx, gpointer fault_ad
 gboolean mono_handle_soft_stack_ovf             (MonoJitTlsData *jit_tls, MonoJitInfo *ji, void *ctx, guint8* fault_addr) MONO_INTERNAL;
 void     mono_handle_hard_stack_ovf             (MonoJitTlsData *jit_tls, MonoJitInfo *ji, void *ctx, guint8* fault_addr) MONO_INTERNAL;
 gpointer mono_arch_ip_from_context              (void *sigctx) MONO_INTERNAL;
-void     mono_arch_sigctx_to_monoctx            (void *sigctx, MonoContext *ctx) MONO_INTERNAL;
-void     mono_arch_monoctx_to_sigctx            (MonoContext *mctx, void *ctx) MONO_INTERNAL;
 mgreg_t mono_arch_context_get_int_reg              (MonoContext *ctx, int reg) MONO_INTERNAL;
 void     mono_arch_context_set_int_reg             (MonoContext *ctx, int reg, mgreg_t val) MONO_INTERNAL;
 void     mono_arch_flush_register_windows       (void) MONO_INTERNAL;
@@ -2762,8 +2737,6 @@ enum {
        SIMD_VERSION_INDEX_END = 6 
 };
 
-#define MASK(x) (1 << x)
-
 enum {
        SIMD_COMP_EQ,
        SIMD_COMP_LT,
@@ -2821,53 +2794,12 @@ void mono_cross_helpers_run (void) MONO_INTERNAL;
 /*
  * Signal handling
  */
-#ifdef MONO_GET_CONTEXT
-#define GET_CONTEXT MONO_GET_CONTEXT
-#endif
-
-#ifndef GET_CONTEXT
-#ifdef HOST_WIN32
-/* seh_vectored_exception_handler () passes in a CONTEXT* */
-#define GET_CONTEXT \
-    void *ctx = context;
-#else
-#ifdef MONO_ARCH_USE_SIGACTION
-#define GET_CONTEXT \
-    void *ctx = context;
-#elif defined(__HAIKU__)
-#define GET_CONTEXT \
-       void *ctx = &regs;
-#else
-#define GET_CONTEXT \
-       void **_p = (void **)&_dummy; \
-       struct sigcontext *ctx = (struct sigcontext *)++_p;
-#endif
-#endif
-#endif
-
-#if defined(MONO_ARCH_USE_SIGACTION) && !defined(HOST_WIN32)
-#define SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy, siginfo_t *info, void *context)
-#define SIG_HANDLER_FUNC(access, ftn) MONO_SIGNAL_HANDLER_FUNC (access, ftn, (int _dummy, siginfo_t *info, void *context))
-#define SIG_HANDLER_PARAMS _dummy, info, context
-#elif defined(HOST_WIN32)
-#define SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy, EXCEPTION_POINTERS *info, void *context)
-#define SIG_HANDLER_FUNC(access, ftn) MONO_SIGNAL_HANDLER_FUNC (access, ftn, (int _dummy, EXCEPTION_POINTERS *info, void *context))
-#define SIG_HANDLER_PARAMS _dummy, info, context
-#elif defined(__HAIKU__)
-#define SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy, void *userData, vregs regs)
-#define SIG_HANDLER_FUNC(access, ftn) MONO_SIGNAL_HANDLER_FUNC (access, ftn, (int _dummy, void *userData, vregs regs))
-#define SIG_HANDLER_PARAMS _dummy, userData, regs
-#else
-#define SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy)
-#define SIG_HANDLER_FUNC(access, ftn) MONO_SIGNAL_HANDLER_FUNC (access, ftn, (int _dummy))
-#define SIG_HANDLER_PARAMS _dummy
-#endif
 
-void SIG_HANDLER_SIGNATURE (mono_sigfpe_signal_handler)  MONO_INTERNAL;
-void SIG_HANDLER_SIGNATURE (mono_sigill_signal_handler)  MONO_INTERNAL;
-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;
+void MONO_SIG_HANDLER_SIGNATURE (mono_sigfpe_signal_handler)  MONO_INTERNAL;
+void MONO_SIG_HANDLER_SIGNATURE (mono_sigill_signal_handler)  MONO_INTERNAL;
+void MONO_SIG_HANDLER_SIGNATURE (mono_sigsegv_signal_handler) MONO_INTERNAL;
+void MONO_SIG_HANDLER_SIGNATURE (mono_sigint_signal_handler)  MONO_INTERNAL;
+gboolean MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal) MONO_INTERNAL;
 
 #ifdef MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE
 #define ARCH_HAVE_DELEGATE_TRAMPOLINES 1