platform_ios=yes
has_dtrace=no
;;
+ aarch64*-darwin20*)
+ # OSX/arm64
+ support_boehm=no
+ ;;
aarch64*-darwin*)
platform_ios=yes
;;
CFLAGS="$CFLAGS -DDISABLE_CRASH_REPORTING=1"
CXXFLAGS="$CXXFLAGS -DDISABLE_CRASH_REPORTING=1"
fi
+AM_CONDITIONAL(DISABLE_CRASH_REPORTING, test x$crash_reporting != xyes)
AC_ARG_ENABLE(monodroid, [ --enable-monodroid Enable runtime support for Monodroid (Xamarin.Android)], enable_monodroid=$enableval, enable_monodroid=no)
AM_CONDITIONAL(ENABLE_MONODROID, test x$enable_monodroid = xyes)
AC_CHECK_HEADERS(pthread_np.h)
AC_CHECK_FUNCS(pthread_mutex_timedlock)
AC_CHECK_FUNCS(pthread_getattr_np pthread_attr_get_np pthread_getname_np pthread_setname_np pthread_cond_timedwait_relative_np)
- AC_CHECK_FUNCS(pthread_kill)
+ AC_CHECK_FUNCS(pthread_kill pthread_jit_write_protect_np)
AC_MSG_CHECKING(for PTHREAD_MUTEX_RECURSIVE)
AC_TRY_COMPILE([ #include <pthread.h>], [
pthread_mutexattr_t attr;
sizeof_register=8
AC_DEFINE(TARGET_WATCHOS, 1, [...])
;;
+ aarch64*darwin*)
+ TARGET=ARM64
+ # Both ios and osx/arm64 have the same aarc64-darwin triple,
+ # assume ios for now when cross compiling
+ TARGET_SYS=IOS
+ ;;
aarch64-*)
TARGET=ARM64
;;
CPPFLAGS_FOR_LIBGC="$CPPFLAGS_FOR_LIBGC -DTARGET_WATCHOS"
CFLAGS_FOR_LIBGC="$CFLAGS_FOR_LIBGC -DTARGET_WATCHOS"
BTLS_SUPPORTED=no
- elif test "x$TARGET" = "xARM" -o "x$TARGET" = "xARM64" -o "x$TARGET" = "xARM6432"; then
+ elif test "x$TARGET_SYS" = "xIOS" -o "x$TARGET" = "xARM" -o "x$TARGET" = "xARM6432"; then
AC_DEFINE(TARGET_IOS,1,[The JIT/AOT targets iOS])
CPPFLAGS_FOR_LIBGC="$CPPFLAGS_FOR_LIBGC -DTARGET_IOS"
CFLAGS_FOR_LIBGC="$CFLAGS_FOR_LIBGC -DTARGET_IOS"
CPPFLAGS_FOR_LIBGC="$CPPFLAGS_FOR_LIBGC -DTARGET_OSX"
CFLAGS_FOR_LIBGC="$CFLAGS_FOR_LIBGC -DTARGET_OSX"
target_osx=yes
+ if test "x$TARGET" = "xARM64"; then
+ BTLS_SUPPORTED=no
+ fi
], [
AC_DEFINE(TARGET_IOS,1,[The JIT/AOT targets iOS])
CPPFLAGS_FOR_LIBGC="$CPPFLAGS_FOR_LIBGC -DTARGET_IOS"
MAKEFLAGS := $(MAKEFLAGS) --no-builtin-rules
EXTRA_DIST = arm64-codegen.h codegen-test.c
+
+test-codegen:
+ $(CC) $(CFLAGS) -I../../.. -I../../eglib/ ../../eglib/.libs/libeglib.a -o codegen-test codegen-test.c
+ ./codegen-test > tmp.s
+ $(CC) $(CFLAGS) -c -o tmp.o tmp.s
+ objdump -d --triple=arm64e tmp.o
#define arm_cmpp arm_cmpx
#endif
+/* ARM v8.3 */
+
+/* PACIA */
+
+#define arm_format_pacia(p, crm, op2) arm_emit ((p), (0b11010101000000110010000000011111 << 0) | ((crm) << 8) | ((op2) << 5))
+#define arm_paciasp(p) arm_format_pacia ((p), 0b0011, 0b001)
+
+/* PACIB */
+
+#define arm_format_pacib(p, crm, op2) arm_emit ((p), (0b11010101000000110010000000011111 << 0) | ((crm) << 8) | ((op2) << 5))
+#define arm_pacibsp(p) arm_format_pacib ((p), 0b0011, 0b011)
+
+/* RETA */
+#define arm_format_reta(p,key) arm_emit ((p), 0b11010110010111110000101111111111 + ((key) << 10))
+
+#define arm_retaa(p) arm_format_reta ((p),0)
+#define arm_retab(p) arm_format_reta ((p),1)
+
+/* BRA */
+
+#define arm_format_bra(p, z, m, rn, rm) arm_emit ((p), (0b1101011000011111000010 << 10) + ((z) << 24) + ((m) << 10) + ((rn) << 5) + ((rm) << 0))
+
+#define arm_braaz(p, rn) arm_format_bra ((p), 0, 0, (rn), 0b11111)
+#define arm_brabz(p, rn) arm_format_bra ((p), 0, 1, (rn), 0b11111)
+#define arm_braa(p, rn, rm) arm_format_bra ((p), 1, 0, (rn), (rm))
+#define arm_brab(p, rn, rm) arm_format_bra ((p), 1, 1, (rn), (rm))
+
+/* BLRA */
+
+#define arm_format_blra(p, z, m, rn, rm) arm_emit ((p), (0b1101011000111111000010 << 10) + ((z) << 24) + ((m) << 10) + ((rn) << 5) + ((rm) << 0))
+
+#define arm_blraaz(p, rn) arm_format_blra ((p), 0, 0, (rn), 0b11111)
+#define arm_blraa(p, rn, rm) arm_format_blra ((p), 1, 0, (rn), (rm))
+#define arm_blrabz(p, rn) arm_format_blra ((p), 0, 1, (rn), 0b11111)
+#define arm_blrab(p, rn, rm) arm_format_blra ((p), 1, 1, (rn), (rm))
+
#endif /* __arm_CODEGEN_H__ */
arm_stlxrx (code, ARMREG_R0, ARMREG_R1, ARMREG_R2);
arm_stlxrw (code, ARMREG_R0, ARMREG_R1, ARMREG_R2);
+ arm_paciasp (code);
+ arm_pacibsp (code);
+ arm_retaa (code);
+ arm_retab (code);
+ arm_braaz (code, ARMREG_R1);
+ arm_brabz (code, ARMREG_R1);
+ arm_braa (code, ARMREG_R1, ARMREG_R2);
+ arm_brab (code, ARMREG_R1, ARMREG_R2);
+ arm_blraaz (code, ARMREG_R1);
+ arm_blraa (code, ARMREG_R1, ARMREG_R2);
+ arm_blrabz (code, ARMREG_R1);
+ arm_blrab (code, ARMREG_R1, ARMREG_R2);
+
for (i = 0; i < code - buf; ++i)
printf (".byte %d\n", buf [i]);
printf ("\n");
#define g_set_printerr_handler monoeg_set_printerr_handler
#define g_size_to_int monoeg_size_to_int
+#define g_ascii_charcmp monoeg_ascii_charcmp
+#define g_ascii_charcasecmp monoeg_ascii_charcasecmp
+#define g_warning_d monoeg_warning_d
#elif defined(TARGET_AMD64) && defined(TARGET_MACH)
#define LD_NAME "clang"
#define LD_OPTIONS "--shared"
+#elif defined(TARGET_ARM64) && defined(TARGET_OSX)
+#define LD_NAME "clang"
+#define LD_OPTIONS "--shared"
#elif defined(TARGET_WIN32_MSVC)
#define LD_NAME "link.exe"
#define LD_OPTIONS "/DLL /MACHINE:X64 /NOLOGO /INCREMENTAL:NO"
size = 256;
code = start = mono_global_codeman_reserve (size);
+ MINI_BEGIN_CODEGEN ();
+
arm_movx (code, ARMREG_IP0, ARMREG_R0);
ctx_reg = ARMREG_IP0;
arm_brk (code, 0);
g_assert ((code - start) < size);
- mono_arch_flush_icache (start, code - start);
- MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL));
+
+ MINI_END_CODEGEN (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL);
if (info)
*info = mono_tramp_info_create ("restore_context", start, code - start, ji, unwind_ops);
* returning the value returned by the call.
*/
+ MINI_BEGIN_CODEGEN ();
+
/* Setup a frame */
arm_stpx_pre (code, ARMREG_FP, ARMREG_LR, ARMREG_SP, -frame_size);
arm_movspx (code, ARMREG_FP, ARMREG_SP);
arm_retx (code, ARMREG_LR);
g_assert ((code - start) < size);
- mono_arch_flush_icache (start, code - start);
- MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL));
+
+ MINI_END_CODEGEN (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL);
if (info)
*info = mono_tramp_info_create ("call_filter", start, code - start, ji, unwind_ops);
offset += num_fregs * 8;
frame_size = ALIGN_TO (offset, MONO_ARCH_FRAME_ALIGNMENT);
+ MINI_BEGIN_CODEGEN ();
+
/* Setup a frame */
arm_stpx_pre (code, ARMREG_FP, ARMREG_LR, ARMREG_SP, -frame_size);
arm_movspx (code, ARMREG_FP, ARMREG_SP);
arm_brk (code, 0x0);
g_assert ((code - start) < size);
- mono_arch_flush_icache (start, code - start);
- MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL));
+
+ MINI_END_CODEGEN (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL);
if (info)
*info = mono_tramp_info_create (tramp_name, start, code - start, ji, unwind_ops);
GSList *tramps, *l;
if (mono_aot_only) {
-
- // FIXME Macroize.
-
tramp = mono_aot_get_trampoline ("llvm_throw_corlib_exception_trampoline");
mono_register_jit_icall_info (&mono_get_jit_icall_info ()->mono_llvm_throw_corlib_exception_trampoline, tramp, "llvm_throw_corlib_exception_trampoline", NULL, TRUE, NULL);
tramp = mono_aot_get_trampoline ("llvm_resume_unwind_trampoline");
mono_register_jit_icall_info (&mono_get_jit_icall_info ()->mono_llvm_resume_unwind_trampoline, tramp, "llvm_resume_unwind_trampoline", NULL, TRUE, NULL);
-
} else {
tramps = mono_arm_get_exception_trampolines (FALSE);
for (l = tramps; l; l = l->next) {
fflush (stdout);
-#if defined(__arm__) || defined(__aarch64__)
+#if (defined(__arm__) || defined(__aarch64__)) && !defined(TARGET_OSX)
/*
* The arm assembler inserts ELF directives instructing objdump to display
* everything as data.
void *sym = nullptr;
auto err = mono_dl_symbol (current, name, &sym);
if (!sym) {
- outs () << "R: " << namestr << "\n";
+ outs () << "R: " << namestr << " " << err << "\n";
}
assert (sym);
return JITSymbol{(uint64_t)(gssize)sym, flags};
{
guint8 *code, *start;
+ MINI_BEGIN_CODEGEN ();
+
if (has_target) {
start = code = mono_global_codeman_reserve (12);
arm_brx (code, ARMREG_IP0);
g_assert ((code - start) <= 12);
-
- mono_arch_flush_icache (start, 12);
- MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE, NULL));
} else {
int size, i;
arm_brx (code, ARMREG_IP0);
g_assert ((code - start) <= size);
-
- mono_arch_flush_icache (start, size);
- MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE, NULL));
}
+ MINI_END_CODEGEN (start, code - start, MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE, NULL);
if (code_size)
*code_size = code - start;
mono_arm_gsharedvt_init ();
-#if defined(TARGET_IOS) || defined(TARGET_WATCHOS)
+#if defined(TARGET_IOS) || defined(TARGET_WATCHOS) || defined(TARGET_OSX)
ios_abi = TRUE;
#endif
}
{
if (cinfo->gr >= PARAM_REGS) {
ainfo->storage = ArgOnStack;
- if (ios_abi) {
+ /*
+ * FIXME: The vararg argument handling code in ves_icall_System_ArgIterator_IntGetNextArg
+ * assumes every argument is allocated to a separate full size stack slot.
+ */
+ if (ios_abi && !cinfo->vararg) {
/* Assume size == align */
} else {
/* Put arguments into 8 byte aligned stack slots */
cinfo->nargs = n;
cinfo->pinvoke = sig->pinvoke;
+ // Constrain this to OSX only for now
+#ifdef TARGET_OSX
+ cinfo->vararg = sig->call_convention == MONO_CALL_VARARG;
+#endif
/* Return value */
add_param (cinfo, &cinfo->ret, sig->ret);
buf = mono_domain_code_reserve (domain, buf_len);
code = buf;
+ MINI_BEGIN_CODEGEN ();
+
/*
* We are called by JITted code, which passes in the IMT argument in
* MONO_ARCH_RGCTX_REG (r27). We need to preserve all caller saved regs
g_assert ((code - buf) <= buf_len);
- mono_arch_flush_icache (buf, code - buf);
- MONO_PROFILER_RAISE (jit_code_buffer, (buf, code - buf, MONO_PROFILER_CODE_BUFFER_IMT_TRAMPOLINE, NULL));
+ MINI_END_CODEGEN (buf, code - buf, MONO_PROFILER_CODE_BUFFER_IMT_TRAMPOLINE, NULL);
return buf;
}
} else {
/* ip points to an ldrx */
code += 4;
+ mono_codeman_enable_write ();
arm_blrx (code, ARMREG_IP0);
+ mono_codeman_disable_write ();
mono_arch_flush_icache (ip, code - ip);
}
}
} else {
/* ip points to an ldrx */
code += 4;
+ mono_codeman_enable_write ();
arm_nop (code);
+ mono_codeman_disable_write ();
mono_arch_flush_icache (ip, code - ip);
}
}
#define MONO_ARCH_FLOAT32_SUPPORTED 1
#define MONO_ARCH_HAVE_INTERP_PINVOKE_TRAMP 1
#define MONO_ARCH_LLVM_TARGET_LAYOUT "e-i64:64-i128:128-n32:64-S128"
+#ifdef TARGET_OSX
+#define MONO_ARCH_FORCE_FLOAT32 1
+#endif
// Does the ABI have a volatile non-parameter register, so tailcall
// can pass context to generics or interfaces?
struct CallInfo {
int nargs;
int gr, fr, stack_usage;
- gboolean pinvoke;
+ gboolean pinvoke, vararg;
ArgInfo ret;
ArgInfo sig_cookie;
ArgInfo args [1];
while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
callee_vars [i ++] = var;
+ mono_codeman_enable_write ();
cfg->native_code = (guint8*)mono_llvm_compile_method (ctx->module->mono_ee, cfg, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
mono_llvm_remove_gc_safepoint_poll (ctx->lmodule);
+ mono_codeman_disable_write ();
if (cfg->verbose_level > 1) {
g_print ("\n*** Optimized LLVM IR for %s ***\n", mono_method_full_name (cfg->method, TRUE));
if (cfg->compile_aot) {
}
}
+ mono_codeman_enable_write ();
for (i = 0; i < patch_info->data.table->table_size; i++) {
jump_table [i] = code + GPOINTER_TO_INT (patch_info->data.table->table [i]);
}
+ mono_codeman_disable_write ();
target = jump_table;
break;
patch_info.type = MONO_PATCH_INFO_METHOD_JUMP;
patch_info.data.method = method;
+ mono_codeman_enable_write ();
+
#ifdef MONO_ARCH_HAVE_PATCH_CODE_NEW
for (tmp = jlist->list; tmp; tmp = tmp->next)
mono_arch_patch_code_new (NULL, domain, (guint8 *)tmp->data, &patch_info, addr);
mono_error_assert_ok (error);
}
#endif
+
+ mono_codeman_disable_write ();
}
}
void mini_register_sigterm_handler (void);
+#define MINI_BEGIN_CODEGEN() do { \
+ mono_codeman_enable_write (); \
+ } while (0)
+
+#define MINI_END_CODEGEN(buf,size,type,arg) do { \
+ mono_codeman_disable_write (); \
+ mono_arch_flush_icache ((buf), (size)); \
+ if ((int)type != -1) \
+ MONO_PROFILER_RAISE (jit_code_buffer, ((buf), (size), (type), (arg))); \
+ } while (0)
+
#endif /* __MONO_MINI_RUNTIME_H__ */
code = (guint8 *)mono_domain_code_reserve (code_domain, cfg->code_size + cfg->thunk_area + unwindlen);
}
+ mono_codeman_enable_write ();
+
if (cfg->thunk_area) {
cfg->thunks_offset = cfg->code_size + unwindlen;
cfg->thunks = code + cfg->thunks_offset;
} else {
mono_domain_code_commit (code_domain, cfg->native_code, cfg->code_size, cfg->code_len);
}
+
+ mono_codeman_disable_write ();
+
MONO_PROFILER_RAISE (jit_code_buffer, (cfg->native_code, cfg->code_len, MONO_PROFILER_CODE_BUFFER_METHOD, cfg->method));
mono_arch_flush_icache (cfg->native_code, cfg->code_len);
#ifdef MONO_ARCH_HAVE_OPTIMIZED_DIV
backend->optimized_div = 1;
#endif
+#ifdef MONO_ARCH_FORCE_FLOAT32
+ backend->force_float32 = 1;
+#endif
}
static gboolean
#ifndef MONO_ARCH_FLOAT32_SUPPORTED
opts &= ~MONO_OPT_FLOAT32;
#endif
+ if (current_backend->force_float32)
+ /* Force float32 mode on newer platforms */
+ opts |= MONO_OPT_FLOAT32;
restart_compile:
if (method_is_gshared) {
guint have_generalized_imt_trampoline : 1;
gboolean have_op_tailcall_membase : 1;
gboolean have_op_tailcall_reg : 1;
- gboolean have_volatile_non_param_register : 1;
+ gboolean have_volatile_non_param_register : 1;
guint gshared_supported : 1;
guint use_fpstack : 1;
guint ilp32 : 1;
guint disable_div_with_mul : 1;
guint explicit_null_checks : 1;
guint optimized_div : 1;
+ guint force_float32 : 1;
int monitor_enter_adjustment;
int dyn_call_param_area;
} MonoBackend;
#pragma warning(disable:4312) // FIXME pointer cast to different size
#endif
-#if defined (HOST_ANDROID) || (defined (TARGET_IOS) && defined (TARGET_IOS))
+#if defined (HOST_ANDROID) || defined (TARGET_IOS)
# undef printf
# define printf(...) g_log("mono", G_LOG_LEVEL_MESSAGE, __VA_ARGS__)
# undef fprintf
#include "mini.h"
#include "mini-arm64.h"
#include "mini-arm64-gsharedvt.h"
+#include "mini-runtime.h"
/*
* GSHAREDVT
*/
buf = code = mono_global_codeman_reserve (buf_len);
+ MINI_BEGIN_CODEGEN ();
+
code = mono_arm_emit_imm64 (code, ARMREG_IP1, (guint64)arg);
code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)addr);
arm_brx (code, ARMREG_IP0);
g_assert ((code - buf) < buf_len);
- mono_arch_flush_icache (buf, code - buf);
+
+ MINI_END_CODEGEN (buf, code - buf, -1, NULL);
return buf;
}
cfa_offset = offset;
+ MINI_BEGIN_CODEGEN ();
+
/* Setup frame */
arm_stpx_pre (code, ARMREG_FP, ARMREG_LR, ARMREG_SP, -cfa_offset);
mono_add_unwind_op_def_cfa (unwind_ops, code, buf, ARMREG_SP, cfa_offset);
if (info)
*info = mono_tramp_info_create ("gsharedvt_trampoline", buf, code - buf, ji, unwind_ops);
- mono_arch_flush_icache (buf, code - buf);
+ MINI_END_CODEGEN (buf, code - buf, -1, NULL);
+
return buf;
}
void
mono_arch_patch_callsite (guint8 *method_start, guint8 *code_ptr, guint8 *addr)
{
+ MINI_BEGIN_CODEGEN ();
mono_arm_patch (code_ptr - 4, addr, MONO_R_ARM64_BL);
- mono_arch_flush_icache (code_ptr - 4, 4);
+ MINI_END_CODEGEN (code_ptr - 4, 4, -1, NULL);
}
void
//offset += 22 * 8;
frame_size = ALIGN_TO (offset, MONO_ARCH_FRAME_ALIGNMENT);
+ MINI_BEGIN_CODEGEN ();
+
/* Setup stack frame */
imm = frame_size;
mono_add_unwind_op_def_cfa (unwind_ops, code, buf, ARMREG_SP, 0);
arm_brx (code, ARMREG_IP0);
g_assert ((code - buf) < buf_len);
- mono_arch_flush_icache (buf, code - buf);
- MONO_PROFILER_RAISE (jit_code_buffer, (buf, code - buf, MONO_PROFILER_CODE_BUFFER_HELPER, NULL));
+
+ MINI_END_CODEGEN (buf, code - buf, MONO_PROFILER_CODE_BUFFER_HELPER, NULL);
if (info) {
tramp_name = mono_get_generic_trampoline_name (tramp_type);
buf = code = mono_domain_code_reserve (domain, buf_len);
+ MINI_BEGIN_CODEGEN ();
+
code = mono_arm_emit_imm64 (code, ARMREG_IP1, (guint64)arg1);
code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)tramp);
arm_brx (code, ARMREG_IP0);
g_assert ((code - buf) < buf_len);
- mono_arch_flush_icache (buf, code - buf);
- MONO_PROFILER_RAISE (jit_code_buffer, (buf, code - buf, MONO_PROFILER_CODE_BUFFER_SPECIFIC_TRAMPOLINE, mono_get_generic_trampoline_simple_name (tramp_type)));
+
+ MINI_END_CODEGEN (buf, code - buf, MONO_PROFILER_CODE_BUFFER_SPECIFIC_TRAMPOLINE, mono_get_generic_trampoline_simple_name (tramp_type));
if (code_len)
*code_len = code - buf;
MonoDomain *domain = mono_domain_get ();
start = code = mono_domain_code_reserve (domain, size);
+
+ MINI_BEGIN_CODEGEN ();
+
code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)addr);
arm_addx_imm (code, ARMREG_R0, ARMREG_R0, MONO_ABI_SIZEOF (MonoObject));
arm_brx (code, ARMREG_IP0);
g_assert ((code - start) <= size);
- mono_arch_flush_icache (start, code - start);
- MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_UNBOX_TRAMPOLINE, m));
+
+ MINI_END_CODEGEN (start, code - start, MONO_PROFILER_CODE_BUFFER_UNBOX_TRAMPOLINE, m);
+
return start;
}
MonoDomain *domain = mono_domain_get ();
start = code = mono_domain_code_reserve (domain, buf_len);
+
+ MINI_BEGIN_CODEGEN ();
+
code = mono_arm_emit_imm64 (code, MONO_ARCH_RGCTX_REG, (guint64)arg);
code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)addr);
arm_brx (code, ARMREG_IP0);
- g_assert ((code - start) <= buf_len);
+ MINI_END_CODEGEN (start, code - start, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL);
- mono_arch_flush_icache (start, code - start);
- MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL));
+ g_assert ((code - start) <= buf_len);
return start;
}
/* The vtable/mrgtx is in R0 */
g_assert (MONO_ARCH_VTABLE_REG == ARMREG_R0);
+ MINI_BEGIN_CODEGEN ();
+
if (is_mrgctx) {
/* get mrgctx ptr */
arm_movx (code, ARMREG_IP1, ARMREG_R0);
}
arm_brx (code, ARMREG_IP0);
- mono_arch_flush_icache (buf, code - buf);
- MONO_PROFILER_RAISE (jit_code_buffer, (buf, code - buf, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL));
-
g_assert (code - buf <= buf_size);
+ MINI_END_CODEGEN (buf, code - buf, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL);
+
if (info) {
char *name = mono_get_rgctx_fetch_trampoline_name (slot);
*info = mono_tramp_info_create (name, buf, code - buf, ji, unwind_ops);
mono_add_unwind_op_def_cfa (unwind_ops, code, buf, ARMREG_SP, 0);
+ MINI_BEGIN_CODEGEN ();
+
// FIXME: Currently, we always go to the slow path.
/* Load trampoline addr */
arm_ldrx (code, ARMREG_IP0, MONO_ARCH_RGCTX_REG, 8);
g_assert (MONO_ARCH_VTABLE_REG == ARMREG_R0);
arm_brx (code, ARMREG_IP0);
- mono_arch_flush_icache (buf, code - buf);
- MONO_PROFILER_RAISE (jit_code_buffer, (buf, code - buf, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL));
-
g_assert (code - buf <= tramp_size);
+ MINI_END_CODEGEN (buf, code - buf, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL);
+
if (info)
*info = mono_tramp_info_create ("rgctx_fetch_trampoline_general", buf, code - buf, ji, unwind_ops);
// FIXME: Unwind info
+ MINI_BEGIN_CODEGEN ();
+
/* Setup stack frame */
imm = frame_size;
while (imm > 256) {
arm_retx (code, ARMREG_LR);
- mono_arch_flush_icache (code, code - buf);
- MONO_PROFILER_RAISE (jit_code_buffer, (buf, code - buf, MONO_PROFILER_CODE_BUFFER_HELPER, NULL));
g_assert (code - buf <= tramp_size);
+ MINI_END_CODEGEN (buf, code - buf, MONO_PROFILER_CODE_BUFFER_HELPER, NULL);
+
const char *tramp_name = single_step ? "sdb_single_step_trampoline" : "sdb_breakpoint_trampoline";
*info = mono_tramp_info_create (tramp_name, buf, code - buf, ji, unwind_ops);
framesize = ALIGN_TO (framesize, MONO_ARCH_FRAME_ALIGNMENT);
+ MINI_BEGIN_CODEGEN ();
+
arm_subx_imm (code, ARMREG_SP, ARMREG_SP, framesize);
arm_stpx (code, ARMREG_FP, ARMREG_LR, ARMREG_SP, 0);
arm_movspx (code, ARMREG_FP, ARMREG_SP);
g_assert (code - start < buf_len);
- mono_arch_flush_icache (start, code - start);
- MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_HELPER, NULL));
+ MINI_END_CODEGEN (start, code - start, MONO_PROFILER_CODE_BUFFER_HELPER, NULL);
if (info)
*info = mono_tramp_info_create ("interp_to_native_trampoline", start, code - start, ji, unwind_ops);
offset += sizeof (CallContext);
framesize = ALIGN_TO (offset, MONO_ARCH_FRAME_ALIGNMENT);
+ MINI_BEGIN_CODEGEN ();
+
mono_add_unwind_op_def_cfa (unwind_ops, code, start, ARMREG_SP, 0);
arm_subx_imm (code, ARMREG_SP, ARMREG_SP, framesize);
g_assert (code - start < buf_len);
- mono_arch_flush_icache (start, code - start);
- MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL));
+ MINI_END_CODEGEN (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL);
if (info)
*info = mono_tramp_info_create ("native_to_interp_trampoline", start, code - start, ji, unwind_ops);
endif
-
+if DISABLE_CRASH_REPORTING
+PLATFORM_DISABLED_TESTS += merp-json-valid.exe merp-crash-test.exe
+endif
if HOST_DARWIN
#endif
#include <mono/utils/mono-os-mutex.h>
-
+#include <mono/utils/mono-tls.h>
static uintptr_t code_memory_used = 0;
static size_t dynamic_code_alloc_count;
static mono_mutex_t valloc_mutex;
static GHashTable *valloc_freelists;
+static MonoNativeTlsKey write_level_tls_id;
static void*
codechunk_valloc (void *preferred, guint32 size)
freelist = (GSList *) g_hash_table_lookup (valloc_freelists, GUINT_TO_POINTER (size));
if (freelist) {
ptr = freelist->data;
+ mono_codeman_enable_write ();
memset (ptr, 0, size);
+ mono_codeman_disable_write ();
freelist = g_slist_delete_link (freelist, freelist);
g_hash_table_insert (valloc_freelists, GUINT_TO_POINTER (size), freelist);
} else {
mono_counters_register ("Dynamic code allocs", MONO_COUNTER_JIT | MONO_COUNTER_ULONG, &dynamic_code_alloc_count);
mono_counters_register ("Dynamic code bytes", MONO_COUNTER_JIT | MONO_COUNTER_ULONG, &dynamic_code_bytes_count);
mono_counters_register ("Dynamic code frees", MONO_COUNTER_JIT | MONO_COUNTER_ULONG, &dynamic_code_frees_count);
+
+ mono_native_tls_alloc (&write_level_tls_id, NULL);
}
void
g_assert (heap);
return HeapAlloc (heap, 0, n);
#else
- return dlmemalign (MIN_ALIGN, n);
+ mono_codeman_enable_write ();
+ gpointer res = dlmemalign (MIN_ALIGN, n);
+ mono_codeman_disable_write ();
+ return res;
#endif
}
g_assert (heap);
HeapFree (heap, 0, p);
#else
+ mono_codeman_enable_write ();
dlfree (p);
+ mono_codeman_disable_write ();
#endif
}
#ifdef BIND_ROOM
if (flags == CODE_FLAG_MALLOC) {
/* Make sure the thunks area is zeroed */
+ mono_codeman_enable_write ();
memset (ptr, 0, bsize);
+ mono_codeman_disable_write ();
}
#endif
*used_size = used;
return size;
}
+
+/*
+ * mono_codeman_enable_write ():
+ *
+ * Enable writing to code memory on the current thread on platforms that need it.
+ * Calls can be nested.
+ */
+void
+mono_codeman_enable_write (void)
+{
+#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP
+ if (__builtin_available (macOS 11, *)) {
+ int level = GPOINTER_TO_INT (mono_native_tls_get_value (write_level_tls_id));
+ level ++;
+ mono_native_tls_set_value (write_level_tls_id, GINT_TO_POINTER (level));
+ pthread_jit_write_protect_np (0);
+ }
+#endif
+}
+
+/*
+ * mono_codeman_disable_write ():
+ *
+ * Disable writing to code memory on the current thread on platforms that need it.
+ * Calls can be nested.
+ */
+void
+mono_codeman_disable_write (void)
+{
+#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP
+ if (__builtin_available (macOS 11, *)) {
+ int level = GPOINTER_TO_INT (mono_native_tls_get_value (write_level_tls_id));
+ g_assert (level);
+ level --;
+ mono_native_tls_set_value (write_level_tls_id, GINT_TO_POINTER (level));
+ if (level == 0)
+ pthread_jit_write_protect_np (1);
+ }
+#endif
+}
typedef int (*MonoCodeManagerFunc) (void *data, int csize, int size, void *user_data);
void mono_code_manager_foreach (MonoCodeManager *cman, MonoCodeManagerFunc func, void *user_data);
+void mono_codeman_enable_write (void);
+void mono_codeman_disable_write (void);
+
#endif /* __MONO_CODEMAN_H__ */