Apple Silicon support (#39939)
authormonojenkins <jo.shields+jenkins@xamarin.com>
Tue, 28 Jul 2020 12:34:29 +0000 (08:34 -0400)
committerGitHub <noreply@github.com>
Tue, 28 Jul 2020 12:34:29 +0000 (08:34 -0400)
<!--
Thank you for your Pull Request!

If you are new to contributing to Mono, please try to do your best at conforming to our coding guidelines http://www.mono-project.com/community/contributing/coding-guidelines/ but don't worry if you get something wrong. One of the project members will help you to get things landed.

Does your pull request fix any of the existing issues? Please use the following format: Fixes #issue-number
-->

Co-authored-by: vargaz <vargaz@users.noreply.github.com>
22 files changed:
src/mono/configure.ac
src/mono/mono/arch/arm64/Makefile.am
src/mono/mono/arch/arm64/arm64-codegen.h
src/mono/mono/arch/arm64/codegen-test.c
src/mono/mono/eglib/eglib-remap.h
src/mono/mono/mini/aot-compiler.c
src/mono/mono/mini/exceptions-arm64.c
src/mono/mono/mini/helpers.c
src/mono/mono/mini/llvm-jit.cpp
src/mono/mono/mini/mini-arm64.c
src/mono/mono/mini/mini-arm64.h
src/mono/mono/mini/mini-llvm.c
src/mono/mono/mini/mini-runtime.c
src/mono/mono/mini/mini-runtime.h
src/mono/mono/mini/mini.c
src/mono/mono/mini/mini.h
src/mono/mono/mini/trace.c
src/mono/mono/mini/tramp-arm64-gsharedvt.c
src/mono/mono/mini/tramp-arm64.c
src/mono/mono/tests/Makefile.am
src/mono/mono/utils/mono-codeman.c
src/mono/mono/utils/mono-codeman.h

index 18f807f842b96f87e0b70f4cb55f03384d48ef32..7a0d36d9ce57dce4984e330515b82925230bf661 100644 (file)
@@ -449,6 +449,10 @@ case "$host" in
                                platform_ios=yes
                                has_dtrace=no
                                ;;
+                       aarch64*-darwin20*)
+                               # OSX/arm64
+                               support_boehm=no
+                               ;;
                        aarch64*-darwin*)
                                platform_ios=yes
                                ;;
@@ -1208,6 +1212,7 @@ if test "x$crash_reporting" != "xyes"; then
 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)
@@ -2815,7 +2820,7 @@ if test x$host_win32 = xno; then
        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;
@@ -4772,6 +4777,12 @@ if test "x$host" != "x$target"; then
                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
                ;;
@@ -4984,7 +4995,7 @@ if test "x$target_mach" = "xyes"; then
          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"
@@ -5000,6 +5011,9 @@ if test "x$target_mach" = "xyes"; then
           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"
index bdc37622a640d6a47bff702c80f3386faee88aff..e735d0ed69aa1dc6a941e3cbd9eff79ad7abdf02 100644 (file)
@@ -1,3 +1,9 @@
 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
index 239f4161fd92d775fdd62588eccee489188b1b48..d35fda11752f5ce1a5bf3aafc820aae9d17a15e2 100644 (file)
@@ -867,4 +867,40 @@ arm_encode_arith_imm (int imm, guint32 *shift)
 #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__ */
index bb9d9dcdecd49e2437dc91bd6f4eb6cd5b1b8409..efb991e842738458566b21fc357fd52e02c5203b 100644 (file)
@@ -416,6 +416,19 @@ main (int argc, char *argv [])
        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");
index c5e27adae85d3cde11b77170e94309cbfc093e96..c9751049c3b7436af7cadad0557a7988586519b6 100644 (file)
 #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
index 7c76e4ce154b105719e623434d53f55e20e63a15..5e8d1d3ab7345aa26a9d578b7409ab9dd04ec8d4 100644 (file)
@@ -12296,6 +12296,9 @@ compile_asm (MonoAotCompile *acfg)
 #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"
index 11cb6ccdd9d37f8b3a3b4634c9d0f19d655c35c1..3c06a2ac070d96e31434de66f42a2f8253909a2a 100644 (file)
@@ -36,6 +36,8 @@ mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot)
        size = 256;
        code = start = mono_global_codeman_reserve (size);
 
+       MINI_BEGIN_CODEGEN ();
+
        arm_movx (code, ARMREG_IP0, ARMREG_R0);
        ctx_reg = ARMREG_IP0;
 
@@ -63,8 +65,8 @@ mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot)
        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);
@@ -106,6 +108,8 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot)
         * 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);
@@ -152,8 +156,8 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot)
        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);
@@ -186,6 +190,8 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm
        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);
@@ -254,8 +260,8 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm
        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);
@@ -329,9 +335,6 @@ mono_arch_exceptions_init (void)
        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);
 
