Skip to content

Commit

Permalink
[mono] Add a no-exec code manager for AOT compilation; switch Catalys…
Browse files Browse the repository at this point in the history
…t CI to JustInterp AOT mode (#53197)

* Initial pass at trying to run catalyst in aot interp only mode

* Cleanup

* Remove yml dup

* Incorporate changes and identify native libraries to skip during System.Diagnostics.FileVersionInfo test run

* [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.

* also set no_exec earlier and create the ALC codeman with noexec

* 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.

* Set ENABLE_MONOTOUCH for MacCatalyst arm64.  Define MONOTOUCH in one place

* [aot] mscorlib.dll isn't CoreLib on netcore

   It's a forwarding assembly.  Don't treat it specially

* [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)

* Update iOS sample to use JustInterp

   and adhoc signing

* Don't run iOS sample on the CI build machine

* Disable some tests

Fixes #53106

Co-authored-by: Steve Pfister <steve.pfister@microsoft.com>
Co-authored-by: Steve Pfister <steve@Steves-M1.fios-router.home>
  • Loading branch information
3 people committed Jun 2, 2021
1 parent a71ea4d commit 1d9ff9e
Show file tree
Hide file tree
Showing 20 changed files with 239 additions and 54 deletions.
43 changes: 42 additions & 1 deletion eng/pipelines/runtime-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ jobs:
platforms:
- iOSSimulator_x64
- tvOSSimulator_x64
- MacCatalyst_x64
variables:
# map dependencies variables to local variables
- name: librariesContainsChange
Expand Down Expand Up @@ -96,6 +95,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
#
Expand Down
21 changes: 19 additions & 2 deletions eng/testing/tests.mobile.targets
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,25 @@
<MainLibraryFileName Condition="'$(MainLibraryFileName)' == ''">AppleTestRunner.dll</MainLibraryFileName>
<_MobileIntermediateOutputPath Condition="'$(RunAOTCompilation)' == 'true'">$(IntermediateOutputPath)mobile</_MobileIntermediateOutputPath>
</PropertyGroup>
<PropertyGroup>
<AOTMode Condition="'$(TargetOS)' != 'MacCatalyst'">Full</AOTMode>
<AOTMode Condition="'$(TargetOS)' == 'MacCatalyst' and '$(MonoForceInterpreter)' != 'true'">Full</AOTMode>
<AOTMode Condition="'$(TargetOS)' == 'MacCatalyst' and '$(MonoForceInterpreter)' == 'true'">JustInterp</AOTMode>
</PropertyGroup>
<ItemGroup>
<AotInputAssemblies Condition="'$(RunAOTCompilation)' == 'true'" Include="$(PublishDir)*.dll" Exclude="$(PublishDir)System.Runtime.WindowsRuntime.dll">
<_AotExcludeAssemblies Include="$(PublishDir)System.Runtime.WindowsRuntime.dll" />
<_AotExcludeAssemblies Include="@(NativeLibraries->'$(PublishDir)%(Identity)')" />

<!-- JustInterp only needs to AOT CoreLib, the other assemblies will just get added to BundleAssemblies via _BundleNonAotAssemblies -->
<_AotIncludeAssemblies Condition="'$(RunAOTCompilation)' == 'true' and '$(AOTMode)' == 'JustInterp'" Include="$(PublishDir)System.Private.CoreLib.dll" />
<_AotIncludeAssemblies Condition="'$(RunAOTCompilation)' == 'true' and '$(AOTMode)' != 'JustInterp'" Include="$(PublishDir)*.dll" />

<AotInputAssemblies Condition="'$(RunAOTCompilation)' == 'true'" Include="@(_AotIncludeAssemblies)" Exclude="@(_AotExcludeAssemblies)">
<AotArguments>@(MonoAOTCompilerDefaultAotArguments, ';')</AotArguments>
<ProcessArguments>@(MonoAOTCompilerDefaultProcessArguments, ';')</ProcessArguments>
</AotInputAssemblies>
<BundleAssemblies Condition="'$(RunAOTCompilation)' != 'true'" Include="$(PublishDir)*.dll" />
<_BundleNonAotAssemblies Condition="'$(RunAOTCompilation)' == 'true' and '$(AOTMode)' == 'JustInterp'" Include="$(PublishDir)*.dll" Exclude="$(PublishDir)System.Private.CoreLib.dll" />
</ItemGroup>

<MakeDir Directories="$(_MobileIntermediateOutputPath)"
Expand All @@ -167,7 +180,7 @@
<MonoAOTCompiler Condition="'$(RunAOTCompilation)' == 'true'"
CompilerBinaryPath="$(MonoAotCrossCompilerPath)"
OutputDir="$(_MobileIntermediateOutputPath)"
Mode="Full"
Mode="$(AOTMode)"
OutputType="AsmOnly"
Assemblies="@(AotInputAssemblies)"
AotModulesTablePath="$(BundleDir)\modules.m"
Expand All @@ -177,6 +190,10 @@
<Output TaskParameter="CompiledAssemblies" ItemName="BundleAssemblies" />
</MonoAOTCompiler>

<ItemGroup>
<BundleAssemblies Include="@(_BundleNonAotAssemblies)" />
</ItemGroup>

<!-- Run App bundler, it uses AOT libs (if needed), link all native bits, compile simple UI (written in ObjC)
and produce an app bundle (with xcode project) -->
<AppleAppBuilderTask
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup Condition="'$(RunAOTCompilation)' == 'true'">
<!-- Identifies native libraries that should be skipped during AOT -->
<NativeLibraries Include="NativeLibrary.dll" />
<NativeLibraries Include="SecondNativeLibrary.dll" />
</ItemGroup>
<ItemGroup>
<Compile Include="FileVersionInfoTest.cs" />
<Compile Include="AssemblyInfo.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Func<Thrower>> e = () => new Thrower(true);
Expand Down
17 changes: 12 additions & 5 deletions src/mono/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -307,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")
Expand Down Expand Up @@ -431,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
######################################
Expand Down Expand Up @@ -765,7 +772,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()
Expand Down
3 changes: 2 additions & 1 deletion src/mono/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
<watchOSVersionMin>2.0</watchOSVersionMin>
<watchOS64_32VersionMin>5.1</watchOS64_32VersionMin>
<macOSVersionMin>10.13</macOSVersionMin>
<macOSVersionMin Condition="'$(TargetOS)' == 'OSX' and '$(TargetArchitecture)' == 'arm64'">11.0</macOSVersionMin>
<!-- FIXME: when we're building ios or tvOS cross-compilers hosted on OSX/arm64 targeting ios/arm64 we should set the min macOS version to 11.0, also -->
<macOSVersionMin Condition="('$(TargetOS)' == 'OSX' or '$(TargetOS)' == 'MacCatalyst') and '$(TargetArchitecture)' == 'arm64'">11.0</macOSVersionMin>

<!-- Version of the OS SDK we target -->
<iOSVersion></iOSVersion>
Expand Down
6 changes: 5 additions & 1 deletion src/mono/mono/metadata/memory-manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion src/mono/mono/mini/aot-compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include <mono/metadata/appdomain.h>
#include <mono/metadata/debug-helpers.h>
#include <mono/metadata/assembly.h>
#include <mono/metadata/assembly-internals.h>
#include <mono/metadata/metadata-internals.h>
#include <mono/metadata/reflection-internals.h>
#include <mono/metadata/marshal.h>
Expand Down Expand Up @@ -14091,7 +14092,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)
Expand Down
8 changes: 5 additions & 3 deletions src/mono/mono/mini/aot-runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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;
Expand Down
31 changes: 20 additions & 11 deletions src/mono/mono/mini/mini-runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -4444,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
Expand Down Expand Up @@ -4500,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
Expand Down
Loading

0 comments on commit 1d9ff9e

Please sign in to comment.