#endif
/* Version number of the AOT file format */
-#define MONO_AOT_FILE_VERSION "70"
+#define MONO_AOT_FILE_VERSION 72
//TODO: This is x86/amd64 specific.
#define mono_simd_shuffle_mask(a,b,c,d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6))
/* This structure is stored in the AOT file */
typedef struct MonoAotFileInfo
{
+ /* The version number of the AOT file format, should match MONO_AOT_FILE_VERSION */
+ guint32 version;
+ /* For alignment */
+ guint32 dummy;
+
+ /* All the pointers should be at the start to avoid alignment problems */
+
+ /* Mono's Global Offset Table */
+ gpointer got;
+ /* Compiled code for methods */
+ gpointer methods;
+ /* Mono EH Frame created by llc when using LLVM */
+ gpointer mono_eh_frame;
+ /* Data blob */
+ gpointer blob;
+ gpointer class_name_table;
+ gpointer class_info_offsets;
+ gpointer method_info_offsets;
+ gpointer ex_info_offsets;
+ gpointer code_offsets;
+ gpointer extra_method_info_offsets;
+ gpointer extra_method_table;
+ gpointer got_info_offsets;
+ gpointer methods_end;
+ gpointer unwind_info;
+ gpointer mem_end;
+ gpointer image_table;
+ /* Start of Mono's Program Linkage Table */
+ gpointer plt;
+ /* End of Mono's Program Linkage Table */
+ gpointer plt_end;
+ /* The GUID of the assembly which the AOT image was generated from */
+ gpointer assembly_guid;
+ /*
+ * The runtime version string for AOT images generated using 'bind-to-runtime-version',
+ * NULL otherwise.
+ */
+ gpointer runtime_version;
+ /* Blocks of various kinds of trampolines */
+ gpointer specific_trampolines;
+ gpointer static_rgctx_trampolines;
+ gpointer imt_thunks;
+ /*
+ * The end of LLVM generated thumb code, or NULL.
+ */
+ gpointer thumb_end;
+
+ /* The index of the first GOT slot used by the PLT */
guint32 plt_got_offset_base;
+ /* Number of entries in the GOT */
guint32 got_size;
+ /* Number of entries in the PLT */
guint32 plt_size;
+ /* Number of methods */
guint32 nmethods;
+ /* A union of MonoAotFileFlags */
guint32 flags;
/* Optimization flags used to compile the module */
guint32 opts;
/* Index of the blob entry holding the GC used by this module */
gint32 gc_name_index;
+ /* Number of trampolines */
guint32 num_trampolines [MONO_AOT_TRAMP_NUM];
+ /* The indexes of the first GOT slots used by the trampolines */
guint32 trampoline_got_offset_base [MONO_AOT_TRAMP_NUM];
+ /* The size of one trampoline */
guint32 trampoline_size [MONO_AOT_TRAMP_NUM];
} MonoAotFileInfo;
int native_offset;
int il_offset;
gpointer lmf;
+ guint32 unwind_info_len;
+ guint8 *unwind_info;
} StackFrameInfo;
typedef struct {
int offset;
};
+/*
+ * Information about a call site for the GC map creation code
+ */
+typedef struct {
+ /* The next offset after the call instruction */
+ int pc_offset;
+ /* The basic block containing the call site */
+ MonoBasicBlock *bb;
+ /*
+ * The set of variables live at the call site.
+ * Has length cfg->num_varinfo in bits.
+ */
+ guint8 *liveness;
+ /*
+ * List of OP_GC_PARAM_SLOT_LIVENESS_DEF instructions defining the param slots
+ * used by this call.
+ */
+ GSList *param_slots;
+} GCCallSite;
+
/*
* The IR-level extended basic block.
*
/* The offset of the generated code, used for fixups */
int native_offset;
+ /* The length of the generated code, doesn't include alignment padding */
int native_length;
+ /* The real native offset, which includes alignment padding too */
+ int real_native_offset;
int max_offset;
int max_length;
GSList *seq_points;
MonoInst *last_seq_point;
+ GSList *spill_slot_defs;
+
+ /* List of call sites in this bblock sorted by pc_offset */
+ GSList *gc_callsites;
+
/*
* The region encodes whether the basic block is inside
* a finally, catch, filter or none of these.
gboolean record_cast_details; /* For CEE_CASTCLASS */
MonoInst *spill_var; /* for OP_ICONV_TO_R8_RAW and OP_FCONV_TO_R8_X */
guint16 source_opcode; /*OP_XCONV_R8_TO_I4 needs to know which op was used to do proper widening*/
+ int pc_offset; /* OP_GC_LIVERANGE_START/END */
} backend;
MonoClass *klass;
/* On loads, the source address can be null */
MONO_INST_FAULT = 32,
/* On loads, the source address points to a constant value */
- MONO_INST_CONSTANT_LOAD = 64
+ MONO_INST_CONSTANT_LOAD = 64,
+ /* On variables, the variable needs GC tracking */
+ MONO_INST_GC_TRACK = 128,
+ /*
+ * Set on instructions during code emission which make calls, i.e. OP_CALL, OP_THROW.
+ * backend.pc_offset will be set to the pc offset at the end of the native call instructions.
+ */
+ MONO_INST_GC_CALLSITE = 128
};
#define inst_c0 data.op[0].const_val
/* Stores state needed by handler block with a guard */
MonoContext ex_ctx;
ResumeState resume_state;
- /* handle block return address */
+
+ /*Variabled use to implement handler blocks (finally/catch/etc) guards during interruption*/
+ /* handler block return address */
gpointer handler_block_return_address;
- /* handler block been guarded */
+
+ /* handler block been guarded. It's safe to store this even for dynamic methods since there
+ is an activation on stack making sure it will remain alive.*/
MonoJitExceptionInfo *handler_block;
+ /* context to be used by the guard trampoline when resuming interruption.*/
+ MonoContext handler_block_context;
/*
* Stores the state at the exception throw site to be used by mono_stack_walk ()
* when it is called from profiler functions during exception handling.
#define vreg_is_volatile(cfg, vreg) (G_UNLIKELY (get_vreg_to_inst ((cfg), (vreg)) && (get_vreg_to_inst ((cfg), (vreg))->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT))))
+#ifdef HAVE_SGEN_GC
+#define vreg_is_ref(cfg, vreg) ((vreg) < (cfg)->vreg_is_ref_len ? (cfg)->vreg_is_ref [(vreg)] : 0)
+#define vreg_is_mp(cfg, vreg) ((vreg) < (cfg)->vreg_is_mp_len ? (cfg)->vreg_is_mp [(vreg)] : 0)
+#else
+#define vreg_is_ref(cfg, vreg) FALSE
+#define vreg_is_mp(cfg, vreg) FALSE
+#endif
+
/*
* Control Flow Graph and compilation unit information
*/
gint stack_offset;
gint max_ireg;
gint cil_offset_to_bb_len;
- gint locals_min_stack_offset, locals_max_stack_offset;
MonoRegState *rs;
MonoSpillInfo *spill_info [16]; /* machine register spills */
gint spill_count;
guint keep_cil_nops : 1;
guint gen_seq_points : 1;
guint explicit_null_checks : 1;
+ guint compute_gc_maps : 1;
gpointer debug_info;
guint32 lmf_offset;
guint16 *intvars;
/* Size of above array */
guint32 vreg_to_inst_len;
+ /* Marks vregs which hold a GC ref */
+ /* FIXME: Use a bitmap */
+ gboolean *vreg_is_ref;
+
+ /* Size of above array */
+ guint32 vreg_is_ref_len;
+
+ /* Marks vregs which hold a managed pointer */
+ /* FIXME: Use a bitmap */
+ gboolean *vreg_is_mp;
+
+ /* Size of above array */
+ guint32 vreg_is_mp_len;
+
/*
* The original method to compile, differs from 'method' when doing generic
* sharing.
guint32 got_offset, ex_info_offset, method_info_offset;
/* Symbol used to refer to this method in generated assembly */
char *asm_symbol;
+ char *llvm_method_name;
MonoJitExceptionInfo *llvm_ex_info;
guint32 llvm_ex_info_len;
int llvm_this_reg, llvm_this_offset;
GSList *try_block_holes;
+
+ /* GC Maps */
+
+ /* The offsets of the locals area relative to the frame pointer */
+ gint locals_min_stack_offset, locals_max_stack_offset;
+
+ /* The final CFA rule at the end of the prolog */
+ int cfa_reg, cfa_offset;
+
+ /* Points to a MonoCompileGC */
+ gpointer gc_info;
+
+ /*
+ * The encoded GC map along with its size. This contains binary data so it can be saved in an AOT
+ * image etc, but it requires a 4 byte alignment.
+ */
+ guint8 *gc_map;
+ guint32 gc_map_size;
} MonoCompile;
typedef enum {
guint32 mono_alloc_freg (MonoCompile *cfg) MONO_LLVM_INTERNAL;
guint32 mono_alloc_preg (MonoCompile *cfg) MONO_LLVM_INTERNAL;
guint32 mono_alloc_dreg (MonoCompile *cfg, MonoStackType stack_type) MONO_INTERNAL;
+guint32 mono_alloc_ireg_ref (MonoCompile *cfg) MONO_LLVM_INTERNAL;
+guint32 mono_alloc_ireg_mp (MonoCompile *cfg) MONO_LLVM_INTERNAL;
+guint32 mono_alloc_ireg_copy (MonoCompile *cfg, guint32 vreg) MONO_LLVM_INTERNAL;
+void mono_mark_vreg_as_ref (MonoCompile *cfg, int vreg) MONO_INTERNAL;
+void mono_mark_vreg_as_mp (MonoCompile *cfg, int vreg) MONO_INTERNAL;
void mono_link_bblock (MonoCompile *cfg, MonoBasicBlock *from, MonoBasicBlock* to) MONO_INTERNAL;
void mono_unlink_bblock (MonoCompile *cfg, MonoBasicBlock *from, MonoBasicBlock* to) MONO_INTERNAL;
GList *mono_varlist_insert_sorted (MonoCompile *cfg, GList *list, MonoMethodVar *mv, int sort_type) MONO_INTERNAL;
GList *mono_varlist_sort (MonoCompile *cfg, GList *list, int sort_type) MONO_INTERNAL;
void mono_analyze_liveness (MonoCompile *cfg) MONO_INTERNAL;
+void mono_analyze_liveness_gc (MonoCompile *cfg) MONO_INTERNAL;
void mono_linear_scan (MonoCompile *cfg, GList *vars, GList *regs, regmask_t *used_mask) MONO_INTERNAL;
void mono_global_regalloc (MonoCompile *cfg) MONO_INTERNAL;
void mono_create_jump_table (MonoCompile *cfg, MonoInst *label, MonoBasicBlock **bbs, int num_blocks) MONO_INTERNAL;
guint32 mono_aot_get_got_offset (MonoJumpInfo *ji) MONO_LLVM_INTERNAL;
char* mono_aot_get_method_name (MonoCompile *cfg) MONO_LLVM_INTERNAL;
char* mono_aot_get_plt_symbol (MonoJumpInfoType type, gconstpointer data) MONO_LLVM_INTERNAL;
-char* mono_aot_get_method_debug_name (MonoCompile *cfg) MONO_LLVM_INTERNAL;
MonoJumpInfo* mono_aot_patch_info_dup (MonoJumpInfo* ji) MONO_LLVM_INTERNAL;
void mono_aot_set_make_unreadable (gboolean unreadable) MONO_INTERNAL;
gboolean mono_aot_is_pagefault (void *ptr) MONO_INTERNAL;
gboolean
mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
MonoJitInfo *ji, MonoContext *ctx,
- MonoContext *new_ctx, MonoLMF **lmf,
+ MonoContext *new_ctx, MonoLMF **lmf,
+ mgreg_t **save_locations,
StackFrameInfo *frame_info) MONO_INTERNAL;
gpointer mono_arch_get_throw_exception_by_name (void) MONO_INTERNAL;
gpointer mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) MONO_INTERNAL;
mono_find_jit_info_ext (MonoDomain *domain, MonoJitTlsData *jit_tls,
MonoJitInfo *prev_ji, MonoContext *ctx,
MonoContext *new_ctx, char **trace, MonoLMF **lmf,
+ mgreg_t **save_locations,
StackFrameInfo *frame) MONO_INTERNAL;
gpointer mono_get_throw_exception (void) MONO_INTERNAL;
MONO_AOT_WRAPPER_MONO_ENTER,
MONO_AOT_WRAPPER_MONO_EXIT,
MONO_AOT_WRAPPER_ELEMENT_ADDR,
+ MONO_AOT_WRAPPER_PTR_TO_STRUCTURE,
+ MONO_AOT_WRAPPER_STRUCTURE_TO_PTR,
MONO_AOT_WRAPPER_LAST
};