#include "regalloc.h"
#include "declsec.h"
+#ifndef G_LIKELY
+#define G_LIKELY(a) (a)
+#define G_UNLIKELY(a) (a)
+#endif
+
+#if DISABLE_LOGGING
+#define MINI_DEBUG(level,limit,code)
+#else
+#define MINI_DEBUG(level,limit,code) do {if (G_UNLIKELY ((level) >= (limit))) code} while (0)
+#endif
+
+#ifndef DISABLE_AOT
#define MONO_USE_AOT_COMPILER
+#endif
/* for 32 bit systems */
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
#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 "24"
-
-#if 1
-#define mono_bitset_test_fast(set,n) (((guint32*)set)[2+(n)/32] & (1 << ((n) % 32)))
-#else
-#define mono_bitset_test_fast(set,n) mono_bitset_test(set,n)
-#endif
+#define MONO_AOT_FILE_VERSION "27"
#if 0
#define mono_bitset_foreach_bit(set,b,n) \
if (mono_bitset_test_fast(set,b))
#else
#define mono_bitset_foreach_bit(set,b,n) \
- for (b = mono_bitset_find_first (set, -1); b < n && b >= 0; b = mono_bitset_find_first (set, b))
+ for (b = mono_bitset_find_start (set); b < n && b >= 0; b = mono_bitset_find_first (set, b))
#define mono_bitset_foreach_bit_rev(set,b,n) \
for (b = mono_bitset_find_last (set, n - 1); b >= 0; b = b ? mono_bitset_find_last (set, b) : -1)
(dest)->inst.opcode = (op); \
} while (0)
+#define MONO_INST_NEW_CALL_ARG(cfg,dest,op) do { \
+ (dest) = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoCallArgParm)); \
+ (dest)->ins.opcode = (op); \
+ } while (0)
+
#define MONO_ADD_INS(b,inst) do { \
if ((b)->last_ins) { \
(b)->last_ins->next = (inst); \
typedef struct MonoInst MonoInst;
typedef struct MonoCallInst MonoCallInst;
+typedef struct MonoCallArgParm MonoCallArgParm;
typedef struct MonoEdge MonoEdge;
typedef struct MonoMethodVar MonoMethodVar;
typedef struct MonoBasicBlock MonoBasicBlock;
};
struct MonoSpillInfo {
+#ifndef MONO_ARCH_HAS_XP_REGALLOC
MonoSpillInfo *next;
+#endif
int offset;
};
struct MonoBasicBlock {
MonoInst *last_ins;
+ /* the next basic block in the order it appears in IL */
+ MonoBasicBlock *next_bb;
+
+ /*
+ * Before instruction selection it is the first tree in the
+ * forest and the first item in the list of trees. After
+ * instruction selection it is the first instruction and the
+ * first item in the list of instructions.
+ */
+ MonoInst *code;
+
+ /* unique block number identification */
+ gint32 block_num;
+
+ gint32 dfn;
+
+ /* Basic blocks: incoming and outgoing counts and pointers */
+ /* Each bb should only appear once in each array */
+ gint16 out_count, in_count;
+ MonoBasicBlock **in_bb;
+ MonoBasicBlock **out_bb;
+
/* Points to the start of the CIL code that initiated this BB */
unsigned char* cil_code;
/* The address of the generated code, used for fixups */
int native_offset;
int max_offset;
-
- gint32 dfn;
-
- /* unique block number identification */
- gint32 block_num;
/* Visited and reachable flags */
guint32 flags;
- /* Basic blocks: incoming and outgoing counts and pointers */
- gint16 out_count, in_count;
- MonoBasicBlock **in_bb;
- MonoBasicBlock **out_bb;
-
- /* the next basic block in the order it appears in IL */
- MonoBasicBlock *next_bb;
-
- /*
- * Before instruction selection it is the first tree in the
- * forest and the first item in the list of trees. After
- * instruction selection it is the first instruction and the
- * first item in the list of instructions.
- */
- MonoInst *code;
-
/*
* SSA and loop based flags
*/
* Whenever the bblock is rarely executed so it should be emitted after
* the function epilog.
*/
- gboolean out_of_line;
+ guint out_of_line : 1;
+ /* Caches the result of uselessness calculation during optimize_branches */
+ guint not_useless : 1;
/* use for liveness analysis */
MonoBitSet *gen_set;
};
/* BBlock flags */
-#define BB_VISITED 1
-#define BB_REACHABLE 2
+enum {
+ BB_VISITED = 1 << 0,
+ BB_REACHABLE = 1 << 1,
+ BB_EXCEPTION_DEAD_OBJ = 1 << 2,
+ BB_EXCEPTION_UNSAFE = 1 << 3,
+ BB_EXCEPTION_HANDLER = 1 << 4
+};
struct MonoInst {
union {
gboolean virtual;
regmask_t used_iregs;
regmask_t used_fregs;
-#if defined(MONO_ARCH_HAS_XP_LOCAL_REGALLOC) || defined(__x86_64__)
+#if defined(MONO_ARCH_HAS_XP_LOCAL_REGALLOC)
GSList *out_ireg_args;
GSList *out_freg_args;
#endif
};
+struct MonoCallArgParm {
+ MonoInst ins;
+ gint32 size;
+ gint32 offset;
+ gint32 offPrm;
+};
+
/*
* flags for MonoInst
* Note: some of the values overlap, because they can't appear
MONO_PATCH_INFO_R8,
MONO_PATCH_INFO_IP,
MONO_PATCH_INFO_IID,
+ MONO_PATCH_INFO_ADJUSTED_IID,
MONO_PATCH_INFO_BB_OVF,
MONO_PATCH_INFO_EXC_OVF,
MONO_PATCH_INFO_WRAPPER,
MONO_TRAMPOLINE_JUMP,
MONO_TRAMPOLINE_CLASS_INIT,
MONO_TRAMPOLINE_AOT,
+ MONO_TRAMPOLINE_AOT_PLT,
MONO_TRAMPOLINE_DELEGATE,
MONO_TRAMPOLINE_NUM
} MonoTrampolineType;
MONO_OPT_AOT = 1 << 16,
MONO_OPT_PRECOMP = 1 << 17,
MONO_OPT_ABCREM = 1 << 18,
- MONO_OPT_SSAPRE = 1 << 19
+ MONO_OPT_SSAPRE = 1 << 19,
+ MONO_OPT_EXCEPTION= 1 << 20,
+ MONO_OPT_SSA = 1 << 21,
+ MONO_OPT_TREEPROP = 1 << 22
};
/* Bit-fields in the MonoBasicBlock.region */
MonoSpillInfo *spill_info; /* machine register spills */
MonoSpillInfo *spill_info_float; /* fp register spills */
gint spill_count;
+ gint spill_info_len, spill_info_float_len;
/* unsigned char *cil_code; */
MonoMethod *inlined_method; /* the method which is currently inlined */
MonoInst *domainvar; /* a cache for the current domain */
MonoInst *got_var; /* Global Offset Table variable */
+
+ struct MonoAliasingInformation *aliasing_info;
/* A hashtable of region ID-> SP var mappings */
/* An SP var is a place to store the stack pointer (used by handlers)*/
guint32 param_area;
guint32 frame_reg;
gint32 sig_cookie;
- gboolean disable_aot;
- gboolean disable_ssa;
- gboolean run_cctors;
- gboolean need_lmf_area;
- gboolean compile_aot;
- gboolean got_var_allocated;
- gboolean ret_var_is_local;
+ guint disable_aot : 1;
+ guint disable_ssa : 1;
+ guint run_cctors : 1;
+ guint need_lmf_area : 1;
+ guint compile_aot : 1;
+ guint got_var_allocated : 1;
+ guint ret_var_is_local : 1;
gpointer debug_info;
guint32 lmf_offset;
guint16 *intvars;
guint32 exception_type; /* MONO_EXCEPTION_* */
guint32 exception_data;
char* exception_message;
-#ifdef __ia64
- guint8 ins, locals, outs; /* reg stack region sizes */
-#endif /* __ia64 */
+
+ /* Fields used by the local reg allocator */
+ void* reginfo;
+ void* reginfof;
+ void* reverse_inst_list;
+ int reginfo_len, reginfof_len;
+ int reverse_inst_list_len;
} MonoCompile;
typedef enum {
/* values for MonoInst.ssa_op */
enum {
- MONO_SSA_NOP,
- MONO_SSA_LOAD,
- MONO_SSA_STORE,
- MONO_SSA_MAYBE_LOAD,
- MONO_SSA_MAYBE_STORE
+ 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
};
#define OP_CEQ (256+CEE_CEQ)
#undef MINI_OP
#if SIZEOF_VOID_P == 8
+#define OP_PCONST OP_I8CONST
#define OP_PADD OP_LADD
#define OP_PNEG OP_LNEG
#define OP_PCONV_TO_U2 OP_LCONV_TO_U2
#define OP_STOREP_MEMBASE_REG OP_STOREI8_MEMBASE_REG
#define OP_STOREP_MEMBASE_IMM OP_STOREI8_MEMBASE_IMM
#else
+#define OP_PCONST OP_ICONST
#define OP_PADD CEE_ADD
#define OP_PNEG CEE_NEG
#define OP_PCONV_TO_U2 CEE_CONV_U2
int type;
} StackSlot;
+#if HAVE_ARRAY_ELEM_INIT
+extern const guint8 mono_burg_arity [];
+#else
+extern guint8 mono_burg_arity [];
+#endif
+
enum {
MONO_COMP_DOM = 1,
MONO_COMP_IDOM = 2,
typedef struct {
gboolean handle_sigint;
gboolean keep_delegates;
- gboolean abort_on_sigsegv;
+ gboolean collect_pagefault_stats;
} MonoDebugOptions;
enum {
void mono_print_tree_nl (MonoInst *tree);
void mono_print_code (MonoCompile *cfg);
void mono_print_method_from_ip (void *ip);
+char *mono_pmip (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);
void mono_disassemble_code (MonoCompile *cfg, guint8 *code, int size, char *id);
-guint mono_type_to_ldind (MonoType *t);
-guint mono_type_to_stind (MonoType *t);
void mono_add_patch_info (MonoCompile *cfg, int ip, MonoJumpInfoType type, gconstpointer target);
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);
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);
+MonoJitICallInfo *mono_find_jit_opcode_emulation (int opcode);
+
+
void mono_aot_init (void);
MonoJitInfo* mono_aot_get_method (MonoDomain *domain,
MonoMethod *method);
gpointer mono_aot_get_method_from_token (MonoDomain *domain, MonoImage *image, guint32 token);
gboolean mono_aot_is_got_entry (guint8 *code, guint8 *addr);
+guint8* mono_aot_get_plt_entry (guint8 *code);
gboolean mono_aot_init_vtable (MonoVTable *vtable);
gboolean mono_aot_get_cached_class_info (MonoClass *klass, MonoCachedClassInfo *res);
MonoJitInfo* mono_aot_find_jit_info (MonoDomain *domain, MonoImage *image, gpointer addr);
+void mono_aot_set_make_unreadable (gboolean unreadable);
+gboolean mono_aot_is_pagefault (void *ptr);
+void mono_aot_handle_pagefault (void *ptr);
+guint32 mono_aot_get_n_pagefaults (void);
+gpointer mono_aot_plt_resolve (gpointer aot_module, guint32 plt_info_offset, guint8 *code);
gboolean mono_method_blittable (MonoMethod *method);
gboolean mono_method_same_domain (MonoJitInfo *caller, MonoJitInfo *callee);
gpointer mono_delegate_trampoline (gssize *regs, guint8 *code, MonoMethod *m, guint8* tramp);
gpointer mono_aot_trampoline (gssize *regs, guint8 *code, guint8 *token_info,
guint8* tramp);
+gpointer mono_aot_plt_trampoline (gssize *regs, guint8 *code, guint8 *token_info,
+ guint8* tramp);
void mono_class_init_trampoline (gssize *regs, guint8 *code, MonoVTable *vtable, guint8 *tramp);
gboolean mono_running_on_valgrind (void);
gint32* mono_allocate_stack_slots_full (MonoCompile *cfg, gboolean backward, guint32 *stack_size, guint32 *stack_align);
gint32* mono_allocate_stack_slots (MonoCompile *cfg, guint32 *stack_size, guint32 *stack_align);
void mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb);
+MonoInst *mono_branch_optimize_exception_target (MonoCompile *cfg, MonoBasicBlock *bb, const char * exname);
/* methods that must be provided by the arch-specific port */
void mono_arch_cpu_init (void);
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);
-MonoInst *mono_arch_get_inst_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);
-void mono_call_inst_add_outarg_reg (MonoCallInst *call, int vreg, int hreg, gboolean fp);
+void mono_call_inst_add_outarg_reg (MonoCompile *cfg, MonoCallInst *call, int vreg, int hreg, gboolean fp);
const char *mono_arch_regname (int reg);
const char *mono_arch_fregname (int reg);
gpointer mono_arch_get_throw_exception (void);
gpointer mono_arch_create_jit_trampoline (MonoMethod *method);
MonoJitInfo *mono_arch_create_jump_trampoline (MonoMethod *method);
gpointer mono_arch_create_class_init_trampoline(MonoVTable *vtable);
-gpointer mono_create_delegate_trampoline (MonoMethod *method, gpointer addr);
GList *mono_arch_get_allocatable_int_vars (MonoCompile *cfg);
GList *mono_arch_get_global_int_regs (MonoCompile *cfg);
guint32 mono_arch_regalloc_cost (MonoCompile *cfg, MonoMethodVar *vmv);
void mono_arch_register_lowlevel_calls (void);
gpointer mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr);
void mono_arch_patch_callsite (guint8 *code, guint8 *addr);
+void mono_arch_patch_plt_entry (guint8 *code, guint8 *addr);
void mono_arch_nullify_class_init_trampoline(guint8 *code, gssize *regs);
+void mono_arch_nullify_plt_entry (guint8 *code);
void mono_arch_patch_delegate_trampoline (guint8 *code, guint8 *tramp, gssize *regs, guint8 *addr);
gpointer mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len);
/* Exception handling */
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);
+void mono_handle_native_sigsegv (int signal, void *sigctx);
+void mono_print_thread_dump (void *sigctx);
+void mono_jit_walk_stack (MonoStackWalk func, gboolean do_il_offset, gpointer user_data);
+void mono_jit_walk_stack_from_ctx (MonoStackWalk func, MonoContext *ctx, gboolean do_il_offset, gpointer user_data);
+void mono_setup_altstack (MonoJitTlsData *tls);
+void mono_free_altstack (MonoJitTlsData *tls);
/* the new function to do stack walks */
typedef gboolean (*MonoStackFrameWalk) (MonoDomain *domain, MonoContext *ctx, MonoJitInfo *ji, gpointer data);
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,
- MonoMethod *method, guint8 *code_start,
- guint8 *debug_info, guint32 debug_info_len);
+ MonoMethod *method, guint8 *code_start,
+ guint8 *debug_info, guint32 debug_info_len);
void mono_debug_add_icall_wrapper (MonoMethod *method, MonoJitICallInfo* info);
+void mono_debugger_run_finally (MonoContext *start_ctx);
+
+/* Mono Debugger support */
+void mono_debugger_init (void);
+int mono_debugger_main (MonoDomain *domain, MonoAssembly *assembly, int argc, char **argv);
/* Tracing */
mono_perform_abc_removal (MonoCompile *cfg);
extern void
mono_perform_ssapre (MonoCompile *cfg);
+extern void
+mono_local_cprop (MonoCompile *cfg);
/* CAS - stack walk */
MonoSecurityFrame* ves_icall_System_Security_SecurityFrame_GetSecurityFrame (gint32 skip);