2008-10-01 Mark Probst <mark.probst@gmail.com>
[mono.git] / mono / mini / mini.h
index 702f4ffcc8fe8bea13cc3a6c484f89c24dc79727..f0398f617e17a3d74ad15ede23410b86bc717773 100644 (file)
 #define MONO_FAKE_VTABLE_METHOD ((MonoMethod*)GINT_TO_POINTER(-2))
 
 /* Version number of the AOT file format */
-#define MONO_AOT_FILE_VERSION "36"
+#define MONO_AOT_FILE_VERSION "38"
  
 /* Per-domain information maintained by the JIT */
 typedef struct
 {
        /* Maps MonoMethod's to a GSList of GOT slot addresses pointing to its code */
        GHashTable *jump_target_got_slot_hash;
+       GHashTable *jump_target_hash;
+       /* Maps methods/klasses to the address of the given type of trampoline */
+       GHashTable *class_init_trampoline_hash;
+       GHashTable *jump_trampoline_hash;
+       GHashTable *jit_trampoline_hash;
+       GHashTable *delegate_trampoline_hash;
+       /* maps MonoMethod -> MonoJitDynamicMethodInfo */
+       GHashTable *dynamic_code_hash;
+       GHashTable *method_code_hash;
 } MonoJitDomainInfo;
 
-#define jit_domain_info(domain) ((MonoJitDomainInfo*)((domain)->runtime_info))
+typedef struct {
+       MonoJitInfo *ji;
+       MonoCodeManager *code_mp;
+} MonoJitDynamicMethodInfo;
+
+#define domain_jit_info(domain) ((MonoJitDomainInfo*)((domain)->runtime_info))
 
 #if 0
 #define mono_bitset_foreach_bit(set,b,n) \
