#define MONO_FAKE_VTABLE_METHOD ((MonoMethod*)GINT_TO_POINTER(-2))
/* Version number of the AOT file format */
-#define MONO_AOT_FILE_VERSION "36"
+#define MONO_AOT_FILE_VERSION "38"
/* Per-domain information maintained by the JIT */
typedef struct
{
/* Maps MonoMethod's to a GSList of GOT slot addresses pointing to its code */
GHashTable *jump_target_got_slot_hash;
+ GHashTable *jump_target_hash;
+ /* Maps methods/klasses to the address of the given type of trampoline */
+ GHashTable *class_init_trampoline_hash;
+ GHashTable *jump_trampoline_hash;
+ GHashTable *jit_trampoline_hash;
+ GHashTable *delegate_trampoline_hash;
+ /* maps MonoMethod -> MonoJitDynamicMethodInfo */
+ GHashTable *dynamic_code_hash;
+ GHashTable *method_code_hash;
} MonoJitDomainInfo;
-#define jit_domain_info(domain) ((MonoJitDomainInfo*)((domain)->runtime_info))
+typedef struct {
+ MonoJitInfo *ji;
+ MonoCodeManager *code_mp;
+} MonoJitDynamicMethodInfo;
+
+#define domain_jit_info(domain) ((MonoJitDomainInfo*)((domain)->runtime_info))
#if 0
#define mono_bitset_foreach_bit(set,b,n) \
#define MONO_IS_CALL(ins) (((ins->opcode >= OP_VOIDCALL) && (ins->opcode <= OP_VOIDCALL_MEMBASE)) || ((ins->opcode >= OP_FCALL) && (ins->opcode <= OP_FCALL_MEMBASE)) || ((ins->opcode >= OP_LCALL) && (ins->opcode <= OP_LCALL_MEMBASE)) || ((ins->opcode >= OP_VCALL) && (ins->opcode <= OP_VCALL_MEMBASE)) || ((ins->opcode >= OP_CALL) && (ins->opcode <= OP_CALL_MEMBASE)) || ((ins->opcode >= OP_VCALL2) && (ins->opcode <= OP_VCALL2_MEMBASE)) || (ins->opcode == OP_TAILCALL))
-/* FIXME: Handle OP_GOT_ENTRY too */
-#define MONO_IS_JUMP_TABLE(ins) (((ins)->opcode == OP_JUMP_TABLE) ? TRUE : ((((ins)->opcode == OP_AOTCONST) && (ins->inst_i1 == (gpointer)MONO_PATCH_INFO_SWITCH)) ? TRUE : ((ins)->opcode == OP_SWITCH) ? TRUE : FALSE))
+#define MONO_IS_JUMP_TABLE(ins) (((ins)->opcode == OP_JUMP_TABLE) ? TRUE : ((((ins)->opcode == OP_AOTCONST) && (ins->inst_i1 == (gpointer)MONO_PATCH_INFO_SWITCH)) ? TRUE : ((ins)->opcode == OP_SWITCH) ? TRUE : ((((ins)->opcode == OP_GOT_ENTRY) && ((ins)->inst_right->inst_i1 == (gpointer)MONO_PATCH_INFO_SWITCH)) ? TRUE : FALSE)))
-#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 : NULL)))
+#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) || (ins->opcode == OP_VZERO) || (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))
extern gboolean check_for_pending_exc;
extern gboolean disable_vtypes_in_regs;
extern gboolean mono_verify_all;
+extern gboolean mono_dont_free_global_codeman;
#define INS_INFO(opcode) (&ins_info [((opcode) - OP_START - 1) * 3])
* calling convention as OP_CALL.
*/
guint vret_in_reg : 1;
+ /* Whenever there is an IMT argument and it is dynamic */
+ guint dynamic_imt_arg : 1;
regmask_t used_iregs;
regmask_t used_fregs;
GSList *out_ireg_args;
MonoLMF *lmf;
#endif
MonoLMF *first_lmf;
+ gpointer restore_stack_prot;
+ guint32 handling_stack_ovf;
gpointer signal_stack;
guint32 signal_stack_size;
gpointer stack_ovf_guard_base;
MONO_TRAMPOLINE_AOT,
MONO_TRAMPOLINE_AOT_PLT,
MONO_TRAMPOLINE_DELEGATE,
+ MONO_TRAMPOLINE_RESTORE_STACK_PROT,
MONO_TRAMPOLINE_NUM
} MonoTrampolineType;
gint max_ireg;
gint cil_offset_to_bb_len;
MonoRegState *rs;
- MonoSpillInfo *spill_info; /* machine register spills */
- MonoSpillInfo *spill_info_float; /* fp register spills */
+ MonoSpillInfo *spill_info [16]; /* machine register spills */
gint spill_count;
- gint spill_info_len, spill_info_float_len;
+ gint spill_info_len [16];
/* unsigned char *cil_code; */
MonoMethod *inlined_method; /* the method which is currently inlined */
MonoInst *domainvar; /* a cache for the current domain */
guint disable_reuse_stack_slots : 1;
guint disable_initlocals_opt : 1;
guint disable_omit_fp : 1;
+ guint disable_vreg_to_lvreg : 1;
guint has_got_slots : 1;
+ guint uses_rgctx_reg : 1;
+ guint uses_vtable_reg : 1;
gpointer debug_info;
guint32 lmf_offset;
guint16 *intvars;
/* Patches which describe absolute addresses embedded into the native code */
GHashTable *abs_patches;
+
+ /* If the arch passes valuetypes by address, then for methods
+ which use JMP the arch code should use these local
+ variables to store the addresses of incoming valuetypes.
+ The addresses should be stored in mono_arch_emit_prolog()
+ and can be used when emitting code for OP_JMP. See
+ mini-ppc.c. */
+ MonoInst **tailcall_valuetype_addrs;
} MonoCompile;
typedef enum {
gulong methods_lookups;
gulong method_trampolines;
gulong allocate_var;
- gulong analyze_stack_repeat;
gulong cil_code_size;
gulong native_code_size;
gulong code_reallocs;
gpointer mono_aot_create_specific_trampoline (MonoImage *image, gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len) MONO_INTERNAL;
gpointer mono_aot_get_named_code (const char *name) MONO_INTERNAL;
gpointer mono_aot_get_unbox_trampoline (MonoMethod *method) MONO_INTERNAL;
+gpointer mono_aot_get_lazy_fetch_trampoline (guint32 slot) MONO_INTERNAL;
/* This is an exported function */
void mono_aot_register_globals (gpointer *globals);
/* This too */
MonoMethod *method,
gboolean add_sync_wrapper) MONO_INTERNAL;
gpointer mono_create_class_init_trampoline (MonoVTable *vtable) MONO_INTERNAL;
+gpointer mono_create_generic_class_init_trampoline (void) MONO_INTERNAL;
gpointer mono_create_jit_trampoline (MonoMethod *method) MONO_INTERNAL;
gpointer mono_create_jit_trampoline_from_token (MonoImage *image, guint32 token) MONO_INTERNAL;
-gpointer mono_create_jit_trampoline_in_domain (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper) MONO_INTERNAL;
+gpointer mono_create_jit_trampoline_in_domain (MonoDomain *domain, MonoMethod *method) MONO_INTERNAL;
gpointer mono_create_delegate_trampoline (MonoClass *klass) MONO_INTERNAL;
gpointer mono_create_rgctx_lazy_fetch_trampoline (guint32 offset) MONO_INTERNAL;
MonoVTable* mono_find_class_init_trampoline_by_addr (gconstpointer addr) MONO_INTERNAL;
gboolean mono_running_on_valgrind (void) MONO_INTERNAL;
void* mono_global_codeman_reserve (int size) MONO_INTERNAL;
-const char *mono_regname_full (int reg, gboolean fp) MONO_INTERNAL;
+const char *mono_regname_full (int reg, int bank) MONO_INTERNAL;
gint32* mono_allocate_stack_slots_full (MonoCompile *cfg, gboolean backward, guint32 *stack_size, guint32 *stack_align) MONO_INTERNAL;
gint32* mono_allocate_stack_slots (MonoCompile *cfg, guint32 *stack_size, guint32 *stack_align) MONO_INTERNAL;
void mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb) MONO_INTERNAL;
void mono_decompose_long_opts (MonoCompile *cfg) MONO_INTERNAL;
void mono_decompose_vtype_opts (MonoCompile *cfg) MONO_INTERNAL;
void mono_decompose_array_access_opts (MonoCompile *cfg) MONO_INTERNAL;
-void mono_handle_soft_float (MonoCompile *cfg) MONO_INTERNAL;
+void mono_decompose_soft_float (MonoCompile *cfg) MONO_INTERNAL;
void mono_handle_global_vregs (MonoCompile *cfg) MONO_INTERNAL;
void mono_spill_global_vars (MonoCompile *cfg, gboolean *need_local_opts) MONO_INTERNAL;
void mono_if_conversion (MonoCompile *cfg) MONO_INTERNAL;
guchar* mono_arch_create_trampoline_code (MonoTrampolineType tramp_type) MONO_INTERNAL;
guchar* mono_arch_create_trampoline_code_full (MonoTrampolineType tramp_type, guint32 *code_size, MonoJumpInfo **ji, gboolean aot) MONO_INTERNAL;
gpointer mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot) MONO_INTERNAL;
-guint32 mono_arch_get_rgctx_lazy_fetch_offset (gpointer *regs) MONO_INTERNAL;
+gpointer mono_arch_create_rgctx_lazy_fetch_trampoline_full (guint32 slot, guint32 *code_size, MonoJumpInfo **ji, gboolean aot) MONO_INTERNAL;
+gpointer mono_arch_create_generic_class_init_trampoline (void) MONO_INTERNAL;
gpointer mono_arch_get_nullified_class_init_trampoline (guint32 *code_len) MONO_INTERNAL;
GList *mono_arch_get_allocatable_int_vars (MonoCompile *cfg) MONO_INTERNAL;
GList *mono_arch_get_global_int_regs (MonoCompile *cfg) MONO_INTERNAL;
gpointer mono_arch_get_throw_corlib_exception_full (guint32 *code_size, MonoJumpInfo **ji, gboolean aot) MONO_INTERNAL;
gboolean mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only) MONO_INTERNAL;
void mono_arch_handle_altstack_exception (void *sigctx, gpointer fault_addr, gboolean stack_ovf) MONO_INTERNAL;
+gboolean mono_handle_soft_stack_ovf (MonoJitTlsData *jit_tls, MonoJitInfo *ji, void *ctx, guint8* fault_addr) MONO_INTERNAL;
gpointer mono_arch_ip_from_context (void *sigctx) MONO_INTERNAL;
void mono_arch_sigctx_to_monoctx (void *sigctx, MonoContext *ctx) MONO_INTERNAL;
void mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *ctx) MONO_INTERNAL;
MonoObject* mono_arch_find_this_argument (gpointer *regs, MonoMethod *method, MonoGenericSharingContext *gsctx) MONO_INTERNAL;
gpointer mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_target) MONO_INTERNAL;
gpointer mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len) MONO_INTERNAL;
-void mono_arch_emit_imt_argument (MonoCompile *cfg, MonoCallInst *call) MONO_INTERNAL;
+void mono_arch_emit_imt_argument (MonoCompile *cfg, MonoCallInst *call, MonoInst *imt_arg) MONO_INTERNAL;
MonoMethod* mono_arch_find_imt_method (gpointer *regs, guint8 *code) MONO_INTERNAL;
MonoVTable* mono_arch_find_static_call_vtable (gpointer *regs, guint8 *code) MONO_INTERNAL;
-gpointer mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckItem **imt_entries, int count) MONO_INTERNAL;
+gpointer mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckItem **imt_entries, int count, gpointer fail_tramp) MONO_INTERNAL;
void mono_arch_notify_pending_exc (void) MONO_INTERNAL;
void mono_arch_fixup_jinfo (MonoCompile *cfg) MONO_INTERNAL;
void mono_jit_walk_stack_from_ctx (MonoStackWalk func, MonoContext *ctx, gboolean do_il_offset, gpointer user_data) MONO_INTERNAL;
void mono_setup_altstack (MonoJitTlsData *tls) MONO_INTERNAL;
void mono_free_altstack (MonoJitTlsData *tls) MONO_INTERNAL;
+gpointer mono_altstack_restore_prot (gssize *regs, guint8 *code, gpointer *tramp_data, guint8* tramp) MONO_INTERNAL;
+
MonoJitInfo * mono_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) MONO_INTERNAL;
gpointer mono_get_throw_exception (void) MONO_INTERNAL;
gboolean mono_generic_context_equal_deep (MonoGenericContext *context1, MonoGenericContext *context2) MONO_INTERNAL;
-gboolean mono_generic_context_is_sharable (MonoGenericContext *context, gboolean allow_type_vars) MONO_INTERNAL;
-
-gboolean mono_method_is_generic_impl (MonoMethod *method) MONO_INTERNAL;
-gboolean mono_method_is_generic_sharable_impl (MonoMethod *method, gboolean allow_type_vars) MONO_INTERNAL;
-
gpointer mono_helper_get_rgctx_other_ptr (MonoClass *caller_class, MonoVTable *vtable,
guint32 token, guint32 token_source, guint32 rgctx_type,
gint32 rgctx_index) MONO_INTERNAL;
MonoGenericContext* mini_class_get_context (MonoClass *class) MONO_INTERNAL;
MonoType* mini_get_basic_type_from_generic (MonoGenericSharingContext *gsctx, MonoType *type) MONO_INTERNAL;
+MonoType* mini_type_get_underlying_type (MonoGenericSharingContext *gsctx, MonoType *type) MONO_INTERNAL;
int mini_type_stack_size (MonoGenericSharingContext *gsctx, MonoType *t, int *align) MONO_INTERNAL;
+int mini_type_stack_size_full (MonoGenericSharingContext *gsctx, MonoType *t, guint32 *align, gboolean pinvoke) MONO_INTERNAL;
+void type_to_eval_stack_type (MonoCompile *cfg, MonoType *type, MonoInst *inst) MONO_INTERNAL;
+guint mono_type_to_regmove (MonoCompile *cfg, MonoType *type) MONO_INTERNAL;
/* wapihandles.c */
int mini_wapi_hps (int argc, char **argv) MONO_INTERNAL;