#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)))
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;
/* 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;
gboolean virtual;
regmask_t used_iregs;
regmask_t used_fregs;
+#ifdef __x86_64__
+ GSList *out_ireg_args;
+ GSList *out_freg_args;
+#endif
};
/*
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;
/*
guint32 token;
} MonoJumpInfoToken;
+typedef struct MonoJumpInfoBBTable {
+ MonoBasicBlock **table;
+ int table_size;
+} MonoJumpInfoBBTable;
+
typedef struct MonoJumpInfo MonoJumpInfo;
struct MonoJumpInfo {
MonoJumpInfo *next;
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;
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,
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
*/
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;
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 */
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 {
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;
};
#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,
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 */
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);
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);
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);
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);
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);
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);
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__ */