@@ -182,10 +196,9 @@ enum {
 
 #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))
 
-/* FIXME: Handle OP_GOT_ENTRY too */
-#define MONO_IS_JUMP_TABLE(ins) (((ins)->opcode == OP_JUMP_TABLE) ? TRUE : ((((ins)->opcode == OP_AOTCONST) && (ins->inst_i1 == (gpointer)MONO_PATCH_INFO_SWITCH)) ? TRUE : ((ins)->opcode == OP_SWITCH) ? TRUE : FALSE))
+#define MONO_IS_JUMP_TABLE(ins) (((ins)->opcode == OP_JUMP_TABLE) ? TRUE : ((((ins)->opcode == OP_AOTCONST) && (ins->inst_i1 == (gpointer)MONO_PATCH_INFO_SWITCH)) ? TRUE : ((ins)->opcode == OP_SWITCH) ? TRUE : ((((ins)->opcode == OP_GOT_ENTRY) && ((ins)->inst_right->inst_i1 == (gpointer)MONO_PATCH_INFO_SWITCH)) ? TRUE : FALSE)))
 
-#define MONO_JUMP_TABLE_FROM_INS(ins) (((ins)->opcode == OP_JUMP_TABLE) ? (ins)->inst_p0 : (((ins)->opcode == OP_AOTCONST) && (ins->inst_i1 == (gpointer)MONO_PATCH_INFO_SWITCH) ? (ins)->inst_p0 : (((ins)->opcode == OP_SWITCH) ? (ins)->inst_p0 : NULL)))
+#define MONO_JUMP_TABLE_FROM_INS(ins) (((ins)->opcode == OP_JUMP_TABLE) ? (ins)->inst_p0 : (((ins)->opcode == OP_AOTCONST) && (ins->inst_i1 == (gpointer)MONO_PATCH_INFO_SWITCH) ? (ins)->inst_p0 : (((ins)->opcode == OP_SWITCH) ? (ins)->inst_p0 : ((((ins)->opcode == OP_GOT_ENTRY) && ((ins)->inst_right->inst_i1 == (gpointer)MONO_PATCH_INFO_SWITCH)) ? (ins)->inst_right->inst_p0 : NULL))))
 
 /* FIXME: Add more instructions */
 #define MONO_INS_HAS_NO_SIDE_EFFECT(ins) (MONO_IS_MOVE (ins) || (ins->opcode == OP_ICONST) || (ins->opcode == OP_I8CONST) || (ins->opcode == OP_VZERO) || (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_INEG) || (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))
@@ -219,6 +232,7 @@ extern int mono_break_at_bb_bb_num;
 extern gboolean check_for_pending_exc;
 extern gboolean disable_vtypes_in_regs;
 extern gboolean mono_verify_all;
+extern gboolean mono_dont_free_global_codeman;
 
 #define INS_INFO(opcode) (&ins_info [((opcode) - OP_START - 1) * 3])
 
@@ -546,6 +560,8 @@ struct MonoCallInst {
         * calling convention as OP_CALL.
         */
        guint vret_in_reg : 1;
+       /* Whenever there is an IMT argument and it is dynamic */
+       guint dynamic_imt_arg : 1;
        regmask_t used_iregs;
        regmask_t used_fregs;
        GSList *out_ireg_args;
@@ -678,6 +694,8 @@ typedef struct {
        MonoLMF          *lmf;
 #endif
        MonoLMF          *first_lmf;
+       gpointer         restore_stack_prot;
+       guint32          handling_stack_ovf;
        gpointer         signal_stack;
        guint32          signal_stack_size;
        gpointer         stack_ovf_guard_base;
@@ -759,6 +777,7 @@ typedef enum {
        MONO_TRAMPOLINE_AOT,
        MONO_TRAMPOLINE_AOT_PLT,
        MONO_TRAMPOLINE_DELEGATE,
+       MONO_TRAMPOLINE_RESTORE_STACK_PROT,
        MONO_TRAMPOLINE_NUM
 } MonoTrampolineType;
 
@@ -810,10 +829,9 @@ typedef struct {
        gint             max_ireg;
        gint             cil_offset_to_bb_len;
        MonoRegState    *rs;
-       MonoSpillInfo   *spill_info; /* machine register spills */
-       MonoSpillInfo   *spill_info_float; /* fp register spills */
+       MonoSpillInfo   *spill_info [16]; /* machine register spills */
        gint             spill_count;
-       gint             spill_info_len, spill_info_float_len;
+       gint             spill_info_len [16];
        /* unsigned char   *cil_code; */
        MonoMethod      *inlined_method; /* the method which is currently inlined */
        MonoInst        *domainvar; /* a cache for the current domain */
@@ -892,7 +910,10 @@ typedef struct {
        guint            disable_reuse_stack_slots : 1;
        guint            disable_initlocals_opt : 1;
        guint            disable_omit_fp : 1;
+       guint            disable_vreg_to_lvreg : 1;
        guint            has_got_slots : 1;
+       guint            uses_rgctx_reg : 1;
+       guint            uses_vtable_reg : 1;
        gpointer         debug_info;
        guint32          lmf_offset;
     guint16          *intvars;
@@ -923,6 +944,14 @@ typedef struct {
 
        /* Patches which describe absolute addresses embedded into the native code */
        GHashTable *abs_patches;
+
+       /* If the arch passes valuetypes by address, then for methods
+          which use JMP the arch code should use these local
+          variables to store the addresses of incoming valuetypes.
+          The addresses should be stored in mono_arch_emit_prolog()
+          and can be used when emitting code for OP_JMP.  See
+          mini-ppc.c. */
+       MonoInst **tailcall_valuetype_addrs;
 } MonoCompile;
 
 typedef enum {
@@ -943,7 +972,6 @@ typedef struct {
        gulong methods_lookups;
        gulong method_trampolines;
        gulong allocate_var;
-       gulong analyze_stack_repeat;
        gulong cil_code_size;
        gulong native_code_size;
        gulong code_reallocs;
@@ -1319,6 +1347,7 @@ gpointer mono_aot_get_method_from_vt_slot   (MonoDomain *domain, MonoVTable *vta
 gpointer mono_aot_create_specific_trampoline   (MonoImage *image, gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len) MONO_INTERNAL;
 gpointer mono_aot_get_named_code            (const char *name) MONO_INTERNAL;
 gpointer mono_aot_get_unbox_trampoline      (MonoMethod *method) MONO_INTERNAL;
+gpointer mono_aot_get_lazy_fetch_trampoline (guint32 slot) MONO_INTERNAL;
 /* This is an exported function */
 void     mono_aot_register_globals          (gpointer *globals);
 /* This too */
@@ -1349,9 +1378,10 @@ gpointer          mono_create_jump_trampoline (MonoDomain *domain,
                                                                                           MonoMethod *method, 
                                                                                           gboolean add_sync_wrapper) MONO_INTERNAL;
 gpointer          mono_create_class_init_trampoline (MonoVTable *vtable) MONO_INTERNAL;
+gpointer          mono_create_generic_class_init_trampoline (void) MONO_INTERNAL;
 gpointer          mono_create_jit_trampoline (MonoMethod *method) MONO_INTERNAL;
 gpointer          mono_create_jit_trampoline_from_token (MonoImage *image, guint32 token) MONO_INTERNAL;
-gpointer          mono_create_jit_trampoline_in_domain (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper) MONO_INTERNAL;
+gpointer          mono_create_jit_trampoline_in_domain (MonoDomain *domain, MonoMethod *method) MONO_INTERNAL;
 gpointer          mono_create_delegate_trampoline (MonoClass *klass) MONO_INTERNAL;
 gpointer          mono_create_rgctx_lazy_fetch_trampoline (guint32 offset) MONO_INTERNAL;
 MonoVTable*       mono_find_class_init_trampoline_by_addr (gconstpointer addr) MONO_INTERNAL;
@@ -1370,7 +1400,7 @@ gpointer          mini_get_vtable_trampoline (void) MONO_INTERNAL;
 
 gboolean          mono_running_on_valgrind (void) MONO_INTERNAL;
 void*             mono_global_codeman_reserve (int size) MONO_INTERNAL;
-const char       *mono_regname_full (int reg, gboolean fp) 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;
 void              mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb) MONO_INTERNAL;
@@ -1389,7 +1419,7 @@ void              mono_decompose_opcode (MonoCompile *cfg, MonoInst *ins) MONO_I
 void              mono_decompose_long_opts (MonoCompile *cfg) MONO_INTERNAL;
 void              mono_decompose_vtype_opts (MonoCompile *cfg) MONO_INTERNAL;
 void              mono_decompose_array_access_opts (MonoCompile *cfg) MONO_INTERNAL;
-void              mono_handle_soft_float (MonoCompile *cfg) MONO_INTERNAL;
+void              mono_decompose_soft_float (MonoCompile *cfg) MONO_INTERNAL;
 void              mono_handle_global_vregs (MonoCompile *cfg) MONO_INTERNAL;
 void              mono_spill_global_vars (MonoCompile *cfg, gboolean *need_local_opts) MONO_INTERNAL;
 void              mono_if_conversion (MonoCompile *cfg) MONO_INTERNAL;
@@ -1415,7 +1445,8 @@ gpointer  mono_arch_get_throw_corlib_exception  (void) MONO_INTERNAL;
 guchar*   mono_arch_create_trampoline_code      (MonoTrampolineType tramp_type) MONO_INTERNAL;
 guchar*   mono_arch_create_trampoline_code_full (MonoTrampolineType tramp_type, guint32 *code_size, MonoJumpInfo **ji, gboolean aot) MONO_INTERNAL;
 gpointer  mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot) MONO_INTERNAL;
-guint32          mono_arch_get_rgctx_lazy_fetch_offset (gpointer *regs) MONO_INTERNAL;
+gpointer  mono_arch_create_rgctx_lazy_fetch_trampoline_full (guint32 slot, guint32 *code_size, MonoJumpInfo **ji, gboolean aot) MONO_INTERNAL;
+gpointer  mono_arch_create_generic_class_init_trampoline (void) MONO_INTERNAL;
 gpointer  mono_arch_get_nullified_class_init_trampoline (guint32 *code_len) MONO_INTERNAL;
 GList    *mono_arch_get_allocatable_int_vars    (MonoCompile *cfg) MONO_INTERNAL;
 GList    *mono_arch_get_global_int_regs         (MonoCompile *cfg) MONO_INTERNAL;
@@ -1466,6 +1497,7 @@ gpointer  mono_arch_get_throw_exception_by_name_full (guint32 *code_size, MonoJu
 gpointer  mono_arch_get_throw_corlib_exception_full (guint32 *code_size, MonoJumpInfo **ji, gboolean aot) MONO_INTERNAL;
 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;
 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;
@@ -1493,10 +1525,10 @@ gpointer mono_arch_get_this_arg_from_call       (MonoGenericSharingContext *gsct
 MonoObject* mono_arch_find_this_argument        (gpointer *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) MONO_INTERNAL;
+void        mono_arch_emit_imt_argument         (MonoCompile *cfg, MonoCallInst *call, MonoInst *imt_arg) MONO_INTERNAL;
 MonoMethod* mono_arch_find_imt_method           (gpointer *regs, guint8 *code) MONO_INTERNAL;
 MonoVTable* mono_arch_find_static_call_vtable   (gpointer *regs, guint8 *code) MONO_INTERNAL;
-gpointer    mono_arch_build_imt_thunk           (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckItem **imt_entries, int count) MONO_INTERNAL;
+gpointer    mono_arch_build_imt_thunk           (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckItem **imt_entries, int count, gpointer fail_tramp) MONO_INTERNAL;
 void    mono_arch_notify_pending_exc            (void) MONO_INTERNAL;
 void    mono_arch_fixup_jinfo                   (MonoCompile *cfg) MONO_INTERNAL;
 
@@ -1510,6 +1542,8 @@ void     mono_jit_walk_stack                    (MonoStackWalk func, gboolean do
 void     mono_jit_walk_stack_from_ctx           (MonoStackWalk func, MonoContext *ctx, gboolean do_il_offset, gpointer user_data) MONO_INTERNAL;
 void     mono_setup_altstack                    (MonoJitTlsData *tls) MONO_INTERNAL;
 void     mono_free_altstack                     (MonoJitTlsData *tls) MONO_INTERNAL;
+gpointer mono_altstack_restore_prot             (gssize *regs, guint8 *code, gpointer *tramp_data, guint8* tramp) 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;
 
 gpointer mono_get_throw_exception               (void) MONO_INTERNAL;
@@ -1602,11 +1636,6 @@ int mono_method_check_context_used (MonoMethod *method) MONO_INTERNAL;
 
 gboolean mono_generic_context_equal_deep (MonoGenericContext *context1, MonoGenericContext *context2) MONO_INTERNAL;
 
-gboolean mono_generic_context_is_sharable (MonoGenericContext *context, gboolean allow_type_vars) MONO_INTERNAL;
-
-gboolean mono_method_is_generic_impl (MonoMethod *method) MONO_INTERNAL;
-gboolean mono_method_is_generic_sharable_impl (MonoMethod *method, gboolean allow_type_vars) MONO_INTERNAL;
-
 gpointer mono_helper_get_rgctx_other_ptr (MonoClass *caller_class, MonoVTable *vtable,
                                          guint32 token, guint32 token_source, guint32 rgctx_type,
                                          gint32 rgctx_index) MONO_INTERNAL;
@@ -1617,8 +1646,12 @@ MonoClass* mini_class_get_container_class (MonoClass *class) MONO_INTERNAL;
 MonoGenericContext* mini_class_get_context (MonoClass *class) MONO_INTERNAL;
 
 MonoType* mini_get_basic_type_from_generic (MonoGenericSharingContext *gsctx, MonoType *type) MONO_INTERNAL;
+MonoType* mini_type_get_underlying_type (MonoGenericSharingContext *gsctx, MonoType *type) MONO_INTERNAL;
 
 int mini_type_stack_size (MonoGenericSharingContext *gsctx, MonoType *t, int *align) MONO_INTERNAL;
+int mini_type_stack_size_full (MonoGenericSharingContext *gsctx, MonoType *t, guint32 *align, gboolean pinvoke) MONO_INTERNAL;
+void type_to_eval_stack_type (MonoCompile *cfg, MonoType *type, MonoInst *inst) MONO_INTERNAL;
+guint mono_type_to_regmove (MonoCompile *cfg, MonoType *type) MONO_INTERNAL;
 
 /* wapihandles.c */
 int mini_wapi_hps (int argc, char **argv) MONO_INTERNAL;