2005-03-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mono / mini / mini.h
index 026cb4346faa4906e5d7dc000b5df023d605c9c8..1cd680fa6c7ac431081bd19faad6d047053684b3 100644 (file)
 #include <mono/metadata/opcodes.h>
 #include <mono/metadata/tabledefs.h>
 #include <mono/metadata/domain-internals.h>
+#include "mono/metadata/class-internals.h"
+#include "mono/metadata/object-internals.h"
 #include <mono/metadata/profiler-private.h>
+#include <mono/utils/mono-compiler.h>
 
 #include "mini-arch.h"
 #include "regalloc.h"
+#include "declsec.h"
 
 #define MONO_USE_AOT_COMPILER
 
 #define inst_ms_word data.op[0].const_val
 #endif
 
+#if SIZEOF_VOID_P == 8
+#define OP_PCONST OP_I8CONST
+#else
+#define OP_PCONST OP_ICONST
+#endif
+
 /* Version number of the AOT file format */
-#define MONO_AOT_FILE_VERSION "7"
+#define MONO_AOT_FILE_VERSION "19"
 
 #if 1
 #define mono_bitset_test_fast(set,n) (((guint32*)set)[2+(n)/32] & (1 << ((n) % 32)))
@@ -102,7 +112,12 @@ extern guint32 mono_jit_tls_id;
 extern MonoTraceSpec *mono_jit_trace_calls;
 extern gboolean mono_break_on_exc;
 extern int mono_exc_esp_offset;
+#ifdef DISABLE_AOT
+#define mono_compile_aot 0
+#else
 extern gboolean mono_compile_aot;
