diff --git a/src/mono/CMakeLists.txt b/src/mono/CMakeLists.txt index 59d9aa5760876..b5a99219fb02e 100644 --- a/src/mono/CMakeLists.txt +++ b/src/mono/CMakeLists.txt @@ -452,6 +452,7 @@ elseif(TARGET_ARCH STREQUAL "x86") set(SIZEOF_REGISTER 4) elseif(TARGET_ARCH STREQUAL "arm64") set(TARGET_ARM64 1) + set(ENABLE_WIP_METHOD_NOLLVM_SELF_INIT 1) set(MONO_ARCHITECTURE "\"arm64\"") set(TARGET_SIZEOF_VOID_P 8) set(SIZEOF_REGISTER 8) diff --git a/src/mono/cmake/config.h.in b/src/mono/cmake/config.h.in index 41286766d7bc4..94d9628beeb50 100644 --- a/src/mono/cmake/config.h.in +++ b/src/mono/cmake/config.h.in @@ -816,6 +816,9 @@ /* define if clockgettime exists */ #cmakedefine HAVE_CLOCK_GETTIME 1 +/* work in progress: nollvm method self initialization */ +#cmakedefine ENABLE_WIP_METHOD_NOLLVM_SELF_INIT 1 + #if defined(ENABLE_LLVM) && defined(HOST_WIN32) && defined(TARGET_WIN32) && (!defined(TARGET_AMD64) || !defined(_MSC_VER)) #error LLVM for host=Windows and target=Windows is only supported on x64 MSVC build. #endif diff --git a/src/mono/cmake/options.cmake b/src/mono/cmake/options.cmake index e5921ac358f5f..15cddf96737f7 100644 --- a/src/mono/cmake/options.cmake +++ b/src/mono/cmake/options.cmake @@ -51,6 +51,7 @@ option (ENABLE_SIGALTSTACK "Enable support for using sigaltstack for SIGSEGV and option (USE_MALLOC_FOR_MEMPOOLS "Use malloc for each single mempool allocation, so tools like Valgrind can run better") option (STATIC_COMPONENTS "Compile mono runtime components as static (not dynamic) libraries") option (ENABLE_WEBCIL "Enable the WebCIL loader") +option (ENABLE_WIP_METHOD_NOLLVM_SELF_INIT, "Enable work in progress nollvm method self initialization") set (MONO_GC "sgen" CACHE STRING "Garbage collector implementation (sgen or boehm). Default: sgen") set (GC_SUSPEND "default" CACHE STRING "GC suspend method (default, preemptive, coop, hybrid)") diff --git a/src/mono/mono/cil/cil-opcodes.xml b/src/mono/mono/cil/cil-opcodes.xml index 5b047e47e1e76..712eb72daf65e 100644 --- a/src/mono/mono/cil/cil-opcodes.xml +++ b/src/mono/mono/cil/cil-opcodes.xml @@ -328,4 +328,5 @@ + diff --git a/src/mono/mono/cil/opcode.def b/src/mono/mono/cil/opcode.def index 47bccb295e99b..439ebb0dd2fe6 100644 --- a/src/mono/mono/cil/opcode.def +++ b/src/mono/mono/cil/opcode.def @@ -328,6 +328,7 @@ OPDEF(CEE_MONO_GET_SP, "mono_get_sp", Pop0, PushI, InlineNone, 0, 2, 0xF0, 0x20, OPDEF(CEE_MONO_METHODCONST, "mono_methodconst", Pop0, PushI, InlineI, 0, 2, 0xF0, 0x21, NEXT) OPDEF(CEE_MONO_PINVOKE_ADDR_CACHE, "mono_pinvoke_addr_cache", Pop0, PushI, InlineI, 0, 2, 0xF0, 0x22, NEXT) OPDEF(CEE_MONO_REMAP_OVF_EXC, "mono_remap_ovf_exc", Pop0, Push0, InlineI, 0, 2, 0xF0, 0x23, NEXT) +OPDEF(CEE_MONO_AOT_MODULE, "mono_aot_module", Pop0, PushI, InlineI, 0, 2, 0xEF, 0x00, NEXT) #ifndef OPALIAS #define _MONO_CIL_OPALIAS_DEFINED_ #define OPALIAS(a,s,r) diff --git a/src/mono/mono/metadata/jit-icall-reg.h b/src/mono/mono/metadata/jit-icall-reg.h index 31ca69e8bab0c..f3f24e609f4ef 100644 --- a/src/mono/mono/metadata/jit-icall-reg.h +++ b/src/mono/mono/metadata/jit-icall-reg.h @@ -130,6 +130,7 @@ MONO_JIT_ICALL (cominterop_type_from_handle) \ MONO_JIT_ICALL (g_free) \ MONO_JIT_ICALL (interp_to_native_trampoline) \ MONO_JIT_ICALL (mini_llvm_init_method) \ +MONO_JIT_ICALL (mini_nollvm_init_method) \ MONO_JIT_ICALL (mini_llvmonly_init_delegate) \ MONO_JIT_ICALL (mini_llvmonly_init_delegate_virtual) \ MONO_JIT_ICALL (mini_llvmonly_init_vtable_slot) \ diff --git a/src/mono/mono/metadata/marshal-lightweight.c b/src/mono/mono/metadata/marshal-lightweight.c index 80a4a000f14c0..546ed8c778802 100644 --- a/src/mono/mono/metadata/marshal-lightweight.c +++ b/src/mono/mono/metadata/marshal-lightweight.c @@ -3361,6 +3361,17 @@ emit_return_ilgen (MonoMethodBuilder *mb) mono_mb_emit_byte (mb, CEE_RET); } +static void +emit_method_init_ilgen (MonoMethodBuilder *mb) +{ + // load aot_module + mono_mb_emit_op (mb, CEE_MONO_AOT_MODULE, NULL); + // load method_index + mono_mb_emit_ldarg (mb, 0); + + mono_mb_emit_icall_id (mb, MONO_JIT_ICALL_mini_nollvm_init_method); +} + void mono_marshal_lightweight_init (void) { @@ -3391,6 +3402,7 @@ mono_marshal_lightweight_init (void) cb.emit_native_icall_wrapper = emit_native_icall_wrapper_ilgen; cb.emit_icall_wrapper = emit_icall_wrapper_ilgen; cb.emit_return = emit_return_ilgen; + cb.emit_method_init_nollvm = emit_method_init_ilgen; cb.emit_vtfixup_ftnptr = emit_vtfixup_ftnptr_ilgen; cb.mb_skip_visibility = mb_skip_visibility_ilgen; cb.mb_emit_exception = mb_emit_exception_ilgen; diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 02309b933f160..e3f8603233a7a 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -2948,12 +2948,12 @@ MonoMethod * mono_marshal_get_aot_init_wrapper (MonoAotInitSubtype subtype) { MonoMethodBuilder *mb; + const char *name = mono_marshal_get_aot_init_wrapper_name (subtype); MonoMethod *res; WrapperInfo *info; MonoMethodSignature *csig = NULL; MonoType *void_type = mono_get_void_type (); MonoType *int_type = mono_get_int_type (); - const char *name = mono_marshal_get_aot_init_wrapper_name (subtype); switch (subtype) { case AOT_INIT_METHOD: @@ -2977,6 +2977,12 @@ mono_marshal_get_aot_init_wrapper (MonoAotInitSubtype subtype) mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_OTHER); +#ifdef ENABLE_WIP_METHOD_NOLLVM_SELF_INIT + if (subtype == AOT_INIT_METHOD) { + get_marshal_cb ()->emit_method_init_nollvm (mb); + } +#endif + // Just stub out the method with a "CEE_RET" // Our codegen backend generates other code here get_marshal_cb ()->emit_return (mb); diff --git a/src/mono/mono/metadata/marshal.h b/src/mono/mono/metadata/marshal.h index eaef14bf7bdcf..6ca9b3c2d76c7 100644 --- a/src/mono/mono/metadata/marshal.h +++ b/src/mono/mono/metadata/marshal.h @@ -349,6 +349,7 @@ typedef struct { void (*emit_native_icall_wrapper) (MonoMethodBuilder *mb, MonoMethod *method, MonoMethodSignature *csig, gboolean check_exceptions, gboolean aot, MonoMethodPInvoke *pinfo); void (*emit_icall_wrapper) (MonoMethodBuilder *mb, MonoJitICallInfo *callinfo, MonoMethodSignature *csig2, gboolean check_exceptions); void (*emit_return) (MonoMethodBuilder *mb); + void (*emit_method_init_nollvm) (MonoMethodBuilder *mb); void (*emit_vtfixup_ftnptr) (MonoMethodBuilder *mb, MonoMethod *method, int param_count, guint16 type); void (*mb_skip_visibility) (MonoMethodBuilder *mb); void (*mb_emit_exception) (MonoMethodBuilder *mb, const char *exc_nspace, const char *exc_name, const char *msg); diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 2cd2dbc234f21..7cd6cc14e229f 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -4466,8 +4466,6 @@ add_jit_icall_wrapper (MonoAotCompile *acfg, MonoJitICallInfo *callinfo) add_method (acfg, mono_marshal_get_icall_wrapper (callinfo, TRUE)); } -#if ENABLE_LLVM - static void add_lazy_init_wrappers (MonoAotCompile *acfg) { @@ -4475,8 +4473,6 @@ add_lazy_init_wrappers (MonoAotCompile *acfg) add_method (acfg, mono_marshal_get_aot_init_wrapper ((MonoAotInitSubtype)i)); } -#endif - static MonoMethod* get_runtime_invoke_sig (MonoMethodSignature *sig) { @@ -6835,7 +6831,9 @@ emit_and_reloc_code (MonoAotCompile *acfg, MonoMethod *method, guint8 *code, gui /* * This is a call from a JITted method to the init wrapper emitted by LLVM. */ +#ifndef ENABLE_WIP_METHOD_NOLLVM_SELF_INIT g_assert (acfg->aot_opts.llvm && acfg->aot_opts.direct_extern_calls); +#endif const char *init_name = mono_marshal_get_aot_init_wrapper_name (info->d.aot_init.subtype); char *symbol = g_strdup_printf ("%s%s_%s", acfg->user_symbol_prefix, acfg->global_prefix, init_name); @@ -7106,7 +7104,14 @@ emit_method_code (MonoAotCompile *acfg, MonoCompile *cfg) if (acfg->global_symbols && acfg->need_no_dead_strip) fprintf (acfg->fp, " .no_dead_strip %s\n", cfg->asm_symbol); - emit_label (acfg, cfg->asm_symbol); + if (method->wrapper_type == MONO_WRAPPER_OTHER && mono_marshal_get_wrapper_info (method)->subtype == WRAPPER_SUBTYPE_AOT_INIT) { + WrapperInfo *info = mono_marshal_get_wrapper_info (method); + const char *init_name = mono_marshal_get_aot_init_wrapper_name (info->d.aot_init.subtype); + char *symbol = g_strdup_printf ("%s%s_%s", acfg->user_symbol_prefix, acfg->global_prefix, init_name); + emit_label (acfg, symbol); + } else { + emit_label (acfg, cfg->asm_symbol); + } if (acfg->aot_opts.write_symbols && !acfg->global_symbols && !acfg->llvm) { /* @@ -7331,6 +7336,7 @@ encode_patch (MonoAotCompile *acfg, MonoJumpInfo *patch_info, guint8 *buf, guint } case MONO_PATCH_INFO_SEQ_POINT_INFO: case MONO_PATCH_INFO_AOT_MODULE: + case MONO_PATCH_INFO_INIT_BITSET: break; case MONO_PATCH_INFO_SIGNATURE: case MONO_PATCH_INFO_GSHAREDVT_IN_WRAPPER: @@ -7492,7 +7498,8 @@ emit_method_info (MonoAotCompile *acfg, MonoCompile *cfg) if (patch_info->type == MONO_PATCH_INFO_GC_CARD_TABLE_ADDR || patch_info->type == MONO_PATCH_INFO_GC_NURSERY_START || patch_info->type == MONO_PATCH_INFO_GC_NURSERY_BITS || - patch_info->type == MONO_PATCH_INFO_AOT_MODULE) { + patch_info->type == MONO_PATCH_INFO_AOT_MODULE || + patch_info->type == MONO_PATCH_INFO_INIT_BITSET) { /* Stored in a GOT slot initialized at module load time */ patch_info->type = MONO_PATCH_INFO_NONE; continue; @@ -14519,6 +14526,7 @@ static void aot_dump (MonoAotCompile *acfg) static const MonoJitICallId preinited_jit_icalls [] = { MONO_JIT_ICALL_mini_llvm_init_method, + MONO_JIT_ICALL_mini_nollvm_init_method, MONO_JIT_ICALL_mini_llvmonly_throw_nullref_exception, MONO_JIT_ICALL_mini_llvmonly_throw_index_out_of_range_exception, MONO_JIT_ICALL_mini_llvmonly_throw_invalid_cast_exception, @@ -14569,6 +14577,10 @@ add_preinit_got_slots (MonoAotCompile *acfg) ji->type = MONO_PATCH_INFO_AOT_MODULE; add_preinit_slot (acfg, ji); + ji = (MonoJumpInfo *)mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJumpInfo)); + ji->type = MONO_PATCH_INFO_INIT_BITSET; + add_preinit_slot (acfg, ji); + ji = (MonoJumpInfo *)mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJumpInfo)); ji->type = MONO_PATCH_INFO_GC_NURSERY_BITS; add_preinit_slot (acfg, ji); @@ -15236,6 +15248,7 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options) add_method (acfg, mono_marshal_get_llvm_func_wrapper (LLVM_FUNC_WRAPPER_GC_POLL)); } #endif + add_lazy_init_wrappers (acfg); if (mono_aot_mode_is_interp (&acfg->aot_opts) && mono_is_corlib_image (acfg->image->assembly->image)) { MonoMethod *wrapper = mini_get_interp_lmf_wrapper ("mono_interp_to_native_trampoline", (gpointer) mono_interp_to_native_trampoline); diff --git a/src/mono/mono/mini/aot-runtime.c b/src/mono/mono/mini/aot-runtime.c index 0faba078d6dac..ebe67015145db 100644 --- a/src/mono/mono/mini/aot-runtime.c +++ b/src/mono/mono/mini/aot-runtime.c @@ -152,6 +152,7 @@ struct MonoAotModule { guint8 *unwind_info; /* Maps method index -> unbox tramp */ gpointer *unbox_tramp_per_method; + MonoBitSet *mono_inited; /* Points to the mono EH data created by LLVM */ guint8 *mono_eh_frame; @@ -2237,6 +2238,11 @@ load_aot_module (MonoAssemblyLoadContext *alc, MonoAssembly *assembly, gpointer mscorlib_aot_module = amodule; } + /* + * Methods init bitset used for initialization during the runtime + */ + amodule->mono_inited = mono_bitset_new (amodule->info.nmethods, 0); + /* Compute method addresses */ amodule->methods = (void **)g_malloc0 (amodule->info.nmethods * sizeof (gpointer)); for (guint32 i = 0; i < amodule->info.nmethods; ++i) { @@ -3546,6 +3552,12 @@ sort_methods (MonoAotModule *amodule) g_free (method_indexes); } +MonoBitSet* +mono_aot_get_mono_inited (MonoAotModule *amodule) +{ + return amodule->mono_inited; +} + /* * mono_aot_find_jit_info: * @@ -4013,6 +4025,10 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin case MONO_PATCH_INFO_AOT_MODULE: case MONO_PATCH_INFO_MSCORLIB_GOT_ADDR: break; + case MONO_PATCH_INFO_INIT_BITSET: { + ji->data.target = aot_module->mono_inited; + break; + } case MONO_PATCH_INFO_SIGNATURE: case MONO_PATCH_INFO_GSHAREDVT_IN_WRAPPER: ji->data.target = decode_signature (aot_module, p, &p); @@ -4372,6 +4388,10 @@ load_method (MonoAotModule *amodule, MonoImage *image, MonoMethod *method, guint res = init_method (amodule, NULL, method_index, method, NULL, error); if (!res) goto cleanup; +#ifdef ENABLE_WIP_METHOD_NOLLVM_SELF_INIT + else + mono_bitset_set (mono_aot_get_mono_inited (amodule), method_index); +#endif } } @@ -5932,6 +5952,20 @@ no_specific_trampoline (void) g_assert_not_reached (); } +void +mini_nollvm_init_method (MonoAotModule* amodule, guint32 method_index) +{ + MonoBitSet *inited_bitset = mono_aot_get_mono_inited (amodule); + + ERROR_DECL (error); + if (!mono_bitset_test (inited_bitset, method_index)) { + if (init_method (amodule, NULL, method_index, NULL, NULL, error)) { + mono_bitset_set (inited_bitset, method_index); + } + } + mono_error_assert_ok (error); +} + /* * Return a specific trampoline from the AOT file. */ diff --git a/src/mono/mono/mini/aot-runtime.h b/src/mono/mono/mini/aot-runtime.h index bd66659353627..53b80e9c7e65a 100644 --- a/src/mono/mono/mini/aot-runtime.h +++ b/src/mono/mono/mini/aot-runtime.h @@ -257,6 +257,7 @@ guint32 mono_aot_get_plt_info_offset (gpointer aot_module, guint8 *plt_en gboolean 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); MonoJitInfo* mono_aot_find_jit_info (MonoImage *image, gpointer addr); +MonoBitSet* mono_aot_get_mono_inited (MonoAotModule *amodule); gpointer mono_aot_plt_resolve (gpointer aot_module, host_mgreg_t *regs, guint8 *code, MonoError *error); void mono_aot_patch_plt_entry (gpointer aot_module, guint8 *code, guint8 *plt_entry, gpointer *got, host_mgreg_t *regs, guint8 *addr); gpointer mono_aot_get_method_from_vt_slot (MonoVTable *vtable, int slot, MonoError *error); @@ -278,6 +279,8 @@ void mono_aot_set_make_unreadable (gboolean unreadable); gboolean mono_aot_is_pagefault (void *ptr); void mono_aot_handle_pagefault (void *ptr); +void mini_nollvm_init_method (MonoAotModule* amodule, guint32 method_index); + guint32 mono_aot_find_method_index (MonoMethod *method); gboolean mono_aot_init_llvm_method (gpointer aot_module, gpointer method_info, MonoClass *init_class, MonoError *error); GHashTable *mono_aot_get_weak_field_indexes (MonoImage *image); diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index fd8a31e1e4360..ab2664a3bc733 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -11380,6 +11380,12 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b *sp++ = ins; break; } + case MONO_CEE_MONO_AOT_MODULE: { + g_assert (cfg->compile_aot); + EMIT_NEW_AOTCONST (cfg, ins, MONO_PATCH_INFO_AOT_MODULE, NULL); + *sp++ = ins; + break; + } case MONO_CEE_MONO_NOT_TAKEN: g_assert (method->wrapper_type != MONO_WRAPPER_NONE); cfg->cbb->out_of_line = TRUE; diff --git a/src/mono/mono/mini/mini-arm64.c b/src/mono/mono/mini/mini-arm64.c index 2fac9738f61c2..2de56794055fc 100644 --- a/src/mono/mono/mini/mini-arm64.c +++ b/src/mono/mono/mini/mini-arm64.c @@ -5990,6 +5990,15 @@ mono_arch_emit_prolog (MonoCompile *cfg) code = emit_addx_imm (code, cfg->arch.args_reg, ARMREG_FP, cfg->stack_offset); } + /* Call the init wrapper which checks if the method needs to be initialised or not */ + /* https://github.com/dotnet/runtime/pull/82711, https://github.com/dotnet/runtime/issues/83378, https://github.com/dotnet/runtime/issues/83379 */ +#ifdef ENABLE_WIP_METHOD_NOLLVM_SELF_INIT + if (cfg->compile_aot && !COMPILE_LLVM (cfg)) { + code = emit_imm (code, ARMREG_R0, cfg->method_index); + code = emit_call (cfg, code, MONO_PATCH_INFO_METHOD, (gconstpointer) mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD)); + } +#endif + /* Save return area addr received in R8 */ if (cfg->vret_addr) { MonoInst *ins = cfg->vret_addr; diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index b7aabc74549ce..42a095b5bd85c 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -1259,6 +1259,7 @@ mono_patch_info_hash (gconstpointer data) case MONO_PATCH_INFO_GOT_OFFSET: case MONO_PATCH_INFO_GC_SAFE_POINT_FLAG: case MONO_PATCH_INFO_AOT_MODULE: + case MONO_PATCH_INFO_INIT_BITSET: case MONO_PATCH_INFO_PROFILER_ALLOCATION_COUNT: case MONO_PATCH_INFO_PROFILER_CLAUSE_COUNT: case MONO_PATCH_INFO_SPECIFIC_TRAMPOLINES: @@ -1536,6 +1537,7 @@ mono_resolve_patch_target_ext (MonoMemoryManager *mem_manager, MonoMethod *metho case MONO_PATCH_INFO_FIELD: case MONO_PATCH_INFO_SIGNATURE: case MONO_PATCH_INFO_AOT_MODULE: + case MONO_PATCH_INFO_INIT_BITSET: target = patch_info->data.target; break; case MONO_PATCH_INFO_IID: @@ -5122,6 +5124,7 @@ register_icalls (void) register_dyn_icall (mono_component_debugger ()->user_break, mono_debugger_agent_user_break, mono_icall_sig_void, FALSE); register_icall (mini_llvm_init_method, mono_icall_sig_void_ptr_ptr_ptr_ptr, TRUE); + register_icall (mini_nollvm_init_method, mono_icall_sig_void_ptr_int, TRUE); register_icall_no_wrapper (mini_llvmonly_resolve_iface_call_gsharedvt, mono_icall_sig_ptr_object_int_ptr_ptr); register_icall_no_wrapper (mini_llvmonly_resolve_vcall_gsharedvt, mono_icall_sig_ptr_object_int_ptr_ptr); register_icall_no_wrapper (mini_llvmonly_resolve_vcall_gsharedvt_fast, mono_icall_sig_ptr_object_int); diff --git a/src/mono/mono/mini/patch-info.h b/src/mono/mono/mini/patch-info.h index eaec7450c24c9..7570999135d9e 100644 --- a/src/mono/mono/mini/patch-info.h +++ b/src/mono/mono/mini/patch-info.h @@ -50,6 +50,7 @@ PATCH_INFO(VIRT_METHOD, "virt_method") PATCH_INFO(GC_SAFE_POINT_FLAG, "gc_safe_point_flag") PATCH_INFO(NONE, "none") PATCH_INFO(AOT_MODULE, "aot_module") +PATCH_INFO(INIT_BITSET, "init_bitset") PATCH_INFO(AOT_JIT_INFO, "aot_jit_info") PATCH_INFO(GC_NURSERY_BITS, "gc_nursery_bits") PATCH_INFO(GSHAREDVT_IN_WRAPPER, "gsharedvt_in_wrapper") diff --git a/src/mono/sample/HelloWorld/HelloWorld.csproj b/src/mono/sample/HelloWorld/HelloWorld.csproj index cc052494b398f..f3a4d42f9ea4c 100644 --- a/src/mono/sample/HelloWorld/HelloWorld.csproj +++ b/src/mono/sample/HelloWorld/HelloWorld.csproj @@ -6,6 +6,10 @@ true + + + + diff --git a/src/mono/sample/HelloWorld/Makefile b/src/mono/sample/HelloWorld/Makefile index bb380b0bc1c85..08ad8fa85de88 100644 --- a/src/mono/sample/HelloWorld/Makefile +++ b/src/mono/sample/HelloWorld/Makefile @@ -31,4 +31,4 @@ run: publish $(TOP)artifacts/bin/HelloWorld/$(MONO_ARCH)/$(MONO_CONFIG)/$(TARGET_OS)-$(MONO_ARCH)/publish/HelloWorld clean: - rm -rf $(TOP)artifacts/bin/HelloWorld/ + rm -rf $(TOP)artifacts/bin/HelloWorld/ \ No newline at end of file diff --git a/src/mono/sample/HelloWorld/Program.cs b/src/mono/sample/HelloWorld/Program.cs index 0a65da4203a6d..59b74eca24281 100644 --- a/src/mono/sample/HelloWorld/Program.cs +++ b/src/mono/sample/HelloWorld/Program.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using MyLib; namespace HelloWorld { @@ -9,11 +10,8 @@ internal class Program { private static void Main(string[] args) { - bool isMono = typeof(object).Assembly.GetType("Mono.RuntimeStructs") != null; - Console.WriteLine($"Hello World {(isMono ? "from Mono!" : "from CoreCLR!")}"); - Console.WriteLine(typeof(object).Assembly.FullName); - Console.WriteLine(System.Reflection.Assembly.GetEntryAssembly ()); - Console.WriteLine(System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription); + Class1 c = new Class1(); + c.getCat(); } } } diff --git a/src/mono/sample/HelloWorld/README b/src/mono/sample/HelloWorld/README new file mode 100644 index 0000000000000..766f7a0ac15cd --- /dev/null +++ b/src/mono/sample/HelloWorld/README @@ -0,0 +1,7 @@ +Steps to run Program.cs + +- build runtime : ./build.sh mono+libs+clr.hosts -c Debug +- cd src/mono/sample/HelloWorld +- make publish +- ./run build.sh (aot-compile) +- ./run run (execute) \ No newline at end of file diff --git a/src/mono/sample/HelloWorld/run.sh b/src/mono/sample/HelloWorld/run.sh new file mode 100755 index 0000000000000..bcc5584040296 --- /dev/null +++ b/src/mono/sample/HelloWorld/run.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +# should be placed in src/mono/sample/HelloWorld/ + +REPO_ROOT=../../../.. +LLVM_PATH=$REPO_ROOT/artifacts/bin/mono/OSX.arm64.Debug +MONO_SGEN=$REPO_ROOT/artifacts/obj/mono/OSX.arm64.Debug/mono/mini/mono-sgen +export MONO_PATH=$REPO_ROOT/artifacts/bin/HelloWorld/arm64/Debug/osx-arm64/publish + +if [ "$1" != "build" ] && [ "$1" != "build-all" ] && [ "$1" != "run" ]; then + echo "Pass 'build', 'build-all' or 'run' as the first parameter"; + exit 1 +fi + +if [ "$1" == "build" ] || [ "$1" == "build-all" ]; then + if [ "$2" == "interp" ]; then + export MONO_ENV_OPTIONS="--aot=full,interp,llvm,llvm-path=$LLVM_PATH,mattr=crc,mattr=crypto" + else + export MONO_ENV_OPTIONS="--aot=full" + # export MONO_ENV_OPTIONS="--aot=full,llvm,llvm-path=$LLVM_PATH,mattr=crc,mattr=crypto" + fi + if [ "$1" == "build-all" ]; then + DLLS=$MONO_PATH/*.dll; + else + DLLS=$MONO_PATH/HelloWorld.dll; + fi + for dll in $DLLS; + do + echo "> AOTing MONO_ENV_OPTIONS=$MONO_ENV_OPTIONS $dll"; + $MONO_SGEN $dll + if [ $? -eq 1 ]; then + echo "> AOTing MONO_ENV_OPTIONS=$MONO_ENV_OPTIONS $dll has failed."; + exit 1 + fi + done +else + if [ "$2" == "interp" ]; then + export MONO_ENV_OPTIONS="--full-aot-interp" + else + export MONO_ENV_OPTIONS="--full-aot" + fi + echo "Running HelloWorld with: MONO_ENV_OPTIONS=$MONO_ENV_OPTIONS $MONO_SGEN $MONO_PATH/HelloWorld.dll"; + $MONO_SGEN $MONO_PATH/HelloWorld.dll +fi +exit 0 + diff --git a/src/mono/sample/MyLib/Class1.cs b/src/mono/sample/MyLib/Class1.cs new file mode 100644 index 0000000000000..3643722dcd6cf --- /dev/null +++ b/src/mono/sample/MyLib/Class1.cs @@ -0,0 +1,25 @@ +namespace MyLib; + + +public class Class1 +{ + public void getCat() { + Animal a = new Animal("DOG"); + Console.WriteLine(a.isCat() ? "YES" : "NO"); + } +} + + +public class Animal +{ + private string animal{get; set;} + + public Animal(string animal) + { + this.animal = animal; + } + + public bool isCat() { + return string.Compare("CAT", animal) == 0 ? true : false; + } +} diff --git a/src/mono/sample/MyLib/MyLib.csproj b/src/mono/sample/MyLib/MyLib.csproj new file mode 100644 index 0000000000000..fa71b7ae6a349 --- /dev/null +++ b/src/mono/sample/MyLib/MyLib.csproj @@ -0,0 +1,9 @@ + + + + net8.0 + enable + enable + + +