Extract the code to emit a memory barrier. Add a memory_barrier_kind field to MonoIns...
[mono.git] / mono / mini / mini.h
index 8bbac35a743cf2cc35338cb195da636068801a93..e3d5e54e1c5c93095f291c11dc86554977c7e7a5 100644 (file)
@@ -4,6 +4,9 @@
 #include "config.h"
 #include <glib.h>
 #include <signal.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
 #include <mono/metadata/loader.h>
 #include <mono/metadata/mempool.h>
 #include <mono/utils/monobitset.h>
 #include <mono/metadata/profiler-private.h>
 #include <mono/metadata/debug-helpers.h>
 #include <mono/utils/mono-compiler.h>
+#include <mono/utils/mono-machine.h>
+#include <mono/utils/mono-stack-unwinding.h>
+#include <mono/utils/mono-threads.h>
 
 #define MONO_BREAKPOINT_ARRAY_SIZE 64
 
-/* C type matching the size of a machine register. Not always the same as 'int' */
-/* Note that member 'p' of MonoInst must be the same type, as OP_PCONST is defined
- * as one of the OP_ICONST types, so inst_c0 must be the same as inst_p0
- */
-#if SIZEOF_REGISTER == 4
-typedef gint32 mgreg_t;
-#elif SIZEOF_REGISTER == 8
-typedef gint64 mgreg_t;
-#endif
-
 #include "mini-arch.h"
 #include "regalloc.h"
 #include "declsec.h"