+#endif
+extern gboolean mono_use_security_manager;
 
 struct MonoEdge {
        MonoEdge *next;
@@ -177,6 +192,13 @@ struct MonoBasicBlock {
        /* loop nesting and recognition */
        GList *loop_blocks;
        gint8  nesting;
+       gint8  loop_body_start;
+
+       /* 
+        * Whenever the bblock is rarely executed so it should be emitted after
+        * the function epilog.
+        */
+       gboolean out_of_line;
 
        /* use for liveness analysis */
        MonoBitSet *gen_set;
@@ -258,6 +280,10 @@ struct MonoCallInst {
        gboolean virtual;
        regmask_t used_iregs;
        regmask_t used_fregs;
+#ifdef __x86_64__
+       GSList *out_ireg_args;
+       GSList *out_freg_args;
+#endif
 };
 
 /* 
@@ -391,7 +417,10 @@ typedef enum {
        MONO_PATCH_INFO_IID,
        MONO_PATCH_INFO_BB_OVF,
        MONO_PATCH_INFO_EXC_OVF,
-       MONO_PATCH_INFO_WRAPPER
+       MONO_PATCH_INFO_WRAPPER,
+       MONO_PATCH_INFO_GOT_OFFSET,
+       MONO_PATCH_INFO_DECLSEC,
+       MONO_PATCH_INFO_NONE
 } MonoJumpInfoType;
 
 /*
@@ -404,6 +433,11 @@ typedef struct MonoJumpInfoToken {
        guint32 token;
 } MonoJumpInfoToken;
 
+typedef struct MonoJumpInfoBBTable {
+       MonoBasicBlock **table;
+       int table_size;
+} MonoJumpInfoBBTable;
+
 typedef struct MonoJumpInfo MonoJumpInfo;
 struct MonoJumpInfo {
        MonoJumpInfo *next;
@@ -416,9 +450,12 @@ struct MonoJumpInfo {
        MonoJumpInfoType type;
        union {
                gconstpointer   target;
+#if SIZEOF_VOID_P == 8
+               gint64          offset;
+#else
                int             offset;
+#endif
                MonoBasicBlock *bb;
-               MonoBasicBlock **table;
                MonoInst       *inst;
                MonoMethod     *method;
                MonoClass      *klass;
@@ -427,11 +464,18 @@ struct MonoJumpInfo {
                MonoVTable     *vtable;
                const char     *name;
                MonoJumpInfoToken  *token;
+               MonoJumpInfoBBTable *table;
        } data;
-
-       int table_size; /* use by switch */
 };
 
+typedef enum {
+       MONO_TRAMPOLINE_GENERIC,
+       MONO_TRAMPOLINE_JUMP,
+       MONO_TRAMPOLINE_CLASS_INIT,
+       MONO_TRAMPOLINE_AOT,
+       MONO_TRAMPOLINE_NUM
+} MonoTrampolineType;
+
 /* optimization flags: keep up to date with the name array in driver.c */
 enum {
        MONO_OPT_PEEPHOLE = 1 << 0,
@@ -452,15 +496,19 @@ enum {
        MONO_OPT_LEAF     = 1 << 15,
        MONO_OPT_AOT      = 1 << 16,
        MONO_OPT_PRECOMP  = 1 << 17,
-       MONO_OPT_ABCREM   = 1 << 18
+       MONO_OPT_ABCREM   = 1 << 18,
+       MONO_OPT_SSAPRE   = 1 << 19
 };
 
 /* Bit-fields in the MonoBasicBlock.region */
+#define MONO_REGION_TRY       0
 #define MONO_REGION_FINALLY  16
 #define MONO_REGION_CATCH    32
 #define MONO_REGION_FAULT    64         /* Currently unused */
 #define MONO_REGION_FILTER  128
 
+#define MONO_BBLOCK_IS_IN_REGION(bblock, regtype) (((bblock)->region & (0xf << 4)) == (regtype))
+
 /*
  * Control Flow Graph and compilation unit information
  */
@@ -480,26 +528,30 @@ typedef struct {
        MonoInst        *prev_ins;   /* in decompose */
        MonoJumpInfo    *patch_info;
        MonoJitInfo     *jit_info;
+       MonoJitDynamicMethodInfo *dynamic_info;
        guint            num_bblocks;
        guint            locals_start;
        guint            num_varinfo; /* used items in varinfo */
        guint            varinfo_count; /* total storage in varinfo */
        gint             stack_offset;
+       gint             max_ireg;
        MonoRegState    *rs;
        MonoSpillInfo   *spill_info; /* machine register spills */
        MonoSpillInfo   *spill_info_float; /* fp register spills */
        gint             spill_count;
        /* unsigned char   *cil_code; */
-
-       /* the exception object passed to catch/filter blocks */
-       MonoInst        *exvar;
-       
+       MonoMethod      *inlined_method; /* the method which is currently inlined */
        MonoInst        *domainvar; /* a cache for the current domain */
+       MonoInst        *got_var; /* Global Offset Table variable */
 
        /* A hashtable of region ID-> SP var mappings */
        /* An SP var is a place to store the stack pointer (used by handlers)*/
        GHashTable      *spvars;
 
+       /* A hashtable of region ID -> EX var mappings */
+       /* An EX var stores the exception object passed to catch/filter blocks */
+       GHashTable      *exvars;
+
        GList           *ldstr_list; /* used by AOT */
        
        MonoDomain      *domain;
@@ -523,11 +575,17 @@ typedef struct {
        gboolean         disable_ssa;
        gboolean         run_cctors;
        gboolean         need_lmf_area;
+       gboolean         compile_aot;
+       gboolean         got_var_allocated;
+       gboolean         ret_var_is_local;
        gpointer         debug_info;
        guint32          lmf_offset;
        guint16          *intvars;
        MonoProfileCoverageInfo *coverage_info;
        MonoCompileArch  arch;
+       guint32          exception_type;        /* MONO_EXCEPTION_* */
+       guint32          exception_data;
+       char*            exception_message;
 #ifdef __ia64
        guint8           ins, locals, outs; /* reg stack region sizes */
 #endif /* __ia64 */
@@ -536,7 +594,9 @@ typedef struct {
 typedef enum {
        MONO_CFG_HAS_ALLOCA = 1 << 0,
        MONO_CFG_HAS_CALLS  = 1 << 1,
-       MONO_CFG_HAS_LDELEMA  = 1 << 2
+       MONO_CFG_HAS_LDELEMA  = 1 << 2,
+       MONO_CFG_HAS_VARARGS  = 1 << 3,
+       MONO_CFG_HAS_TAIL     = 1 << 4
 } MonoCompileFlags;
 
 typedef struct {
@@ -556,6 +616,12 @@ typedef struct {
        gulong inlined_methods;
        gulong basic_blocks;
        gulong max_basic_blocks;
+       gulong cas_declsec_check;
+       gulong cas_linkdemand_icall;
+       gulong cas_linkdemand_pinvoke;
+       gulong cas_linkdemand_aptc;
+       gulong cas_linkdemand;
+       gulong cas_demand_generation;
        MonoMethod *max_ratio_method;
        MonoMethod *biggest_method;
        gboolean enabled;
@@ -591,13 +657,25 @@ enum {
 };
 #undef MINI_OP
 
-/* make this depend on 32bit platform (use OP_LADD otherwise) */
+#if SIZEOF_VOID_P == 8
+#define OP_PADD OP_LADD
+#define OP_PNEG OP_LNEG
+#define OP_PCONV_TO_U2 OP_LCONV_TO_U2
+#define OP_PCONV_TO_OVF_I1_UN OP_LCONV_TO_OVF_I1_UN
+#define OP_PCONV_TO_OVF_I1 OP_LCONV_TO_OVF_I1
+#define OP_PCEQ CEE_CEQ
+#define OP_STOREP_MEMBASE_REG OP_STOREI8_MEMBASE_REG
+#define OP_STOREP_MEMBASE_IMM OP_STOREI8_MEMBASE_IMM
+#else
 #define OP_PADD CEE_ADD
 #define OP_PNEG CEE_NEG
 #define OP_PCONV_TO_U2 CEE_CONV_U2
 #define OP_PCONV_TO_OVF_I1_UN CEE_CONV_OVF_I1_UN
 #define OP_PCONV_TO_OVF_I1 CEE_CONV_OVF_I1
 #define OP_PCEQ CEE_CEQ
+#define OP_STOREP_MEMBASE_REG OP_STOREI4_MEMBASE_REG
+#define OP_STOREP_MEMBASE_IMM OP_STOREI4_MEMBASE_IMM
+#endif
 
 typedef enum {
        STACK_INV,
@@ -642,19 +720,30 @@ typedef enum {
        MONO_GRAPH_CFG_OPTCODE = 16
 } MonoGraphOptions;
 
-typedef struct {
-       const char *name;
-       gconstpointer func;
-       gconstpointer wrapper;
-       MonoMethodSignature *sig;
-} MonoJitICallInfo;
-
 typedef struct {
        guint16 size;
        guint16 offset;
        guint8  pad;
 } MonoJitArgumentInfo;
 
+enum {
+       BRANCH_NOT_TAKEN,
+       BRANCH_TAKEN,
+       BRANCH_UNDEF
+};
+
+/* Implicit exceptions */
+enum {
+       MONO_EXC_INDEX_OUT_OF_RANGE,
+       MONO_EXC_OVERFLOW,
+       MONO_EXC_ARITHMETIC,
+       MONO_EXC_DIVIDE_BY_ZERO,
+       MONO_EXC_INVALID_CAST,
+       MONO_EXC_NULL_REF,
+       MONO_EXC_ARRAY_TYPE_MISMATCH,
+       MONO_EXC_INTRINS_NUM
+};
+
 typedef void (*MonoInstFunc) (MonoInst *tree, gpointer data);
 
 /* main function */
@@ -671,13 +760,19 @@ int       mono_parse_default_optimizations  (const char* p);
 void      mono_bblock_add_inst              (MonoBasicBlock *bb, MonoInst *inst);
 void      mono_constant_fold                (MonoCompile *cfg);
 void      mono_constant_fold_inst           (MonoInst *inst, gpointer data);
+int       mono_eval_cond_branch             (MonoInst *branch);
 int       mono_is_power_of_two              (guint32 val);
 void      mono_cprop_local                  (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst **acp, int acp_size);
 MonoInst* mono_compile_create_var           (MonoCompile *cfg, MonoType *type, int opcode);
+void      mono_compile_make_var_load        (MonoCompile *cfg, MonoInst *dest, gssize var_index);
+MonoInst* mono_compile_create_var_load      (MonoCompile *cfg, gssize var_index);
+MonoInst* mono_compile_create_var_store     (MonoCompile *cfg, gssize var_index, MonoInst *value);
+MonoType* mono_type_from_stack_type         (MonoInst *ins);
 void      mono_blockset_print               (MonoCompile *cfg, MonoBitSet *set, const char *name, guint idom);
 void      mono_print_tree                   (MonoInst *tree);
 void      mono_print_tree_nl                (MonoInst *tree);
 void      mono_print_code                   (MonoCompile *cfg);
+void      mono_print_method_from_ip         (void *ip);
 void      mono_select_instructions          (MonoCompile *cfg);
 const char* mono_inst_name                  (int op);
 void      mono_inst_foreach                 (MonoInst *tree, MonoInstFunc func, gpointer data);
@@ -688,23 +783,30 @@ void      mono_add_patch_info               (MonoCompile *cfg, int ip, MonoJumpI
 void      mono_remove_patch_info            (MonoCompile *cfg, int ip);
 gpointer  mono_resolve_patch_target         (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *patch_info, gboolean run_cctors);
 MonoLMF** mono_get_lmf_addr                 (void);
+void      mono_jit_thread_attach            (MonoDomain *domain);
+guint32   mono_get_jit_tls_key              (void);
+gint32    mono_get_lmf_tls_offset           (void);
 GList    *mono_varlist_insert_sorted        (MonoCompile *cfg, GList *list, MonoMethodVar *mv, gboolean sort_end);
 GList    *mono_varlist_sort                 (MonoCompile *cfg, GList *list, int sort_type);
 void      mono_analyze_liveness             (MonoCompile *cfg);
 void      mono_linear_scan                  (MonoCompile *cfg, GList *vars, GList *regs, regmask_t *used_mask);
 void      mono_create_jump_table            (MonoCompile *cfg, MonoInst *label, MonoBasicBlock **bbs, int num_blocks);
-int       mono_compile_assembly             (MonoAssembly *ass, guint32 opts);
-MonoCompile *mini_method_compile            (MonoMethod *method, guint32 opts, MonoDomain *domain, gboolean run_cctors, int parts);
+int       mono_compile_assembly             (MonoAssembly *ass, guint32 opts, const char *aot_options);
+MonoCompile *mini_method_compile            (MonoMethod *method, guint32 opts, MonoDomain *domain, gboolean run_cctors, gboolean compile_aot, int parts);
 void      mono_destroy_compile              (MonoCompile *cfg);
 void      mono_aot_init                     (void);
 MonoJitInfo*  mono_aot_get_method           (MonoDomain *domain,
                                                                                         MonoMethod *method);
+gboolean  mono_aot_is_got_entry             (guint8 *code, guint8 *addr);
+gboolean  mono_aot_init_vtable              (MonoVTable *vtable);
+gboolean  mono_aot_get_cached_class_info    (MonoClass *klass, MonoCachedClassInfo *res);
 gboolean  mono_method_blittable             (MonoMethod *method);
 gboolean  mono_method_same_domain           (MonoJitInfo *caller, MonoJitInfo *callee);
 void      mono_register_opcode_emulation    (int opcode, const char* name, MonoMethodSignature *sig, gpointer func, gboolean no_throw);
 void      mono_arch_register_lowlevel_calls (void);
 void      mono_draw_graph                   (MonoCompile *cfg, MonoGraphOptions draw_options);
 void      mono_add_varcopy_to_end           (MonoCompile *cfg, MonoBasicBlock *bb, int src, int dest);
+void      mono_add_ins_to_end               (MonoBasicBlock *bb, MonoInst *inst);
 
 int               mono_find_method_opcode      (MonoMethod *method);
 MonoJitICallInfo *mono_find_jit_icall_by_name  (const char *name);
@@ -712,12 +814,18 @@ MonoJitICallInfo *mono_find_jit_icall_by_addr  (gconstpointer addr);
 MonoJitICallInfo *mono_register_jit_icall      (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save);
 gconstpointer     mono_icall_get_wrapper       (MonoJitICallInfo* callinfo);
 
+guint8 *          mono_get_trampoline_code (MonoTrampolineType tramp_type);
 gpointer          mono_create_jump_trampoline (MonoDomain *domain, 
                                                                                           MonoMethod *method, 
                                                                                           gboolean add_sync_wrapper);
 gpointer          mono_create_class_init_trampoline (MonoVTable *vtable);
+gpointer          mono_create_jit_trampoline (MonoMethod *method);
+gpointer          mono_create_jit_trampoline_from_token (MonoImage *image, guint32 token);
 MonoVTable*       mono_find_class_init_trampoline_by_addr (gconstpointer addr);
+
 gboolean          mono_running_on_valgrind (void);
+void*             mono_global_codeman_reserve (int size);
+gint32*           mono_allocate_stack_slots (MonoCompile *cfg, guint32 *stack_size, guint32 *stack_align);
 
 /* methods that must be provided by the arch-specific port */
 void      mono_arch_cpu_init                    (void);
@@ -726,12 +834,16 @@ void      mono_arch_instrument_mem_needs        (MonoMethod *method, int *stack,
 void     *mono_arch_instrument_prolog           (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments);
 void     *mono_arch_instrument_epilog           (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments);
 MonoCallInst *mono_arch_call_opcode             (MonoCompile *cfg, MonoBasicBlock* bb, MonoCallInst *call, int is_virtual);
-gint      mono_arch_get_opcode_for_method       (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args);
+MonoInst *mono_arch_get_inst_for_method       (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args);
 void      mono_codegen                          (MonoCompile *cfg);
 const char *mono_arch_regname                   (int reg);
 gpointer  mono_arch_get_throw_exception         (void);
+gpointer  mono_arch_get_rethrow_exception       (void);
 gpointer  mono_arch_get_throw_exception_by_name (void);
+gpointer  mono_arch_get_throw_corlib_exception  (void);
+guchar*   mono_arch_create_trampoline_code      (MonoTrampolineType tramp_type);
 gpointer  mono_arch_create_jit_trampoline       (MonoMethod *method);
+gpointer  mono_arch_create_jit_trampoline_from_token (MonoImage *image, guint32 token);
 MonoJitInfo *mono_arch_create_jump_trampoline      (MonoMethod *method);
 gpointer  mono_arch_create_class_init_trampoline(MonoVTable *vtable);
 GList    *mono_arch_get_allocatable_int_vars    (MonoCompile *cfg);
@@ -742,6 +854,7 @@ void      mono_arch_flush_icache                (guint8 *code, gint size);
 int       mono_arch_max_epilog_size             (MonoCompile *cfg);
 guint8   *mono_arch_emit_prolog                 (MonoCompile *cfg);
 void      mono_arch_emit_epilog                 (MonoCompile *cfg);
+void      mono_arch_emit_exceptions             (MonoCompile *cfg);
 void      mono_arch_local_regalloc              (MonoCompile *cfg, MonoBasicBlock *bb);
 void      mono_arch_output_basic_block          (MonoCompile *cfg, MonoBasicBlock *bb);
 gboolean  mono_arch_has_unwind_info             (gconstpointer addr);
@@ -765,16 +878,34 @@ gpointer mono_arch_get_call_filter              (void);
 gpointer mono_arch_get_restore_context          (void);
 gboolean mono_arch_handle_exception             (void *sigctx, gpointer obj, gboolean test_only);
 gpointer mono_arch_ip_from_context              (void *sigctx);
+void     mono_arch_sigctx_to_monoctx            (void *sigctx, MonoContext *ctx);
+void     mono_arch_monoctx_to_sigctx            (MonoContext *mctx, void *ctx);
 void     mono_arch_flush_register_windows       (void);
+gboolean mono_arch_is_inst_imm                  (gint64 imm);
+MonoInst* mono_arch_get_domain_intrinsic        (MonoCompile* cfg);
+MonoInst* mono_arch_get_thread_intrinsic        (MonoCompile* cfg);
+gboolean mono_arch_is_int_overflow              (void *sigctx, void *info);
+void     mono_arch_invalidate_method            (MonoJitInfo *ji, void *func, gpointer func_arg);
+guint32  mono_arch_get_patch_offset             (guint8 *code);
+gpointer*mono_arch_get_vcall_slot_addr          (guint8* code, gpointer *regs);
+gpointer*mono_arch_get_delegate_method_ptr_addr (guint8* code, gpointer *regs);
+void     mono_arch_create_vars                  (MonoCompile *cfg);
 
 /* Exception handling */
-gboolean mono_handle_exception                  (MonoContext *ctx, gpointer obj, gboolean test_only);
-void      mono_jit_walk_stack                   (MonoStackWalk func, gpointer user_data);
+gboolean mono_handle_exception                  (MonoContext *ctx, gpointer obj,
+                                                gpointer original_ip, gboolean test_only);
+void      mono_jit_walk_stack                   (MonoStackWalk func, gboolean do_il_offset, gpointer user_data);
+
+/* the new function to do stack walks */
+typedef gboolean (*MonoStackFrameWalk)          (MonoDomain *domain, MonoContext *ctx, MonoJitInfo *ji, gpointer data);
+void      mono_walk_stack                       (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoContext *start_ctx, MonoStackFrameWalk func, gpointer user_data);
+
 MonoArray *ves_icall_get_trace                  (MonoException *exc, gint32 skip, MonoBoolean need_file_info);
 MonoBoolean ves_icall_get_frame_info            (gint32 skip, MonoBoolean need_file_info, 
                                                 MonoReflectionMethod **method, 
                                                 gint32 *iloffset, gint32 *native_offset,
                                                 MonoString **file, gint32 *line, gint32 *column);
+MonoString *ves_icall_System_Exception_get_trace (MonoException *exc);
 
 /* Dominator/SSA methods */
 void        mono_compile_dominator_info         (MonoCompile *cfg, int dom_flags);
@@ -795,15 +926,24 @@ void      mono_debug_close_method               (MonoCompile *cfg);
 void      mono_debug_open_block                 (MonoCompile *cfg, MonoBasicBlock *bb, guint32 address);
 void      mono_debug_record_line_number         (MonoCompile *cfg, MonoInst *ins, guint32 address);
 void      mono_debug_serialize_debug_info       (MonoCompile *cfg, guint8 **out_buf, guint32 *buf_len);
-void      mono_debug_add_aot_method            (MonoDomain *domain,
+void      mono_debug_add_aot_method             (MonoDomain *domain,
                                                                                                MonoMethod *method, guint8 *code_start, 
                                                                                                guint8 *debug_info, guint32 debug_info_len);
+void      mono_debug_add_icall_wrapper          (MonoMethod *method, MonoJitICallInfo* info);
+
 
 /* Tracing */
-MonoTraceSpec *mono_trace_parse_options         (MonoAssembly *assembly, char *options);
+MonoTraceSpec *mono_trace_parse_options         (char *options);
+void           mono_trace_set_assembly          (MonoAssembly *assembly);
 gboolean       mono_trace_eval                  (MonoMethod *method);
 
 extern void
 mono_perform_abc_removal (MonoCompile *cfg);
+extern void
+mono_perform_ssapre (MonoCompile *cfg);
+
+/* CAS - stack walk */
+MonoSecurityFrame* ves_icall_System_Security_SecurityFrame_GetSecurityFrame (gint32 skip);
+MonoArray* ves_icall_System_Security_SecurityFrame_GetSecurityStack (gint32 skip);
 
-#endif /* __MONO_MINI_H__ */  
+#endif /* __MONO_MINI_H__ */