diff --git a/.gitignore b/.gitignore index d28a63ee19eb..cd73f7596d9a 100644 --- a/.gitignore +++ b/.gitignore @@ -154,3 +154,4 @@ artifacts /builds/ /tmp/ external/buildscripts/build.gen.* +.idea diff --git a/.gitmodules b/.gitmodules index 8544f0560694..32ea8a9e4d82 100644 --- a/.gitmodules +++ b/.gitmodules @@ -66,7 +66,7 @@ url = git://github.com/mono/illinker-test-assets.git [submodule "external/llvm-project"] path = external/llvm-project - url = git://github.com/dotnet/llvm-project.git + url = git://github.com/ecuzzillo/llvm-project.git branch = release/6.x [submodule "external/bdwgc"] path = external/bdwgc diff --git a/.yamato/AOT ClassLibs Windows x64.yml b/.yamato/AOT ClassLibs Windows x64.yml new file mode 100644 index 000000000000..914530bffbe6 --- /dev/null +++ b/.yamato/AOT ClassLibs Windows x64.yml @@ -0,0 +1,18 @@ +name: AOT ClassLibs Windows x64 + +agent: + type: Unity::VM + image: platform-foundation/windows-vs2019-il2cpp-bokken:stable + flavor: b1.xlarge + +dependencies: + - .yamato/Build Classlibs OSX.yml + - .yamato/Build Windows x64.yml + +commands: + - cd external\buildscripts\bcl_aot && ..\bee.exe + +artifacts: + win64: + paths: + - incomingbuilds\aot-classlibs-win64\** \ No newline at end of file diff --git a/.yamato/Collate Builds.yml b/.yamato/Collate Builds.yml index 6dd5348e78ef..93dcc4ad5fe1 100644 --- a/.yamato/Collate Builds.yml +++ b/.yamato/Collate Builds.yml @@ -11,6 +11,7 @@ dependencies: - .yamato/Build Classlibs OSX.yml - .yamato/Build Runtime OSX.yml - .yamato/Build Windows x64.yml + - .yamato/AOT ClassLibs Windows x64.yml - .yamato/Build Windows x86.yml commands: diff --git a/external/buildscripts/bcl_aot/Build.bee.cs b/external/buildscripts/bcl_aot/Build.bee.cs new file mode 100644 index 000000000000..c4a6db8c67fd --- /dev/null +++ b/external/buildscripts/bcl_aot/Build.bee.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Bee.Core; +using Bee.Core.Stevedore; +using Bee.NativeProgramSupport; +using Bee.Stevedore.Program; +using Bee.Tools; +using NiceIO; + +class Build +{ + static void Main() + { + NPath root = "../../.."; + NPath monoDir = $@"{root}/incomingbuilds\win64\monodistribution\bin-x64"; + + NPath unityJitRelative = @"monodistribution\lib\mono\unityjit-win32"; + NPath classLibDir = $@"{root}/incomingbuilds\classlibs\{unityJitRelative}"; + NPath outputDir = $@"{root}/incomingbuilds\aot-classlibs-win64\{unityJitRelative}"; + + // TODO: this is the version yamato has right now. Do stevedore here. + NPath msvcRoot = @"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30037"; + NPath winSdkLib = @"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\ucrt\x64"; + + var clangExecutableArtifact = new StevedoreArtifact(new RepoName("testing"), new ArtifactId("llvm-clang-win64/12.0.0_73aaea91fe24775a257cf553f0a6db3e8845890cc8c6e35eecba97ec45fc93b6.7z")); + + var paths = new NPath[] + { + monoDir, + $@"{msvcRoot}\bin\Hostx64\x64", + clangExecutableArtifact.Path, + }; + + var _envVar = new Dictionary + { + {"PATH", paths.Select(p => p.ResolveWithFileSystem().ToString(SlashMode.Native)).Append(Environment.GetEnvironmentVariable("PATH")).SeparateWith(";")}, + {"MONO_PATH", classLibDir.ToString(SlashMode.Native)} + }; + + var libPaths = new[] {$@"{msvcRoot}\lib\x64", winSdkLib}; + var libpathstr = libPaths.Select(p => $"/LIBPATH:\\\"{p.ResolveWithFileSystem().ToString(SlashMode.Native)}\\\"").SeparateWithSpace(); + + var classLibs = classLibDir.Files("*.dll"); + foreach (var classLib in classLibs) + { + var nativeTarget = classLib.ChangeExtension($".{classLib.Extension}.dll"); + NPath pdb = $"{nativeTarget}.pdb"; + var outputFile = outputDir.Combine(nativeTarget.FileName); + + Backend.Current.AddAction("MonoAot", + new[] {nativeTarget, pdb}, + classLibs.Append(clangExecutableArtifact.Path).ToArray(), + monoDir.Combine("mono-bdwgc.exe").InQuotes(), + new[] {$"--aot=keep-temps,ld-flags=\"{libpathstr}\"", "--llvm", classLib.InQuotesResolved()}, + environmentVariables: _envVar); + Backend.Current.SetupCopyFile(outputFile, nativeTarget); + Backend.Current.SetupCopyFile(outputDir.Combine(pdb.FileName), pdb); + } + } +} diff --git a/external/buildscripts/build_win_no_cygwin.pl b/external/buildscripts/build_win_no_cygwin.pl index 1d46b47e7ea5..b4d205f487f9 100644 --- a/external/buildscripts/build_win_no_cygwin.pl +++ b/external/buildscripts/build_win_no_cygwin.pl @@ -126,6 +126,20 @@ my $archNameForBuild = $arch32 ? 'Win32' : 'x64'; my $configDirName = $debug ? "Debug" : "Release"; + if ($arch32) + { + + } else { + print(">>> copying llvm binaries...\n"); + copy("$monoroot/msvc/build/boehm/$archNameForBuild/bin/$configDirName/opt.exe", "$monoprefix/bin/opt.exe") or die ("failed copying opt.exe\n"); + copy("$monoroot/msvc/build/boehm/$archNameForBuild/bin/$configDirName/llvm-as.exe", "$monoprefix/bin/llvm-as.exe") or die ("failed copying llvm-as.exe\n"); + copy("$monoroot/msvc/build/boehm/$archNameForBuild/bin/$configDirName/llvm-dis.exe", "$monoprefix/bin/llvm-dis.exe") or die ("failed copying llvm-dis.exe\n"); + copy("$monoroot/msvc/build/boehm/$archNameForBuild/bin/$configDirName/llvm-mc.exe", "$monoprefix/bin/llvm-mc.exe") or die ("failed copying llvm-mc.exe\n"); + copy("$monoroot/msvc/build/boehm/$archNameForBuild/bin/$configDirName/llc.exe", "$monoprefix/bin/llc.exe") or die ("failed copying llc.exe\n"); + } + + print(">>> copying mono binaries...\n"); + copy("$monoroot/msvc/build/boehm/$archNameForBuild/bin/$configDirName/mono-bdwgc.exe", "$monoprefix/bin/mono-bdwgc.exe") or die ("failed copying mono-bdwgc.exe\n"); copy("$monoroot/msvc/build/boehm/$archNameForBuild/bin/$configDirName/mono-2.0-bdwgc.dll", "$monoprefix/bin/mono-2.0-bdwgc.dll") or die ("failed copying mono-2.0-bdwgc.dll\n"); copy("$monoroot/msvc/build/boehm/$archNameForBuild/bin/$configDirName/mono-2.0-bdwgc.pdb", "$monoprefix/bin/mono-2.0-bdwgc.pdb") or die ("failed copying mono-2.0-bdwgc.pdb\n"); @@ -221,6 +235,16 @@ copy("$monoprefix/bin/MonoPosixHelper.dll", "$distDirArchBin/.") or die ("failed copying MonoPosixHelper.dll\n"); copy("$monoprefix/bin/MonoPosixHelper.pdb", "$distDirArchBin/.") or die ("failed copying MonoPosixHelper.pdb\n"); + if ($arch32) + { + } else { + print(">>> copying llvm binaries to monodistribution...\n"); + copy("$monoprefix/bin/opt.exe", "$distDirArchBin/.") or die ("failed copying opt.exe\n"); + copy("$monoprefix/bin/llvm-as.exe", "$distDirArchBin/.") or die ("failed copying llvm-as.exe\n"); + copy("$monoprefix/bin/llvm-dis.exe", "$distDirArchBin/.") or die ("failed copying llvm-dis.exe\n"); + copy("$monoprefix/bin/llvm-mc.exe", "$distDirArchBin/.") or die ("failed copying llvm-mc.exe\n"); + copy("$monoprefix/bin/llc.exe", "$distDirArchBin/.") or die ("failed copying llc.exe\n"); + } # Output version information print(">>> Creating version file : $versionsOutputFile\n"); diff --git a/external/llvm-project b/external/llvm-project index 7dfdea1267f0..c8c66c84d975 160000 --- a/external/llvm-project +++ b/external/llvm-project @@ -1 +1 @@ -Subproject commit 7dfdea1267f0a40955e02567dcbcd1bcb987e825 +Subproject commit c8c66c84d975df4a52b79b1e8d32af3288133b03 diff --git a/mono/metadata/appdomain.c b/mono/metadata/appdomain.c index 5754f9f75046..3918ce821d9f 100644 --- a/mono/metadata/appdomain.c +++ b/mono/metadata/appdomain.c @@ -817,6 +817,9 @@ mono_domain_create_appdomain_internal (char *friendly_name, MonoAppDomainSetupHa data->domain = MONO_HANDLE_RAW (ad); mono_gc_wbarrier_generic_nostore_internal (&data->domain); data->friendly_name = g_strdup (friendly_name); + // hack to setup AOT domain earlier than Unity can with embedding API. + if (!strcmp(data->friendly_name, "Unity Child Domain")) + mono_aot_domain_set (data); MONO_PROFILER_RAISE (domain_name, (data, data->friendly_name)); @@ -1604,6 +1607,7 @@ mono_domain_assembly_postload_search (MonoAssemblyLoadContext *alc, MonoAssembly return assembly; } +extern MonoDomainAssemblyLoadedFunc domain_image_loaded; /* * LOCKING: assumes assemblies_lock in the domain is already locked. */ @@ -1631,6 +1635,8 @@ add_assemblies_to_domain (MonoDomain *domain, MonoAssembly *ass, GHashTable *ht) g_hash_table_add (ht, ass); domain->domain_assemblies = g_slist_append (domain->domain_assemblies, ass); mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "Assembly %s[%p] added to domain %s, ref_count=%d", ass->aname.name, ass, domain->friendly_name, ass->ref_count); + if (domain_image_loaded) + domain_image_loaded (domain, ass); } #ifndef ENABLE_NETCORE diff --git a/mono/metadata/appdomain.h b/mono/metadata/appdomain.h index 016ddf6bad1c..5aa4e2448182 100644 --- a/mono/metadata/appdomain.h +++ b/mono/metadata/appdomain.h @@ -29,6 +29,9 @@ typedef void (*MonoDomainFunc) (MonoDomain *domain, void* user_data); typedef void (*MonoJitInfoFunc)(MonoDomain *domain, MonoMethod* method, MonoJitInfo* jinfo, void* user_data); typedef void (*MonoUnityExceptionFunc) (MonoObject* exc); typedef void (*MonoDomainAssemblyFunc) (MonoAssembly *assembly, void* user_data); +typedef void (*MonoDomainAssemblyLoadedFunc) (MonoDomain* domain, MonoAssembly* assembly); +typedef void (*MonoImageAOTModuleDestroyFunc) (MonoDomain* domain, MonoImage* image); +typedef void (*MonoAOTResetFunc) (); MONO_API MonoDomain* mono_init (const char *filename); @@ -64,6 +67,9 @@ mono_runtime_is_shutting_down (void); MONO_API const char* mono_check_corlib_version (void); +void +mono_domain_install_aot_callbacks (MonoDomainAssemblyLoadedFunc image_loaded, MonoAOTResetFunc aot_reset, MonoImageAOTModuleDestroyFunc image_aot_module_destroy); + MONO_API MonoDomain * mono_domain_create (void); @@ -73,6 +79,15 @@ mono_domain_create_appdomain (char *friendly_name, char *configuration_file); MONO_API MONO_RT_EXTERNAL_ONLY void mono_domain_set_config (MonoDomain *domain, const char *base_dir, const char *config_file_name); +MONO_API MonoDomain* +mono_aot_domain_get (void); + +MONO_API void +mono_aot_domain_set (MonoDomain* domain); + +MONO_API void +mono_aot_domain_init_root_domain_set (mono_bool init_root_domain); + MONO_API MonoDomain * mono_domain_get (void); diff --git a/mono/metadata/boehm-gc.c b/mono/metadata/boehm-gc.c index 4fa5f9cd3183..2ce9528f8c81 100644 --- a/mono/metadata/boehm-gc.c +++ b/mono/metadata/boehm-gc.c @@ -1249,7 +1249,8 @@ mono_gc_is_moving (void) gboolean mono_gc_needs_write_barriers(void) { - return GC_is_incremental_mode (); + /* FIXME: Jon can we detect we are doing AOT compile and force this? */ + /*return GC_is_incremental_mode ();*/ return TRUE; } gboolean diff --git a/mono/metadata/domain-internals.h b/mono/metadata/domain-internals.h index ce37fe8f041d..8717e2c76d8e 100644 --- a/mono/metadata/domain-internals.h +++ b/mono/metadata/domain-internals.h @@ -406,6 +406,8 @@ struct _MonoDomain { MonoJitInfoTable * volatile aot_modules; GSList *jit_info_free_queue; + /* maps MonoImage to MonoAotModule */ + GHashTable* aot_module_hash; /* Used when loading assemblies */ gchar **search_path; gchar *private_bin_path; diff --git a/mono/metadata/domain.c b/mono/metadata/domain.c index c29a9e627079..e60557e7813b 100644 --- a/mono/metadata/domain.c +++ b/mono/metadata/domain.c @@ -87,6 +87,8 @@ gboolean mono_dont_free_domains; static MonoCoopMutex appdomains_mutex; static MonoDomain *mono_root_domain = NULL; +static MonoDomain* mono_aot_domain = NULL; +static gboolean mono_aot_domain_init_root_domain = TRUE; /* some statistics */ static int max_domain_code_size = 0; @@ -452,6 +454,8 @@ mono_domain_create (void) domain->memory_manager = (MonoMemoryManager *)mono_mem_manager_create_singleton (NULL, domain, TRUE); #endif + domain->aot_module_hash = g_hash_table_new (mono_aligned_addr_hash, NULL); + domain->lock_free_mp = lock_free_mempool_new (); domain->env = mono_g_hash_table_new_type_internal ((GHashFunc)mono_string_hash_internal, (GCompareFunc)mono_string_equal_internal, MONO_HASH_KEY_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, domain, "Domain Environment Variable Table"); domain->domain_assemblies = NULL; @@ -572,6 +576,11 @@ mono_init_internal (const char *filename, const char *exe_filename, const char * domain = mono_domain_create (); mono_root_domain = domain; + if (mono_aot_domain_init_root_domain) + { + mono_aot_domain = mono_root_domain; + } + SET_APPDOMAIN (domain); #if defined(ENABLE_EXPERIMENT_null) @@ -958,6 +967,24 @@ mono_get_root_domain (void) return mono_root_domain; } +MonoDomain* +mono_aot_domain_get (void) +{ + return mono_aot_domain; +} + +void +mono_aot_domain_set (MonoDomain* domain) +{ + mono_aot_domain = domain; +} + +void +mono_aot_domain_init_root_domain_set (gboolean init_root_domain) +{ + mono_aot_domain_init_root_domain = init_root_domain; +} + /** * mono_domain_get: * @@ -1141,6 +1168,18 @@ mono_domain_assembly_open_internal (MonoDomain *domain, MonoAssemblyLoadContext return ass; } +MonoDomainAssemblyLoadedFunc domain_image_loaded = NULL; +static MonoAOTResetFunc domain_unload_aot_reset = NULL; +static MonoImageAOTModuleDestroyFunc domain_unload_image_aot_module_destroy = NULL; + +void +mono_domain_install_aot_callbacks (MonoDomainAssemblyLoadedFunc image_loaded, MonoAOTResetFunc aot_reset, MonoImageAOTModuleDestroyFunc image_aot_module_destroy) +{ + domain_image_loaded = image_loaded; + domain_unload_aot_reset = aot_reset; + domain_unload_image_aot_module_destroy = image_aot_module_destroy; +} + /** * mono_domain_free: * \param domain the domain to release @@ -1223,6 +1262,8 @@ mono_domain_free (MonoDomain *domain, gboolean force) if (!ass->image || image_is_dynamic (ass->image)) continue; mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "Unloading domain %s[%p], assembly %s[%p], ref_count=%d", domain->friendly_name, domain, ass->aname.name, ass, ass->ref_count); + if (domain_unload_image_aot_module_destroy) + domain_unload_image_aot_module_destroy (domain, ass->image); if (!mono_assembly_close_except_image_pools (ass)) tmp->data = NULL; } @@ -1235,6 +1276,9 @@ mono_domain_free (MonoDomain *domain, gboolean force) g_slist_free (domain->domain_assemblies); domain->domain_assemblies = NULL; + if (domain_unload_aot_reset) + domain_unload_aot_reset (); + /* * Send this after the assemblies have been unloaded and the domain is still in a * usable state. diff --git a/mono/metadata/jit-info.c b/mono/metadata/jit-info.c index 45edf0d0de1e..6e47082c94ff 100644 --- a/mono/metadata/jit-info.c +++ b/mono/metadata/jit-info.c @@ -303,8 +303,8 @@ mono_jit_info_table_find_internal (MonoDomain *domain, gpointer addr, gboolean t return ji; /* Maybe its an AOT module */ - if (try_aot && mono_get_root_domain () && mono_get_root_domain ()->aot_modules) { - table = (MonoJitInfoTable *)mono_get_hazardous_pointer ((gpointer volatile*)&mono_get_root_domain ()->aot_modules, hp, JIT_INFO_TABLE_HAZARD_INDEX); + if (try_aot && mono_aot_domain_get () && mono_aot_domain_get ()->aot_modules) { + table = (MonoJitInfoTable *)mono_get_hazardous_pointer ((gpointer volatile*)&mono_aot_domain_get ()->aot_modules, hp, JIT_INFO_TABLE_HAZARD_INDEX); module_ji = jit_info_table_find (table, hp, (gint8*)addr); if (module_ji) ji = jit_info_find_in_aot_func (domain, module_ji->d.image, addr); @@ -809,7 +809,7 @@ void mono_jit_info_add_aot_module (MonoImage *image, gpointer start, gpointer end) { MonoJitInfo *ji; - MonoDomain *domain = mono_get_root_domain (); + MonoDomain *domain = mono_aot_domain_get (); g_assert (domain); mono_domain_lock (domain); diff --git a/mono/metadata/metadata-internals.h b/mono/metadata/metadata-internals.h index dfa127ba6a46..82b089ee3966 100644 --- a/mono/metadata/metadata-internals.h +++ b/mono/metadata/metadata-internals.h @@ -457,7 +457,7 @@ struct _MonoImage { MonoImage **files; guint32 file_count; - MonoAotModule *aot_module; + //MonoAotModule *aot_module; guint8 aotid[16]; diff --git a/mono/mini/aot-runtime.c b/mono/mini/aot-runtime.c index 884c5f2a708b..4e64a187b54f 100644 --- a/mono/mini/aot-runtime.c +++ b/mono/mini/aot-runtime.c @@ -279,6 +279,25 @@ amodule_unlock (MonoAotModule *amodule) mono_os_mutex_unlock (&amodule->mutex); } +void +domain_set_aot_module (MonoDomain* domain, MonoImage* image, MonoAotModule* aot_module) +{ + GHashTable* table = domain->aot_module_hash; + if (aot_module == NULL) + g_hash_table_remove (table, image); + else + g_hash_table_insert (table, image, aot_module); +} + +MonoAotModule* +domain_get_aot_module (MonoDomain* domain, MonoImage* image) +{ + GHashTable* table = domain->aot_module_hash; + MonoAotModule* aot_module = g_hash_table_lookup (table, image); + + return aot_module; +} + /* * load_image: * @@ -290,7 +309,7 @@ load_image (MonoAotModule *amodule, int index, MonoError *error) { MonoAssembly *assembly; MonoImageOpenStatus status; - MonoAssemblyLoadContext *alc = mono_domain_ambient_alc (mono_domain_get ()); + MonoAssemblyLoadContext *alc = mono_domain_ambient_alc (mono_aot_domain_get ()); g_assert (index < amodule->image_table_len); @@ -2077,7 +2096,7 @@ init_amodule_got (MonoAotModule *amodule, gboolean preinit) amodule->shared_got [i] = amodule->assembly->image; } else if (ji->type == MONO_PATCH_INFO_MSCORLIB_GOT_ADDR) { if (mono_defaults.corlib) { - MonoAotModule *mscorlib_amodule = mono_defaults.corlib->aot_module; + MonoAotModule* mscorlib_amodule = domain_get_aot_module (mono_aot_domain_get (), mono_defaults.corlib); if (mscorlib_amodule) amodule->shared_got [i] = mscorlib_amodule->got; @@ -2088,7 +2107,7 @@ init_amodule_got (MonoAotModule *amodule, gboolean preinit) amodule->shared_got [i] = amodule; } else if (ji->type == MONO_PATCH_INFO_NONE) { } else { - amodule->shared_got [i] = mono_resolve_patch_target (NULL, mono_get_root_domain (), NULL, ji, FALSE, error); + amodule->shared_got [i] = mono_resolve_patch_target (NULL, mono_aot_domain_get (), NULL, ji, FALSE, error); mono_error_assert_ok (error); } } @@ -2212,7 +2231,7 @@ register_methods_in_jinfo (MonoAotModule *amodule) #endif static void -load_aot_module (MonoAssemblyLoadContext *alc, MonoAssembly *assembly, gpointer user_data, MonoError *error) +load_aot_module (MonoDomain *domain, MonoAssembly *assembly, gpointer user_data, MonoError *error) { char *aot_name, *found_aot_name; MonoAotModule *amodule; @@ -2233,17 +2252,21 @@ load_aot_module (MonoAssemblyLoadContext *alc, MonoAssembly *assembly, gpointer if (mono_aot_mode == MONO_AOT_MODE_NONE) return; - if (assembly->image->aot_module) - /* + if (image_is_dynamic (assembly->image) || mono_asmctx_get_kind (&assembly->context) == MONO_ASMCTX_REFONLY || domain != mono_aot_domain_get ()) + return; + + mono_aot_lock (); + + amodule = domain_get_aot_module (domain, assembly->image); + + if (amodule) { + mono_aot_unlock (); + /* * Already loaded. This can happen because the assembly loading code might invoke * the assembly load hooks multiple times for the same assembly. */ return; - - if (image_is_dynamic (assembly->image) || mono_asmctx_get_kind (&assembly->context) == MONO_ASMCTX_REFONLY || mono_domain_get () != mono_get_root_domain ()) - return; - - mono_aot_lock (); + } if (static_aot_modules) info = (MonoAotFileInfo *)g_hash_table_lookup (static_aot_modules, assembly->aname.name); @@ -2368,7 +2391,7 @@ load_aot_module (MonoAssemblyLoadContext *alc, MonoAssembly *assembly, gpointer g_free (found_aot_name); if (sofile) mono_dl_close (sofile); - assembly->image->aot_module = NULL; + domain_set_aot_module (domain, assembly->image, NULL); return; } @@ -2572,13 +2595,15 @@ load_aot_module (MonoAssemblyLoadContext *alc, MonoAssembly *assembly, gpointer #ifdef HOST_WASM register_methods_in_jinfo (amodule); #else - if (amodule->jit_code_start) - mono_jit_info_add_aot_module (assembly->image, amodule->jit_code_start, amodule->jit_code_end); - if (amodule->llvm_code_start) - mono_jit_info_add_aot_module (assembly->image, amodule->llvm_code_start, amodule->llvm_code_end); + //if (mono_aot_domain_get ()) { + if (amodule->jit_code_start) + mono_jit_info_add_aot_module (assembly->image, amodule->jit_code_start, amodule->jit_code_end); + if (amodule->llvm_code_start) + mono_jit_info_add_aot_module (assembly->image, amodule->llvm_code_start, amodule->llvm_code_end); + //} #endif - assembly->image->aot_module = amodule; + domain_set_aot_module (domain, assembly->image, amodule); if (mono_aot_only && !mono_llvm_only) { char *code; @@ -2602,7 +2627,7 @@ load_aot_module (MonoAssemblyLoadContext *alc, MonoAssembly *assembly, gpointer NULL, mono_unwind_get_cie_program () ), - NULL + domain ); /* @@ -2629,6 +2654,14 @@ load_aot_module (MonoAssemblyLoadContext *alc, MonoAssembly *assembly, gpointer } } +static void +load_aot_module2 (MonoDomain* domain, MonoAssembly* assembly) +{ + ERROR_DECL (error); + load_aot_module (domain, assembly, NULL, error); + mono_error_assert_ok (error); /* FIXME don't swallow the error */ +} + /* * mono_aot_register_module: * @@ -2675,6 +2708,68 @@ mono_aot_register_module (gpointer *aot_info) mono_aot_unlock (); } +static void +mono_aot_reset (void) +{ + mono_aot_lock (); + + /*if (aot_jit_icall_hash) + g_hash_table_remove_all (aot_jit_icall_hash);*/ + + if (aot_modules) + g_hash_table_remove_all (aot_modules); + + if (ji_to_amodule) + g_hash_table_remove_all (ji_to_amodule); + + enable_aot_cache = FALSE; + mscorlib_aot_loaded = FALSE; + + aot_code_low_addr = (gssize)-1; + aot_code_high_addr = 0; + + async_jit_info_size = 0; + + mono_aot_unlock (); +} + +static void +mono_aot_image_aot_module_destroy (MonoDomain* domain, MonoImage* image) +{ + mono_aot_lock (); + MonoAotModule* aot_module = domain_get_aot_module (domain, image); + + if (aot_module == NULL) { + mono_aot_unlock (); + return; + } + + g_free (aot_module->llvm_got); + g_hash_table_destroy (aot_module->method_to_code); + g_hash_table_destroy (aot_module->extra_methods); + g_free (aot_module->shared_got); + + guint32 i; + for (i = 0; i < aot_module->image_table_len; ++i) { + g_free (aot_module->image_guids[i]); + } + + g_free (aot_module->image_table); + g_free (aot_module->image_names); + g_free (aot_module->image_guids); + + mono_os_mutex_destroy (&aot_module->mutex); + + g_free (aot_module->methods); + + if (aot_module->sofile) + mono_dl_close (aot_module->sofile); + + g_free (aot_module); + domain_set_aot_module (domain, image, NULL); + mono_aot_unlock (); +} + void mono_aot_init (void) { @@ -2682,7 +2777,7 @@ mono_aot_init (void) mono_os_mutex_init_recursive (&aot_page_mutex); aot_modules = g_hash_table_new (NULL, NULL); - mono_install_assembly_load_hook_v2 (load_aot_module, NULL, FALSE); + //mono_install_assembly_load_hook_v2 (load_aot_module, NULL, FALSE); mono_counters_register ("Async JIT info size", MONO_COUNTER_INT|MONO_COUNTER_JIT, &async_jit_info_size); char *lastaot = g_getenv ("MONO_LASTAOT"); @@ -2690,6 +2785,9 @@ mono_aot_init (void) mono_last_aot_method = atoi (lastaot); g_free (lastaot); } + + mono_domain_install_aot_callbacks (load_aot_module2, mono_aot_reset, mono_aot_image_aot_module_destroy); + aot_cache_init (); } @@ -2729,7 +2827,7 @@ load_container_amodule (MonoAssemblyLoadContext *alc) } g_assert (assm); load_aot_module (alc, assm, NULL, error); - container_amodule = assm->image->aot_module; + container_amodule = domain_get_aot_module (mono_domain_get (), assm->image); } static gboolean @@ -2787,7 +2885,7 @@ mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int sl { int i; MonoClass *klass = vtable->klass; - MonoAotModule *amodule = m_class_get_image (klass)->aot_module; + MonoAotModule *amodule = domain_get_aot_module(domain, m_class_get_image (klass)); guint8 *info, *p; MonoCachedClassInfo class_info; gboolean err; @@ -2830,11 +2928,17 @@ mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int sl gboolean mono_aot_get_cached_class_info (MonoClass *klass, MonoCachedClassInfo *res) { - MonoAotModule *amodule = m_class_get_image (klass)->aot_module; + MonoDomain* domain = mono_aot_domain_get (); + MonoAotModule* amodule = NULL; guint8 *p; gboolean err; - if (m_class_get_rank (klass) || !m_class_get_type_token (klass) || !amodule) + if (m_class_get_rank (klass) || !m_class_get_type_token (klass) || !domain) + return FALSE; + + amodule = domain_get_aot_module (domain, m_class_get_image (klass)); + + if (!amodule) return FALSE; p = (guint8*)&amodule->blob [mono_aot_get_offset (amodule->class_info_offsets, mono_metadata_token_index (m_class_get_type_token (klass)) - 1)]; @@ -2859,7 +2963,7 @@ mono_aot_get_cached_class_info (MonoClass *klass, MonoCachedClassInfo *res) gboolean mono_aot_get_class_from_name (MonoImage *image, const char *name_space, const char *name, MonoClass **klass) { - MonoAotModule *amodule = image->aot_module; + MonoAotModule *amodule = domain_get_aot_module(mono_domain_get(), image); guint16 *table, *entry; guint16 table_size; guint32 hash; @@ -2960,7 +3064,7 @@ mono_aot_get_class_from_name (MonoImage *image, const char *name_space, const ch GHashTable * mono_aot_get_weak_field_indexes (MonoImage *image) { - MonoAotModule *amodule = image->aot_module; + MonoAotModule *amodule = domain_get_aot_module(mono_domain_get(), image); if (!amodule) return NULL; @@ -3599,7 +3703,7 @@ decode_exception_debug_info (MonoAotModule *amodule, MonoDomain *domain, p += map_size; } - if (amodule != m_class_get_image (jinfo->d.method->klass)->aot_module) { + if (amodule != domain_get_aot_module(domain, m_class_get_image (jinfo->d.method->klass))) { mono_aot_lock (); if (!ji_to_amodule) ji_to_amodule = g_hash_table_new (NULL, NULL); @@ -3632,7 +3736,7 @@ mono_aot_get_unwind_info (MonoJitInfo *ji, guint32 *unwind_info_len) if (ji->async) amodule = ji->d.aot_info; else - amodule = m_class_get_image (jinfo_get_method (ji)->klass)->aot_module; + amodule = domain_get_aot_module(mono_aot_domain_get(), m_class_get_image (jinfo_get_method (ji)->klass)); g_assert (amodule); g_assert (ji->from_aot); @@ -3757,7 +3861,7 @@ mono_aot_find_jit_info (MonoDomain *domain, MonoImage *image, gpointer addr) int pos, left, right, code_len; int method_index, table_len; guint32 token; - MonoAotModule *amodule = image->aot_module; + MonoAotModule *amodule = domain_get_aot_module(domain, image); MonoMethod *method = NULL; MonoJitInfo *jinfo; guint8 *code, *ex_info, *p; @@ -3774,7 +3878,7 @@ mono_aot_find_jit_info (MonoDomain *domain, MonoImage *image, gpointer addr) nmethods = amodule->info.nmethods; - if (domain != mono_get_root_domain ()) + if (domain != mono_aot_domain_get ()) /* FIXME: */ return NULL; @@ -4367,7 +4471,7 @@ load_method (MonoDomain *domain, MonoAotModule *amodule, MonoImage *image, MonoM init_amodule_got (amodule, FALSE); - if (domain != mono_get_root_domain ()) + if (domain != mono_aot_domain_get ()) /* Non shared AOT code can't be used in other appdomains */ return NULL; @@ -4568,7 +4672,7 @@ find_aot_method_in_amodule (MonoAotModule *code_amodule, MonoMethod *method, gui // The reference to the metadata amodule will differ among multiple dedup methods // which mangle to the same name but live in different assemblies. This leads to // the caching breaking. The solution seems to be to cache using the "metadata" amodule. - MonoAotModule *metadata_amodule = m_class_get_image (method->klass)->aot_module; + MonoAotModule *metadata_amodule = domain_get_aot_module(mono_domain_get(), m_class_get_image (method->klass)); if (!metadata_amodule || metadata_amodule->out_of_date || !code_amodule || code_amodule->out_of_date) return 0xffffff; @@ -4728,8 +4832,8 @@ find_aot_method (MonoMethod *method, MonoAotModule **out_amodule) } /* Try the method's module first */ - *out_amodule = m_class_get_image (method->klass)->aot_module; - index = find_aot_method_in_amodule (m_class_get_image (method->klass)->aot_module, method, hash); + *out_amodule = domain_get_aot_module(mono_domain_get(), m_class_get_image (method->klass)); + index = find_aot_method_in_amodule (*out_amodule, method, hash); if (index != 0xffffff) return index; @@ -4750,7 +4854,7 @@ find_aot_method (MonoMethod *method, MonoAotModule **out_amodule) for (i = 0; i < modules->len; ++i) { MonoAotModule *amodule = (MonoAotModule *)g_ptr_array_index (modules, i); - if (amodule != m_class_get_image (method->klass)->aot_module) + if (amodule != *out_amodule) index = find_aot_method_in_amodule (amodule, method, hash); if (index != 0xffffff) { *out_amodule = amodule; @@ -4961,14 +5065,14 @@ mono_aot_get_method (MonoDomain *domain, MonoMethod *method, MonoError *error) MonoClass *klass = method->klass; MonoMethod *orig_method = method; guint32 method_index; - MonoAotModule *amodule = m_class_get_image (klass)->aot_module; + MonoAotModule *amodule = domain_get_aot_module (domain, m_class_get_image (klass)); guint8 *code; gboolean cache_result = FALSE; ERROR_DECL (inner_error); error_init (error); - if (domain != mono_get_root_domain ()) + if (domain != mono_aot_domain_get ()) /* Non shared AOT code can't be used in other appdomains */ return NULL; @@ -4977,7 +5081,7 @@ mono_aot_get_method (MonoDomain *domain, MonoMethod *method, MonoError *error) if (!mscorlib_aot_loaded) { mscorlib_aot_loaded = TRUE; load_aot_module (mono_domain_default_alc (domain), m_class_get_image (klass)->assembly, NULL, error); - amodule = m_class_get_image (klass)->aot_module; + amodule = amodule; } } @@ -5197,7 +5301,7 @@ mono_aot_get_method (MonoDomain *domain, MonoMethod *method, MonoError *error) gpointer mono_aot_get_method_from_token (MonoDomain *domain, MonoImage *image, guint32 token, MonoError *error) { - MonoAotModule *aot_module = image->aot_module; + MonoAotModule *aot_module = domain_get_aot_module (domain, image); int method_index; gpointer res; @@ -5297,11 +5401,11 @@ mono_aot_patch_plt_entry (gpointer aot_module, guint8 *code, guint8 *plt_entry, /* * Since AOT code is only used in the root domain, - * mono_domain_get () != mono_get_root_domain () means the calling method + * mono_domain_get () != mono_aot_domain_get () means the calling method * is AppDomain:InvokeInDomain, so this is the same check as in * mono_method_same_domain () but without loading the metadata for the method. */ - if (mono_domain_get () == mono_get_root_domain ()) { + if (mono_domain_get () == mono_aot_domain_get ()) { if (!amodule) { amodule = find_aot_module (code); } @@ -5435,8 +5539,8 @@ init_plt (MonoAotModule *amodule) if (amodule->plt_inited) return; - tramp = mono_create_specific_trampoline (amodule, MONO_TRAMPOLINE_AOT_PLT, mono_get_root_domain (), NULL); - tramp = mono_create_ftnptr (mono_domain_get (), tramp); + tramp = mono_create_specific_trampoline (amodule, MONO_TRAMPOLINE_AOT_PLT, mono_aot_domain_get (), NULL); + tramp = mono_create_ftnptr (mono_aot_domain_get (), tramp); amodule_lock (amodule); @@ -5638,7 +5742,7 @@ load_function_full (MonoAotModule *amodule, const char *name, MonoTrampInfo **ou * resolve the patch info by hand. */ if (ji->type == MONO_PATCH_INFO_SPECIFIC_TRAMPOLINE_LAZY_FETCH_ADDR) { - target = mono_create_specific_trampoline (GUINT_TO_POINTER (ji->data.uindex), MONO_TRAMPOLINE_RGCTX_LAZY_FETCH, mono_get_root_domain (), NULL); + target = mono_create_specific_trampoline (GUINT_TO_POINTER (ji->data.uindex), MONO_TRAMPOLINE_RGCTX_LAZY_FETCH, mono_aot_domain_get (), NULL); target = mono_create_ftnptr_malloc ((guint8 *)target); } else if (ji->type == MONO_PATCH_INFO_SPECIFIC_TRAMPOLINES) { target = amodule->info.specific_trampolines; @@ -5717,8 +5821,9 @@ get_mscorlib_aot_module (void) MonoAotModule *amodule; image = mono_defaults.corlib; - if (image && image->aot_module) - amodule = image->aot_module; + if (image && (amodule = domain_get_aot_module (mono_domain_get (), image))) + ; + //amodule = image->aot_module; else amodule = mscorlib_aot_module; g_assert (amodule); @@ -6206,7 +6311,7 @@ mono_aot_get_unbox_trampoline (MonoMethod *method, gpointer addr) method_index = find_aot_method (shared, &amodule); } } else - amodule = m_class_get_image (method->klass)->aot_module; + amodule = domain_get_aot_module (mono_domain_get(), m_class_get_image (method->klass)); if (amodule == NULL || method_index == 0xffffff || aot_is_slim_amodule (amodule)) { /* couldn't find unbox trampoline specifically generated for that @@ -6334,9 +6439,9 @@ mono_aot_get_lazy_fetch_trampoline (guint32 slot) */ if (!addr) addr = load_function (amodule, "rgctx_fetch_trampoline_general"); - info = (void **)mono_domain_alloc0 (mono_get_root_domain (), sizeof (gpointer) * 2); + info = (void **)mono_domain_alloc0 (mono_aot_domain_get (), sizeof (gpointer) * 2); info [0] = GUINT_TO_POINTER (slot); - info [1] = mono_create_specific_trampoline (GUINT_TO_POINTER (slot), MONO_TRAMPOLINE_RGCTX_LAZY_FETCH, mono_get_root_domain (), NULL); + info [1] = mono_create_specific_trampoline (GUINT_TO_POINTER (slot), MONO_TRAMPOLINE_RGCTX_LAZY_FETCH, mono_aot_domain_get (), NULL); code = mono_aot_get_static_rgctx_trampoline (info, addr); return mono_create_ftnptr (mono_domain_get (), code); } diff --git a/mono/mini/interp/transform.c b/mono/mini/interp/transform.c index b4284ae084e1..688b0ce233eb 100644 --- a/mono/mini/interp/transform.c +++ b/mono/mini/interp/transform.c @@ -1108,7 +1108,8 @@ mono_interp_jit_call_supported (MonoMethod *method, MonoMethodSignature *sig) if (method->wrapper_type != MONO_WRAPPER_NONE) return FALSE; - if (mono_aot_only && m_class_get_image (method->klass)->aot_module && !(method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)) { + g_assert_not_reached (); + if (mono_aot_only /*&& m_class_get_image (method->klass)->aot_module*/ && !(method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)) { ERROR_DECL (error); gpointer addr = mono_jit_compile_method_jit_only (method, error); if (addr && is_ok (error)) diff --git a/mono/mini/mini-amd64.c b/mono/mini/mini-amd64.c index 2e25c1387578..5ff03d8f6267 100644 --- a/mono/mini/mini-amd64.c +++ b/mono/mini/mini-amd64.c @@ -3064,7 +3064,8 @@ emit_call (MonoCompile *cfg, MonoCallInst *call, guint8 *code, MonoJitICallId ji MonoMethod* const method = call->method; - if (m_class_get_image (method->klass)->aot_module) + // JON FIXME + //if (m_class_get_image (method->klass)->aot_module) /* The callee might be an AOT method */ near_call = FALSE; if (method->dynamic) diff --git a/mono/mini/mini-llvm.c b/mono/mini/mini-llvm.c index 29658abd89dc..73c479be68af 100644 --- a/mono/mini/mini-llvm.c +++ b/mono/mini/mini-llvm.c @@ -9344,6 +9344,7 @@ mono_llvm_check_method_supported (MonoCompile *cfg) if (cfg->disable_llvm) return; + /* * Nested clauses where one of the clauses is a finally clause is * not supported, because LLVM can't figure out the control flow, @@ -9364,6 +9365,38 @@ mono_llvm_check_method_supported (MonoCompile *cfg) } } } + if (cfg->disable_llvm) + return; + + MonoClass* klass = cfg->method->klass; + MonoType* type = m_class_get_byval_arg(klass); + int32_t instance_size = mono_class_instance_size(klass); + if (MONO_TYPE_ISSTRUCT(type) ) + { + const int size_threshold = 256; + if (instance_size > size_threshold) + { + printf("Disabling LLVM compilation for %s.%s (struct size %d > %d)\n", + m_class_get_name(klass), cfg->method->name, instance_size, size_threshold); + cfg->disable_llvm = TRUE; + } + + if (strcmp(mono_method_get_name(cfg->method), "Execute") == 0) + { + printf("Disabling LLVM compilation for %s.%s (in case it references a large struct)\n", + m_class_get_name(klass), cfg->method->name); + cfg->disable_llvm = TRUE; + } + } + + + if (strstr(klass->name_space, "") != NULL) + { + //printf("Disabling LLVM compilation for %s.%s (in global namespace)\n", + // m_class_get_name(klass), cfg->method->name, instance_size); + cfg->disable_llvm = TRUE; + } + if (cfg->disable_llvm) return; diff --git a/mono/mini/mini-runtime.c b/mono/mini/mini-runtime.c index fe4a1d2e33cc..540d0b2fed12 100644 --- a/mono/mini/mini-runtime.c +++ b/mono/mini/mini-runtime.c @@ -868,7 +868,7 @@ mono_jit_thread_attach (MonoDomain *domain) if (!domain) { /* Happens when called from AOTed code which is only used in the root domain. */ - domain = mono_get_root_domain (); + domain = mono_aot_domain_get (); } g_assert (domain); @@ -878,7 +878,7 @@ mono_jit_thread_attach (MonoDomain *domain) if (!attached) { // #678164 gboolean background = TRUE; - mono_thread_attach_external_native_thread (mono_get_root_domain (), background); + mono_thread_attach_external_native_thread (mono_aot_domain_get (), background); /* mono_jit_thread_attach is external-only and not called by * the runtime on any of our own threads. So if we get here, @@ -2622,7 +2622,7 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, gboolean jit_ g_assert (info); if (info->subtype == WRAPPER_SUBTYPE_INTERP_IN || info->subtype == WRAPPER_SUBTYPE_INTERP_LMF) /* AOT'd wrappers for interp must be owned by root domain */ - domain = mono_get_root_domain (); + domain = mono_aot_domain_get (); } if (!domain) diff --git a/msvc/mono.props b/msvc/mono.props index e1b71ebb990c..7d088d2beb59 100644 --- a/msvc/mono.props +++ b/msvc/mono.props @@ -16,7 +16,7 @@ false - false + true false