@@ -264,50 +260,21 @@ typedef struct {
 
 #define domain_jit_info(domain) ((MonoJitDomainInfo*)((domain)->runtime_info))
 
+/* Contains a list of ips which needs to be patched when a method is compiled */
+typedef struct {
+       GSList *list;
+} MonoJumpList;
+
 /* Arch-specific */
 typedef struct {
        int dummy;
 } MonoDynCallInfo;
 
 /*
- * Possible frame types returned by the stack walker.
+ * Information about a stack frame.
+ * FIXME This typedef exists only to avoid tons of code rewriting
  */
-typedef enum {
-       /* Normal managed frames */
-       FRAME_TYPE_MANAGED = 0,
-       /* Pseudo frame marking the start of a method invocation done by the soft debugger */
-       FRAME_TYPE_DEBUGGER_INVOKE = 1,
-       /* Frame for transitioning to native code */
-       FRAME_TYPE_MANAGED_TO_NATIVE = 2,
-       FRAME_TYPE_SENTINEL = 3
-} StackFrameType;
-
-/*
- * Information about a stack frame
- */
-typedef struct {
-       StackFrameType type;
-       /* 
-        * For FRAME_TYPE_MANAGED, otherwise NULL.
-        */
-       MonoJitInfo *ji;
-       /*
-        * Same as ji->method.
-        */
-       MonoMethod *method;
-       /*
-        * If ji->method is a gshared method, this is the actual method instance.
-        */
-       MonoMethod *actual_method;
-       /* The domain containing the code executed by this frame */
-       MonoDomain *domain;
-       gboolean managed;
-       int native_offset;
-       int il_offset;
-       gpointer lmf;
-       guint32 unwind_info_len;
-       guint8 *unwind_info;
-} StackFrameInfo;
+typedef MonoStackFrameInfo StackFrameInfo;
 
 typedef struct {
        int il_offset, native_offset;
@@ -768,6 +735,7 @@ 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 */
        } backend;
        
        MonoClass *klass;
@@ -835,6 +803,11 @@ enum {
        MONO_INST_NORANGECHECK   = 16,
        /* On loads, the source address can be null */
        MONO_INST_FAULT = 32,
+       /* 
+        * On variables, identifies LMF variables. These variables have a dummy type (int), but
+        * require stack space for a MonoLMF struct.
+        */
+       MONO_INST_LMF = 32,
        /* On loads, the source address points to a constant value */
        MONO_INST_CONSTANT_LOAD = 64,
        /* On variables, the variable needs GC tracking */
@@ -1270,6 +1243,7 @@ typedef struct {
        guint            gen_seq_points : 1;
        guint            explicit_null_checks : 1;
        guint            compute_gc_maps : 1;
+       guint            soft_breakpoints : 1;
        gpointer         debug_info;
        guint32          lmf_offset;
     guint16          *intvars;
@@ -1384,6 +1358,17 @@ typedef struct {
         */
        guint8 *gc_map;
        guint32 gc_map_size;
+
+       /* Stats */
+       int stat_allocate_var;
+       int stat_locals_stack_size;
+       int stat_basic_blocks;
+       int stat_cil_code_size;
+       int stat_n_regvars;
+       int stat_inlineable_methods;
+       int stat_inlined_methods;
+       int stat_cas_demand_generation;
+       int stat_code_reallocs;
 } MonoCompile;
 
 typedef enum {
@@ -1399,30 +1384,30 @@ typedef enum {
 } MonoCompileFlags;
 
 typedef struct {
-       gulong methods_compiled;
-       gulong methods_aot;
-       gulong methods_lookups;
-       gulong allocate_var;
-       gulong cil_code_size;
-       gulong native_code_size;
-       gulong code_reallocs;
-       gulong max_code_size_ratio;
-       gulong biggest_method_size;
-       gulong allocated_code_size;
-       gulong inlineable_methods;
-       gulong inlined_methods;
-       gulong basic_blocks;
-       gulong max_basic_blocks;
-       gulong locals_stack_size;
-       gulong regvars;
-       gulong cas_declsec_check;
-       gulong cas_linkdemand_icall;
-       gulong cas_linkdemand_pinvoke;
-       gulong cas_linkdemand_aptc;
-       gulong cas_linkdemand;
-       gulong cas_demand_generation;
-       gulong generic_virtual_invocations;
-    int methods_with_llvm;
+       gint32 methods_compiled;
+       gint32 methods_aot;
+       gint32 methods_lookups;
+       gint32 allocate_var;
+       gint32 cil_code_size;
+       gint32 native_code_size;
+       gint32 code_reallocs;
+       gint32 max_code_size_ratio;
+       gint32 biggest_method_size;
+       gint32 allocated_code_size;
+       gint32 inlineable_methods;
+       gint32 inlined_methods;
+       gint32 basic_blocks;
+       gint32 max_basic_blocks;
+       gint32 locals_stack_size;
+       gint32 regvars;
+       gint32 cas_declsec_check;
+       gint32 cas_linkdemand_icall;
+       gint32 cas_linkdemand_pinvoke;
+       gint32 cas_linkdemand_aptc;
+       gint32 cas_linkdemand;
+       gint32 cas_demand_generation;
+       gint32 generic_virtual_invocations;
+       int methods_with_llvm;
        int methods_without_llvm;
        char *max_ratio_method;
        char *biggest_method;
@@ -1587,6 +1572,14 @@ typedef struct {
         * debugging of the stack marking code in the GC.
         */
        gboolean init_stacks;
+
+       /*
+        * Whenever to implement single stepping and breakpoints without signals in the
+        * soft debugger. This is useful on platforms without signals, like the ps3, or during
+        * runtime debugging, since it avoids SIGSEGVs when a single step location or breakpoint
+        * is hit.
+        */
+       gboolean soft_breakpoints;
 } MonoDebugOptions;
 
 enum {
@@ -1920,8 +1913,7 @@ void*             nacl_global_codeman_get_dest(void *data) MONO_INTERNAL;
 void              mono_global_codeman_commit(void *data, int size, int newsize) MONO_INTERNAL;
 void              nacl_global_codeman_validate(guint8 **buf_base, int buf_size, guint8 **code_end) MONO_INTERNAL;
 const char       *mono_regname_full (int reg, int bank) MONO_INTERNAL;
-gint32*           mono_allocate_stack_slots_full (MonoCompile *cfg, gboolean backward, guint32 *stack_size, guint32 *stack_align) MONO_INTERNAL;
-gint32*           mono_allocate_stack_slots (MonoCompile *cfg, guint32 *stack_size, guint32 *stack_align) MONO_INTERNAL;
+gint32*           mono_allocate_stack_slots (MonoCompile *cfg, gboolean backward, guint32 *stack_size, guint32 *stack_align) MONO_INTERNAL;
 void              mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb) MONO_INTERNAL;
 MonoInst         *mono_branch_optimize_exception_target (MonoCompile *cfg, MonoBasicBlock *bb, const char * exname) MONO_INTERNAL;
 void              mono_remove_critical_edges (MonoCompile *cfg) MONO_INTERNAL;
@@ -1982,7 +1974,7 @@ GList    *mono_arch_get_global_fp_regs          (MonoCompile *cfg) MONO_INTERNAL
 GList    *mono_arch_get_iregs_clobbered_by_call (MonoCallInst *call) MONO_INTERNAL;
 GList    *mono_arch_get_fregs_clobbered_by_call (MonoCallInst *call) MONO_INTERNAL;
 guint32   mono_arch_regalloc_cost               (MonoCompile *cfg, MonoMethodVar *vmv) MONO_INTERNAL;
-void      mono_arch_patch_code                  (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *ji, gboolean run_cctors) MONO_INTERNAL;
+void      mono_arch_patch_code                  (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *ji, MonoCodeManager *dyn_code_mp, gboolean run_cctors) MONO_INTERNAL;
 void      mono_arch_flush_icache                (guint8 *code, gint size) MONO_INTERNAL;
 int       mono_arch_max_epilog_size             (MonoCompile *cfg) MONO_INTERNAL;
 guint8   *mono_arch_emit_prolog                 (MonoCompile *cfg) MONO_INTERNAL;
@@ -1992,7 +1984,6 @@ void      mono_arch_lowering_pass               (MonoCompile *cfg, MonoBasicBloc
 void      mono_arch_peephole_pass_1             (MonoCompile *cfg, MonoBasicBlock *bb) MONO_INTERNAL;
 void      mono_arch_peephole_pass_2             (MonoCompile *cfg, MonoBasicBlock *bb) MONO_INTERNAL;
 void      mono_arch_output_basic_block          (MonoCompile *cfg, MonoBasicBlock *bb) MONO_INTERNAL;
-gboolean  mono_arch_has_unwind_info             (gconstpointer addr) MONO_INTERNAL;
 void      mono_arch_setup_jit_tls_data          (MonoJitTlsData *tls) MONO_INTERNAL;
 void      mono_arch_free_jit_tls_data           (MonoJitTlsData *tls) MONO_INTERNAL;
 void      mono_arch_fill_argument_info          (MonoCompile *cfg) MONO_INTERNAL;
@@ -2048,10 +2039,12 @@ gpointer  mono_arch_get_throw_pending_exception (MonoTrampInfo **info, gboolean
 gboolean mono_arch_handle_exception             (void *sigctx, gpointer obj, gboolean test_only) 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_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;
-gpointer mono_arch_context_get_int_reg         (MonoContext *ctx, int reg) 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;
 gboolean mono_arch_is_inst_imm                  (gint64 imm) MONO_INTERNAL;
 MonoInst* mono_arch_get_domain_intrinsic        (MonoCompile* cfg) MONO_INTERNAL;
@@ -2086,19 +2079,20 @@ GSList *mono_arch_get_trampolines               (gboolean aot) MONO_INTERNAL;
 gpointer mono_arch_install_handler_block_guard (MonoJitInfo *ji, MonoJitExceptionInfo *clause, MonoContext *ctx, gpointer new_value) MONO_INTERNAL;
 gpointer mono_arch_create_handler_block_trampoline (void) MONO_INTERNAL;
 gpointer mono_create_handler_block_trampoline (void) MONO_INTERNAL;
-gboolean mono_install_handler_block_guard (MonoInternalThread *thread, MonoContext *ctx) MONO_INTERNAL;
+gboolean mono_install_handler_block_guard (MonoThreadUnwindState *ctx) MONO_INTERNAL;
 
-/* Exception handling */
+/*New interruption machinery */
+void
+mono_setup_async_callback (MonoContext *ctx, void (*async_cb)(void *fun), gpointer user_data) MONO_INTERNAL;
+
+void
+mono_arch_setup_async_callback (MonoContext *ctx, void (*async_cb)(void *fun), gpointer user_data) MONO_INTERNAL;
+
+gboolean
+mono_thread_state_init_from_handle (MonoThreadUnwindState *tctx, MonoNativeThreadId thread_id, MonoNativeThreadHandle thread_handle) MONO_INTERNAL;
 
-typedef enum {
-       MONO_UNWIND_NONE = 0x0,
-       MONO_UNWIND_LOOKUP_IL_OFFSET = 0x1,
-       MONO_UNWIND_LOOKUP_ACTUAL_METHOD = 0x2,
-       MONO_UNWIND_DEFAULT = MONO_UNWIND_LOOKUP_ACTUAL_METHOD,
-       MONO_UNWIND_SIGNAL_SAFE = MONO_UNWIND_NONE,
-       MONO_UNWIND_LOOKUP_ALL = MONO_UNWIND_LOOKUP_IL_OFFSET | MONO_UNWIND_LOOKUP_ACTUAL_METHOD,
-} MonoUnwindOptions;
 
+/* Exception handling */
 typedef gboolean (*MonoJitStackWalk)            (StackFrameInfo *frame, MonoContext *ctx, gpointer data);
 
 void     mono_exceptions_init                   (void) MONO_INTERNAL;
@@ -2107,9 +2101,13 @@ gboolean mono_handle_exception                  (MonoContext *ctx, gpointer obj,
 void     mono_handle_native_sigsegv             (int signal, void *sigctx) MONO_INTERNAL;
 void     mono_print_thread_dump                 (void *sigctx);
 void     mono_print_thread_dump_from_ctx        (MonoContext *ctx);
-void     mono_jit_walk_stack                    (MonoStackWalk func, gboolean do_il_offset, gpointer user_data) MONO_INTERNAL;
-void     mono_jit_walk_stack_from_ctx           (MonoStackWalk func, MonoContext *ctx, MonoUnwindOptions unwind_options, gpointer user_data) MONO_INTERNAL;
-void     mono_walk_stack                        (MonoJitStackWalk func, MonoDomain *domain, MonoContext *start_ctx, MonoUnwindOptions unwind_options, MonoInternalThread *thread, MonoLMF *lmf, gpointer user_data) MONO_INTERNAL;
+void     mono_walk_stack_with_ctx               (MonoJitStackWalk func, MonoContext *start_ctx, MonoUnwindOptions unwind_options, void *user_data) MONO_INTERNAL;
+void     mono_walk_stack_with_state             (MonoJitStackWalk func, MonoThreadUnwindState *state, MonoUnwindOptions unwind_options, void *user_data) MONO_INTERNAL;
+void     mono_walk_stack                        (MonoJitStackWalk func, MonoUnwindOptions options, void *user_data) MONO_INTERNAL;
+gboolean mono_thread_state_init_from_sigctx     (MonoThreadUnwindState *ctx, void *sigctx) MONO_INTERNAL;
+gboolean mono_thread_state_init_from_current    (MonoThreadUnwindState *ctx) MONO_INTERNAL;
+gboolean mono_thread_state_init_from_monoctx    (MonoThreadUnwindState *ctx, MonoContext *mctx) MONO_INTERNAL;
+
 void     mono_setup_altstack                    (MonoJitTlsData *tls) MONO_INTERNAL;
 void     mono_free_altstack                     (MonoJitTlsData *tls) MONO_INTERNAL;
 gpointer mono_altstack_restore_prot             (mgreg_t *regs, guint8 *code, gpointer *tramp_data, guint8* tramp) MONO_INTERNAL;
@@ -2239,6 +2237,9 @@ mono_method_lookup_or_register_other_info (MonoMethod *method, gboolean in_mrgct
 MonoGenericContext
 mono_method_construct_object_context (MonoMethod *method) MONO_INTERNAL;
 
+MonoMethod*
+mono_method_get_declaring_generic_method (MonoMethod *method) MONO_INTERNAL;
+
 int
 mono_generic_context_check_used (MonoGenericContext *context) MONO_INTERNAL;
 
@@ -2294,6 +2295,8 @@ guint mono_type_to_regmove (MonoCompile *cfg, MonoType *type) MONO_INTERNAL;
 void mono_cfg_add_try_hole (MonoCompile *cfg, MonoExceptionClause *clause, guint8 *start, MonoBasicBlock *bb) MONO_INTERNAL;
 
 void mono_cfg_set_exception (MonoCompile *cfg, int type) MONO_INTERNAL;
+gboolean mini_type_is_reference (MonoCompile *cfg, MonoType *type) MONO_INTERNAL;
+
 
 /* wapihandles.c */
 int mini_wapi_hps (int argc, char **argv) MONO_INTERNAL;
@@ -2407,7 +2410,7 @@ gboolean mono_gdb_render_native_backtraces (void) MONO_INTERNAL;
 #define SIG_HANDLER_SIGNATURE(ftn) 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_RECORD *info, void *context)
+#define SIG_HANDLER_SIGNATURE(ftn) 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)
@@ -2425,12 +2428,14 @@ gboolean SIG_HANDLER_SIGNATURE (mono_chain_signal) MONO_INTERNAL;
 
 /* for MONO_WRAPPER_UNKNOWN/MANAGED_TO_MANAGED subtypes */
 enum {
-       MONO_AOT_WRAPPER_MONO_ENTER,
-       MONO_AOT_WRAPPER_MONO_EXIT,
+       MONO_AOT_WRAPPER_MONITOR_ENTER,
+       MONO_AOT_WRAPPER_MONITOR_EXIT,
        MONO_AOT_WRAPPER_ELEMENT_ADDR,
        MONO_AOT_WRAPPER_PTR_TO_STRUCTURE,
        MONO_AOT_WRAPPER_STRUCTURE_TO_PTR,
        MONO_AOT_WRAPPER_CASTCLASS_WITH_CACHE,
+       MONO_AOT_WRAPPER_ISINST_WITH_CACHE,
+       MONO_AOT_WRAPPER_MONITOR_ENTER_V4,
        MONO_AOT_WRAPPER_LAST
 };