-/*
+/**
+ * \file
* Copyright 2002-2003 Ximian Inc
* Copyright 2003-2011 Novell Inc
* Copyright 2011 Xamarin Inc
#include "mono/metadata/security-manager.h"
#include "mono/metadata/exception.h"
-#ifdef __native_client_codegen__
-#include <nacl/nacl_dyncode.h>
-#endif
-
-
/*
* The mini code should not have any compile time dependencies on the GC being used, so the same object file from mini/
* can be linked into both mono and mono-sgen.
#endif
/* Version number of the AOT file format */
-#define MONO_AOT_FILE_VERSION 139
+#define MONO_AOT_FILE_VERSION 141
//TODO: This is x86/amd64 specific.
#define mono_simd_shuffle_mask(a,b,c,d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6))
/* Remap printf to g_print (we use a mix of these in the mini code) */
-#ifdef PLATFORM_ANDROID
+#ifdef HOST_ANDROID
#define printf g_print
#endif
gpointer llvm_module;
/* Maps MonoMethod -> GSlist of addresses */
GHashTable *llvm_jit_callees;
+ /* Maps MonoMethod -> RuntimeMethod */
+ MonoInternalHashTable interp_code_hash;
} MonoJitDomainInfo;
typedef struct {
extern int mono_break_at_bb_bb_num;
extern gboolean mono_verify_all;
extern gboolean mono_do_x86_stack_align;
-extern const char *mono_build_date;
+extern MONO_API const char *mono_build_date;
extern gboolean mono_do_signal_chaining;
extern gboolean mono_do_crash_chaining;
extern MONO_API gboolean mono_use_llvm;
#define mono_bb_first_ins(bb) (bb)->code
+/*
+ * Iterate through all used registers in the instruction.
+ * Relies on the existing order of the MONO_INST enum: MONO_INST_{DREG,SREG1,SREG2,SREG3,LEN}
+ * INS is the instruction, IDX is the register index, REG is the pointer to a register.
+ */
+#define MONO_INS_FOR_EACH_REG(ins, idx, reg) for ((idx) = INS_INFO ((ins)->opcode)[MONO_INST_DEST] != ' ' ? MONO_INST_DEST : \
+ (mono_inst_get_num_src_registers (ins) ? MONO_INST_SRC1 : MONO_INST_LEN); \
+ (reg) = (idx) == MONO_INST_DEST ? &(ins)->dreg : \
+ ((idx) == MONO_INST_SRC1 ? &(ins)->sreg1 : \
+ ((idx) == MONO_INST_SRC2 ? &(ins)->sreg2 : \
+ ((idx) == MONO_INST_SRC3 ? &(ins)->sreg3 : NULL))), \
+ idx < MONO_INST_LEN; \
+ (idx) = (idx) > mono_inst_get_num_src_registers (ins) + (INS_INFO ((ins)->opcode)[MONO_INST_DEST] != ' ') ? MONO_INST_LEN : (idx) + 1)
+
struct MonoSpillInfo {
int offset;
};
/* List of call sites in this bblock sorted by pc_offset */
GSList *gc_callsites;
+ /* If this is not null, the basic block is a try hole for this clause */
+ MonoExceptionClause *clause_hole;
+
/*
* The region encodes whether the basic block is inside
* a finally, catch, filter or none of these.
typedef struct {
gpointer end_of_stack;
guint32 stack_size;
- /* !defined(HAVE_KW_THREAD) || !defined(MONO_ARCH_ENABLE_MONO_LMF_VAR) */
MonoLMF *lmf;
MonoLMF *first_lmf;
gpointer restore_stack_prot;
MonoContext ex_ctx;
ResumeState resume_state;
- /*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. 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;
* the catch block that caught the ThreadAbortException).
*/
gpointer abort_exc_stack_threshold;
+
+ /*
+ * List of methods being JIT'd in the current thread.
+ */
+ int active_jit_methods;
+
+ gpointer interp_context;
+
+#if defined(TARGET_WIN32)
+ MonoContext stack_restore_ctx;
+#endif
} MonoJitTlsData;
/*
typedef struct {
struct MonoLMF lmf;
gboolean debugger_invoke;
+ gboolean interp_exit;
MonoContext ctx; /* if debugger_invoke is TRUE */
+ /* If interp_exit is TRUE */
+ gpointer interp_exit_data;
} MonoLMFExt;
/* Generic sharing */
* which implements the method.
*/
MONO_RGCTX_INFO_VIRT_METHOD_BOX_TYPE,
+ /* Resolve to 2 (TRUE) or 1 (FALSE) */
+ MONO_RGCTX_INFO_CLASS_IS_REF_OR_CONTAINS_REFS
} MonoRgctxInfoType;
typedef struct _MonoRuntimeGenericContextInfoTemplate {
MONO_TRAMPOLINE_RESTORE_STACK_PROT,
MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING,
MONO_TRAMPOLINE_VCALL,
- MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD,
MONO_TRAMPOLINE_NUM
} MonoTrampolineType;
/* These trampolines receive an argument directly in a register */
#define MONO_TRAMPOLINE_TYPE_HAS_ARG(t) \
- ((t) == MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD)
+ (FALSE)
/* optimization flags */
#define OPTFLAG(id,shift,name,descr) MONO_OPT_ ## id = 1 << shift,
/* A hashtable of region ID-> SP var mappings */
/* An SP var is a place to store the stack pointer (used by handlers)*/
+ /*
+ * FIXME We can potentially get rid of this, since it was mainly used
+ * for hijacking return address for handler.
+ */
GHashTable *spvars;
- /* A hashtable of region ID -> EX var mappings */
- /* An EX var stores the exception object passed to catch/filter blocks */
+ /*
+ * A hashtable of region ID -> EX var mappings
+ * An EX var stores the exception object passed to catch/filter blocks
+ * For finally blocks, it is set to TRUE if we should throw an abort
+ * once the execution of the finally block is over.
+ */
GHashTable *exvars;
GList *ldstr_list; /* used by AOT */
MonoInst *stack_inbalance_var;
unsigned char *cil_start;
-#ifdef __native_client_codegen__
- /* this alloc is not aligned, native_code */
- /* is the 32-byte aligned version of this */
- unsigned char *native_code_alloc;
-#endif
unsigned char *native_code;
guint code_size;
guint code_len;
guint epilog_end;
regmask_t used_int_regs;
guint32 opt;
- guint32 prof_options;
guint32 flags;
guint32 comp_done;
guint32 verbose_level;
* Whenever to use the mono_lmf TLS variable instead of indirection through the
* mono_lmf_addr TLS variable.
*/
- guint lmf_ir_mono_lmf : 1;
guint gen_write_barriers : 1;
guint init_ref_vars : 1;
guint extend_live_ranges : 1;
gpointer debug_info;
guint32 lmf_offset;
guint16 *intvars;
- MonoProfileCoverageInfo *coverage_info;
+ MonoProfilerCoverageInfo *coverage_info;
GHashTable *token_info_hash;
MonoCompileArch arch;
guint32 inline_depth;
int stat_inlineable_methods;
int stat_inlined_methods;
int stat_code_reallocs;
+
+ MonoProfilerCallInstrumentationFlags prof_flags;
} MonoCompile;
+#define MONO_CFG_PROFILE(cfg, flag) \
+ G_UNLIKELY ((cfg)->prof_flags & MONO_PROFILER_CALL_INSTRUMENTATION_ ## flag)
+
+#define MONO_CFG_PROFILE_CALL_CONTEXT(cfg) \
+ (MONO_CFG_PROFILE (cfg, ENTER_CONTEXT) || MONO_CFG_PROFILE (cfg, LEAVE_CONTEXT))
+
typedef enum {
MONO_CFG_HAS_ALLOCA = 1 << 0,
MONO_CFG_HAS_CALLS = 1 << 1,
gint32 loads_eliminated;
gint32 stores_eliminated;
gint32 optimized_divisions;
- int methods_with_llvm;
- int methods_without_llvm;
+ gint32 methods_with_llvm;
+ gint32 methods_without_llvm;
char *max_ratio_method;
char *biggest_method;
- double jit_method_to_ir;
- double jit_liveness_handle_exception_clauses;
- double jit_handle_out_of_line_bblock;
- double jit_decompose_long_opts;
- double jit_decompose_typechecks;
- double jit_local_cprop;
- double jit_local_emulate_ops;
- double jit_optimize_branches;
- double jit_handle_global_vregs;
- double jit_local_deadce;
- double jit_local_alias_analysis;
- double jit_if_conversion;
- double jit_bb_ordering;
- double jit_compile_dominator_info;
- double jit_compute_natural_loops;
- double jit_insert_safepoints;
- double jit_ssa_compute;
- double jit_ssa_cprop;
- double jit_ssa_deadce;
- double jit_perform_abc_removal;
- double jit_ssa_remove;
- double jit_local_cprop2;
- double jit_handle_global_vregs2;
- double jit_local_deadce2;
- double jit_optimize_branches2;
- double jit_decompose_vtype_opts;
- double jit_decompose_array_access_opts;
- double jit_liveness_handle_exception_clauses2;
- double jit_analyze_liveness;
- double jit_linear_scan;
- double jit_arch_allocate_vars;
- double jit_spill_global_vars;
- double jit_local_cprop3;
- double jit_local_deadce3;
- double jit_codegen;
- double jit_create_jit_info;
- double jit_gc_create_gc_map;
- double jit_save_seq_point_info;
- double jit_time;
+ gdouble jit_method_to_ir;
+ gdouble jit_liveness_handle_exception_clauses;
+ gdouble jit_handle_out_of_line_bblock;
+ gdouble jit_decompose_long_opts;
+ gdouble jit_decompose_typechecks;
+ gdouble jit_local_cprop;
+ gdouble jit_local_emulate_ops;
+ gdouble jit_optimize_branches;
+ gdouble jit_handle_global_vregs;
+ gdouble jit_local_deadce;
+ gdouble jit_local_alias_analysis;
+ gdouble jit_if_conversion;
+ gdouble jit_bb_ordering;
+ gdouble jit_compile_dominator_info;
+ gdouble jit_compute_natural_loops;
+ gdouble jit_insert_safepoints;
+ gdouble jit_ssa_compute;
+ gdouble jit_ssa_cprop;
+ gdouble jit_ssa_deadce;
+ gdouble jit_perform_abc_removal;
+ gdouble jit_ssa_remove;
+ gdouble jit_local_cprop2;
+ gdouble jit_handle_global_vregs2;
+ gdouble jit_local_deadce2;
+ gdouble jit_optimize_branches2;
+ gdouble jit_decompose_vtype_opts;
+ gdouble jit_decompose_array_access_opts;
+ gdouble jit_liveness_handle_exception_clauses2;
+ gdouble jit_analyze_liveness;
+ gdouble jit_linear_scan;
+ gdouble jit_arch_allocate_vars;
+ gdouble jit_spill_global_vars;
+ gdouble jit_local_cprop3;
+ gdouble jit_local_deadce3;
+ gdouble jit_codegen;
+ gdouble jit_create_jit_info;
+ gdouble jit_gc_create_gc_map;
+ gdouble jit_save_seq_point_info;
+ gdouble jit_time;
gboolean enabled;
} MonoJitStats;
*/
guint8 *uw_info;
guint32 uw_info_len;
+ /* Whenever uw_info is owned by this structure */
+ gboolean owns_uw_info;
} MonoTrampInfo;
typedef void (*MonoInstFunc) (MonoInst *tree, gpointer data);
void mini_cleanup (MonoDomain *domain);
MONO_API MonoDebugOptions *mini_get_debug_options (void);
MONO_API gboolean mini_parse_debug_option (const char *option);
-void mini_profiler_enable_with_options (const char *profile_options);
+
+/* profiler support */
+void mini_add_profiler_argument (const char *desc);
+void mini_profiler_emit_enter (MonoCompile *cfg);
+void mini_profiler_emit_leave (MonoCompile *cfg, MonoInst *ret);
+void mini_profiler_emit_tail_call (MonoCompile *cfg, MonoMethod *target);
+void mini_profiler_context_enable (void);
+gpointer mini_profiler_context_get_this (MonoProfilerCallContext *ctx);
+gpointer mini_profiler_context_get_argument (MonoProfilerCallContext *ctx, guint32 pos);
+gpointer mini_profiler_context_get_local (MonoProfilerCallContext *ctx, guint32 pos);
+gpointer mini_profiler_context_get_result (MonoProfilerCallContext *ctx);
+void mini_profiler_context_free_buffer (gpointer buffer);
/* graph dumping */
void mono_cfg_dump_create_context (MonoCompile *cfg);
MONO_API void mono_print_method_from_ip (void *ip);
MONO_API char *mono_pmip (void *ip);
gboolean mono_debug_count (void);
-MONO_API const char* mono_inst_name (int op);
+MONO_LLVM_INTERNAL const char* mono_inst_name (int op);
int mono_op_to_op_imm (int opcode);
int mono_op_imm_to_op (int opcode);
int mono_load_membase_to_load_mem (int opcode);
gpointer mono_jit_find_compiled_method_with_jit_info (MonoDomain *domain, MonoMethod *method, MonoJitInfo **ji);
gpointer mono_jit_find_compiled_method (MonoDomain *domain, MonoMethod *method);
gpointer mono_jit_compile_method (MonoMethod *method, MonoError *error);
+gpointer mono_jit_compile_method_jit_only (MonoMethod *method, MonoError *error);
gpointer mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, int opt, MonoError *error);
MonoLMF * mono_get_lmf (void);
MonoLMF** mono_get_lmf_addr (void);
void mono_set_lmf (MonoLMF *lmf);
+void mono_push_lmf (MonoLMFExt *ext);
+void mono_pop_lmf (MonoLMF *lmf);
MonoJitTlsData* mono_get_jit_tls (void);
MONO_API MonoDomain* mono_jit_thread_attach (MonoDomain *domain);
MONO_API void mono_jit_set_domain (MonoDomain *domain);
MonoInst* mono_emit_jit_icall_by_info (MonoCompile *cfg, int il_offset, MonoJitICallInfo *info, MonoInst **args);
MonoInst* mono_emit_method_call (MonoCompile *cfg, MonoMethod *method, MonoInst **args, MonoInst *this_ins);
void mono_create_helper_signatures (void);
+MonoInst* mono_emit_native_call (MonoCompile *cfg, gconstpointer func, MonoMethodSignature *sig, MonoInst **args);
+gboolean mini_should_insert_breakpoint (MonoMethod *method);
gboolean mini_class_is_system_array (MonoClass *klass);
MonoMethodSignature *mono_get_element_address_signature (int arity);
/* Native Client functions */
gpointer mono_realloc_native_code(MonoCompile *cfg);
-#if defined(__native_client__) || defined(__native_client_codegen__)
-extern volatile int __nacl_thread_suspension_needed;
-void __nacl_suspend_thread_if_needed(void);
-void mono_nacl_gc(void);
-#endif
-
extern MonoDebugOptions debug_options;
static inline MonoMethod*
void mono_add_ins_to_end (MonoBasicBlock *bb, MonoInst *inst);
gpointer mono_create_ftnptr (MonoDomain *domain, gpointer addr);
-MONO_API void mono_replace_ins (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins, MonoInst **prev, MonoBasicBlock *first_bb, MonoBasicBlock *last_bb);
+void mono_replace_ins (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins, MonoInst **prev, MonoBasicBlock *first_bb, MonoBasicBlock *last_bb);
int mono_find_method_opcode (MonoMethod *method);
MonoJitICallInfo *mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save);
void mono_remove_critical_edges (MonoCompile *cfg);
gboolean mono_is_regsize_var (MonoType *t);
void mini_emit_memcpy (MonoCompile *cfg, int destreg, int doffset, int srcreg, int soffset, int size, int align);
+void mini_emit_memset (MonoCompile *cfg, int destreg, int offset, int size, int val, int align);
void mini_emit_stobj (MonoCompile *cfg, MonoInst *dest, MonoInst *src, MonoClass *klass, gboolean native);
void mini_emit_initobj (MonoCompile *cfg, MonoInst *dest, const guchar *ip, MonoClass *klass);
MonoInst* mini_emit_ldelema_1_ins (MonoCompile *cfg, MonoClass *klass, MonoInst *arr, MonoInst *index, gboolean bcheck);
+MonoInst* mini_emit_get_gsharedvt_info_klass (MonoCompile *cfg, MonoClass *klass, MonoRgctxInfoType rgctx_type);
+MonoInst* mini_emit_calli (MonoCompile *cfg, MonoMethodSignature *sig, MonoInst **args, MonoInst *addr, MonoInst *imt_arg, MonoInst *rgctx_arg);
+MonoInst* mini_emit_memory_barrier (MonoCompile *cfg, int kind);
+void mini_emit_write_barrier (MonoCompile *cfg, MonoInst *ptr, MonoInst *value);
+MonoInst* mini_emit_memory_load (MonoCompile *cfg, MonoType *type, MonoInst *src, int offset, int ins_flag);
+void mini_emit_memory_store (MonoCompile *cfg, MonoType *type, MonoInst *dest, MonoInst *value, int ins_flag);
+void mini_emit_memory_copy_bytes (MonoCompile *cfg, MonoInst *dest, MonoInst *src, MonoInst *size, int ins_flag);
+void mini_emit_memory_init_bytes (MonoCompile *cfg, MonoInst *dest, MonoInst *value, MonoInst *size, int ins_flag);
+void mini_emit_memory_copy (MonoCompile *cfg, MonoInst *dest, MonoInst *src, MonoClass *klass, gboolean native, int ins_flag);
+
+MonoMethod* mini_get_memcpy_method (void);
+MonoMethod* mini_get_memset_method (void);
+int mini_class_check_context_used (MonoCompile *cfg, MonoClass *klass);
+
+
CompRelation mono_opcode_to_cond (int opcode) MONO_LLVM_INTERNAL;
CompType mono_opcode_to_type (int opcode, int cmp_opcode);
CompRelation mono_negate_cond (CompRelation cond);
int val);
MonoTrampInfo* mono_tramp_info_create (const char *name, guint8 *code, guint32 code_size, MonoJumpInfo *ji, GSList *unwind_ops);
void mono_tramp_info_free (MonoTrampInfo *info);
+void mono_aot_tramp_info_register (MonoTrampInfo *info, MonoDomain *domain);
void mono_tramp_info_register (MonoTrampInfo *info, MonoDomain *domain);
int mini_exception_id_by_name (const char *name);
gboolean mini_type_is_hfa (MonoType *t, int *out_nfields, int *out_esize) MONO_LLVM_INTERNAL;
void mono_arch_fill_argument_info (MonoCompile *cfg);
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);
void mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call);
void mono_arch_emit_outarg_vt (MonoCompile *cfg, MonoInst *ins, MonoInst *src);
void mono_arch_emit_setret (MonoCompile *cfg, MonoMethod *method, MonoInst *val);
MonoDynCallInfo *mono_arch_dyn_call_prepare (MonoMethodSignature *sig);
void mono_arch_dyn_call_free (MonoDynCallInfo *info);
-void mono_arch_start_dyn_call (MonoDynCallInfo *info, gpointer **args, guint8 *ret, guint8 *buf, int buf_len);
+int mono_arch_dyn_call_get_buf_size (MonoDynCallInfo *info);
+void mono_arch_start_dyn_call (MonoDynCallInfo *info, gpointer **args, guint8 *ret, guint8 *buf);
void mono_arch_finish_dyn_call (MonoDynCallInfo *info, guint8 *buf);
MonoInst *mono_arch_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args);
void mono_arch_decompose_opts (MonoCompile *cfg, MonoInst *ins);
void mono_arch_skip_breakpoint (MonoContext *ctx, MonoJitInfo *ji);
void mono_arch_skip_single_step (MonoContext *ctx);
gpointer mono_arch_get_seq_point_info (MonoDomain *domain, guint8 *code);
+#endif
+
+#ifdef MONO_ARCH_HAVE_INIT_LMF_EXT
void mono_arch_init_lmf_ext (MonoLMFExt *ext, gpointer prev_lmf);
#endif
void mono_arch_save_unwind_info (MonoCompile *cfg);
void mono_arch_register_lowlevel_calls (void);
gpointer mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr);
-gpointer mono_arch_get_static_rgctx_trampoline (MonoMethod *m, MonoMethodRuntimeGenericContext *mrgctx, gpointer addr);
+gpointer mono_arch_get_static_rgctx_trampoline (gpointer arg, gpointer addr);
gpointer mono_arch_get_llvm_imt_trampoline (MonoDomain *domain, MonoMethod *method, int vt_offset);
gpointer mono_arch_get_gsharedvt_arg_trampoline (MonoDomain *domain, gpointer arg, gpointer addr);
void mono_arch_patch_callsite (guint8 *method_start, guint8 *code, guint8 *addr);
GSList *mono_arch_get_trampolines (gboolean aot);
gpointer mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info);
-/* Handle block guard */
-gpointer mono_arch_install_handler_block_guard (MonoJitInfo *ji, MonoJitExceptionInfo *clause, MonoContext *ctx, gpointer new_value);
-gpointer mono_arch_create_handler_block_trampoline (MonoTrampInfo **info, gboolean aot);
-gpointer mono_create_handler_block_trampoline (void);
-gboolean mono_install_handler_block_guard (MonoThreadUnwindState *ctx);
-
/*New interruption machinery */
void
mono_setup_async_callback (MonoContext *ctx, void (*async_cb)(void *fun), gpointer user_data);
MonoObject *mono_llvm_load_exception (void);
void mono_llvm_reset_exception (void);
void mono_llvm_raise_exception (MonoException *e);
+void mono_llvm_reraise_exception (MonoException *e);
gint32 mono_llvm_match_exception (MonoJitInfo *jinfo, guint32 region_start, guint32 region_end, gpointer rgctx, MonoObject *this_obj);
gboolean
MonoType* mini_get_underlying_type (MonoType *type) MONO_LLVM_INTERNAL;
MonoType* mini_type_get_underlying_type (MonoType *type);
+MonoClass* mini_get_class (MonoMethod *method, guint32 token, MonoGenericContext *context);
MonoMethod* mini_get_shared_method (MonoMethod *method);
MonoMethod* mini_get_shared_method_to_register (MonoMethod *method);
MonoMethod* mini_get_shared_method_full (MonoMethod *method, gboolean all_vt, gboolean is_gsharedvt);
}
GTimer *mono_time_track_start (void);
-void mono_time_track_end (double *time, GTimer *timer);
+void mono_time_track_end (gdouble *time, GTimer *timer);
void mono_update_jit_stats (MonoCompile *cfg);
MonoMethod* mini_get_gsharedvt_out_sig_wrapper (MonoMethodSignature *sig);
MonoMethodSignature* mini_get_gsharedvt_out_sig_wrapper_signature (gboolean has_this, gboolean has_ret, int param_count);
gboolean mini_gsharedvt_runtime_invoke_supported (MonoMethodSignature *sig);
+MonoMethod* mini_get_interp_in_wrapper (MonoMethodSignature *sig);
/* SIMD support */
guint32 mono_arch_cpu_enumerate_simd_versions (void);
void mono_simd_intrinsics_init (void);
+gboolean mono_class_is_magic_int (MonoClass *klass);
+gboolean mono_class_is_magic_float (MonoClass *klass);
MonoInst* mono_emit_native_types_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args);
MonoType* mini_native_type_replace_type (MonoType *type) MONO_LLVM_INTERNAL;
*/
void mono_interruption_checkpoint_from_trampoline (void);
+
+#if defined (HOST_WASM)
+
+#define RETURN_ADDRESS_N(N) NULL
+#define RETURN_ADDRESS() RETURN_ADDRESS_N(0)
+
+
+#elif defined (__GNUC__)
+
+#define RETURN_ADDRESS_N(N) (__builtin_extract_return_addr (__builtin_return_address (N)))
+#define RETURN_ADDRESS() RETURN_ADDRESS_N(0)
+
+#elif defined(_MSC_VER)
+
+#include <intrin.h>
+#pragma intrinsic(_ReturnAddress)
+
+#define RETURN_ADDRESS() _ReturnAddress()
+#define RETURN_ADDRESS_N(N) NULL
+
+#else
+
+#error "Missing return address intrinsics implementation"
+
+#endif
+
+
#endif /* __MONO_MINI_H__ */