Merge pull request #607 from maksimenko/master
[mono.git] / mono / mini / mini.h
index 9d788873078a5d1e455251231820fae80bfb8d5a..1b6f5b550ec4a9284636aa8751959ba8c2cea54b 100644 (file)
 #endif
 
 /* Version number of the AOT file format */
-#define MONO_AOT_FILE_VERSION 86
+#define MONO_AOT_FILE_VERSION 88
 
 //TODO: This is x86/amd64 specific.
 #define mono_simd_shuffle_mask(a,b,c,d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6))
@@ -269,6 +269,7 @@ typedef struct MonoAotFileInfo
        guint32 trampoline_got_offset_base [MONO_AOT_TRAMP_NUM];
        /* The size of one trampoline */
        guint32 trampoline_size [MONO_AOT_TRAMP_NUM];
+       guint32 num_rgctx_fetch_trampolines;
 
        /* These are used for sanity checking object layout problems when cross-compiling */
        guint32 double_align, long_align;
@@ -298,6 +299,8 @@ typedef struct
        gpointer agent_info;
        /* Maps MonoMethod to an arch-specific structure */
        GHashTable *arch_seq_points;
+       /* Maps a GSharedVtTrampInfo structure to a trampoline address */
+       GHashTable *gsharedvt_arg_tramp_hash;
 } MonoJitDomainInfo;
 
 typedef struct {
@@ -449,7 +452,8 @@ enum {
 #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) || 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_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) || (ins->opcode == OP_LDADDR))
+/* 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))
 
 #define MONO_METHOD_IS_FINAL(m) (((m)->flags & METHOD_ATTRIBUTE_FINAL) || ((m)->klass && ((m)->klass->flags & TYPE_ATTRIBUTE_SEALED)))
 
@@ -512,7 +516,12 @@ extern gboolean mono_use_llvm;
 extern const char ins_info[];
 extern const gint8 ins_sreg_counts [];
 
+#ifndef DISABLE_JIT
 #define mono_inst_get_num_src_registers(ins) (ins_sreg_counts [(ins)->opcode - OP_START - 1])
+#else
+#define mono_inst_get_num_src_registers(ins) 0
+#endif
+
 #define mono_inst_get_src_registers(ins, regs) (((regs) [0] = (ins)->sreg1), ((regs) [1] = (ins)->sreg2), ((regs) [2] = (ins)->sreg3), mono_inst_get_num_src_registers ((ins)))
 
 #define MONO_BB_FOR_EACH_INS(bb, ins) for ((ins) = (bb)->code; (ins); (ins) = (ins)->next)
@@ -1085,6 +1094,8 @@ typedef struct {
 #define MONO_RGCTX_SLOT_INDEX(s)       ((s) & 0x7fffffff)
 #define MONO_RGCTX_SLOT_IS_MRGCTX(s)   (((s) & 0x80000000) ? TRUE : FALSE)
 
+#define MONO_GSHAREDVT_DEL_INVOKE_VT_OFFSET -2
+
 typedef enum {
 #define PATCH_INFO(a,b) MONO_PATCH_INFO_ ## a,
 #include "patch-info.h"
@@ -1117,6 +1128,8 @@ typedef struct MonoJumpInfoImtTramp {
        int vt_offset;
 } MonoJumpInfoImtTramp;
 
+typedef struct MonoJumpInfoGSharedVtCall MonoJumpInfoGSharedVtCall;
+
 typedef struct MonoJumpInfo MonoJumpInfo;
 struct MonoJumpInfo {
        MonoJumpInfo *next;
@@ -1146,6 +1159,7 @@ struct MonoJumpInfo {
                MonoJumpInfoBBTable *table;
                MonoJumpInfoRgctxEntry *rgctx_entry;
                MonoJumpInfoImtTramp *imt_tramp;
+               MonoJumpInfoGSharedVtCall *gsharedvt;
                MonoMethodSignature *sig;
        } data;
 };
@@ -1158,6 +1172,14 @@ struct MonoJumpInfoRgctxEntry {
        MonoRgctxInfoType info_type;
 };
 
+/* Contains information about a gsharedvt call */
+struct MonoJumpInfoGSharedVtCall {
+       /* The original signature of the call */
+       MonoMethodSignature *sig;
+       /* The method which is called */
+       MonoMethod *method;
+};
+
 typedef enum {
        MONO_TRAMPOLINE_JIT,
        MONO_TRAMPOLINE_JUMP,
@@ -1168,7 +1190,9 @@ typedef enum {
        MONO_TRAMPOLINE_AOT_PLT,
        MONO_TRAMPOLINE_DELEGATE,
        MONO_TRAMPOLINE_RESTORE_STACK_PROT,
+#ifndef DISABLE_REMOTING
        MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING,
+#endif
        MONO_TRAMPOLINE_MONITOR_ENTER,
        MONO_TRAMPOLINE_MONITOR_EXIT,
        MONO_TRAMPOLINE_VCALL,
@@ -1839,6 +1863,7 @@ void      mono_merge_basic_blocks           (MonoCompile *cfg, MonoBasicBlock *b
 void      mono_optimize_branches            (MonoCompile *cfg) MONO_INTERNAL;
 
 void      mono_blockset_print               (MonoCompile *cfg, MonoBitSet *set, const char *name, guint idom) MONO_INTERNAL;
+void      mono_print_ji                     (const MonoJumpInfo *ji) MONO_INTERNAL;
 void      mono_print_ins_index              (int i, MonoInst *ins) MONO_INTERNAL;
 void      mono_print_ins                    (MonoInst *ins) MONO_INTERNAL;
 void      mono_print_bb                     (MonoBasicBlock *bb, const char *msg) MONO_INTERNAL;
@@ -1965,7 +1990,6 @@ gpointer mono_aot_get_imt_thunk             (MonoVTable *vtable, MonoDomain *dom
 gpointer mono_aot_get_gsharedvt_arg_trampoline(gpointer arg, gpointer addr) MONO_INTERNAL;
 guint8*  mono_aot_get_unwind_info           (MonoJitInfo *ji, guint32 *unwind_info_len) MONO_INTERNAL;
 guint32  mono_aot_method_hash               (MonoMethod *method) MONO_INTERNAL;
-char*    mono_aot_wrapper_name              (MonoMethod *method) MONO_INTERNAL;
 MonoMethod* mono_aot_get_array_helper_from_wrapper (MonoMethod *method) MONO_INTERNAL;
 guint32  mono_aot_get_got_offset            (MonoJumpInfo *ji) MONO_LLVM_INTERNAL;
 char*    mono_aot_get_method_name           (MonoCompile *cfg) MONO_LLVM_INTERNAL;
@@ -2032,7 +2056,9 @@ gpointer          mono_create_llvm_imt_trampoline (MonoDomain *domain, MonoMetho
 MonoVTable*       mono_find_class_init_trampoline_by_addr (gconstpointer addr) MONO_INTERNAL;
 guint32           mono_find_rgctx_lazy_fetch_trampoline_by_addr (gconstpointer addr) MONO_INTERNAL;
 gpointer          mono_magic_trampoline (mgreg_t *regs, guint8 *code, gpointer arg, guint8* tramp) MONO_INTERNAL;
+#ifndef DISABLE_REMOTING
 gpointer          mono_generic_virtual_remoting_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, guint8 *tramp) MONO_INTERNAL;
+#endif
 gpointer          mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *tramp_data, guint8* tramp) MONO_INTERNAL;
 gpointer          mono_aot_trampoline (mgreg_t *regs, guint8 *code, guint8 *token_info, 
                                                                           guint8* tramp) MONO_INTERNAL;
@@ -2046,7 +2072,7 @@ gconstpointer     mono_get_trampoline_func (MonoTrampolineType tramp_type);
 gpointer          mini_get_vtable_trampoline (int slot_index) 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_add_method_trampoline (MonoMethod *orig_method, MonoMethod *m, gpointer compiled_method, MonoJitInfo *caller_ji, gboolean add_static_rgctx_tramp) MONO_INTERNAL;
+gpointer          mini_add_method_trampoline (MonoMethod *orig_method, MonoMethod *m, gpointer compiled_method, gboolean add_static_rgctx_tramp) MONO_INTERNAL;
 
 gboolean          mono_running_on_valgrind (void) MONO_INTERNAL;
 void*             mono_global_codeman_reserve (int size) MONO_INTERNAL;
@@ -2108,6 +2134,7 @@ const char *mono_arch_fregname                  (int reg) MONO_INTERNAL;
 void      mono_arch_exceptions_init             (void) MONO_INTERNAL;
 guchar*   mono_arch_create_generic_trampoline   (MonoTrampolineType tramp_type, MonoTrampInfo **info, gboolean aot) MONO_INTERNAL;
 gpointer  mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info, gboolean aot) MONO_INTERNAL;
+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;
@@ -2168,6 +2195,21 @@ gpointer mono_arch_get_seq_point_info           (MonoDomain *domain, guint8 *cod
 void     mono_arch_setup_resume_sighandler_ctx  (MonoContext *ctx, gpointer func) MONO_INTERNAL;
 #endif
 
+#ifdef USE_JUMP_TABLES
+void
+mono_jumptable_init  (void) MONO_INTERNAL;
+gpointer*
+mono_jumptable_add_entry (void) MONO_INTERNAL;
+gpointer*
+mono_jumptable_add_entries (guint32 entries) MONO_INTERNAL;
+void
+mono_jumptable_cleanup  (void) MONO_INTERNAL;
+gpointer*
+mono_arch_jumptable_entry_from_code (guint8 *code);
+gpointer*
+mono_jumptable_get_entry (guint8 *code);
+#endif
+
 gboolean
 mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, 
                                                 MonoJitInfo *ji, MonoContext *ctx, 
@@ -2422,6 +2464,9 @@ mono_method_is_generic_sharable_impl (MonoMethod *method, gboolean allow_type_va
 gboolean
 mono_method_is_generic_sharable_impl_full (MonoMethod *method, gboolean allow_type_vars, gboolean allow_partial, gboolean allow_gsharedvt) MONO_INTERNAL;
 
+gboolean
+mini_class_is_generic_sharable (MonoClass *klass) MONO_INTERNAL;
+
 gboolean
 mono_is_partially_sharable_inst (MonoGenericInst *inst) MONO_INTERNAL;
 
@@ -2468,9 +2513,13 @@ gboolean mini_is_gsharedvt_variable_type (MonoCompile *cfg, MonoType *t) MONO_IN
 MonoType* mini_get_gsharedvt_alloc_type_for_type (MonoCompile *cfg, MonoType *t) MONO_INTERNAL;
 gboolean mini_is_gsharedvt_sharable_method (MonoMethod *method) MONO_INTERNAL;
 gboolean mini_is_gsharedvt_variable_signature (MonoMethodSignature *sig) MONO_INTERNAL;
+gboolean mini_is_gsharedvt_sharable_inst (MonoGenericInst *inst) MONO_INTERNAL;
 gpointer mini_method_get_rgctx (MonoMethod *m) MONO_INTERNAL;
 void mini_init_gsctx (MonoGenericContext *context, MonoGenericSharingContext *gsctx) MONO_INTERNAL;
 
+gpointer mini_get_gsharedvt_wrapper (gboolean gsharedvt_in, gpointer addr, MonoMethodSignature *normal_sig, MonoMethodSignature *gsharedvt_sig, MonoGenericSharingContext *gsctx,
+                                                                        gint32 vcall_offset, gboolean calli) MONO_INTERNAL;
+
 /* wapihandles.c */
 int mini_wapi_hps (int argc, char **argv) MONO_INTERNAL;