#ifndef __MONO_MINI_H__
#define __MONO_MINI_H__
+#include "config.h"
#include <glib.h>
#include <signal.h>
#include <mono/metadata/loader.h>
#include <mono/metadata/object.h>
#include <mono/metadata/opcodes.h>
#include <mono/metadata/tabledefs.h>
-#include "regalloc.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>
-/* fixme: configure should set this */
-#define SIZEOF_VOID_P 4
+#include "mini-arch.h"
+#include "regalloc.h"
#define MONO_USE_AOT_COMPILER
+/* for 32 bit systems */
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+#define MINI_LS_WORD_OFFSET 0
+#define MINI_MS_WORD_OFFSET 4
+#define inst_ls_word data.op[0].const_val
+#define inst_ms_word data.op[1].const_val
+#else
+#define MINI_LS_WORD_OFFSET 4
+#define MINI_MS_WORD_OFFSET 0
+#define inst_ls_word data.op[1].const_val
+#define inst_ms_word data.op[0].const_val
+#endif
+
+/* Version number of the AOT file format */
+#define MONO_AOT_FILE_VERSION "7"
+
#if 1
#define mono_bitset_test_fast(set,n) (((guint32*)set)[2+(n)/32] & (1 << ((n) % 32)))
#else
typedef struct MonoBasicBlock MonoBasicBlock;
typedef struct MonoLMF MonoLMF;
typedef struct MonoSpillInfo MonoSpillInfo;
+typedef struct MonoTraceSpec MonoTraceSpec;
extern guint32 mono_jit_tls_id;
-extern gboolean mono_jit_trace_calls;
+extern MonoTraceSpec *mono_jit_trace_calls;
extern gboolean mono_break_on_exc;
extern int mono_exc_esp_offset;
extern gboolean mono_compile_aot;
-extern gboolean mono_trace_coverage;
-extern gboolean mono_jit_profile;
-
-extern CRITICAL_SECTION *metadata_section;
struct MonoEdge {
MonoEdge *next;
/* we use that to prevent merging of bblock covered by different clauses*/
guint real_offset;
+
+ /*
+ * The region encodes whether the basic block is inside
+ * a finally, catch, filter or none of thoese.
+ *
+ * If the value is -1, then it is neither finally, catch nor filter
+ *
+ * Otherwise the format is:
+ *
+ * Bits: | 0-3 | 4-7 | 8-31
+ * | | |
+ * | clause-flags | MONO_REGION | clause-index
+ *
+ */
guint region;
/* The current symbolic register number, used in local register allocation. */
- guint16 max_ireg, max_freg;
+ guint32 max_ireg, max_freg;
};
/* BBlock flags */
union {
MonoInst *src;
MonoMethodVar *var;
- gint32 const_val;
+ gssize const_val;
gpointer p;
MonoMethod *method;
MonoMethodSignature *signature;
guint8 flags : 5;
/* used by the register allocator */
- gint16 dreg, sreg1, sreg2, unused;
+ gint32 dreg, sreg1, sreg2, unused;
MonoInst *next;
MonoClass *klass;
MonoMethodSignature *signature;
MonoMethod *method;
MonoInst **args;
+ MonoInst *out_args;
gconstpointer fptr;
guint stack_usage;
- guint32 used_iregs;
- guint32 used_fregs;
+ gboolean virtual;
+ regmask_t used_iregs;
+ regmask_t used_fregs;
};
/*
MONO_INST_TAILCALL = 4,
MONO_INST_VOLATILE = 4,
MONO_INST_BRLABEL = 4,
+ MONO_INST_NOTYPECHECK = 4,
MONO_INST_UNALIGNED = 8,
/* the address of the variable has been taken */
- MONO_INST_INDIRECT = 16
+ MONO_INST_INDIRECT = 16,
+ MONO_INST_NORANGECHECK = 16
};
#define inst_c0 data.op[0].const_val
#define inst_newa_len data.op[0].src
#define inst_newa_class data.op[1].klass
-#define inst_switch data.op[0].switch_blocks
#define inst_var data.op[0].var
#define inst_vtype data.op[1].vtype
/* in branch instructions */
typedef struct {
gpointer end_of_stack;
+ guint32 stack_size;
MonoLMF *lmf;
+ MonoLMF *first_lmf;
+ gpointer signal_stack;
+ guint32 signal_stack_size;
void (*abort_func) (MonoObject *object);
} MonoJitTlsData;
MONO_PATCH_INFO_LABEL,
MONO_PATCH_INFO_METHOD,
MONO_PATCH_INFO_METHOD_JUMP,
+ MONO_PATCH_INFO_METHOD_REL,
MONO_PATCH_INFO_METHODCONST,
MONO_PATCH_INFO_INTERNAL_METHOD,
MONO_PATCH_INFO_SWITCH,
MONO_PATCH_INFO_EXC,
+ MONO_PATCH_INFO_EXC_NAME,
MONO_PATCH_INFO_CLASS,
- MONO_PATCH_INFO_IMAGE,
- MONO_PATCH_INFO_FIELD,
- MONO_PATCH_INFO_R4,
+ MONO_PATCH_INFO_IMAGE,
+ MONO_PATCH_INFO_FIELD,
+ MONO_PATCH_INFO_VTABLE,
+ MONO_PATCH_INFO_CLASS_INIT,
+ MONO_PATCH_INFO_SFLDA,
+ MONO_PATCH_INFO_LDSTR,
+ MONO_PATCH_INFO_LDTOKEN,
+ MONO_PATCH_INFO_TYPE_FROM_HANDLE,
+ MONO_PATCH_INFO_R4,
MONO_PATCH_INFO_R8,
- MONO_PATCH_INFO_IP
+ MONO_PATCH_INFO_IP,
+ MONO_PATCH_INFO_IID,
+ MONO_PATCH_INFO_BB_OVF,
+ MONO_PATCH_INFO_EXC_OVF,
+ MONO_PATCH_INFO_WRAPPER
} MonoJumpInfoType;
+/*
+ * We need to store the image which the token refers to along with the token,
+ * since the image might not be the same as the image of the method which
+ * contains the relocation, because of inlining.
+ */
+typedef struct MonoJumpInfoToken {
+ MonoImage *image;
+ guint32 token;
+} MonoJumpInfoToken;
+
typedef struct MonoJumpInfo MonoJumpInfo;
struct MonoJumpInfo {
MonoJumpInfo *next;
MonoClass *klass;
MonoClassField *field;
MonoImage *image;
+ MonoVTable *vtable;
const char *name;
+ MonoJumpInfoToken *token;
} data;
int table_size; /* use by switch */
};
-/* optimization flags: keep up to date with the name array in mini.c */
+/* optimization flags: keep up to date with the name array in driver.c */
enum {
MONO_OPT_PEEPHOLE = 1 << 0,
MONO_OPT_BRANCH = 1 << 1,
MONO_OPT_TAILC = 1 << 12,
MONO_OPT_LOOP = 1 << 13,
MONO_OPT_FCMOV = 1 << 14,
- MONO_OPT_LEAF = 1 << 15
+ MONO_OPT_LEAF = 1 << 15,
+ MONO_OPT_AOT = 1 << 16,
+ MONO_OPT_PRECOMP = 1 << 17,
+ MONO_OPT_ABCREM = 1 << 18
};
+/* Bit-fields in the MonoBasicBlock.region */
+#define MONO_REGION_FINALLY 16
+#define MONO_REGION_CATCH 32
+#define MONO_REGION_FAULT 64 /* Currently unused */
+#define MONO_REGION_FILTER 128
+
/*
* Control Flow Graph and compilation unit information
*/
MonoBasicBlock *cbb; /* used by instruction selection */
MonoInst *prev_ins; /* in decompose */
MonoJumpInfo *patch_info;
+ MonoJitInfo *jit_info;
guint num_bblocks;
guint locals_start;
guint num_varinfo; /* used items in varinfo */
guint varinfo_count; /* total storage in varinfo */
gint stack_offset;
MonoRegState *rs;
- MonoSpillInfo *spill_info;
+ MonoSpillInfo *spill_info; /* machine register spills */
+ MonoSpillInfo *spill_info_float; /* fp register spills */
gint spill_count;
- // unsigned char *cil_code;
+ /* unsigned char *cil_code; */
- MonoInst *exvar; /* the exception object passed to catch/filter blocks */
+ /* the exception object passed to catch/filter blocks */
+ MonoInst *exvar;
+
MonoInst *domainvar; /* a cache for the current domain */
- MonoInst *spvar; /* a place to store the stack pointer (used by handlers) */
+
+ /* A hashtable of region ID-> SP var mappings */
+ /* An SP var is a place to store the stack pointer (used by handlers)*/
+ GHashTable *spvars;
GList *ldstr_list; /* used by AOT */
guint code_len;
guint prolog_end;
guint epilog_begin;
- guint32 used_int_regs;
+ regmask_t used_int_regs;
guint32 opt;
+ guint32 prof_options;
guint32 flags;
guint32 comp_done;
guint32 verbose_level;
guint32 stack_usage;
guint32 param_area;
guint32 frame_reg;
+ gint32 sig_cookie;
gboolean disable_aot;
gboolean disable_ssa;
+ gboolean run_cctors;
+ gboolean need_lmf_area;
gpointer debug_info;
+ guint32 lmf_offset;
guint16 *intvars;
+ MonoProfileCoverageInfo *coverage_info;
+ MonoCompileArch arch;
+#ifdef __ia64
+ guint8 ins, locals, outs; /* reg stack region sizes */
+#endif /* __ia64 */
} MonoCompile;
typedef enum {
MONO_CFG_HAS_ALLOCA = 1 << 0,
- MONO_CFG_HAS_CALLS = 1 << 1
+ MONO_CFG_HAS_CALLS = 1 << 1,
+ MONO_CFG_HAS_LDELEMA = 1 << 2,
+ MONO_CFG_HAS_VARARGS = 1 << 3
} MonoCompileFlags;
-typedef struct {
- int entries;
- struct {
- int iloffset;
- int count;
- } data [0];
-} MonoCoverageInfo;
-
typedef struct {
gulong methods_compiled;
gulong methods_aot;
MonoMethodSignature *sig;
} MonoJitICallInfo;
+typedef struct {
+ guint16 size;
+ guint16 offset;
+ guint8 pad;
+} MonoJitArgumentInfo;
+
typedef void (*MonoInstFunc) (MonoInst *tree, gpointer data);
/* main function */
MonoDomain* mini_init (const char *filename);
void mini_cleanup (MonoDomain *domain);
-MonoDomain* mono_jit_init (const char *filename);
-void mono_jit_cleanup (MonoDomain *domain);
-
/* helper methods */
+MonoJumpInfoToken * mono_jump_info_token_new (MonoMemPool *mp, MonoImage *image, guint32 token);
+MonoInst* mono_find_spvar_for_region (MonoCompile *cfg, int region);
+void mono_precompile_assemblies (void);
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_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_blockset_print (MonoCompile *cfg, MonoBitSet *set, const char *name, guint idom);
void mono_print_tree (MonoInst *tree);
-int mono_spillvar_offset (MonoCompile *cfg, int spillvar);
+void mono_print_tree_nl (MonoInst *tree);
+void mono_print_code (MonoCompile *cfg);
void mono_select_instructions (MonoCompile *cfg);
const char* mono_inst_name (int op);
void mono_inst_foreach (MonoInst *tree, MonoInstFunc func, gpointer data);
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_get_lmf_addr (void);
+gpointer mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *patch_info, gboolean run_cctors);
+MonoLMF** mono_get_lmf_addr (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, guint32 *used_mask);
+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, int parts);
+MonoCompile *mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gboolean run_cctors, int parts);
void mono_destroy_compile (MonoCompile *cfg);
-gpointer mono_aot_get_method (MonoMethod *method);
+void mono_aot_init (void);
+MonoJitInfo* mono_aot_get_method (MonoDomain *domain,
+ MonoMethod *method);
gboolean mono_method_blittable (MonoMethod *method);
-void mono_register_opcode_emulation (int opcode, const char* name, MonoMethodSignature *sig, gpointer func);
+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);
MonoJitICallInfo *mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save);
gconstpointer mono_icall_get_wrapper (MonoJitICallInfo* callinfo);
-MonoCoverageInfo *mono_allocate_coverage_info (MonoMethod *method, int size);
-MonoCoverageInfo *mono_get_coverage_info (MonoMethod *method);
+gpointer mono_create_jump_trampoline (MonoDomain *domain,
+ MonoMethod *method,
+ gboolean add_sync_wrapper);
+gpointer mono_create_class_init_trampoline (MonoVTable *vtable);
+MonoVTable* mono_find_class_init_trampoline_by_addr (gconstpointer addr);
+gboolean mono_running_on_valgrind (void);
/* methods that must be provided by the arch-specific port */
+void mono_arch_cpu_init (void);
guint32 mono_arch_cpu_optimizazions (guint32 *exclude_mask);
void mono_arch_instrument_mem_needs (MonoMethod *method, int *stack, int *code);
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);
void mono_codegen (MonoCompile *cfg);
const char *mono_arch_regname (int reg);
gpointer mono_arch_get_throw_exception (void);
gpointer mono_arch_get_throw_exception_by_name (void);
gpointer mono_arch_create_jit_trampoline (MonoMethod *method);
-gpointer mono_arch_create_jump_trampoline (MonoMethod *method);
+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);
GList *mono_arch_get_global_int_regs (MonoCompile *cfg);
-void mono_arch_patch_code (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *ji);
+guint32 mono_arch_regalloc_cost (MonoCompile *cfg, MonoMethodVar *vmv);
+void mono_arch_patch_code (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *ji, gboolean run_cctors);
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_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb);
void mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb);
gboolean mono_arch_has_unwind_info (gconstpointer addr);
+void mono_arch_setup_jit_tls_data (MonoJitTlsData *tls);
+void mono_arch_free_jit_tls_data (MonoJitTlsData *tls);
+void mono_arch_emit_this_vret_args (MonoCompile *cfg, MonoCallInst *inst, int this_reg, int this_type, int vt_reg);
void mono_arch_allocate_vars (MonoCompile *m);
+int mono_arch_get_argument_info (MonoMethodSignature *csig, int param_count, MonoJitArgumentInfo *arg_info);
+gboolean mono_arch_print_tree (MonoInst *tree, int arity);
+MonoJitInfo *mono_arch_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);
+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_flush_register_windows (void);
+
+/* Exception handling */
+gboolean mono_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only);
void mono_jit_walk_stack (MonoStackWalk 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,
void mono_ssa_cprop (MonoCompile *cfg);
void mono_ssa_deadce (MonoCompile *cfg);
void mono_ssa_strength_reduction (MonoCompile *cfg);
+void mono_free_loop_info (MonoCompile *cfg);
/* debugging support */
void mono_debug_init_method (MonoCompile *cfg, MonoBasicBlock *start_block,
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,
+ MonoMethod *method, guint8 *code_start,
+ guint8 *debug_info, guint32 debug_info_len);
+
+/* Tracing */
+MonoTraceSpec *mono_trace_parse_options (MonoAssembly *assembly, char *options);
+gboolean mono_trace_eval (MonoMethod *method);
+
+extern void
+mono_perform_abc_removal (MonoCompile *cfg);
#endif /* __MONO_MINI_H__ */