@@ -340,7 +343,6 @@ mono_arch_exceptions_init (void)
 
                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) {
index 3ceffe6f13765ca00c17abddf91e4349a7e943ca..b62361ed532a151156db3eb52082cd7ff9509ce8 100644 (file)
@@ -263,7 +263,7 @@ mono_disassemble_code (MonoCompile *cfg, guint8 *code, int size, char *id)
 
        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.
index 1e896419f0b48f5303e942b9d3493c4c561274df..8307990a4e251d076da026cb4d8992502d337c01 100644 (file)
@@ -247,7 +247,7 @@ struct MonoLLVMJIT {
                        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};
index 7907193b5e0ffd5fabd28e277610d15d56cacdb9..30992b6cd8818d0304ce0c618ff746d5976cb6c4 100644 (file)
@@ -114,6 +114,8 @@ get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *co
 {
        guint8 *code, *start;
 
+       MINI_BEGIN_CODEGEN ();
+
        if (has_target) {
                start = code = mono_global_codeman_reserve (12);
 
@@ -123,9 +125,6 @@ get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *co
                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;
 
@@ -139,10 +138,8 @@ get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *co
                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;
@@ -255,7 +252,7 @@ mono_arch_init (void)
 
        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
 }
@@ -1076,7 +1073,11 @@ add_general (CallInfo *cinfo, ArgInfo *ainfo, int size, gboolean sign)
 {
        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 */
@@ -1344,6 +1345,10 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig)
 
        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);
@@ -5350,6 +5355,8 @@ mono_arch_build_imt_trampoline (MonoVTable *vtable, MonoDomain *domain, MonoIMTC
                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
@@ -5419,8 +5426,7 @@ mono_arch_build_imt_trampoline (MonoVTable *vtable, MonoDomain *domain, MonoIMTC
 
        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;
 }
@@ -5460,7 +5466,9 @@ mono_arch_set_breakpoint (MonoJitInfo *ji, guint8 *ip)
        } 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);
        }
 }
@@ -5479,7 +5487,9 @@ mono_arch_clear_breakpoint (MonoJitInfo *ji, guint8 *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);
        }
 }
index 41590fb0e87fcedb5644d5fd1fbc5671d11555ab..4074aa8b43f2c8ab6a7b4616d655e098c32d7562 100644 (file)
@@ -177,6 +177,9 @@ typedef struct {
 #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?
@@ -250,7 +253,7 @@ typedef struct {
 struct CallInfo {
        int nargs;
        int gr, fr, stack_usage;
-       gboolean pinvoke;
+       gboolean pinvoke, vararg;
        ArgInfo ret;
        ArgInfo sig_cookie;
        ArgInfo args [1];
index c400e94f81642d170afb86947cc98660b109c1d9..4ac4e72eece29c160a910f3ff77515f37e8dd712 100644 (file)
@@ -11675,8 +11675,10 @@ llvm_jit_finalize_method (EmitContext *ctx)
        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) {
index 2176226b554b5ead0d33f8f75080ee66b13266e0..82a8da22d6f7bdb1e6559cb8e2639ee2dc54b241 100644 (file)
@@ -1460,9 +1460,11 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
                        }
                }
 
+               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;
@@ -1754,6 +1756,8 @@ mini_patch_jump_sites (MonoDomain *domain, MonoMethod *method, gpointer addr)
                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);
@@ -1766,6 +1770,8 @@ mini_patch_jump_sites (MonoDomain *domain, MonoMethod *method, gpointer addr)
                        mono_error_assert_ok (error);
                }
 #endif
+
+               mono_codeman_disable_write ();
        }
 }
 
index 7061283543cc42d0886eb33e6c802a2d0c62e41d..9eea434e05e78a8fe5743ef386b643a666eba99a 100644 (file)
@@ -611,5 +611,16 @@ gboolean MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal);
 
 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__ */
 
index 965771de378d463e255303f8382636bfc42184d8..2a6ca7f4b16c2197fd303e07b13daf71162bf388 100644 (file)
@@ -2248,6 +2248,8 @@ mono_codegen (MonoCompile *cfg)
                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;
@@ -2339,6 +2341,9 @@ mono_codegen (MonoCompile *cfg)
        } 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);
@@ -3044,6 +3049,9 @@ init_backend (MonoBackend *backend)
 #ifdef MONO_ARCH_HAVE_OPTIMIZED_DIV
        backend->optimized_div = 1;
 #endif
+#ifdef MONO_ARCH_FORCE_FLOAT32
+       backend->force_float32 = 1;
+#endif
 }
 
 static gboolean
@@ -3146,6 +3154,9 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl
 #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) {
