From 469bb936987d67cca86b1fc54a4abb31331f0ea9 Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Mon, 17 May 2021 12:09:38 -0400 Subject: [PATCH 01/13] Initial pass at trying to run catalyst in aot interp only mode --- eng/pipelines/runtime-staging.yml | 42 +++++++++++++++++++ eng/testing/tests.mobile.targets | 7 +++- src/tasks/AppleAppBuilder/AppleAppBuilder.cs | 2 +- src/tasks/AppleAppBuilder/Templates/runtime.m | 10 ++++- src/tasks/AppleAppBuilder/Xcode.cs | 3 +- 5 files changed, 60 insertions(+), 4 deletions(-) diff --git a/eng/pipelines/runtime-staging.yml b/eng/pipelines/runtime-staging.yml index a778f606253b02..6ac61d654a55cf 100644 --- a/eng/pipelines/runtime-staging.yml +++ b/eng/pipelines/runtime-staging.yml @@ -96,6 +96,48 @@ jobs: eq(variables['monoContainsChange'], true), eq(variables['isFullMatrix'], true)) +# +# MacCatalyst interp - requires AOT Compilation and Interp flags +# Build the whole product using Mono and run libraries tests +# +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml + buildConfig: Release + runtimeFlavor: mono + platforms: + - MacCatalyst_x64 + - MacCatalyst_arm64 + variables: + # map dependencies variables to local variables + - name: librariesContainsChange + value: $[ dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'] ] + - name: monoContainsChange + value: $[ dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'] ] + jobParameters: + testGroup: innerloop + nameSuffix: AllSubsets_Mono + buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:RunAOTCompilation=true /p:MonoForceInterpreter=true + timeoutInMinutes: 180 + condition: >- + or( + eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), + eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true), + eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true), + eq(variables['isFullMatrix'], true)) + # extra steps, run tests + extraStepsTemplate: /eng/pipelines/libraries/helix.yml + extraStepsParameters: + creator: dotnet-bot + interpreter: true + testRunNamePrefixSuffix: Mono_$(_BuildConfig) + condition: >- + or( + eq(variables['librariesContainsChange'], true), + eq(variables['monoContainsChange'], true), + eq(variables['isFullMatrix'], true)) + # # Build the whole product using Mono and run libraries tests # diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets index 2fedf68d956005..a2ad345b3ff3fa 100644 --- a/eng/testing/tests.mobile.targets +++ b/eng/testing/tests.mobile.targets @@ -160,6 +160,11 @@ AppleTestRunner.dll <_MobileIntermediateOutputPath Condition="'$(RunAOTCompilation)' == 'true'">$(IntermediateOutputPath)mobile + + Full + Full + JustInterp + @(MonoAOTCompilerDefaultAotArguments, ';') @@ -175,7 +180,7 @@ Date: Mon, 17 May 2021 12:27:20 -0400 Subject: [PATCH 02/13] Cleanup --- src/tasks/AppleAppBuilder/Xcode.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tasks/AppleAppBuilder/Xcode.cs b/src/tasks/AppleAppBuilder/Xcode.cs index 9ea613caf33947..34982bb28c36a1 100644 --- a/src/tasks/AppleAppBuilder/Xcode.cs +++ b/src/tasks/AppleAppBuilder/Xcode.cs @@ -197,7 +197,7 @@ public string GenerateXCode( { defines.AppendLine("add_definitions(-DFORCE_INTERPRETER=1)"); } - + if (forceAOT) { defines.AppendLine("add_definitions(-DFORCE_AOT=1)"); From 0949826247ee5f261cf00577e0933ccc5e46a052 Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Mon, 17 May 2021 13:18:17 -0400 Subject: [PATCH 03/13] Remove yml dup --- eng/pipelines/runtime-staging.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/eng/pipelines/runtime-staging.yml b/eng/pipelines/runtime-staging.yml index 6ac61d654a55cf..7b29783774ef11 100644 --- a/eng/pipelines/runtime-staging.yml +++ b/eng/pipelines/runtime-staging.yml @@ -66,7 +66,6 @@ jobs: platforms: - iOSSimulator_x64 - tvOSSimulator_x64 - - MacCatalyst_x64 variables: # map dependencies variables to local variables - name: librariesContainsChange From 227847cb6b1ea703d7f4ac27d30422245022df7a Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Thu, 20 May 2021 20:51:09 -0400 Subject: [PATCH 04/13] Incorporate @lambdageek's changes and identify native libraries to skip during System.Diagnostics.FileVersionInfo test run --- eng/testing/tests.mobile.targets | 5 ++++- .../System.Diagnostics.FileVersionInfo.Tests.csproj | 5 +++++ src/mono/CMakeLists.txt | 9 +++------ src/mono/Directory.Build.props | 3 ++- src/mono/mono/utils/mono-mmap.c | 2 +- 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets index a2ad345b3ff3fa..1a8c3d9405909d 100644 --- a/eng/testing/tests.mobile.targets +++ b/eng/testing/tests.mobile.targets @@ -166,7 +166,10 @@ JustInterp - + <_AotExcludeAssemblies Include="$(PublishDir)System.Runtime.WindowsRuntime.dll" /> + <_AotExcludeAssemblies Include="@(NativeLibraries->'$(PublishDir)%(Identity)')" /> + + @(MonoAOTCompilerDefaultAotArguments, ';') @(MonoAOTCompilerDefaultProcessArguments, ';') diff --git a/src/libraries/System.Diagnostics.FileVersionInfo/tests/System.Diagnostics.FileVersionInfo.Tests/System.Diagnostics.FileVersionInfo.Tests.csproj b/src/libraries/System.Diagnostics.FileVersionInfo/tests/System.Diagnostics.FileVersionInfo.Tests/System.Diagnostics.FileVersionInfo.Tests.csproj index 7efbc8bc54c827..ad027e8be25474 100644 --- a/src/libraries/System.Diagnostics.FileVersionInfo/tests/System.Diagnostics.FileVersionInfo.Tests/System.Diagnostics.FileVersionInfo.Tests.csproj +++ b/src/libraries/System.Diagnostics.FileVersionInfo/tests/System.Diagnostics.FileVersionInfo.Tests/System.Diagnostics.FileVersionInfo.Tests.csproj @@ -19,6 +19,11 @@ PreserveNewest + + + + + diff --git a/src/mono/CMakeLists.txt b/src/mono/CMakeLists.txt index 22cf849b4460f2..801610da782fbc 100644 --- a/src/mono/CMakeLists.txt +++ b/src/mono/CMakeLists.txt @@ -160,11 +160,11 @@ if(NOT AOT_TARGET_TRIPLE STREQUAL "") elseif(AOT_TARGET_TRIPLE STREQUAL "x86_64-apple-maccatalyst") set(TARGET_SYSTEM_NAME "Darwin") set(TARGET_ARCH "x86_64") - set(CMAKE_SYSTEM_VARIANT "MacCatalyst") + set(TARGET_MACCAT 1) elseif(AOT_TARGET_TRIPLE STREQUAL "aarch64-apple-maccatalyst") set(TARGET_SYSTEM_NAME "Darwin") set(TARGET_ARCH "arm64") - set(CMAKE_SYSTEM_VARIANT "MacCatalyst") + set(TARGET_MACCAT 1) elseif(AOT_TARGET_TRIPLE STREQUAL "wasm32-unknown-none") set(TARGET_SYSTEM_NAME "Emscripten") set(TARGET_ARCH "wasm") @@ -296,9 +296,6 @@ if(TARGET_SYSTEM_NAME STREQUAL "Darwin") set(TARGET_MACH 1) set(TARGET_OSX 1) set(TARGET_DARWIN 1) - if(CMAKE_SYSTEM_VARIANT STREQUAL "MacCatalyst") - set(TARGET_MACCAT 1) - endif() elseif(TARGET_SYSTEM_NAME STREQUAL "iOS" OR TARGET_SYSTEM_NAME STREQUAL "tvOS") set(TARGET_MACH 1) set(TARGET_IOS 1) @@ -744,7 +741,7 @@ set(FULL_VERSION ${product_version_string}) ###################################### # OS SPECIFIC CHECKS ###################################### -if(TARGET_IOS OR TARGET_ANDROID OR TARGET_MACCAT) +if(HOST_IOS OR HOST_ANDROID OR HOST_MACCAT) # FIXME: the mobile products use mono_dllmap_insert so allow this unset(DISABLE_DLLMAP) else() diff --git a/src/mono/Directory.Build.props b/src/mono/Directory.Build.props index 356a3175019ad8..2eb7bc5647519c 100644 --- a/src/mono/Directory.Build.props +++ b/src/mono/Directory.Build.props @@ -18,7 +18,8 @@ 2.0 5.1 10.13 - 11.0 + + 11.0 diff --git a/src/mono/mono/utils/mono-mmap.c b/src/mono/mono/utils/mono-mmap.c index e362b698dc454c..08ce984f25e6c5 100644 --- a/src/mono/mono/utils/mono-mmap.c +++ b/src/mono/mono/utils/mono-mmap.c @@ -305,7 +305,7 @@ mono_valloc (void *addr, size_t length, int flags, MonoMemAccountType type) } if ((flags & MONO_MMAP_JIT) && (use_mmap_jit || is_hardened_runtime == 1)) mflags |= MAP_JIT; -#if defined(HOST_ARM64) +#if defined(HOST_ARM64) && !defined(HOST_MACCAT) /* Patching code on apple silicon seems to cause random crashes without this flag */ /* No __builtin_available in old versions of Xcode that could be building Mono on x86 or amd64 */ if (__builtin_available (macOS 11, *)) From 9bc0eb9fc1e76e83f0079659733239af83ca7e8b Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 24 May 2021 16:35:02 -0400 Subject: [PATCH 05/13] [mini] Add a no-exec code manager for AOT compilation Don't allocate pages with execute permission if we're never going to be executing code. Also don't try to toggle per-thread write protection if we're not expecting to write to executable pages. --- src/mono/mono/mini/mini-runtime.c | 15 +++-- src/mono/mono/utils/mono-codeman.c | 99 ++++++++++++++++++++++++++---- src/mono/mono/utils/mono-codeman.h | 3 +- 3 files changed, 100 insertions(+), 17 deletions(-) diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index 0443d8ed7af679..a9ef109023f4dd 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -378,7 +378,10 @@ void *(mono_global_codeman_reserve) (int size) if (!global_codeman) { /* This can happen during startup */ - global_codeman = mono_code_manager_new (); + if (!mono_compile_aot) + global_codeman = mono_code_manager_new (); + else + global_codeman = mono_code_manager_new_aot (); return mono_code_manager_reserve (global_codeman, size); } else { @@ -4292,8 +4295,12 @@ mini_init (const char *filename, const char *runtime_version) mono_tls_init_runtime_keys (); - if (!global_codeman) - global_codeman = mono_code_manager_new (); + if (!global_codeman) { + if (!mono_compile_aot) + global_codeman = mono_code_manager_new (); + else + global_codeman = mono_code_manager_new_aot (); + } memset (&callbacks, 0, sizeof (callbacks)); callbacks.create_ftnptr = mini_create_ftnptr; @@ -4346,7 +4353,7 @@ mini_init (const char *filename, const char *runtime_version) mini_parse_debug_options (); } - mono_code_manager_init (); + mono_code_manager_init (mono_compile_aot); #ifdef MONO_ARCH_HAVE_CODE_CHUNK_TRACKING diff --git a/src/mono/mono/utils/mono-codeman.c b/src/mono/mono/utils/mono-codeman.c index 10cc823eddf649..526813c9092fe6 100644 --- a/src/mono/mono/utils/mono-codeman.c +++ b/src/mono/mono/utils/mono-codeman.c @@ -70,6 +70,7 @@ static const MonoCodeManagerCallbacks *code_manager_callbacks; #endif #define MONO_PROT_RWX (MONO_MMAP_READ|MONO_MMAP_WRITE|MONO_MMAP_EXEC|MONO_MMAP_JIT) +#define MONO_PROT_RW (MONO_MMAP_READ|MONO_MMAP_WRITE) typedef struct _CodeChunk CodeChunk; @@ -94,6 +95,7 @@ struct _MonoCodeManager { CodeChunk *last; int dynamic : 1; int read_only : 1; + int no_exec : 1; }; #define ALIGN_INT(val,alignment) (((val) + (alignment - 1)) & ~(alignment - 1)) @@ -105,7 +107,7 @@ static GHashTable *valloc_freelists; static MonoNativeTlsKey write_level_tls_id; static void* -codechunk_valloc (void *preferred, guint32 size) +codechunk_valloc (void *preferred, guint32 size, gboolean no_exec) { void *ptr; GSList *freelist; @@ -128,9 +130,14 @@ codechunk_valloc (void *preferred, guint32 size) freelist = g_slist_delete_link (freelist, freelist); g_hash_table_insert (valloc_freelists, GUINT_TO_POINTER (size), freelist); } else { - ptr = mono_valloc (preferred, size, MONO_PROT_RWX | ARCH_MAP_FLAGS, MONO_MEM_ACCOUNT_CODE); + int prot; + if (!no_exec) + prot = MONO_PROT_RWX | ARCH_MAP_FLAGS; + else + prot = MONO_PROT_RW | ARCH_MAP_FLAGS; + ptr = mono_valloc (preferred, size, prot, MONO_MEM_ACCOUNT_CODE); if (!ptr && preferred) - ptr = mono_valloc (NULL, size, MONO_PROT_RWX | ARCH_MAP_FLAGS, MONO_MEM_ACCOUNT_CODE); + ptr = mono_valloc (NULL, size, prot, MONO_MEM_ACCOUNT_CODE); } mono_os_mutex_unlock (&valloc_mutex); return ptr; @@ -173,14 +180,34 @@ codechunk_cleanup (void) g_hash_table_destroy (valloc_freelists); } +/* non-zero if we don't need to toggle write protection on individual threads */ +static int +codeman_no_exec; + +/** + * mono_codeman_set_code_no_exec: + * + * If set to a non-zero value, + * \c mono_codeman_enable_write and \c mono_codeman_disable_write turn into no-ops. + * + * The AOT compiler should do this if it is allocating RW (no X) memory for code. + */ +static void +mono_codeman_set_code_no_exec (int no_exec) +{ + codeman_no_exec = no_exec; +} + void -mono_code_manager_init (void) +mono_code_manager_init (gboolean no_exec) { 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); + + mono_codeman_set_code_no_exec (no_exec); } void @@ -206,6 +233,34 @@ mono_codeman_allocation_type (MonoCodeManager const *cman) #endif } +enum CodeManagerType { + MONO_CODEMAN_TYPE_JIT, + MONO_CODEMAN_TYPE_DYNAMIC, + MONO_CODEMAN_TYPE_AOT, +}; + +static gboolean +codeman_type_is_dynamic (int codeman_type) +{ + switch (codeman_type) { + case MONO_CODEMAN_TYPE_DYNAMIC: + return TRUE; + default: + return FALSE; + } +} + +static gboolean +codeman_type_is_aot (int codeman_type) +{ + switch (codeman_type) { + case MONO_CODEMAN_TYPE_AOT: + return TRUE; + default: + return FALSE; + } +} + /** * mono_code_manager_new_internal * @@ -213,11 +268,12 @@ mono_codeman_allocation_type (MonoCodeManager const *cman) */ static MonoCodeManager* -mono_code_manager_new_internal (gboolean dynamic) +mono_code_manager_new_internal (int codeman_type) { MonoCodeManager* cman = g_new0 (MonoCodeManager, 1); if (cman) { - cman->dynamic = dynamic; + cman->dynamic = codeman_type_is_dynamic (codeman_type); + cman->no_exec = codeman_type_is_aot (codeman_type); #if _WIN32 // It would seem the heap should live and die with the codemanager, // but that was failing, so try a global. @@ -250,7 +306,7 @@ mono_code_manager_new_internal (gboolean dynamic) MonoCodeManager* mono_code_manager_new (void) { - return mono_code_manager_new_internal (FALSE); + return mono_code_manager_new_internal (MONO_CODEMAN_TYPE_JIT); } /** @@ -265,7 +321,21 @@ mono_code_manager_new (void) MonoCodeManager* mono_code_manager_new_dynamic (void) { - return mono_code_manager_new_internal (TRUE); + return mono_code_manager_new_internal (MONO_CODEMAN_TYPE_DYNAMIC); +} + +/** + * mono_code_manager_new_aot: + * + * Creates a new code manager that will hold code that is never + * executed. This can be used by the AOT compiler to allocate pages + * on W^X platforms without asking for execute permission (which may + * require additional entitlements, or AOT-time OS calls). + */ +MonoCodeManager* +mono_code_manager_new_aot (void) +{ + return mono_code_manager_new_internal (MONO_CODEMAN_TYPE_AOT); } static gpointer @@ -424,6 +494,7 @@ new_codechunk (MonoCodeManager *cman, int size) { CodeChunk * const last = cman->last; int const dynamic = cman->dynamic; + int const no_exec = cman->no_exec; int chunk_size, bsize = 0; CodeChunk *chunk; void *ptr; @@ -440,8 +511,8 @@ new_codechunk (MonoCodeManager *cman, int size) chunk_size = minsize; else { /* Allocate MIN_ALIGN-1 more than we need so we can still */ - /* guarantee MIN_ALIGN alignment for individual allocs */ - /* from mono_code_manager_reserve_align. */ + /* guarantee MIN_ALIGN alignment for individual allocs */ + /* from mono_code_manager_reserve_align. */ size += MIN_ALIGN - 1; size &= ~(MIN_ALIGN - 1); chunk_size = size; @@ -476,9 +547,9 @@ new_codechunk (MonoCodeManager *cman, int size) /* Try to allocate code chunks next to each other to help the VM */ ptr = NULL; if (last) - ptr = codechunk_valloc ((guint8*)last->data + last->size, chunk_size); + ptr = codechunk_valloc ((guint8*)last->data + last->size, chunk_size, no_exec); if (!ptr) - ptr = codechunk_valloc (NULL, chunk_size); + ptr = codechunk_valloc (NULL, chunk_size, no_exec); if (!ptr) return NULL; } @@ -661,6 +732,8 @@ mono_code_manager_size (MonoCodeManager *cman, int *used_size) void mono_codeman_enable_write (void) { + if (codeman_no_exec) + return; #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)); @@ -683,6 +756,8 @@ mono_codeman_enable_write (void) void mono_codeman_disable_write (void) { + if (codeman_no_exec) + return; #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)); diff --git a/src/mono/mono/utils/mono-codeman.h b/src/mono/mono/utils/mono-codeman.h index fbe2a2f2d4f443..69893b401c9118 100644 --- a/src/mono/mono/utils/mono-codeman.h +++ b/src/mono/mono/utils/mono-codeman.h @@ -24,6 +24,7 @@ typedef struct { MonoCodeManager* mono_code_manager_new (void); MonoCodeManager* mono_code_manager_new_dynamic (void); +MonoCodeManager* mono_code_manager_new_aot (void); void mono_code_manager_destroy (MonoCodeManager *cman); void mono_code_manager_invalidate (MonoCodeManager *cman); void mono_code_manager_set_read_only (MonoCodeManager *cman); @@ -33,7 +34,7 @@ void* mono_code_manager_reserve_align (MonoCodeManager *cman, int siz void* mono_code_manager_reserve (MonoCodeManager *cman, int size); void mono_code_manager_commit (MonoCodeManager *cman, void *data, int size, int newsize); int mono_code_manager_size (MonoCodeManager *cman, int *used_size); -void mono_code_manager_init (void); +void mono_code_manager_init (gboolean no_exec); void mono_code_manager_cleanup (void); void mono_code_manager_install_callbacks (const MonoCodeManagerCallbacks* callbacks); From d357178595f860e65ba697d867340fe276260224 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 24 May 2021 17:00:27 -0400 Subject: [PATCH 06/13] also set no_exec earlier and create the ALC codeman with noexec --- src/mono/mono/metadata/memory-manager.c | 6 +++++- src/mono/mono/mini/mini-runtime.c | 16 +++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/mono/mono/metadata/memory-manager.c b/src/mono/mono/metadata/memory-manager.c index 38979f4bd65200..04f489124c0da8 100644 --- a/src/mono/mono/metadata/memory-manager.c +++ b/src/mono/mono/metadata/memory-manager.c @@ -105,7 +105,11 @@ mono_mem_manager_new (MonoAssemblyLoadContext **alcs, int nalcs, gboolean collec mono_os_mutex_init (&memory_manager->mp_mutex); memory_manager->_mp = mono_mempool_new (); - memory_manager->code_mp = mono_code_manager_new (); + if (mono_runtime_get_no_exec()) { + memory_manager->code_mp = mono_code_manager_new_aot (); + } else { + memory_manager->code_mp = mono_code_manager_new (); + } memory_manager->lock_free_mp = lock_free_mempool_new (); memory_manager->alcs = mono_mempool_alloc0 (memory_manager->_mp, sizeof (MonoAssemblyLoadContext *) * nalcs); diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index a9ef109023f4dd..7f30902b62604f 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -4451,6 +4451,15 @@ mini_init (const char *filename, const char *runtime_version) if (mini_debug_options.collect_pagefault_stats) mono_aot_set_make_unreadable (TRUE); + /* set no-exec before the default ALC is created */ + if (mono_compile_aot) { + /* + * Avoid running managed code when AOT compiling, since the platform + * might only support aot-only execution. + */ + mono_runtime_set_no_exec (TRUE); + } + if (runtime_version) domain = mono_init_version (filename, runtime_version); else @@ -4507,13 +4516,6 @@ mini_init (const char *filename, const char *runtime_version) register_trampolines (domain); - if (mono_compile_aot) - /* - * Avoid running managed code when AOT compiling, since the platform - * might only support aot-only execution. - */ - mono_runtime_set_no_exec (TRUE); - mono_mem_account_register_counters (); #define JIT_RUNTIME_WORKS From 3de37e4e6c9bb47deb6122f81c604feea4d0548b Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 24 May 2021 20:38:59 -0400 Subject: [PATCH 07/13] Don't assert on Catalyst in mono_codeman_enable_write We defensively also toggle the page write protect bits when resolving some AOT patch targets in mono_resolve_patch_target_ext. Instead allow the call, but don't do anything. --- src/mono/mono/utils/mono-codeman.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/mono/mono/utils/mono-codeman.c b/src/mono/mono/utils/mono-codeman.c index 526813c9092fe6..c7ff9326ed710c 100644 --- a/src/mono/mono/utils/mono-codeman.c +++ b/src/mono/mono/utils/mono-codeman.c @@ -742,8 +742,7 @@ mono_codeman_enable_write (void) pthread_jit_write_protect_np (0); } #elif defined(HOST_MACCAT) && defined(__aarch64__) - /* JITing in Catalyst apps is not allowed on Apple Silicon. */ - g_assert_not_reached (); + /* JITing in Catalyst apps is not allowed on Apple Silicon, so assume if we're here we don't really have executable pages. */ #endif } @@ -768,7 +767,6 @@ mono_codeman_disable_write (void) pthread_jit_write_protect_np (1); } #elif defined(HOST_MACCAT) && defined(__aarch64__) - /* JITing in Catalyst apps is not allowed on Apple Silicon. */ - g_assert_not_reached (); + /* JITing in Catalyst apps is not allowed on Apple Silicon, so assume if we're here we don't really have executable pages */ #endif } From 396681d3ddaa55afa3dad88137943f55b9b39132 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 24 May 2021 21:02:04 -0400 Subject: [PATCH 08/13] Set ENABLE_MONOTOUCH for MacCatalyst arm64. Define MONOTOUCH in one place --- src/mono/CMakeLists.txt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/mono/CMakeLists.txt b/src/mono/CMakeLists.txt index 5a85e092538d0e..5eaaaa91b6504e 100644 --- a/src/mono/CMakeLists.txt +++ b/src/mono/CMakeLists.txt @@ -225,7 +225,6 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS" OR CMAKE_SYSTEM_NAME STREQUAL "tvOS") set(DISABLE_EXECUTABLES 1) set(DISABLE_CRASH_REPORTING 1) set(ENABLE_MONOTOUCH 1) - add_definitions(-DMONOTOUCH=1) add_definitions("-DSMALL_CONFIG") add_definitions("-D_XOPEN_SOURCE") add_definitions("-DHAVE_LARGE_FILE_SUPPORT=1") @@ -296,6 +295,9 @@ if(TARGET_SYSTEM_NAME STREQUAL "Darwin") set(TARGET_MACH 1) set(TARGET_OSX 1) set(TARGET_DARWIN 1) + if(CMAKE_SYSTEM_VARIANT STREQUAL "MacCatalyst") + set(TARGET_MACCAT 1) + endif() elseif(TARGET_SYSTEM_NAME STREQUAL "iOS" OR TARGET_SYSTEM_NAME STREQUAL "tvOS") set(TARGET_MACH 1) set(TARGET_IOS 1) @@ -304,7 +306,6 @@ elseif(TARGET_SYSTEM_NAME STREQUAL "iOS" OR TARGET_SYSTEM_NAME STREQUAL "tvOS") set(TARGET_TVOS 1) endif() set(ENABLE_MONOTOUCH 1) - add_definitions(-DMONOTOUCH=1) elseif(TARGET_SYSTEM_NAME STREQUAL "Linux") set(TARGET_LINUX 1) elseif(TARGET_SYSTEM_NAME STREQUAL "Android") @@ -428,6 +429,15 @@ else() message(FATAL_ERROR "TARGET_ARCH='${TARGET_ARCH}' not supported.") endif() +# arm64 MacCatalyst runtime host or AOT target is more like Apple mobile targets than x64 +if ((HOST_MACCAT AND HOST_ARCH STREQUAL "arm64") OR (TARGET_MACCAT AND TARGET_ARCH STREQUAL "arm64")) + set(ENABLE_MONOTOUCH 1) +endif() + +if(ENABLE_MONOTOUCH) + add_definitions(-DMONOTOUCH=1) +endif() + ###################################### # HEADER/FUNCTION CHECKS ###################################### From cdff6f79bd171913d0005a5cf8ae831ec46989f8 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 24 May 2021 23:41:56 -0400 Subject: [PATCH 09/13] [aot] mscorlib.dll isn't CoreLib on netcore It's a forwarding assembly. Don't treat it specially --- src/mono/mono/mini/aot-compiler.c | 3 ++- src/mono/mono/mini/aot-runtime.c | 8 +++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 6fde9c65e3f192..9c4c6f770ff817 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -14089,7 +14090,7 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options, #endif /* required for mixed mode */ - if (strcmp (acfg->image->assembly->aname.name, "mscorlib") == 0) { + if (strcmp (acfg->image->assembly->aname.name, MONO_ASSEMBLY_CORLIB_NAME) == 0) { add_gc_wrappers (acfg); for (int i = 0; i < MONO_JIT_ICALL_count; ++i) diff --git a/src/mono/mono/mini/aot-runtime.c b/src/mono/mono/mini/aot-runtime.c index 7aad2d17889589..545487122f098c 100644 --- a/src/mono/mono/mini/aot-runtime.c +++ b/src/mono/mono/mini/aot-runtime.c @@ -1577,7 +1577,7 @@ check_usable (MonoAssembly *assembly, MonoAotFileInfo *info, guint8 *blob, char msg = g_strdup ("compiled with --aot=full"); usable = FALSE; } - if (mono_use_interpreter && !interp && !strcmp (assembly->aname.name, "mscorlib")) { + if (mono_use_interpreter && !interp && !strcmp (assembly->aname.name, MONO_ASSEMBLY_CORLIB_NAME)) { /* mscorlib contains necessary interpreter trampolines */ msg = g_strdup ("not compiled with --aot=interp"); usable = FALSE; @@ -2183,8 +2183,10 @@ load_aot_module (MonoAssemblyLoadContext *alc, MonoAssembly *assembly, gpointer amodule->trampolines [MONO_AOT_TRAMP_FTNPTR_ARG] = (guint8 *)info->ftnptr_arg_trampolines; amodule->trampolines [MONO_AOT_TRAMP_UNBOX_ARBITRARY] = (guint8 *)info->unbox_arbitrary_trampolines; - if (mono_is_corlib_image (assembly->image) || !strcmp (assembly->aname.name, "mscorlib") || !strcmp (assembly->aname.name, "System.Private.CoreLib")) + if (mono_is_corlib_image (assembly->image) || !strcmp (assembly->aname.name, MONO_ASSEMBLY_CORLIB_NAME)) { + g_assert (!mscorlib_aot_module); mscorlib_aot_module = amodule; + } /* Compute method addresses */ amodule->methods = (void **)g_malloc0 (amodule->info.nmethods * sizeof (gpointer)); @@ -5834,7 +5836,7 @@ aot_is_slim_amodule (MonoAotModule *amodule) return FALSE; /* "slim" only applies to mscorlib.dll */ - if (strcmp (amodule->aot_name, "mscorlib")) + if (strcmp (amodule->aot_name, MONO_ASSEMBLY_CORLIB_NAME)) return FALSE; guint32 f = amodule->info.flags; From 1a48c4bee4a481e5fa911e054b5b6e6499bd97a5 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Tue, 25 May 2021 15:50:44 -0400 Subject: [PATCH 10/13] [testing] In JustInterp mode, only AOT System.Private.CoreLib We only need to AOT the trampolines in System.Private.CoreLib in interpreter-only mode. We don't need to AOT any of the user code in other assemblies. Side effect: fixes the System.Runtime.Loader.DefaultContext testsuite in JustInterp mode. Still broken in Full AOT mode. (That testsuite references the System.Runtime.Loader.Noop.Assembly assembly, but with a different filename System.Runtime.Loader.Noop.Assembly_test.dll which causes linking errors due to incorrect symbols in AOT module registration in AppleAppBuilder) --- eng/testing/tests.mobile.targets | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets index cd6dbd2d9fde25..15e73eb874085b 100644 --- a/eng/testing/tests.mobile.targets +++ b/eng/testing/tests.mobile.targets @@ -172,17 +172,22 @@ Full Full - JustInterp + JustInterp <_AotExcludeAssemblies Include="$(PublishDir)System.Runtime.WindowsRuntime.dll" /> <_AotExcludeAssemblies Include="@(NativeLibraries->'$(PublishDir)%(Identity)')" /> - + + <_AotIncludeAssemblies Condition="'$(RunAOTCompilation)' == 'true' and '$(AOTMode)' == 'JustInterp'" Include="$(PublishDir)System.Private.CoreLib.dll" /> + <_AotIncludeAssemblies Condition="'$(RunAOTCompilation)' == 'true' and '$(AOTMode)' != 'JustInterp'" Include="$(PublishDir)*.dll" /> + + @(MonoAOTCompilerDefaultAotArguments, ';') @(MonoAOTCompilerDefaultProcessArguments, ';') + <_BundleNonAotAssemblies Condition="'$(RunAOTCompilation)' == 'true' and '$(AOTMode)' == 'JustInterp'" Include="$(PublishDir)*.dll" Exclude="$(PublishDir)System.Private.CoreLib.dll" /> + + + + Date: Wed, 26 May 2021 12:20:52 -0400 Subject: [PATCH 11/13] Update iOS sample to use JustInterp and adhoc signing --- src/mono/sample/iOS/Makefile | 4 ++-- src/mono/sample/iOS/Program.csproj | 18 ++++++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/mono/sample/iOS/Makefile b/src/mono/sample/iOS/Makefile index be7c2bcefe0aa6..76b56deecb5f0f 100644 --- a/src/mono/sample/iOS/Makefile +++ b/src/mono/sample/iOS/Makefile @@ -24,7 +24,7 @@ run-sim: clean appbuilder run-catalyst: $(DOTNET) publish -c $(MONO_CONFIG) /p:TargetOS=MacCatalyst /p:TargetArchitecture=$(MONO_ARCH) \ - /p:UseLLVM=False /p:ForceAOT=False + /p:UseLLVM=False /p:ForceAOT=True run-sim-interp: clean appbuilder $(DOTNET) publish -c $(MONO_CONFIG) /p:TargetOS=iOSSimulator /p:TargetArchitecture=$(MONO_ARCH) \ @@ -32,7 +32,7 @@ run-sim-interp: clean appbuilder run-catalyst-interp: $(DOTNET) publish -c $(MONO_CONFIG) /p:TargetOS=MacCatalyst /p:TargetArchitecture=$(MONO_ARCH) \ - /p:UseLLVM=False /p:ForceAOT=False /p:MonoForceInterpreter=true + /p:UseLLVM=False /p:ForceAOT=True /p:MonoForceInterpreter=True clean: rm -rf bin diff --git a/src/mono/sample/iOS/Program.csproj b/src/mono/sample/iOS/Program.csproj index 242896e764b15e..86fc16c77d3559 100644 --- a/src/mono/sample/iOS/Program.csproj +++ b/src/mono/sample/iOS/Program.csproj @@ -3,7 +3,7 @@ Exe bin $(NetCoreAppToolCurrent) - iOS + iOS iOSSimulator $(ArtifactsBinDir)microsoft.netcore.app.runtime.$(TargetOS.ToLower())-$(TargetArchitecture)\$(Configuration)\runtimes\$(TargetOS.ToLower())-$(TargetArchitecture)\ false @@ -18,7 +18,7 @@ - - + adhoc @@ -56,10 +56,16 @@ + + Full + Full + JustInterp + + @@ -104,8 +110,8 @@ - From cd74cb8416f087bbccf665b183f48a8f23d65c27 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Wed, 26 May 2021 14:18:58 -0400 Subject: [PATCH 12/13] Don't run iOS sample on the CI build machine --- src/mono/sample/iOS/Program.csproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mono/sample/iOS/Program.csproj b/src/mono/sample/iOS/Program.csproj index 86fc16c77d3559..8fcb8fa46e79b3 100644 --- a/src/mono/sample/iOS/Program.csproj +++ b/src/mono/sample/iOS/Program.csproj @@ -97,6 +97,12 @@ + + + + From c8cb35a050be10639e409c3e9dcdf6a9c5f27f4a Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Wed, 2 Jun 2021 09:57:14 -0400 Subject: [PATCH 13/13] Disable some tests --- .../tests/MemoryMappedViewAccessor.Tests.cs | 1 + .../tests/MemoryMappedViewStream.Tests.cs | 1 + src/libraries/System.Linq.Expressions/tests/InterpreterTests.cs | 1 + 3 files changed, 3 insertions(+) diff --git a/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedViewAccessor.Tests.cs b/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedViewAccessor.Tests.cs index 512748b10f9252..b4db65b5a851fc 100644 --- a/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedViewAccessor.Tests.cs +++ b/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedViewAccessor.Tests.cs @@ -75,6 +75,7 @@ public void InvalidArguments() [InlineData(MemoryMappedFileAccess.ReadWrite, MemoryMappedFileAccess.CopyOnWrite)] [InlineData(MemoryMappedFileAccess.Read, MemoryMappedFileAccess.Read)] [InlineData(MemoryMappedFileAccess.Read, MemoryMappedFileAccess.CopyOnWrite)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/53601", runtimes: TestRuntimes.Mono, platforms: TestPlatforms.MacCatalyst)] public void ValidAccessLevelCombinations(MemoryMappedFileAccess mapAccess, MemoryMappedFileAccess viewAccess) { const int Capacity = 4096; diff --git a/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedViewStream.Tests.cs b/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedViewStream.Tests.cs index 5903d4756ed978..a29a5bf3538762 100644 --- a/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedViewStream.Tests.cs +++ b/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedViewStream.Tests.cs @@ -75,6 +75,7 @@ public void InvalidArguments() [InlineData(MemoryMappedFileAccess.ReadWrite, MemoryMappedFileAccess.CopyOnWrite)] [InlineData(MemoryMappedFileAccess.Read, MemoryMappedFileAccess.Read)] [InlineData(MemoryMappedFileAccess.Read, MemoryMappedFileAccess.CopyOnWrite)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/53601", runtimes: TestRuntimes.Mono, platforms: TestPlatforms.MacCatalyst)] public void ValidAccessLevelCombinations(MemoryMappedFileAccess mapAccess, MemoryMappedFileAccess viewAccess) { const int Capacity = 4096; diff --git a/src/libraries/System.Linq.Expressions/tests/InterpreterTests.cs b/src/libraries/System.Linq.Expressions/tests/InterpreterTests.cs index 11c22f7418324b..146dffb4be4c40 100644 --- a/src/libraries/System.Linq.Expressions/tests/InterpreterTests.cs +++ b/src/libraries/System.Linq.Expressions/tests/InterpreterTests.cs @@ -102,6 +102,7 @@ .maxcontinuation 1 } [Fact] + [ActiveIssue ("https://github.com/dotnet/runtime/issues/53599", platforms: TestPlatforms.MacCatalyst, runtimes: TestRuntimes.Mono)] public static void ConstructorThrows_StackTrace() { Expression> e = () => new Thrower(true);