2010-02-24 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / mini / mini.h
index 4957d3da53c8a150ff81ff47a197cc938a87051b..0d9fe14859d27be0634849673239f4557a00bf6d 100644 (file)
@@ -33,7 +33,7 @@ typedef gint64 mgreg_t;
 #include "mini-arch.h"
 #include "regalloc.h"
 #include "declsec.h"
-#include "unwind.h"
+#include "mini-unwind.h"
 
 #ifndef G_LIKELY
 #define G_LIKELY(a) (a)
@@ -66,6 +66,12 @@ typedef gint64 mgreg_t;
 #define LLVM_ENABLED FALSE
 #endif
 
+#ifdef MONO_ARCH_SOFT_FLOAT
+#define COMPILE_SOFT_FLOAT(cfg) (!COMPILE_LLVM ((cfg)))
+#else
+#define COMPILE_SOFT_FLOAT(cfg) 0
+#endif
+
 #define NOT_IMPLEMENTED do { g_assert_not_reached (); } while (0)
 
 /* for 32 bit systems */
@@ -89,7 +95,7 @@ typedef gint64 mgreg_t;
 #endif
 
 /* Version number of the AOT file format */
-#define MONO_AOT_FILE_VERSION "62"
+#define MONO_AOT_FILE_VERSION "67"
 
 //TODO: This is x86/amd64 specific.
 #define mono_simd_shuffle_mask(a,b,c,d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6))
@@ -119,7 +125,8 @@ typedef enum {
 } MonoAotTrampoline;
 
 typedef enum {
-       MONO_AOT_FILE_FLAG_WITH_LLVM = 1
+       MONO_AOT_FILE_FLAG_WITH_LLVM = 1,
+       MONO_AOT_FILE_FLAG_FULL_AOT = 2
 } MonoAotFileFlags;
 
 /* This structure is stored in the AOT file */
@@ -130,6 +137,8 @@ typedef struct MonoAotFileInfo
        guint32 plt_size;
        guint32 nmethods;
        guint32 flags;
+       /* Optimization flags used to compile the module */
+       guint32 opts;
 
        guint32 num_trampolines [MONO_AOT_TRAMP_NUM];
        guint32 trampoline_got_offset_base [MONO_AOT_TRAMP_NUM];
@@ -208,8 +217,22 @@ typedef struct {
        gboolean managed;
        int native_offset;
        int il_offset;
+       gpointer lmf;
 } StackFrameInfo;
 
