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
+
+
+