Merge pull request #1548 from akoeplinger/stubs
[mono.git] / mono / mini / mini.h
index cfd1053320746dbe7dc71be133f232f62413a561..1e789fbddcf6abf6e753698f47d22f1434818ac4 100755 (executable)
@@ -8,7 +8,9 @@
 
 #include "config.h"
 #include <glib.h>
+#ifdef HAVE_SIGNAL_H
 #include <signal.h>
+#endif
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
 #endif
 
 /* Version number of the AOT file format */
-#define MONO_AOT_FILE_VERSION 104
+#define MONO_AOT_FILE_VERSION 107
 
 //TODO: This is x86/amd64 specific.
 #define mono_simd_shuffle_mask(a,b,c,d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6))
@@ -164,7 +166,6 @@ typedef enum {
        MONO_AOT_FILE_FLAG_WITH_LLVM = 1,
        MONO_AOT_FILE_FLAG_FULL_AOT = 2,
        MONO_AOT_FILE_FLAG_DEBUG = 4,
-       MONO_AOT_FILE_FLAG_DIRECT_METHOD_ADDRESSES = 8
 } MonoAotFileFlags;
 
 /* This structure is stored in the AOT file */
@@ -179,8 +180,12 @@ typedef struct MonoAotFileInfo
 
        /* Mono's Global Offset Table */
        gpointer got;
+       /* Global Offset Table for LLVM code */
+       gpointer llvm_got;
        /* Compiled code for methods */
        gpointer methods;
+       gpointer jit_code_start;
+       gpointer jit_code_end;
        /* Mono EH Frame created by llc when using LLVM */
        gpointer mono_eh_frame;
        /* Data blob */
@@ -189,11 +194,11 @@ typedef struct MonoAotFileInfo
        gpointer class_info_offsets;
        gpointer method_info_offsets;
        gpointer ex_info_offsets;
-       gpointer code_offsets;
        gpointer method_addresses;
        gpointer extra_method_info_offsets;
        gpointer extra_method_table;
        gpointer got_info_offsets;
+       gpointer llvm_got_info_offsets;
        gpointer methods_end;
        gpointer unwind_info;
        gpointer mem_end;
@@ -226,6 +231,8 @@ typedef struct MonoAotFileInfo
        gpointer unbox_trampolines;
        /* Points to the end of the previous table */
        gpointer unbox_trampolines_end;
+       /* Points to a table of unbox trampoline addresses/offsets */
+       gpointer unbox_trampoline_addresses;
 
        /* The index of the first GOT slot used by the PLT */
        guint32 plt_got_offset_base;