+typedef struct {
+       int il_offset, native_offset;
+       /* 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++)\
@@ -278,7 +301,6 @@ enum {
         (ins)->opcode = OP_NOP; \
         (ins)->dreg = -1;                              \
        MONO_INST_NULLIFY_SREGS ((ins));                \
-               (ins)->ssa_op = MONO_SSA_NOP; \
     } while (0)
 
 /* Remove INS from BB */
@@ -356,7 +378,6 @@ typedef struct MonoInstList MonoInstList;
 typedef struct MonoInst MonoInst;
 typedef struct MonoCallInst MonoCallInst;
 typedef struct MonoCallArgParm MonoCallArgParm;
-typedef struct MonoEdge MonoEdge;
 typedef struct MonoMethodVar MonoMethodVar;
 typedef struct MonoBasicBlock MonoBasicBlock;
 typedef struct MonoLMF MonoLMF;
@@ -399,12 +420,6 @@ extern const gint8 ins_sreg_counts [];
 
 #define mono_bb_first_ins(bb) (bb)->code
 
-struct MonoEdge {
-       MonoEdge *next;
-       MonoBasicBlock *bb;
-       /* add edge type? */
-};
-
 struct MonoSpillInfo {
        int offset;
 };
@@ -467,7 +482,6 @@ struct MonoBasicBlock {
        GSList *dominated;
        /* fast dominator algorithm */
        MonoBasicBlock *df_parent, *ancestor, *child, *label;
-       MonoEdge *bucket;
        int size, sdom, idomn;
        
        /* loop nesting and recognition */
@@ -505,6 +519,9 @@ struct MonoBasicBlock {
        /* we use that to prevent merging of bblocks covered by different clauses*/
        guint real_offset;
 
+       GSList *seq_points;
+       MonoInst *last_seq_point;
+
        /*
         * The region encodes whether the basic block is inside
         * a finally, catch, filter or none of these.
@@ -564,8 +581,7 @@ typedef struct {
 struct MonoInst {
        guint16 opcode;
        guint8  type; /* stack type */
-       guint   ssa_op : 3;
-       guint8  flags  : 5;
+       guint8  flags;
        
        /* used by the register allocator */
        gint32 dreg, sreg1, sreg2, sreg3;
@@ -677,6 +693,8 @@ enum {
        /* the address of the variable has been taken */
        MONO_INST_INDIRECT   = 16,
        MONO_INST_NORANGECHECK   = 16,
+       /* On loads, the source address can be null */
+       MONO_INST_FAULT = 32
 };
 
 #define inst_c0 data.op[0].const_val
@@ -796,6 +814,11 @@ typedef struct {
        void            (*abort_func) (MonoObject *object);
        /* Used to implement --debug=casts */
        MonoClass       *class_cast_from, *class_cast_to;
+
+       /* Stores state needed by mono_resume_unwind () */
+       MonoContext     ex_ctx;
+       /* FIXME: GC */
+       gpointer        ex_obj;
 } MonoJitTlsData;
 
 typedef enum {
@@ -1027,11 +1050,16 @@ typedef struct {
        guint            skip_visibility : 1;
        guint            disable_reuse_registers : 1;
        guint            disable_reuse_stack_slots : 1;
+       guint            disable_reuse_ref_stack_slots : 1;
        guint            disable_initlocals_opt : 1;
+       guint            disable_initlocals_opt_refs : 1;
        guint            disable_omit_fp : 1;
        guint            disable_vreg_to_lvreg : 1;
        guint            disable_deadce_vars : 1;
+       guint            disable_out_of_line_bblocks : 1;
+       guint            init_ref_vars : 1;
        guint            extend_live_ranges : 1;
+       guint            compute_precise_live_ranges : 1;
        guint            has_got_slots : 1;
        guint            uses_rgctx_reg : 1;
        guint            uses_vtable_reg : 1;
@@ -1104,8 +1132,16 @@ typedef struct {
         */
        GPtrArray *seq_points;
 
+       /* The encoded sequence point info */
+       MonoSeqPointInfo *seq_point_info;
+
        /* Used by AOT */
-       guint32 got_offset;
+       guint32 got_offset, ex_info_offset, method_info_offset;
+       /* Symbol used to refer to this method in generated assembly */
+       char *asm_symbol;
+
+       MonoJitExceptionInfo *llvm_ex_info;
+       guint32 llvm_ex_info_len;
 } MonoCompile;
 
 typedef enum {
@@ -1152,19 +1188,6 @@ typedef struct {
 
 extern MonoJitStats mono_jit_stats;
 
-/* values for MonoInst.ssa_op */
-enum {
-       MONO_SSA_NOP = 0,
-       MONO_SSA_ADDRESS_TAKEN = 1,
-       MONO_SSA_LOAD = 2,
-       MONO_SSA_STORE = 4,
-       MONO_SSA_LOAD_STORE = MONO_SSA_LOAD|MONO_SSA_STORE,
-       MONO_SSA_INDIRECT_LOAD = MONO_SSA_LOAD|MONO_SSA_ADDRESS_TAKEN,
-       MONO_SSA_INDIRECT_STORE = MONO_SSA_STORE|MONO_SSA_ADDRESS_TAKEN,
-       MONO_SSA_INDIRECT_LOAD_STORE =
-       MONO_SSA_LOAD|MONO_SSA_STORE|MONO_SSA_ADDRESS_TAKEN
-};
-
 /* opcodes: value assigned after all the CIL opcodes */
 #ifdef MINI_OP
 #undef MINI_OP
@@ -1311,6 +1334,11 @@ typedef struct {
        gboolean gdb;
        gboolean gen_seq_points;
        gboolean explicit_null_checks;
+       /*
+        * Fill stack frames with 0x2a in method prologs. This helps with the
+        * debugging of the stack marking code in the GC.
+        */
+       gboolean init_stacks;
 } MonoDebugOptions;
 
 enum {
@@ -1382,6 +1410,9 @@ void      mono_disable_optimizations       (guint32 opts) MONO_INTERNAL;
 MonoJumpInfoToken* mono_jump_info_token_new (MonoMemPool *mp, MonoImage *image, guint32 token) MONO_INTERNAL;
 MonoJumpInfoToken* mono_jump_info_token_new2 (MonoMemPool *mp, MonoImage *image, guint32 token, MonoGenericContext *context) MONO_INTERNAL;
 MonoInst* mono_find_spvar_for_region        (MonoCompile *cfg, int region) MONO_INTERNAL;
+MonoInst* mono_find_exvar_for_offset        (MonoCompile *cfg, int offset) MONO_INTERNAL;
+int       mono_get_block_region_notry       (MonoCompile *cfg, int region) MONO_INTERNAL;
+
 void      mono_precompile_assemblies        (void) MONO_INTERNAL;
 int       mono_parse_default_optimizations  (const char* p);
 void      mono_bblock_add_inst              (MonoBasicBlock *bb, MonoInst *inst) MONO_INTERNAL;
@@ -1450,6 +1481,7 @@ gint32    mono_get_lmf_tls_offset           (void) MONO_INTERNAL;
 gint32    mono_get_lmf_addr_tls_offset      (void) 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;
 GList    *mono_varlist_insert_sorted        (MonoCompile *cfg, GList *list, MonoMethodVar *mv, gboolean sort_end) MONO_INTERNAL;
 GList    *mono_varlist_sort                 (MonoCompile *cfg, GList *list, int sort_type) MONO_INTERNAL;
 void      mono_analyze_liveness             (MonoCompile *cfg) MONO_INTERNAL;
@@ -1465,6 +1497,10 @@ void       mono_print_ins (MonoInst *ins) MONO_INTERNAL;
 gboolean  mini_assembly_can_skip_verification (MonoDomain *domain, MonoMethod *method) MONO_INTERNAL;
 gboolean  mini_method_verify (MonoCompile *cfg, MonoMethod *method) MONO_INTERNAL;
 MonoInst *mono_get_got_var (MonoCompile *cfg) MONO_INTERNAL;
+void      mono_add_seq_point (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins, int native_offset) MONO_INTERNAL;
+MonoInst* mono_emit_jit_icall (MonoCompile *cfg, gconstpointer func, MonoInst **args) MONO_INTERNAL;
+MonoInst* mono_emit_method_call (MonoCompile *cfg, MonoMethod *method, MonoInst **args, MonoInst *this) MONO_INTERNAL;
+
 
 gboolean  mini_class_is_system_array (MonoClass *klass) MONO_INTERNAL;
 MonoMethodSignature *mono_get_element_address_signature (int arity) MONO_INTERNAL;
@@ -1502,13 +1538,15 @@ guint8*  mono_aot_get_unwind_info           (MonoJitInfo *ji, guint32 *unwind_in
 guint32  mono_aot_method_hash               (MonoMethod *method) MONO_INTERNAL;
 char*    mono_aot_wrapper_name              (MonoMethod *method) MONO_INTERNAL;
 MonoAotTrampInfo* mono_aot_tramp_info_create (const char *name, guint8 *code, guint32 code_len) MONO_INTERNAL;
-guint    mono_aot_str_hash                  (gconstpointer v1) MONO_INTERNAL;
 MonoMethod* mono_aot_get_array_helper_from_wrapper (MonoMethod *method) MONO_INTERNAL;
 guint32  mono_aot_get_got_offset            (MonoJumpInfo *ji) MONO_INTERNAL;
 char*    mono_aot_get_method_name           (MonoCompile *cfg) MONO_INTERNAL;
 char*    mono_aot_get_plt_symbol            (MonoJumpInfoType type, gconstpointer data) MONO_INTERNAL;
 char*    mono_aot_get_method_debug_name     (MonoCompile *cfg) MONO_INTERNAL;
 MonoJumpInfo* mono_aot_patch_info_dup       (MonoJumpInfo* ji) MONO_INTERNAL;
+void     mono_aot_set_make_unreadable       (gboolean unreadable) MONO_INTERNAL;
+gboolean mono_aot_is_pagefault              (void *ptr) MONO_INTERNAL;
+void     mono_aot_handle_pagefault          (void *ptr) MONO_INTERNAL;
 
 /* This is an exported function */
 void     mono_aot_register_globals          (gpointer *globals);
@@ -1519,7 +1557,7 @@ void     mono_xdebug_init                   (char *xdebug_opts) MONO_INTERNAL;
 void     mono_save_xdebug_info              (MonoCompile *cfg) MONO_INTERNAL;
 void     mono_save_trampoline_xdebug_info   (const char *tramp_name, guint8 *code, guint32 code_size, GSList *unwind_info) MONO_INTERNAL;
 /* This is an exported function */
-void     mono_xdebug_emit                   (void) MONO_INTERNAL;
+void     mono_xdebug_flush                  (void) MONO_INTERNAL;
 
 /* LLVM backend */
 void     mono_llvm_init                     (void) MONO_INTERNAL;
@@ -1578,7 +1616,7 @@ void              mono_generic_class_init_trampoline (mgreg_t *regs, guint8 *cod
 void              mono_monitor_enter_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 (void) MONO_INTERNAL;
+gpointer          mini_get_vtable_trampoline (int slot_index) MONO_INTERNAL;
 gpointer*         mono_get_vcall_slot_addr (guint8* code, mgreg_t *regs) MONO_INTERNAL;
 
 gboolean          mono_running_on_valgrind (void) MONO_INTERNAL;
@@ -1682,7 +1720,8 @@ void      mono_arch_decompose_long_opts         (MonoCompile *cfg, MonoInst *ins
 GSList*   mono_arch_get_delegate_invoke_impls   (void) MONO_INTERNAL;
 LLVMCallInfo* mono_arch_get_llvm_call_info      (MonoCompile *cfg, MonoMethodSignature *sig) MONO_INTERNAL;
 guint8*   mono_arch_emit_load_got_addr          (guint8 *start, guint8 *code, MonoCompile *cfg, MonoJumpInfo **ji) MONO_INTERNAL;
-guint8*   mono_arch_emit_load_aotconst (guint8 *start, guint8 *code, MonoJumpInfo **ji, int tramp_type, gconstpointer target) MONO_INTERNAL;
+guint8*   mono_arch_emit_load_aotconst          (guint8 *start, guint8 *code, MonoJumpInfo **ji, int tramp_type, gconstpointer target) MONO_INTERNAL;
+GSList*   mono_arch_get_cie_program             (void) MONO_INTERNAL;
 
 /* Soft Debug support */
 #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
@@ -1748,7 +1787,6 @@ void     mono_arch_nullify_class_init_trampoline(guint8 *code, mgreg_t *regs) MO
 void     mono_arch_nullify_plt_entry            (guint8 *code, mgreg_t *regs) MONO_INTERNAL;
 int      mono_arch_get_this_arg_reg             (MonoMethodSignature *sig, MonoGenericSharingContext *gsctx, guint8 *code) MONO_INTERNAL;
 gpointer mono_arch_get_this_arg_from_call       (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, mgreg_t *regs, guint8 *code) MONO_INTERNAL;
-MonoObject* mono_arch_find_this_argument        (mgreg_t *regs, MonoMethod *method, MonoGenericSharingContext *gsctx) MONO_INTERNAL;
 gpointer mono_arch_get_delegate_invoke_impl     (MonoMethodSignature *sig, gboolean has_target) MONO_INTERNAL;
 gpointer mono_arch_create_specific_trampoline   (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len) MONO_INTERNAL;
 void        mono_arch_emit_imt_argument         (MonoCompile *cfg, MonoCallInst *call, MonoInst *imt_arg) MONO_INTERNAL;
@@ -1767,6 +1805,7 @@ gboolean mono_handle_exception                  (MonoContext *ctx, gpointer obj,
                                                 gpointer original_ip, gboolean test_only) MONO_INTERNAL;
 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, gboolean do_il_offset, gpointer user_data) MONO_INTERNAL;
 void     mono_jit_walk_stack_from_ctx_in_thread (MonoJitStackWalk func, MonoDomain *domain, MonoContext *start_ctx, gboolean do_il_offset, MonoInternalThread *thread, MonoLMF *lmf, gpointer user_data) MONO_INTERNAL;
@@ -1774,9 +1813,16 @@ void     mono_setup_altstack                    (MonoJitTlsData *tls) MONO_INTER
 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;
 MonoJitInfo* mini_jit_info_table_find           (MonoDomain *domain, char *addr, MonoDomain **out_domain) MONO_INTERNAL;
+void     mono_resume_unwind                     (void) MONO_INTERNAL;
 
 MonoJitInfo * mono_find_jit_info                (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInfo *res, MonoJitInfo *prev_ji, MonoContext *ctx, MonoContext *new_ctx, char **trace, MonoLMF **lmf, int *native_offset, gboolean *managed) MONO_INTERNAL;
 
+gboolean
+mono_find_jit_info_ext (MonoDomain *domain, MonoJitTlsData *jit_tls, 
+                                               MonoJitInfo *prev_ji, MonoContext *ctx,
+                                               MonoContext *new_ctx, char **trace, MonoLMF **lmf,
+                                               StackFrameInfo *frame) MONO_INTERNAL;
+
 gpointer mono_get_throw_exception               (void) MONO_INTERNAL;
 gpointer mono_get_rethrow_exception             (void) MONO_INTERNAL;
 gpointer mono_get_call_filter                   (void) MONO_INTERNAL;
@@ -1993,10 +2039,11 @@ 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;
 
-/* for MONO_WRAPPER_UNKNOWN subtypes */
+/* for MONO_WRAPPER_UNKNOWN/MANAGED_TO_MANAGED subtypes */
 enum {
        MONO_AOT_WRAPPER_MONO_ENTER,
        MONO_AOT_WRAPPER_MONO_EXIT,
+       MONO_AOT_WRAPPER_ELEMENT_ADDR,
        MONO_AOT_WRAPPER_LAST
 };