index e782440c7e18e71f447ffbea2246a48cd17d13b2..58eb136d318140f2935723fe10cef537f36df3d3 100644 (file)
@@ -1193,7 +1193,7 @@ typedef struct {
        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;
@@ -1203,6 +1203,7 @@ typedef struct {
        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;
index 0e28cc773ee22fbaa21472c3931529fdf759dbbe..56e19a857512b674963b4b4e55bb7a1594290613 100644 (file)
@@ -31,7 +31,7 @@
 #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
index c1038511d67fde5f9110aa38246eb470d82c1bf3..269624c259da69a41e5055ad8b595429c626f235 100644 (file)
@@ -13,6 +13,7 @@
 #include "mini.h"
 #include "mini-arm64.h"
 #include "mini-arm64-gsharedvt.h"
+#include "mini-runtime.h"
 
 /*
  * GSHAREDVT
@@ -36,13 +37,16 @@ mono_arch_get_gsharedvt_arg_trampoline (MonoDomain *domain, gpointer arg, gpoint
         */
        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;
 }
@@ -248,6 +252,8 @@ mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot)
 
        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);
@@ -547,7 +553,8 @@ mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot)
        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;
 }
 
index 04eda906c469d8b60cd836da190d5150ec86238f..7b889a3ffde4d2cb46b479369d782ff8fd811ebb 100644 (file)
@@ -30,8 +30,9 @@
 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
@@ -133,6 +134,8 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
        //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);
@@ -303,8 +306,8 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
        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);
@@ -328,14 +331,16 @@ mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_ty
 
        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;
@@ -351,13 +356,17 @@ mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr)
        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;
 }
 
@@ -369,14 +378,16 @@ mono_arch_get_static_rgctx_trampoline (gpointer arg, gpointer addr)
        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;
 }
@@ -415,6 +426,8 @@ mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info
        /* 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);
@@ -468,11 +481,10 @@ mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info
        }
        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);
@@ -498,6 +510,8 @@ mono_arch_create_general_rgctx_lazy_fetch_trampoline (MonoTrampInfo **info, gboo
 
        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);
@@ -505,11 +519,10 @@ mono_arch_create_general_rgctx_lazy_fetch_trampoline (MonoTrampInfo **info, gboo
        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);
 
@@ -547,6 +560,8 @@ mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo **info, gbo
 
        // FIXME: Unwind info
 
+       MINI_BEGIN_CODEGEN ();
+
        /* Setup stack frame */
        imm = frame_size;
        while (imm > 256) {
@@ -605,10 +620,10 @@ mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo **info, gbo
 
        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);
 
@@ -644,6 +659,8 @@ mono_arch_get_interp_to_native_trampoline (MonoTrampInfo **info)
 
        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);
@@ -712,8 +729,7 @@ mono_arch_get_interp_to_native_trampoline (MonoTrampInfo **info)
 
        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);
@@ -744,6 +760,8 @@ mono_arch_get_native_to_interp_trampoline (MonoTrampInfo **info)
        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);
@@ -788,8 +806,7 @@ mono_arch_get_native_to_interp_trampoline (MonoTrampInfo **info)
 
        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);
index fc2a7661882d4080c118d725c622647051fdc51e..6a3af788dfe401e0f30c67a5dfe46945c205dabf 100755 (executable)
@@ -1121,7 +1121,9 @@ endif
 
 endif
 
-
+if DISABLE_CRASH_REPORTING
+PLATFORM_DISABLED_TESTS += merp-json-valid.exe merp-crash-test.exe
+endif
 
 if HOST_DARWIN
 
index a69f25bb43ecfbf19371e859476747fd5af321b9..24c90a3e6dd462704138f3b5c28e5a4de81dd61a 100644 (file)
@@ -27,7 +27,7 @@ static void* mono_code_manager_heap;
 #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;
@@ -102,6 +102,7 @@ struct _MonoCodeManager {
 
 static mono_mutex_t valloc_mutex;
 static GHashTable *valloc_freelists;
+static MonoNativeTlsKey write_level_tls_id;
 
 static void*
 codechunk_valloc (void *preferred, guint32 size)
@@ -121,7 +122,9 @@ 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 {
@@ -176,6 +179,8 @@ mono_code_manager_init (void)
        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
@@ -271,7 +276,10 @@ mono_codeman_malloc (gsize n)
        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
 }
 
@@ -285,7 +293,9 @@ mono_codeman_free (gpointer p)
        g_assert (heap);
        HeapFree (heap, 0, p);
 #else
+       mono_codeman_enable_write ();
        dlfree (p);
+       mono_codeman_disable_write ();
 #endif
 }
 
@@ -476,7 +486,9 @@ new_codechunk (MonoCodeManager *cman, int size)
 #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
 
@@ -639,3 +651,43 @@ mono_code_manager_size (MonoCodeManager *cman, int *used_size)
                *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
+}
index 4cf447f6e0867d2995d3b459683f7add05d08264..fbe2a2f2d4f4431f1ae73124fcdf8caf198993a3 100644 (file)
@@ -41,5 +41,8 @@ void             mono_code_manager_install_callbacks (const MonoCodeManagerCallb
 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__ */