@@ -329,21 +336,6 @@ 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++)\
@@ -435,8 +427,8 @@ enum {
 #define MONO_IS_SETCC(ins) ((((ins)->opcode >= OP_CEQ) && ((ins)->opcode <= OP_CLT_UN)) || (((ins)->opcode >= OP_ICEQ) && ((ins)->opcode <= OP_ICLT_UN)) || (((ins)->opcode >= OP_LCEQ) && ((ins)->opcode <= OP_LCLT_UN)) || (((ins)->opcode >= OP_FCEQ) && ((ins)->opcode <= OP_FCLT_UN)))
 
 
-#define MONO_IS_LOAD_MEMBASE(ins) (((ins)->opcode >= OP_LOAD_MEMBASE) && ((ins)->opcode <= OP_LOADV_MEMBASE))
-#define MONO_IS_STORE_MEMBASE(ins) (((ins)->opcode >= OP_STORE_MEMBASE_REG) && ((ins)->opcode <= OP_STOREV_MEMBASE))
+#define MONO_IS_LOAD_MEMBASE(ins) (((ins)->opcode >= OP_LOAD_MEMBASE && (ins)->opcode <= OP_LOADV_MEMBASE) || ((ins)->opcode >= OP_ATOMIC_LOAD_I1 && (ins)->opcode <= OP_ATOMIC_LOAD_R8))
+#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))
@@ -447,7 +439,7 @@ enum {
 
 /* FIXME: Add more instructions */
 /* INEG sets the condition codes, and the OP_LNEG decomposition depends on this on x86 */
-#define MONO_INS_HAS_NO_SIDE_EFFECT(ins) (MONO_IS_MOVE (ins) || (ins->opcode == OP_ICONST) || (ins->opcode == OP_I8CONST) || MONO_IS_ZERO (ins) || (ins->opcode == OP_ADD_IMM) || (ins->opcode == OP_R8CONST) || (ins->opcode == OP_LADD_IMM) || (ins->opcode == OP_ISUB_IMM) || (ins->opcode == OP_IADD_IMM) || (ins->opcode == OP_LNEG) || (ins->opcode == OP_ISUB) || (ins->opcode == OP_CMOV_IGE) || (ins->opcode == OP_ISHL_IMM) || (ins->opcode == OP_ISHR_IMM) || (ins->opcode == OP_ISHR_UN_IMM) || (ins->opcode == OP_IAND_IMM) || (ins->opcode == OP_ICONV_TO_U1) || (ins->opcode == OP_ICONV_TO_I1) || (ins->opcode == OP_SEXT_I4) || (ins->opcode == OP_LCONV_TO_U1) || (ins->opcode == OP_ICONV_TO_U2) || (ins->opcode == OP_ICONV_TO_I2) || (ins->opcode == OP_LCONV_TO_I2) || (ins->opcode == OP_LDADDR) || (ins->opcode == OP_PHI) || (ins->opcode == OP_NOP) || (ins->opcode == OP_ZEXT_I4) || (ins->opcode == OP_NOT_NULL))
+#define MONO_INS_HAS_NO_SIDE_EFFECT(ins) (MONO_IS_MOVE (ins) || (ins->opcode == OP_ICONST) || (ins->opcode == OP_I8CONST) || MONO_IS_ZERO (ins) || (ins->opcode == OP_ADD_IMM) || (ins->opcode == OP_R8CONST) || (ins->opcode == OP_LADD_IMM) || (ins->opcode == OP_ISUB_IMM) || (ins->opcode == OP_IADD_IMM) || (ins->opcode == OP_LNEG) || (ins->opcode == OP_ISUB) || (ins->opcode == OP_CMOV_IGE) || (ins->opcode == OP_ISHL_IMM) || (ins->opcode == OP_ISHR_IMM) || (ins->opcode == OP_ISHR_UN_IMM) || (ins->opcode == OP_IAND_IMM) || (ins->opcode == OP_ICONV_TO_U1) || (ins->opcode == OP_ICONV_TO_I1) || (ins->opcode == OP_SEXT_I4) || (ins->opcode == OP_LCONV_TO_U1) || (ins->opcode == OP_ICONV_TO_U2) || (ins->opcode == OP_ICONV_TO_I2) || (ins->opcode == OP_LCONV_TO_I2) || (ins->opcode == OP_LDADDR) || (ins->opcode == OP_PHI) || (ins->opcode == OP_NOP) || (ins->opcode == OP_ZEXT_I4) || (ins->opcode == OP_NOT_NULL) || (ins->opcode == OP_IL_SEQ_POINT))
 
 #define MONO_METHOD_IS_FINAL(m) (((m)->flags & METHOD_ATTRIBUTE_FINAL) || ((m)->klass && ((m)->klass->flags & TYPE_ATTRIBUTE_SEALED)))
 
@@ -712,13 +704,28 @@ typedef enum {
        LLVMArgVtypeByVal,
        LLVMArgVtypeRetAddr, /* On on cinfo->ret */
        LLVMArgGSharedVt,
+       /* Vtype passed as one int array argument */
+       LLVMArgAsIArgs,
+       /* Vtype passed as a set of fp arguments */
+       LLVMArgAsFpArgs
 } LLVMArgStorage;
 
 typedef struct {
        LLVMArgStorage storage;
 
-       /* Only if storage == ArgValuetypeInReg */
-       LLVMArgStorage pair_storage [2];
+       /*
+        * Only if storage == ArgValuetypeInReg/LLVMArgAsFpArgs.
+        * This contains how the parts of the vtype are passed.
+        */
+       LLVMArgStorage pair_storage [8];
+       /*
+        * Only if storage == LLVMArgAsIArgs/LLVMArgAsFpArgs.
+        * If storage == LLVMArgAsFpArgs, this is the number of arguments
+        * used to pass the value.
+        */
+       int nslots;
+       /* Only if storage == LLVMArgAsFpArgs (4/8) */
+       int esize;
 } LLVMArgInfo;
 
 typedef struct {
@@ -791,7 +798,13 @@ struct MonoInst {
                MonoInst *spill_var; /* for OP_ICONV_TO_R8_RAW and OP_FCONV_TO_R8_X */
                guint16 source_opcode; /*OP_XCONV_R8_TO_I4 needs to know which op was used to do proper widening*/
                int pc_offset; /* OP_GC_LIVERANGE_START/END */
-               int memory_barrier_kind; /* see mono-memory-model.h for valid values */
+
+               /*
+                * memory_barrier: MONO_MEMORY_BARRIER_{ACQ,REL,SEQ}
+                * atomic_load_*: MONO_MEMORY_BARRIER_{ACQ,SEQ}
+                * atomic_store_*: MONO_MEMORY_BARRIER_{REL,SEQ}
+                */
+               int memory_barrier_kind;
        } backend;
        
        MonoClass *klass;
@@ -1260,6 +1273,7 @@ typedef enum {
        MONO_TRAMPOLINE_RESTORE_STACK_PROT,
        MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING,
        MONO_TRAMPOLINE_MONITOR_ENTER,
+       MONO_TRAMPOLINE_MONITOR_ENTER_V4,
        MONO_TRAMPOLINE_MONITOR_EXIT,
        MONO_TRAMPOLINE_VCALL,
        MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD,
@@ -1273,12 +1287,14 @@ typedef enum {
         (t) == MONO_TRAMPOLINE_RESTORE_STACK_PROT ||   \
         (t) == MONO_TRAMPOLINE_RGCTX_LAZY_FETCH ||     \
         (t) == MONO_TRAMPOLINE_MONITOR_ENTER ||        \
+        (t) == MONO_TRAMPOLINE_MONITOR_ENTER_V4 ||     \
         (t) == MONO_TRAMPOLINE_MONITOR_EXIT)
 
 /* These trampolines receive an argument directly in a register */
 #define MONO_TRAMPOLINE_TYPE_HAS_ARG(t)                \
        ((t) == MONO_TRAMPOLINE_GENERIC_CLASS_INIT ||   \
         (t) == MONO_TRAMPOLINE_MONITOR_ENTER ||                \
+        (t) == MONO_TRAMPOLINE_MONITOR_ENTER_V4 ||             \
         (t) == MONO_TRAMPOLINE_MONITOR_EXIT ||                 \
         (t) == MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD)
 
@@ -1488,6 +1504,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;
@@ -1583,7 +1600,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;
@@ -1666,6 +1683,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;
@@ -1844,7 +1862,12 @@ 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 gen_seq_points_compact_data;
        gboolean explicit_null_checks;
        /*
         * Fill stack frames with 0x2a in method prologs. This helps with the
@@ -1950,6 +1973,66 @@ enum {
 
 typedef void (*MonoInstFunc) (MonoInst *tree, gpointer data);
 
+enum {
+       FILTER_IL_SEQ_POINT = 1 << 0,
+       FILTER_NOP          = 1 << 1,
+};
+
+static inline gboolean
+mono_inst_filter (MonoInst *ins, int filter)
+{
+       if (!ins || !filter)
+               return FALSE;
+
+       if ((filter & FILTER_IL_SEQ_POINT) && ins->opcode == OP_IL_SEQ_POINT)
+               return TRUE;
+
+       if ((filter & FILTER_NOP) && ins->opcode == OP_NOP)
+               return TRUE;
+
+       return FALSE;
+}
+
+static inline MonoInst*
+mono_inst_next (MonoInst *ins, int filter)
+{
+       do {
+               ins = ins->next;
+       } while (mono_inst_filter (ins, filter));
+
+       return ins;
+}
+
+static inline MonoInst*
+mono_inst_prev (MonoInst *ins, int filter)
+{
+       do {
+               ins = ins->prev;
+       } while (mono_inst_filter (ins, filter));
+
+       return ins;
+}
+
+static inline MonoInst*
+mono_bb_first_inst (MonoBasicBlock *bb, int filter)
+{
+       MonoInst *ins = bb->code;
+       if (mono_inst_filter (ins, filter))
+               ins = mono_inst_next (ins, filter);
+
+       return ins;
+}
+
+static inline MonoInst*
+mono_bb_last_inst (MonoBasicBlock *bb, int filter)
+{
+       MonoInst *ins = bb->last_ins;
+       if (mono_inst_filter (ins, filter))
+               ins = mono_inst_prev (ins, filter);
+
+       return ins;
+}
+
 /* main function */
 MONO_API int         mono_main                      (int argc, char* argv[]);
 MONO_API void        mono_set_defaults              (int verbose_level, guint32 opts);
@@ -2185,8 +2268,8 @@ void     mono_llvm_init                     (void) MONO_LLVM_INTERNAL;
 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, const char *cu_name, int got_size) MONO_LLVM_INTERNAL;
+void     mono_llvm_create_aot_module        (const char *got_symbol, gboolean external_symbols, gboolean emit_dwarf) MONO_LLVM_INTERNAL;
+void     mono_llvm_emit_aot_module          (const char *filename, const char *cu_name) 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;
 
@@ -2223,6 +2306,7 @@ MonoDelegateTrampInfo* mono_create_delegate_trampoline_info (MonoDomain *domain,
 gpointer          mono_create_delegate_virtual_trampoline (MonoDomain *domain, MonoClass *klass, MonoMethod *method) MONO_INTERNAL;
 gpointer          mono_create_rgctx_lazy_fetch_trampoline (guint32 offset) MONO_INTERNAL;
 gpointer          mono_create_monitor_enter_trampoline (void) MONO_INTERNAL;
+gpointer          mono_create_monitor_enter_v4_trampoline (void) MONO_INTERNAL;
 gpointer          mono_create_monitor_exit_trampoline (void) MONO_INTERNAL;
 gpointer          mono_create_static_rgctx_trampoline (MonoMethod *m, gpointer addr) MONO_INTERNAL;
 gpointer          mono_create_llvm_imt_trampoline (MonoDomain *domain, MonoMethod *m, int vt_offset) MONO_LLVM_INTERNAL;
@@ -2240,9 +2324,11 @@ gpointer          mono_aot_plt_trampoline (mgreg_t *regs, guint8 *code, guint8 *
 void              mono_class_init_trampoline (mgreg_t *regs, guint8 *code, MonoVTable *vtable, guint8 *tramp) MONO_INTERNAL;
 void              mono_generic_class_init_trampoline (mgreg_t *regs, guint8 *code, MonoVTable *vtable, guint8 *tramp) MONO_INTERNAL;
 void              mono_monitor_enter_trampoline (mgreg_t *regs, guint8 *code, MonoObject *obj, guint8 *tramp) MONO_INTERNAL;
+void              mono_monitor_enter_v4_trampoline (mgreg_t *regs, guint8 *code, MonoObject *obj, guint8 *tramp) MONO_INTERNAL;
 void              mono_monitor_exit_trampoline (mgreg_t *regs, guint8 *code, MonoObject *obj, guint8 *tramp) MONO_INTERNAL;
 gconstpointer     mono_get_trampoline_func (MonoTrampolineType tramp_type);
 gpointer          mini_get_vtable_trampoline (int slot_index) MONO_INTERNAL;
+const char*       mono_get_generic_trampoline_simple_name (MonoTrampolineType tramp_type) 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_get_nullified_class_init_trampoline (void) MONO_INTERNAL;
@@ -2318,7 +2404,7 @@ gpointer  mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampI
 gpointer  mono_arch_create_general_rgctx_lazy_fetch_trampoline (MonoTrampInfo **info, gboolean aot) MONO_INTERNAL;
 gpointer  mono_arch_create_generic_class_init_trampoline (MonoTrampInfo **info, gboolean aot) MONO_INTERNAL;
 gpointer  mono_arch_get_nullified_class_init_trampoline (MonoTrampInfo **info) MONO_INTERNAL;
-gpointer  mono_arch_create_monitor_enter_trampoline (MonoTrampInfo **info, gboolean aot) MONO_INTERNAL;
+gpointer  mono_arch_create_monitor_enter_trampoline (MonoTrampInfo **info, gboolean is_v4, gboolean aot) MONO_INTERNAL;
 gpointer  mono_arch_create_monitor_exit_trampoline (MonoTrampInfo **info, gboolean aot) MONO_INTERNAL;
 guint8   *mono_arch_create_llvm_native_thunk     (MonoDomain *domain, guint8* addr) MONO_LLVM_INTERNAL;
 GList    *mono_arch_get_allocatable_int_vars    (MonoCompile *cfg) MONO_INTERNAL;
@@ -2420,8 +2506,8 @@ gpointer  mono_arch_get_rethrow_exception       (MonoTrampInfo **info, gboolean
 gpointer  mono_arch_get_throw_corlib_exception  (MonoTrampInfo **info, gboolean aot) MONO_INTERNAL;
 gpointer  mono_arch_get_throw_pending_exception (MonoTrampInfo **info, gboolean aot) MONO_INTERNAL;
 gboolean mono_arch_handle_exception             (void *sigctx, gpointer obj) MONO_INTERNAL;
-void     mono_arch_handle_altstack_exception    (void *sigctx, gpointer fault_addr, gboolean stack_ovf) MONO_INTERNAL;
-gboolean mono_handle_soft_stack_ovf             (MonoJitTlsData *jit_tls, MonoJitInfo *ji, void *ctx, guint8* fault_addr) MONO_INTERNAL;
+void     mono_arch_handle_altstack_exception    (void *sigctx, MONO_SIG_HANDLER_INFO_TYPE *siginfo, gpointer fault_addr, gboolean stack_ovf) MONO_INTERNAL;
+gboolean mono_handle_soft_stack_ovf             (MonoJitTlsData *jit_tls, MonoJitInfo *ji, void *ctx, MONO_SIG_HANDLER_INFO_TYPE *siginfo, 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;
 mgreg_t mono_arch_context_get_int_reg              (MonoContext *ctx, int reg) MONO_INTERNAL;
@@ -2478,7 +2564,7 @@ typedef gboolean (*MonoJitStackWalk)            (StackFrameInfo *frame, MonoCont
 
 void     mono_exceptions_init                   (void) MONO_INTERNAL;
 gboolean mono_handle_exception                  (MonoContext *ctx, gpointer obj) MONO_INTERNAL;
-void     mono_handle_native_sigsegv             (int signal, void *sigctx) MONO_INTERNAL;
+void     mono_handle_native_sigsegv             (int signal, void *sigctx, MONO_SIG_HANDLER_INFO_TYPE *siginfo) MONO_INTERNAL;
 MONO_API void     mono_print_thread_dump                 (void *sigctx);
 MONO_API void     mono_print_thread_dump_from_ctx        (MonoContext *ctx);
 void     mono_walk_stack_with_ctx               (MonoJitStackWalk func, MonoContext *start_ctx, MonoUnwindOptions unwind_options, void *user_data) MONO_INTERNAL;