From a6b88f9f276c06f0226968fa52c4bc309ac51a56 Mon Sep 17 00:00:00 2001 From: Vlad - Alexandru Ionescu Date: Fri, 30 Jun 2023 12:27:51 +0200 Subject: [PATCH 01/14] Preliminary work for nollvm init method Signed-off-by: Vlad - Alexandru Ionescu --- src/mono/mono/metadata/jit-icall-reg.h | 2 ++ src/mono/mono/metadata/marshal-lightweight.c | 17 +++++++++ src/mono/mono/metadata/marshal.c | 10 ++++-- src/mono/mono/metadata/marshal.h | 3 +- src/mono/mono/mini/aot-compiler.c | 22 ++++++++++-- src/mono/mono/mini/aot-runtime.c | 38 +++++++++++++++++++- src/mono/mono/mini/aot-runtime.h | 4 +++ src/mono/mono/mini/method-to-ir.c | 2 +- src/mono/mono/mini/mini-amd64.c | 14 ++++---- src/mono/mono/mini/mini-arm64.c | 31 +++++++++++----- src/mono/mono/mini/mini-runtime.c | 4 +++ src/mono/mono/mini/patch-info.h | 1 + src/mono/sample/HelloWorld/HelloWorld.csproj | 10 +++--- src/mono/sample/HelloWorld/Program.cs | 8 ++--- src/mono/sample/MyLib/Class1.cs | 25 +++++++++++++ src/mono/sample/MyLib/MyLib.csproj | 9 +++++ 16 files changed, 167 insertions(+), 33 deletions(-) create mode 100644 src/mono/sample/MyLib/Class1.cs create mode 100644 src/mono/sample/MyLib/MyLib.csproj diff --git a/src/mono/mono/metadata/jit-icall-reg.h b/src/mono/mono/metadata/jit-icall-reg.h index 122d8dcdd18b7..d8ea043ed463b 100644 --- a/src/mono/mono/metadata/jit-icall-reg.h +++ b/src/mono/mono/metadata/jit-icall-reg.h @@ -130,6 +130,8 @@ 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_nollvm_init_method1) \ 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 06a20123dbee6..f38950500faff 100644 --- a/src/mono/mono/metadata/marshal-lightweight.c +++ b/src/mono/mono/metadata/marshal-lightweight.c @@ -3123,6 +3123,22 @@ emit_return_ilgen (MonoMethodBuilder *mb) mono_mb_emit_byte (mb, CEE_RET); } +static void +emit_method_init_ilgen (MonoMethodBuilder *mb, MonoAotModule *aot_module, MonoMethod *method, MonoBitSet *bitset, guint32 index, MonoBitSet* mono_inited) +{ + // load aot_module + mono_mb_emit_ptr (mb, aot_module); + // load method + mono_mb_emit_ptr (mb, method); + // load method_index + mono_mb_emit_i4 (mb, index); + /// load bitset + mono_mb_emit_ptr (mb, bitset); + mono_mb_emit_icall_id (mb, MONO_JIT_ICALL_mini_nollvm_init_method); + + mono_mb_emit_byte (mb, CEE_RET); +} + void mono_marshal_lightweight_init (void) { @@ -3152,6 +3168,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 = emit_method_init_ilgen; cb.emit_vtfixup_ftnptr = emit_vtfixup_ftnptr_ilgen; cb.mb_skip_visibility = mb_skip_visibility_ilgen; cb.mb_set_dynamic = mb_set_dynamic_ilgen; diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 61cc96bbf7cad..10675a1a20035 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -2954,15 +2954,15 @@ mono_marshal_get_aot_init_wrapper_name (MonoAotInitSubtype subtype) } MonoMethod * -mono_marshal_get_aot_init_wrapper (MonoAotInitSubtype subtype) +mono_marshal_get_aot_init_wrapper (MonoAotInitSubtype subtype, MonoBitSet *bitset, guint32 token, MonoAotModule *aot_module, MonoMethod *method) { 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: @@ -2986,9 +2986,15 @@ mono_marshal_get_aot_init_wrapper (MonoAotInitSubtype subtype) mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_OTHER); +#if ENABLE_LLVM // Just stub out the method with a "CEE_RET" // Our codegen backend generates other code here get_marshal_cb ()->emit_return (mb); +#else + if (!mono_bitset_test(bitset, token)) { + get_marshal_cb ()->emit_method_init(mb, aot_module, method, bitset, token, bitset); + } +#endif info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_AOT_INIT); info->d.aot_init.subtype = subtype; diff --git a/src/mono/mono/metadata/marshal.h b/src/mono/mono/metadata/marshal.h index e6ad3153bbfda..fc500fea9ce74 100644 --- a/src/mono/mono/metadata/marshal.h +++ b/src/mono/mono/metadata/marshal.h @@ -338,6 +338,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) (MonoMethodBuilder *mb, MonoAotModule *aot_module, MonoMethod *method, MonoBitSet *bitset, guint32 index, MonoBitSet* mono_inited); void (*emit_vtfixup_ftnptr) (MonoMethodBuilder *mb, MonoMethod *method, int param_count, guint16 type); void (*mb_skip_visibility) (MonoMethodBuilder *mb); void (*mb_set_dynamic) (MonoMethodBuilder *mb); @@ -516,7 +517,7 @@ MonoMethod * mono_marshal_get_icall_wrapper (MonoJitICallInfo *callinfo, gboolean check_exceptions); MonoMethod * -mono_marshal_get_aot_init_wrapper (MonoAotInitSubtype subtype); +mono_marshal_get_aot_init_wrapper (MonoAotInitSubtype subtype, MonoBitSet *bitset, guint32 token, MonoAotModule *aot_module, MonoMethod *method); const char * mono_marshal_get_aot_init_wrapper_name (MonoAotInitSubtype subtype); diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index a5d36d9c93901..cc21ed9fb6c30 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -4455,7 +4455,7 @@ static void add_lazy_init_wrappers (MonoAotCompile *acfg) { for (int i = 0; i < AOT_INIT_METHOD_NUM; ++i) - add_method (acfg, mono_marshal_get_aot_init_wrapper ((MonoAotInitSubtype)i)); + add_method (acfg, mono_marshal_get_aot_init_wrapper ((MonoAotInitSubtype)i, NULL, 0, NULL, NULL)); } #endif @@ -7213,7 +7213,13 @@ 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; + // encode_value (mono_bitset_size (acfg->mono_inited) , p, &p); + // for (guint32 i = 0 ; i < mono_bitset_size (acfg->mono_inited); i++) { + // encode_value (i , p, &p); + // } + // break; case MONO_PATCH_INFO_SIGNATURE: case MONO_PATCH_INFO_GSHAREDVT_IN_WRAPPER: encode_signature (acfg, (MonoMethodSignature*)patch_info->data.target, p, &p); @@ -7374,7 +7380,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; @@ -10806,6 +10813,13 @@ emit_code (MonoAotCompile *acfg) */ emit_padding (acfg, 16); + // /* + // * Methods init bitset used for initialization during the runtime + // */ + // acfg->mono_inited = mono_bitset_mem_new ( + // mono_mempool_alloc0 (acfg->mempool, mono_bitset_alloc_size (acfg->method_order->len, 0)), + // acfg->method_order->len, 0); + for (guint oindex = 0; oindex < acfg->method_order->len; ++oindex) { MonoCompile *cfg; MonoMethod *method; @@ -14417,6 +14431,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); diff --git a/src/mono/mono/mini/aot-runtime.c b/src/mono/mono/mini/aot-runtime.c index 1b273de6c0146..6fa9003e4b5ab 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; @@ -1093,7 +1094,7 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod g_free (sig); } else if (subtype == WRAPPER_SUBTYPE_AOT_INIT) { guint32 init_type = decode_value (p, &p); - ref->method = mono_marshal_get_aot_init_wrapper ((MonoAotInitSubtype) init_type); + ref->method = mono_marshal_get_aot_init_wrapper ((MonoAotInitSubtype) init_type, NULL, 0, NULL, NULL); } else if (subtype == WRAPPER_SUBTYPE_LLVM_FUNC) { guint32 init_type = decode_value (p, &p); ref->method = mono_marshal_get_llvm_func_wrapper ((MonoLLVMFuncWrapperSubtype) init_type); @@ -2218,6 +2219,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) { @@ -3528,6 +3534,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: * @@ -3995,6 +4007,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); @@ -5913,6 +5929,26 @@ no_specific_trampoline (void) g_assert_not_reached (); } +void +mini_nollvm_init_method (MonoAotModule* amodule, MonoMethod* method, guint32 method_index, MonoBitSet* mono_inited) +{ + ERROR_DECL (error); + if (init_method (amodule, NULL, method_index, method, NULL, error)) { + mono_bitset_set(mono_inited, method_index); + } + mono_error_assert_ok (error); +} + +void +mini_nollvm_init_method1 (MonoMethod* method, guint32 method_index, MonoBitSet* mono_inited) +{ + ERROR_DECL (error); + if (init_method (m_class_get_image (method->klass)->aot_module, NULL, method_index, method, NULL, error)) { + mono_bitset_set(mono_inited, 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..033faa261d9d6 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,9 @@ 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, MonoMethod* method, guint32 method_index, MonoBitSet* mono_inited); +void mini_nollvm_init_method1 (MonoMethod* method, guint32 method_index, MonoBitSet* mono_inited); + 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 3e84e55c45f5e..20f50ea825238 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -6694,7 +6694,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b * FIXME: Optimize this */ g_assert (!cfg->gshared); - wrapper = mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD); + wrapper = mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD, NULL, 0, NULL, NULL); /* Emit this into the entry bb so it comes before the GC safe point which depends on an inited GOT */ cfg->cbb = cfg->bb_entry; idx = mono_aot_get_method_index (cfg->method); diff --git a/src/mono/mono/mini/mini-amd64.c b/src/mono/mono/mini/mini-amd64.c index 10c964b9beff2..96cf2121158d1 100644 --- a/src/mono/mono/mini/mini-amd64.c +++ b/src/mono/mono/mini/mini-amd64.c @@ -5479,7 +5479,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) call = (MonoCallInst*)ins; code = amd64_handle_varargs_call (cfg, code, call, FALSE); - code = emit_call (cfg, call, code, MONO_JIT_ICALL_ZeroIsReserved); + code = emit_call (cfg, call, code, MONO_JIT_ICALL_ZeroIsReserved, NULL); ins->flags |= MONO_INST_GC_CALLSITE; ins->backend.pc_offset = GPTRDIFF_TO_INT (code - cfg->native_code); code = emit_move_return_value (cfg, ins, code); @@ -5639,7 +5639,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) jump = code; amd64_branch8 (code, X86_CC_NZ, -1, 1); - code = emit_call (cfg, NULL, code, MONO_JIT_ICALL_mono_generic_class_init); + code = emit_call (cfg, NULL, code, MONO_JIT_ICALL_mono_generic_class_init, NULL); ins->flags |= MONO_INST_GC_CALLSITE; ins->backend.pc_offset = GPTRDIFF_TO_INT (code - cfg->native_code); @@ -5697,14 +5697,14 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) } case OP_THROW: { amd64_mov_reg_reg (code, AMD64_ARG_REG1, ins->sreg1, 8); - code = emit_call (cfg, NULL, code, MONO_JIT_ICALL_mono_arch_throw_exception); + code = emit_call (cfg, NULL, code, MONO_JIT_ICALL_mono_arch_throw_exception, NULL); ins->flags |= MONO_INST_GC_CALLSITE; ins->backend.pc_offset = GPTRDIFF_TO_INT (code - cfg->native_code); break; } case OP_RETHROW: { amd64_mov_reg_reg (code, AMD64_ARG_REG1, ins->sreg1, 8); - code = emit_call (cfg, NULL, code, MONO_JIT_ICALL_mono_arch_rethrow_exception); + code = emit_call (cfg, NULL, code, MONO_JIT_ICALL_mono_arch_rethrow_exception, NULL); ins->flags |= MONO_INST_GC_CALLSITE; ins->backend.pc_offset = GPTRDIFF_TO_INT (code - cfg->native_code); break; @@ -7328,7 +7328,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) amd64_test_membase_imm_size (code, ins->sreg1, 0, 1, 4); br[0] = code; x86_branch8 (code, X86_CC_EQ, 0, FALSE); - code = emit_call (cfg, NULL, code, MONO_JIT_ICALL_mono_threads_state_poll); + code = emit_call (cfg, NULL, code, MONO_JIT_ICALL_mono_threads_state_poll, NULL); amd64_patch (br[0], code); break; } @@ -7455,7 +7455,7 @@ emit_prolog_setup_sp_win64 (MonoCompile *cfg, guint8 *code, int alloc_size, int if (alloc_size >= 0x1000) { amd64_mov_reg_imm (code, AMD64_RAX, alloc_size); - code = emit_call (cfg, NULL, code, MONO_JIT_ICALL_mono_chkstk_win64); + code = emit_call (cfg, NULL, code, MONO_JIT_ICALL_mono_chkstk_win64, NULL); } amd64_alu_reg_imm (code, X86_SUB, AMD64_RSP, alloc_size); @@ -8128,7 +8128,7 @@ mono_arch_emit_exceptions (MonoCompile *cfg) patch_info->type = MONO_PATCH_INFO_NONE; - code = emit_call (cfg, NULL, code, MONO_JIT_ICALL_mono_arch_throw_corlib_exception); + code = emit_call (cfg, NULL, code, MONO_JIT_ICALL_mono_arch_throw_corlib_exception, NULL); amd64_mov_reg_imm (buf, AMD64_ARG_REG2, (code - cfg->native_code) - throw_ip); while (buf < buf2) diff --git a/src/mono/mono/mini/mini-arm64.c b/src/mono/mono/mini/mini-arm64.c index f163a76f50508..192f8d7dfe323 100644 --- a/src/mono/mono/mini/mini-arm64.c +++ b/src/mono/mono/mini/mini-arm64.c @@ -1049,14 +1049,14 @@ emit_xinsert_i8_r8 (guint8* code, MonoTypeEnum type, int dreg, int src_reg, int } static guint8* -emit_call (MonoCompile *cfg, guint8* code, MonoJumpInfoType patch_type, gconstpointer data) +emit_call (MonoCompile *cfg, guint8* code, MonoJumpInfoType patch_type, gconstpointer data, MonoMethod *method) { /* mono_add_patch_info_rel (cfg, code - cfg->native_code, patch_type, data, MONO_R_ARM64_IMM); code = emit_imm64_template (code, ARMREG_LR); arm_blrx (code, ARMREG_LR); */ - mono_add_patch_info_rel (cfg, code - cfg->native_code, patch_type, data, MONO_R_ARM64_BL); + mono_add_patch_info_rel (cfg, code - cfg->native_code, patch_type, method ? method : data, MONO_R_ARM64_BL); arm_bl (code, code); cfg->thunk_area += THUNK_SIZE; return code; @@ -3665,7 +3665,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) * So instead of emitting a trap, we emit a call a C function and place a * breakpoint there. */ - code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID, GUINT_TO_POINTER (MONO_JIT_ICALL_mono_break)); + code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID, GUINT_TO_POINTER (MONO_JIT_ICALL_mono_break), NULL); break; case OP_LOCALLOC: { guint8 *buf [16]; @@ -4976,7 +4976,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) call = (MonoCallInst*)ins; const MonoJumpInfoTarget patch = mono_call_to_patch (call); - code = emit_call (cfg, code, patch.type, patch.target); + code = emit_call (cfg, code, patch.type, patch.target, NULL); code = emit_move_return_value (cfg, code, ins); break; } @@ -5194,7 +5194,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) /* Slowpath */ g_assert (sreg1 == ARMREG_R0); code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID, - GUINT_TO_POINTER (MONO_JIT_ICALL_mono_generic_class_init)); + GUINT_TO_POINTER (MONO_JIT_ICALL_mono_generic_class_init), NULL); mono_arm_patch (jump, code, MONO_R_ARM64_CBZ); break; @@ -5215,7 +5215,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) if (sreg2 != ARMREG_R1) arm_movx (code, ARMREG_R1, sreg2); code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID, - GUINT_TO_POINTER (MONO_JIT_ICALL_mini_init_method_rgctx)); + GUINT_TO_POINTER (MONO_JIT_ICALL_mini_init_method_rgctx), NULL); mono_arm_patch (jump, code, MONO_R_ARM64_CBZ); break; @@ -5271,13 +5271,13 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) if (sreg1 != ARMREG_R0) arm_movx (code, ARMREG_R0, sreg1); code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID, - GUINT_TO_POINTER (MONO_JIT_ICALL_mono_arch_throw_exception)); + GUINT_TO_POINTER (MONO_JIT_ICALL_mono_arch_throw_exception), NULL); break; case OP_RETHROW: if (sreg1 != ARMREG_R0) arm_movx (code, ARMREG_R0, sreg1); code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID, - GUINT_TO_POINTER (MONO_JIT_ICALL_mono_arch_rethrow_exception)); + GUINT_TO_POINTER (MONO_JIT_ICALL_mono_arch_rethrow_exception), NULL); break; case OP_CALL_HANDLER: mono_add_patch_info_rel (cfg, offset, MONO_PATCH_INFO_BB, ins->inst_target_bb, MONO_R_ARM64_BL); @@ -5339,7 +5339,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) /* Call it if it is non-null */ buf [0] = code; arm_cbzx (code, ARMREG_IP1, 0); - code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID, GUINT_TO_POINTER (MONO_JIT_ICALL_mono_threads_state_poll)); + code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID, GUINT_TO_POINTER (MONO_JIT_ICALL_mono_threads_state_poll), NULL); mono_arm_patch (buf [0], code, MONO_R_ARM64_CBZ); break; } @@ -5731,9 +5731,11 @@ guint8 * mono_arch_emit_prolog (MonoCompile *cfg) { MonoMethod *method = cfg->method; + MonoAotModule *aot_module = m_class_get_image (method->klass)->aot_module; MonoMethodSignature *sig; MonoBasicBlock *bb; guint8 *code; + guint32 token = mono_method_get_token (method); int cfa_offset, max_offset; sig = mono_method_signature_internal (method); @@ -5785,6 +5787,17 @@ mono_arch_emit_prolog (MonoCompile *cfg) code = emit_addx_imm (code, cfg->arch.args_reg, ARMREG_FP, cfg->stack_offset); } + // code = emit_imm (code, ARMREG_R0, AOT_INIT_METHOD); + // code = emit_aotconst (cfg, code, ARMREG_R1, MONO_PATCH_INFO_INIT_BITSET, aot_module); + // code = emit_imm (code, ARMREG_R2, token); + // code = emit_call (cfg, code, MONO_PATCH_INFO_METHOD, NULL, mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD, mono_aot_get_mono_inited(aot_module), token, aot_module, method)); + + // emit_imm (code, ARMREG_R0, method); + // Load token + // code = emit_aotconst (cfg, code, ARMREG_R1, MONO_PATCH_INFO_INIT_BITSET, NULL); + // code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID, GUINT_TO_POINTER (MONO_JIT_ICALL_mini_nollvm_init_method1), NULL); + + /* 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 9532703fa1a66..2ac65282617bc 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -1258,6 +1258,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: @@ -1534,6 +1535,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: @@ -4978,6 +4980,8 @@ 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_ptr_int_ptr, TRUE); + register_icall (mini_nollvm_init_method1, mono_icall_sig_void_ptr_int_ptr, 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 b4e843e802673..5f59f7678efa6 100644 --- a/src/mono/sample/HelloWorld/HelloWorld.csproj +++ b/src/mono/sample/HelloWorld/HelloWorld.csproj @@ -4,6 +4,10 @@ $(NetCoreAppCurrent) + + + + @@ -27,11 +31,7 @@ OutputDir="$(PublishDir)" IntermediateOutputPath="$(IntermediateOutputPath)" UseAotDataFile="$(UseAotDataFile)" - CacheFilePath="$(IntermediateOutputPath)aot_compiler_cache.json" - NetTracePath="$(NetTracePath)" - PgoBinaryPath="$(PgoBinaryPath)" - ReferenceAssembliesForPGO="@(ReferenceAssembliesForPGO)" - MibcProfilePath="$(MibcProfilePath)"> + CacheFilePath="$(IntermediateOutputPath)aot_compiler_cache.json"> 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/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 + + + From c6fc40a54b18036258573b89aa1eeb0f0bbe3cd5 Mon Sep 17 00:00:00 2001 From: Vlad - Alexandru Ionescu Date: Wed, 12 Jul 2023 16:02:56 +0200 Subject: [PATCH 02/14] Added cee opcodes for amodule and init_bitset Signed-off-by: Vlad - Alexandru Ionescu --- src/mono/mono/cil/cil-opcodes.xml | 2 ++ src/mono/mono/cil/opcode.def | 2 ++ src/mono/mono/metadata/jit-icall-reg.h | 1 - src/mono/mono/metadata/marshal-lightweight.c | 9 ++++++--- src/mono/mono/metadata/marshal.c | 6 ++---- src/mono/mono/metadata/marshal.h | 4 ++-- src/mono/mono/mini/aot-compiler.c | 6 +++--- src/mono/mono/mini/aot-runtime.c | 20 +++++++------------- src/mono/mono/mini/aot-runtime.h | 1 - src/mono/mono/mini/method-to-ir.c | 16 +++++++++++++++- src/mono/mono/mini/mini-arm64.c | 8 ++------ src/mono/mono/mini/mini-runtime.c | 1 - 12 files changed, 41 insertions(+), 35 deletions(-) diff --git a/src/mono/mono/cil/cil-opcodes.xml b/src/mono/mono/cil/cil-opcodes.xml index 5b047e47e1e76..050266e607990 100644 --- a/src/mono/mono/cil/cil-opcodes.xml +++ b/src/mono/mono/cil/cil-opcodes.xml @@ -328,4 +328,6 @@ + + diff --git a/src/mono/mono/cil/opcode.def b/src/mono/mono/cil/opcode.def index 47bccb295e99b..f3692409280fe 100644 --- a/src/mono/mono/cil/opcode.def +++ b/src/mono/mono/cil/opcode.def @@ -328,6 +328,8 @@ 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_AOT_INIT_BITSET, "aot_init_bitset", Pop0, PushI, InlineI, 0, 2, 0xF0, 0x24, NEXT) +OPDEF(CEE_AOT_MODULE, "aot_module", Pop0, PushI, InlineI, 0, 2, 0xF0, 0x25, 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 d8ea043ed463b..46c176eb5c908 100644 --- a/src/mono/mono/metadata/jit-icall-reg.h +++ b/src/mono/mono/metadata/jit-icall-reg.h @@ -131,7 +131,6 @@ 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_nollvm_init_method1) \ 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 f38950500faff..5998562359e49 100644 --- a/src/mono/mono/metadata/marshal-lightweight.c +++ b/src/mono/mono/metadata/marshal-lightweight.c @@ -3124,16 +3124,19 @@ emit_return_ilgen (MonoMethodBuilder *mb) } static void -emit_method_init_ilgen (MonoMethodBuilder *mb, MonoAotModule *aot_module, MonoMethod *method, MonoBitSet *bitset, guint32 index, MonoBitSet* mono_inited) +emit_method_init_ilgen (MonoMethodBuilder *mb, MonoMethod *method, guint32 index) { // load aot_module - mono_mb_emit_ptr (mb, aot_module); + // mono_mb_emit_ptr (mb, aot_module); + mono_mb_emit_op (mb, MONO_CEE_AOT_MODULE, NULL); // load method mono_mb_emit_ptr (mb, method); // load method_index mono_mb_emit_i4 (mb, index); /// load bitset - mono_mb_emit_ptr (mb, bitset); + // mono_mb_emit_ptr (mb, bitset); + mono_mb_emit_op (mb, MONO_CEE_AOT_INIT_BITSET, NULL); + mono_mb_emit_icall_id (mb, MONO_JIT_ICALL_mini_nollvm_init_method); mono_mb_emit_byte (mb, CEE_RET); diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 10675a1a20035..3f831fe48f192 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -2954,7 +2954,7 @@ mono_marshal_get_aot_init_wrapper_name (MonoAotInitSubtype subtype) } MonoMethod * -mono_marshal_get_aot_init_wrapper (MonoAotInitSubtype subtype, MonoBitSet *bitset, guint32 token, MonoAotModule *aot_module, MonoMethod *method) +mono_marshal_get_aot_init_wrapper (MonoAotInitSubtype subtype, guint32 token, MonoMethod *method) { MonoMethodBuilder *mb; const char *name = mono_marshal_get_aot_init_wrapper_name (subtype); @@ -2991,9 +2991,7 @@ mono_marshal_get_aot_init_wrapper (MonoAotInitSubtype subtype, MonoBitSet *bitse // Our codegen backend generates other code here get_marshal_cb ()->emit_return (mb); #else - if (!mono_bitset_test(bitset, token)) { - get_marshal_cb ()->emit_method_init(mb, aot_module, method, bitset, token, bitset); - } + get_marshal_cb ()->emit_method_init(mb, method, token); #endif info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_AOT_INIT); diff --git a/src/mono/mono/metadata/marshal.h b/src/mono/mono/metadata/marshal.h index fc500fea9ce74..6f8b0821a2669 100644 --- a/src/mono/mono/metadata/marshal.h +++ b/src/mono/mono/metadata/marshal.h @@ -338,7 +338,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) (MonoMethodBuilder *mb, MonoAotModule *aot_module, MonoMethod *method, MonoBitSet *bitset, guint32 index, MonoBitSet* mono_inited); + void (*emit_method_init) (MonoMethodBuilder *mb, MonoMethod *method, guint32 index); void (*emit_vtfixup_ftnptr) (MonoMethodBuilder *mb, MonoMethod *method, int param_count, guint16 type); void (*mb_skip_visibility) (MonoMethodBuilder *mb); void (*mb_set_dynamic) (MonoMethodBuilder *mb); @@ -517,7 +517,7 @@ MonoMethod * mono_marshal_get_icall_wrapper (MonoJitICallInfo *callinfo, gboolean check_exceptions); MonoMethod * -mono_marshal_get_aot_init_wrapper (MonoAotInitSubtype subtype, MonoBitSet *bitset, guint32 token, MonoAotModule *aot_module, MonoMethod *method); +mono_marshal_get_aot_init_wrapper (MonoAotInitSubtype subtype, guint32 token, MonoMethod *method); const char * mono_marshal_get_aot_init_wrapper_name (MonoAotInitSubtype subtype); diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index cc21ed9fb6c30..e69befb9cf57a 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -4455,7 +4455,7 @@ static void add_lazy_init_wrappers (MonoAotCompile *acfg) { for (int i = 0; i < AOT_INIT_METHOD_NUM; ++i) - add_method (acfg, mono_marshal_get_aot_init_wrapper ((MonoAotInitSubtype)i, NULL, 0, NULL, NULL)); + add_method (acfg, mono_marshal_get_aot_init_wrapper ((MonoAotInitSubtype)i, 0, NULL)); } #endif @@ -6717,7 +6717,7 @@ 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. */ - g_assert (acfg->aot_opts.llvm && acfg->aot_opts.direct_extern_calls); + // g_assert (acfg->aot_opts.llvm && acfg->aot_opts.direct_extern_calls); 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); @@ -13236,7 +13236,7 @@ compile_asm (MonoAotCompile *acfg) g_string_append_printf (str, "%s", acfg->aot_opts.clangxx); else g_string_append_printf (str, "\"%s%s\"", tool_prefix, ld_binary_name); - g_string_append_printf (str, " -shared"); + g_string_append_printf (str, " -shared -v"); #endif g_string_append_printf (str, " -o %s %s %s %s", wrap_path (tmp_outfile_name), wrap_path (llvm_ofile), diff --git a/src/mono/mono/mini/aot-runtime.c b/src/mono/mono/mini/aot-runtime.c index 6fa9003e4b5ab..8a6abd884d085 100644 --- a/src/mono/mono/mini/aot-runtime.c +++ b/src/mono/mono/mini/aot-runtime.c @@ -1094,7 +1094,7 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod g_free (sig); } else if (subtype == WRAPPER_SUBTYPE_AOT_INIT) { guint32 init_type = decode_value (p, &p); - ref->method = mono_marshal_get_aot_init_wrapper ((MonoAotInitSubtype) init_type, NULL, 0, NULL, NULL); + ref->method = mono_marshal_get_aot_init_wrapper ((MonoAotInitSubtype) init_type, 0, NULL); } else if (subtype == WRAPPER_SUBTYPE_LLVM_FUNC) { guint32 init_type = decode_value (p, &p); ref->method = mono_marshal_get_llvm_func_wrapper ((MonoLLVMFuncWrapperSubtype) init_type); @@ -4369,6 +4369,8 @@ load_method (MonoAotModule *amodule, MonoImage *image, MonoMethod *method, guint res = init_method (amodule, NULL, method_index, method, NULL, error); if (!res) goto cleanup; + else + mono_bitset_set (mono_aot_get_mono_inited(amodule), method_index); } } @@ -5933,18 +5935,10 @@ void mini_nollvm_init_method (MonoAotModule* amodule, MonoMethod* method, guint32 method_index, MonoBitSet* mono_inited) { ERROR_DECL (error); - if (init_method (amodule, NULL, method_index, method, NULL, error)) { - mono_bitset_set(mono_inited, method_index); - } - mono_error_assert_ok (error); -} - -void -mini_nollvm_init_method1 (MonoMethod* method, guint32 method_index, MonoBitSet* mono_inited) -{ - ERROR_DECL (error); - if (init_method (m_class_get_image (method->klass)->aot_module, NULL, method_index, method, NULL, error)) { - mono_bitset_set(mono_inited, method_index); + if (!mono_bitset_test(mono_inited, method_index)) { + if (init_method (amodule, NULL, method_index, method, NULL, error)) { + mono_bitset_set (mono_inited, method_index); + } } mono_error_assert_ok (error); } diff --git a/src/mono/mono/mini/aot-runtime.h b/src/mono/mono/mini/aot-runtime.h index 033faa261d9d6..bf75c7c0aecc5 100644 --- a/src/mono/mono/mini/aot-runtime.h +++ b/src/mono/mono/mini/aot-runtime.h @@ -280,7 +280,6 @@ gboolean mono_aot_is_pagefault (void *ptr); void mono_aot_handle_pagefault (void *ptr); void mini_nollvm_init_method (MonoAotModule* amodule, MonoMethod* method, guint32 method_index, MonoBitSet* mono_inited); -void mini_nollvm_init_method1 (MonoMethod* method, guint32 method_index, MonoBitSet* mono_inited); 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); diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index 20f50ea825238..85dc3f80b96a5 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -6694,7 +6694,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b * FIXME: Optimize this */ g_assert (!cfg->gshared); - wrapper = mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD, NULL, 0, NULL, NULL); + wrapper = mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD, 0, NULL); /* Emit this into the entry bb so it comes before the GC safe point which depends on an inited GOT */ cfg->cbb = cfg->bb_entry; idx = mono_aot_get_method_index (cfg->method); @@ -11300,6 +11300,20 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b *sp++ = ins; break; } + case MONO_CEE_AOT_INIT_BITSET: { + if (cfg->compile_aot) { + EMIT_NEW_AOTCONST (cfg, ins, MONO_PATCH_INFO_INIT_BITSET, NULL); + *sp++ = ins; + } + break; + } + case MONO_CEE_AOT_MODULE: { + if (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 192f8d7dfe323..c0ed2e1f67c2a 100644 --- a/src/mono/mono/mini/mini-arm64.c +++ b/src/mono/mono/mini/mini-arm64.c @@ -5731,7 +5731,7 @@ guint8 * mono_arch_emit_prolog (MonoCompile *cfg) { MonoMethod *method = cfg->method; - MonoAotModule *aot_module = m_class_get_image (method->klass)->aot_module; + // MonoAotModule *aot_module = m_class_get_image (method->klass)->aot_module; MonoMethodSignature *sig; MonoBasicBlock *bb; guint8 *code; @@ -5791,11 +5791,7 @@ mono_arch_emit_prolog (MonoCompile *cfg) // code = emit_aotconst (cfg, code, ARMREG_R1, MONO_PATCH_INFO_INIT_BITSET, aot_module); // code = emit_imm (code, ARMREG_R2, token); // code = emit_call (cfg, code, MONO_PATCH_INFO_METHOD, NULL, mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD, mono_aot_get_mono_inited(aot_module), token, aot_module, method)); - - // emit_imm (code, ARMREG_R0, method); - // Load token - // code = emit_aotconst (cfg, code, ARMREG_R1, MONO_PATCH_INFO_INIT_BITSET, NULL); - // code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID, GUINT_TO_POINTER (MONO_JIT_ICALL_mini_nollvm_init_method1), NULL); + code = emit_call (cfg, code, MONO_PATCH_INFO_METHOD, NULL, mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD, token, method)); /* Save return area addr received in R8 */ diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index 2ac65282617bc..ea679e0058810 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -4981,7 +4981,6 @@ register_icalls (void) 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_ptr_int_ptr, TRUE); - register_icall (mini_nollvm_init_method1, mono_icall_sig_void_ptr_int_ptr, 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); From 95a8470fc5755efb82a1e71b41f0ae66a862c669 Mon Sep 17 00:00:00 2001 From: Vlad - Alexandru Ionescu Date: Fri, 14 Jul 2023 15:17:26 +0200 Subject: [PATCH 03/14] Passing only method_index to init wrapper Signed-off-by: Vlad - Alexandru Ionescu --- src/mono/mono/metadata/marshal-lightweight.c | 6 +-- src/mono/mono/metadata/marshal.c | 4 +- src/mono/mono/metadata/marshal.h | 4 +- src/mono/mono/mini/aot-compiler.c | 8 ++-- src/mono/mono/mini/aot-runtime.c | 6 +-- src/mono/mono/mini/aot-runtime.h | 2 +- src/mono/mono/mini/method-to-ir.c | 2 +- src/mono/mono/mini/mini-arm64.c | 4 +- .../sample/HelloWorld/hello_llvmfullaot.sh | 46 +++++++++++++++++++ 9 files changed, 64 insertions(+), 18 deletions(-) create mode 100755 src/mono/sample/HelloWorld/hello_llvmfullaot.sh diff --git a/src/mono/mono/metadata/marshal-lightweight.c b/src/mono/mono/metadata/marshal-lightweight.c index 5998562359e49..409c40f50cf21 100644 --- a/src/mono/mono/metadata/marshal-lightweight.c +++ b/src/mono/mono/metadata/marshal-lightweight.c @@ -3124,15 +3124,15 @@ emit_return_ilgen (MonoMethodBuilder *mb) } static void -emit_method_init_ilgen (MonoMethodBuilder *mb, MonoMethod *method, guint32 index) +emit_method_init_ilgen (MonoMethodBuilder *mb) { // load aot_module // mono_mb_emit_ptr (mb, aot_module); mono_mb_emit_op (mb, MONO_CEE_AOT_MODULE, NULL); // load method - mono_mb_emit_ptr (mb, method); + // mono_mb_emit_ptr (mb, method); // load method_index - mono_mb_emit_i4 (mb, index); + // mono_mb_emit_i4 (mb, index); /// load bitset // mono_mb_emit_ptr (mb, bitset); mono_mb_emit_op (mb, MONO_CEE_AOT_INIT_BITSET, NULL); diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 3f831fe48f192..62166478c522c 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -2954,7 +2954,7 @@ mono_marshal_get_aot_init_wrapper_name (MonoAotInitSubtype subtype) } MonoMethod * -mono_marshal_get_aot_init_wrapper (MonoAotInitSubtype subtype, guint32 token, MonoMethod *method) +mono_marshal_get_aot_init_wrapper (MonoAotInitSubtype subtype) { MonoMethodBuilder *mb; const char *name = mono_marshal_get_aot_init_wrapper_name (subtype); @@ -2991,7 +2991,7 @@ mono_marshal_get_aot_init_wrapper (MonoAotInitSubtype subtype, guint32 token, Mo // Our codegen backend generates other code here get_marshal_cb ()->emit_return (mb); #else - get_marshal_cb ()->emit_method_init(mb, method, token); + get_marshal_cb ()->emit_method_init(mb); #endif info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_AOT_INIT); diff --git a/src/mono/mono/metadata/marshal.h b/src/mono/mono/metadata/marshal.h index 6f8b0821a2669..c6667b87dd15e 100644 --- a/src/mono/mono/metadata/marshal.h +++ b/src/mono/mono/metadata/marshal.h @@ -338,7 +338,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) (MonoMethodBuilder *mb, MonoMethod *method, guint32 index); + void (*emit_method_init) (MonoMethodBuilder *mb); void (*emit_vtfixup_ftnptr) (MonoMethodBuilder *mb, MonoMethod *method, int param_count, guint16 type); void (*mb_skip_visibility) (MonoMethodBuilder *mb); void (*mb_set_dynamic) (MonoMethodBuilder *mb); @@ -517,7 +517,7 @@ MonoMethod * mono_marshal_get_icall_wrapper (MonoJitICallInfo *callinfo, gboolean check_exceptions); MonoMethod * -mono_marshal_get_aot_init_wrapper (MonoAotInitSubtype subtype, guint32 token, MonoMethod *method); +mono_marshal_get_aot_init_wrapper (MonoAotInitSubtype subtype); const char * mono_marshal_get_aot_init_wrapper_name (MonoAotInitSubtype subtype); diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index e69befb9cf57a..0308e6dd0a958 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -4449,16 +4449,16 @@ add_jit_icall_wrapper (MonoAotCompile *acfg, MonoJitICallInfo *callinfo) add_method (acfg, mono_marshal_get_icall_wrapper (callinfo, TRUE)); } -#if ENABLE_LLVM +// #if ENABLE_LLVM static void add_lazy_init_wrappers (MonoAotCompile *acfg) { for (int i = 0; i < AOT_INIT_METHOD_NUM; ++i) - add_method (acfg, mono_marshal_get_aot_init_wrapper ((MonoAotInitSubtype)i, 0, NULL)); + add_method (acfg, mono_marshal_get_aot_init_wrapper ((MonoAotInitSubtype)i)); } -#endif +// #endif static MonoMethod* get_runtime_invoke_sig (MonoMethodSignature *sig) @@ -15094,10 +15094,10 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options) flags = (LLVMModuleFlags)(flags | LLVM_MODULE_FLAG_INTERP); mono_llvm_create_aot_module (acfg->image->assembly, acfg->global_prefix, acfg->nshared_got_entries, flags); - add_lazy_init_wrappers (acfg); 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 8a6abd884d085..86b62a2037555 100644 --- a/src/mono/mono/mini/aot-runtime.c +++ b/src/mono/mono/mini/aot-runtime.c @@ -1094,7 +1094,7 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod g_free (sig); } else if (subtype == WRAPPER_SUBTYPE_AOT_INIT) { guint32 init_type = decode_value (p, &p); - ref->method = mono_marshal_get_aot_init_wrapper ((MonoAotInitSubtype) init_type, 0, NULL); + ref->method = mono_marshal_get_aot_init_wrapper ((MonoAotInitSubtype) init_type); } else if (subtype == WRAPPER_SUBTYPE_LLVM_FUNC) { guint32 init_type = decode_value (p, &p); ref->method = mono_marshal_get_llvm_func_wrapper ((MonoLLVMFuncWrapperSubtype) init_type); @@ -5932,11 +5932,11 @@ no_specific_trampoline (void) } void -mini_nollvm_init_method (MonoAotModule* amodule, MonoMethod* method, guint32 method_index, MonoBitSet* mono_inited) +mini_nollvm_init_method (guint32 method_index, MonoAotModule* amodule, MonoBitSet* mono_inited) { ERROR_DECL (error); if (!mono_bitset_test(mono_inited, method_index)) { - if (init_method (amodule, NULL, method_index, method, NULL, error)) { + if (init_method (amodule, NULL, method_index, NULL, NULL, error)) { mono_bitset_set (mono_inited, method_index); } } diff --git a/src/mono/mono/mini/aot-runtime.h b/src/mono/mono/mini/aot-runtime.h index bf75c7c0aecc5..9a0b555b2971d 100644 --- a/src/mono/mono/mini/aot-runtime.h +++ b/src/mono/mono/mini/aot-runtime.h @@ -279,7 +279,7 @@ 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, MonoMethod* method, guint32 method_index, MonoBitSet* mono_inited); +void mini_nollvm_init_method (guint32 method_index, MonoAotModule* amodule, MonoBitSet* mono_inited); 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); diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index 85dc3f80b96a5..d4d846cab5b15 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -6694,7 +6694,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b * FIXME: Optimize this */ g_assert (!cfg->gshared); - wrapper = mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD, 0, NULL); + wrapper = mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD); /* Emit this into the entry bb so it comes before the GC safe point which depends on an inited GOT */ cfg->cbb = cfg->bb_entry; idx = mono_aot_get_method_index (cfg->method); diff --git a/src/mono/mono/mini/mini-arm64.c b/src/mono/mono/mini/mini-arm64.c index c0ed2e1f67c2a..ab8ae26dbaa75 100644 --- a/src/mono/mono/mini/mini-arm64.c +++ b/src/mono/mono/mini/mini-arm64.c @@ -5787,11 +5787,11 @@ mono_arch_emit_prolog (MonoCompile *cfg) code = emit_addx_imm (code, cfg->arch.args_reg, ARMREG_FP, cfg->stack_offset); } - // code = emit_imm (code, ARMREG_R0, AOT_INIT_METHOD); + code = emit_imm (code, ARMREG_R0, cfg->method_index); // code = emit_aotconst (cfg, code, ARMREG_R1, MONO_PATCH_INFO_INIT_BITSET, aot_module); // code = emit_imm (code, ARMREG_R2, token); // code = emit_call (cfg, code, MONO_PATCH_INFO_METHOD, NULL, mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD, mono_aot_get_mono_inited(aot_module), token, aot_module, method)); - code = emit_call (cfg, code, MONO_PATCH_INFO_METHOD, NULL, mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD, token, method)); + code = emit_call (cfg, code, MONO_PATCH_INFO_METHOD, NULL, mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD)); /* Save return area addr received in R8 */ diff --git a/src/mono/sample/HelloWorld/hello_llvmfullaot.sh b/src/mono/sample/HelloWorld/hello_llvmfullaot.sh new file mode 100755 index 0000000000000..bb9c0df8011de --- /dev/null +++ b/src/mono/sample/HelloWorld/hello_llvmfullaot.sh @@ -0,0 +1,46 @@ +#!/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="-O=gsharedvt --aot=full,llvm,llvm-path=$LLVM_PATH,mattr=crc,mattr=crypto" + export MONO_ENV_OPTIONS="--aot=full" + 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 + + From 03e1389043e56bc79a1f36e4693cda494172720a Mon Sep 17 00:00:00 2001 From: Vlad - Alexandru Ionescu Date: Mon, 17 Jul 2023 14:21:41 +0200 Subject: [PATCH 04/14] Small changes and cleanup Signed-off-by: Vlad - Alexandru Ionescu --- src/mono/mono/metadata/marshal-lightweight.c | 12 ++--- src/mono/mono/mini/aot-compiler.c | 20 ++------ src/mono/mono/mini/aot-runtime.c | 12 +++-- src/mono/mono/mini/aot-runtime.h | 2 +- src/mono/mono/mini/mini-amd64.c | 14 +++--- src/mono/mono/mini/mini-arm64.c | 10 ++-- src/mono/mono/mini/mini-runtime.c | 2 +- src/mono/sample/HelloWorld/HelloWorld.csproj | 38 ++++++++++++--- src/mono/sample/HelloWorld/Makefile | 6 ++- src/mono/sample/HelloWorld/Program.cs | 10 ++-- .../sample/HelloWorld/hello_llvmfullaot.sh | 46 ------------------- src/mono/sample/MyLib/Class1.cs | 25 ---------- src/mono/sample/MyLib/MyLib.csproj | 9 ---- 13 files changed, 70 insertions(+), 136 deletions(-) delete mode 100755 src/mono/sample/HelloWorld/hello_llvmfullaot.sh delete mode 100644 src/mono/sample/MyLib/Class1.cs delete mode 100644 src/mono/sample/MyLib/MyLib.csproj diff --git a/src/mono/mono/metadata/marshal-lightweight.c b/src/mono/mono/metadata/marshal-lightweight.c index 409c40f50cf21..7dd0f28272d22 100644 --- a/src/mono/mono/metadata/marshal-lightweight.c +++ b/src/mono/mono/metadata/marshal-lightweight.c @@ -3125,17 +3125,11 @@ emit_return_ilgen (MonoMethodBuilder *mb) static void emit_method_init_ilgen (MonoMethodBuilder *mb) -{ +{ // load aot_module - // mono_mb_emit_ptr (mb, aot_module); - mono_mb_emit_op (mb, MONO_CEE_AOT_MODULE, NULL); - // load method - // mono_mb_emit_ptr (mb, method); + mono_mb_emit_op (mb, CEE_AOT_MODULE, NULL); // load method_index - // mono_mb_emit_i4 (mb, index); - /// load bitset - // mono_mb_emit_ptr (mb, bitset); - mono_mb_emit_op (mb, MONO_CEE_AOT_INIT_BITSET, NULL); + mono_mb_emit_ldarg (mb, 0); mono_mb_emit_icall_id (mb, MONO_JIT_ICALL_mini_nollvm_init_method); diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 0308e6dd0a958..624f5cec068f8 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -6716,8 +6716,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. + * Disable this assert when nollvm init is enabled */ - // g_assert (acfg->aot_opts.llvm && acfg->aot_opts.direct_extern_calls); + g_assert (acfg->aot_opts.llvm && acfg->aot_opts.direct_extern_calls); 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); @@ -7215,11 +7216,6 @@ encode_patch (MonoAotCompile *acfg, MonoJumpInfo *patch_info, guint8 *buf, guint case MONO_PATCH_INFO_AOT_MODULE: case MONO_PATCH_INFO_INIT_BITSET: break; - // encode_value (mono_bitset_size (acfg->mono_inited) , p, &p); - // for (guint32 i = 0 ; i < mono_bitset_size (acfg->mono_inited); i++) { - // encode_value (i , p, &p); - // } - // break; case MONO_PATCH_INFO_SIGNATURE: case MONO_PATCH_INFO_GSHAREDVT_IN_WRAPPER: encode_signature (acfg, (MonoMethodSignature*)patch_info->data.target, p, &p); @@ -10813,13 +10809,6 @@ emit_code (MonoAotCompile *acfg) */ emit_padding (acfg, 16); - // /* - // * Methods init bitset used for initialization during the runtime - // */ - // acfg->mono_inited = mono_bitset_mem_new ( - // mono_mempool_alloc0 (acfg->mempool, mono_bitset_alloc_size (acfg->method_order->len, 0)), - // acfg->method_order->len, 0); - for (guint oindex = 0; oindex < acfg->method_order->len; ++oindex) { MonoCompile *cfg; MonoMethod *method; @@ -13236,7 +13225,7 @@ compile_asm (MonoAotCompile *acfg) g_string_append_printf (str, "%s", acfg->aot_opts.clangxx); else g_string_append_printf (str, "\"%s%s\"", tool_prefix, ld_binary_name); - g_string_append_printf (str, " -shared -v"); + g_string_append_printf (str, " -shared"); #endif g_string_append_printf (str, " -o %s %s %s %s", wrap_path (tmp_outfile_name), wrap_path (llvm_ofile), @@ -15094,10 +15083,11 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options) flags = (LLVMModuleFlags)(flags | LLVM_MODULE_FLAG_INTERP); mono_llvm_create_aot_module (acfg->image->assembly, acfg->global_prefix, acfg->nshared_got_entries, flags); + /* This will need to be moved outside to enable nollvm init method */ + add_lazy_init_wrappers (acfg); 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 86b62a2037555..f0469f37fb43c 100644 --- a/src/mono/mono/mini/aot-runtime.c +++ b/src/mono/mono/mini/aot-runtime.c @@ -4369,8 +4369,8 @@ load_method (MonoAotModule *amodule, MonoImage *image, MonoMethod *method, guint res = init_method (amodule, NULL, method_index, method, NULL, error); if (!res) goto cleanup; - else - mono_bitset_set (mono_aot_get_mono_inited(amodule), method_index); + // else + // mono_bitset_set (mono_aot_get_mono_inited(amodule), method_index); } } @@ -5932,12 +5932,14 @@ no_specific_trampoline (void) } void -mini_nollvm_init_method (guint32 method_index, MonoAotModule* amodule, MonoBitSet* mono_inited) +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(mono_inited, method_index)) { + if (!mono_bitset_test(inited_bitset, method_index)) { if (init_method (amodule, NULL, method_index, NULL, NULL, error)) { - mono_bitset_set (mono_inited, method_index); + mono_bitset_set (inited_bitset, method_index); } } mono_error_assert_ok (error); diff --git a/src/mono/mono/mini/aot-runtime.h b/src/mono/mono/mini/aot-runtime.h index 9a0b555b2971d..53b80e9c7e65a 100644 --- a/src/mono/mono/mini/aot-runtime.h +++ b/src/mono/mono/mini/aot-runtime.h @@ -279,7 +279,7 @@ 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 (guint32 method_index, MonoAotModule* amodule, MonoBitSet* mono_inited); +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); diff --git a/src/mono/mono/mini/mini-amd64.c b/src/mono/mono/mini/mini-amd64.c index 96cf2121158d1..10c964b9beff2 100644 --- a/src/mono/mono/mini/mini-amd64.c +++ b/src/mono/mono/mini/mini-amd64.c @@ -5479,7 +5479,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) call = (MonoCallInst*)ins; code = amd64_handle_varargs_call (cfg, code, call, FALSE); - code = emit_call (cfg, call, code, MONO_JIT_ICALL_ZeroIsReserved, NULL); + code = emit_call (cfg, call, code, MONO_JIT_ICALL_ZeroIsReserved); ins->flags |= MONO_INST_GC_CALLSITE; ins->backend.pc_offset = GPTRDIFF_TO_INT (code - cfg->native_code); code = emit_move_return_value (cfg, ins, code); @@ -5639,7 +5639,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) jump = code; amd64_branch8 (code, X86_CC_NZ, -1, 1); - code = emit_call (cfg, NULL, code, MONO_JIT_ICALL_mono_generic_class_init, NULL); + code = emit_call (cfg, NULL, code, MONO_JIT_ICALL_mono_generic_class_init); ins->flags |= MONO_INST_GC_CALLSITE; ins->backend.pc_offset = GPTRDIFF_TO_INT (code - cfg->native_code); @@ -5697,14 +5697,14 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) } case OP_THROW: { amd64_mov_reg_reg (code, AMD64_ARG_REG1, ins->sreg1, 8); - code = emit_call (cfg, NULL, code, MONO_JIT_ICALL_mono_arch_throw_exception, NULL); + code = emit_call (cfg, NULL, code, MONO_JIT_ICALL_mono_arch_throw_exception); ins->flags |= MONO_INST_GC_CALLSITE; ins->backend.pc_offset = GPTRDIFF_TO_INT (code - cfg->native_code); break; } case OP_RETHROW: { amd64_mov_reg_reg (code, AMD64_ARG_REG1, ins->sreg1, 8); - code = emit_call (cfg, NULL, code, MONO_JIT_ICALL_mono_arch_rethrow_exception, NULL); + code = emit_call (cfg, NULL, code, MONO_JIT_ICALL_mono_arch_rethrow_exception); ins->flags |= MONO_INST_GC_CALLSITE; ins->backend.pc_offset = GPTRDIFF_TO_INT (code - cfg->native_code); break; @@ -7328,7 +7328,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) amd64_test_membase_imm_size (code, ins->sreg1, 0, 1, 4); br[0] = code; x86_branch8 (code, X86_CC_EQ, 0, FALSE); - code = emit_call (cfg, NULL, code, MONO_JIT_ICALL_mono_threads_state_poll, NULL); + code = emit_call (cfg, NULL, code, MONO_JIT_ICALL_mono_threads_state_poll); amd64_patch (br[0], code); break; } @@ -7455,7 +7455,7 @@ emit_prolog_setup_sp_win64 (MonoCompile *cfg, guint8 *code, int alloc_size, int if (alloc_size >= 0x1000) { amd64_mov_reg_imm (code, AMD64_RAX, alloc_size); - code = emit_call (cfg, NULL, code, MONO_JIT_ICALL_mono_chkstk_win64, NULL); + code = emit_call (cfg, NULL, code, MONO_JIT_ICALL_mono_chkstk_win64); } amd64_alu_reg_imm (code, X86_SUB, AMD64_RSP, alloc_size); @@ -8128,7 +8128,7 @@ mono_arch_emit_exceptions (MonoCompile *cfg) patch_info->type = MONO_PATCH_INFO_NONE; - code = emit_call (cfg, NULL, code, MONO_JIT_ICALL_mono_arch_throw_corlib_exception, NULL); + code = emit_call (cfg, NULL, code, MONO_JIT_ICALL_mono_arch_throw_corlib_exception); amd64_mov_reg_imm (buf, AMD64_ARG_REG2, (code - cfg->native_code) - throw_ip); while (buf < buf2) diff --git a/src/mono/mono/mini/mini-arm64.c b/src/mono/mono/mini/mini-arm64.c index ab8ae26dbaa75..71c5748879bf1 100644 --- a/src/mono/mono/mini/mini-arm64.c +++ b/src/mono/mono/mini/mini-arm64.c @@ -5731,11 +5731,9 @@ guint8 * mono_arch_emit_prolog (MonoCompile *cfg) { MonoMethod *method = cfg->method; - // MonoAotModule *aot_module = m_class_get_image (method->klass)->aot_module; MonoMethodSignature *sig; MonoBasicBlock *bb; guint8 *code; - guint32 token = mono_method_get_token (method); int cfa_offset, max_offset; sig = mono_method_signature_internal (method); @@ -5787,11 +5785,9 @@ mono_arch_emit_prolog (MonoCompile *cfg) code = emit_addx_imm (code, cfg->arch.args_reg, ARMREG_FP, cfg->stack_offset); } - code = emit_imm (code, ARMREG_R0, cfg->method_index); - // code = emit_aotconst (cfg, code, ARMREG_R1, MONO_PATCH_INFO_INIT_BITSET, aot_module); - // code = emit_imm (code, ARMREG_R2, token); - // code = emit_call (cfg, code, MONO_PATCH_INFO_METHOD, NULL, mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD, mono_aot_get_mono_inited(aot_module), token, aot_module, method)); - code = emit_call (cfg, code, MONO_PATCH_INFO_METHOD, NULL, mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD)); + /* Call the init wrapper which check if the methos needs to be initialised or not */ + // code = emit_imm (code, ARMREG_R0, cfg->method_index); + // code = emit_call (cfg, code, MONO_PATCH_INFO_METHOD, NULL, mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD)); /* Save return area addr received in R8 */ diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index ea679e0058810..3cdbffd613ca3 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -4980,7 +4980,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_ptr_int_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/sample/HelloWorld/HelloWorld.csproj b/src/mono/sample/HelloWorld/HelloWorld.csproj index 5f59f7678efa6..575586952a01e 100644 --- a/src/mono/sample/HelloWorld/HelloWorld.csproj +++ b/src/mono/sample/HelloWorld/HelloWorld.csproj @@ -2,12 +2,10 @@ Exe $(NetCoreAppCurrent) + + true - - - - @@ -29,10 +27,38 @@ LibraryFormat="$(_AotLibraryFormat)" Assemblies="@(AotInputAssemblies)" OutputDir="$(PublishDir)" + CollectCompiledMethods="$(StripILCode)" + CompiledMethodsOutputDirectory="$(CompiledMethodsOutputDirectory)" IntermediateOutputPath="$(IntermediateOutputPath)" UseAotDataFile="$(UseAotDataFile)" - CacheFilePath="$(IntermediateOutputPath)aot_compiler_cache.json"> + CacheFilePath="$(IntermediateOutputPath)aot_compiler_cache.json" + NetTracePath="$(NetTracePath)" + PgoBinaryPath="$(PgoBinaryPath)" + ReferenceAssembliesForPGO="@(ReferenceAssembliesForPGO)" + MibcProfilePath="$(MibcProfilePath)"> - + + + + + + true + + + + + + + + + + \ No newline at end of file diff --git a/src/mono/sample/HelloWorld/Makefile b/src/mono/sample/HelloWorld/Makefile index 8b18dc45c65a0..44c2c4a8a92d0 100644 --- a/src/mono/sample/HelloWorld/Makefile +++ b/src/mono/sample/HelloWorld/Makefile @@ -6,6 +6,8 @@ MONO_CONFIG?=Debug MONO_ARCH?=$(shell . $(TOP)eng/native/init-os-and-arch.sh && echo $${arch}) TARGET_OS?=$(shell . $(TOP)eng/native/init-os-and-arch.sh && echo $${os}) AOT?=false +StripILCode?=false +CompiledMethodsOutputDirectory?= # #NET_TRACE_PATH= #PGO_BINARY_PATH= @@ -18,6 +20,8 @@ publish: -c $(MONO_CONFIG) \ -r $(TARGET_OS)-$(MONO_ARCH) \ /p:RunAOTCompilation=$(AOT) \ + /p:StripILCode=$(StripILCode) \ + /p:CompiledMethodsOutputDirectory=$(CompiledMethodsOutputDirectory) \ '/p:NetTracePath="$(NET_TRACE_PATH)"' \ '/p:PgoBinaryPath="$(PGO_BINARY_PATH)"' \ '/p:MibcProfilePath="$(MIBC_PROFILE_PATH)"' @@ -28,4 +32,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 59b74eca24281..6d0b31d30dc6f 100644 --- a/src/mono/sample/HelloWorld/Program.cs +++ b/src/mono/sample/HelloWorld/Program.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; -using MyLib; namespace HelloWorld { @@ -10,8 +9,11 @@ internal class Program { private static void Main(string[] args) { - Class1 c = new Class1(); - c.getCat(); + 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); } } -} +} \ No newline at end of file diff --git a/src/mono/sample/HelloWorld/hello_llvmfullaot.sh b/src/mono/sample/HelloWorld/hello_llvmfullaot.sh deleted file mode 100755 index bb9c0df8011de..0000000000000 --- a/src/mono/sample/HelloWorld/hello_llvmfullaot.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/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="-O=gsharedvt --aot=full,llvm,llvm-path=$LLVM_PATH,mattr=crc,mattr=crypto" - export MONO_ENV_OPTIONS="--aot=full" - 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 deleted file mode 100644 index 3643722dcd6cf..0000000000000 --- a/src/mono/sample/MyLib/Class1.cs +++ /dev/null @@ -1,25 +0,0 @@ -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 deleted file mode 100644 index fa71b7ae6a349..0000000000000 --- a/src/mono/sample/MyLib/MyLib.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - - net8.0 - enable - enable - - - From 914066189d1fbe4caa2a570353a468c217c29583 Mon Sep 17 00:00:00 2001 From: Vlad - Alexandru Ionescu Date: Mon, 17 Jul 2023 14:27:52 +0200 Subject: [PATCH 05/14] Commented Signed-off-by: Vlad - Alexandru Ionescu --- src/mono/mono/metadata/marshal.c | 8 ++++---- src/mono/mono/mini/aot-compiler.c | 4 ++-- src/mono/mono/mini/mini-arm64.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 62166478c522c..7a35862e9b689 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -2986,13 +2986,13 @@ mono_marshal_get_aot_init_wrapper (MonoAotInitSubtype subtype) mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_OTHER); -#if ENABLE_LLVM +// #if ENABLE_LLVM // Just stub out the method with a "CEE_RET" // Our codegen backend generates other code here get_marshal_cb ()->emit_return (mb); -#else - get_marshal_cb ()->emit_method_init(mb); -#endif +// #else + // get_marshal_cb ()->emit_method_init(mb); +// #endif info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_AOT_INIT); info->d.aot_init.subtype = subtype; diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 624f5cec068f8..4564a77d27a17 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -4449,7 +4449,7 @@ add_jit_icall_wrapper (MonoAotCompile *acfg, MonoJitICallInfo *callinfo) add_method (acfg, mono_marshal_get_icall_wrapper (callinfo, TRUE)); } -// #if ENABLE_LLVM +#if ENABLE_LLVM static void add_lazy_init_wrappers (MonoAotCompile *acfg) @@ -4458,7 +4458,7 @@ add_lazy_init_wrappers (MonoAotCompile *acfg) add_method (acfg, mono_marshal_get_aot_init_wrapper ((MonoAotInitSubtype)i)); } -// #endif +#endif static MonoMethod* get_runtime_invoke_sig (MonoMethodSignature *sig) diff --git a/src/mono/mono/mini/mini-arm64.c b/src/mono/mono/mini/mini-arm64.c index 71c5748879bf1..65fb38e1946ec 100644 --- a/src/mono/mono/mini/mini-arm64.c +++ b/src/mono/mono/mini/mini-arm64.c @@ -5785,7 +5785,7 @@ 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 check if the methos needs to be initialised or not */ + /* Call the init wrapper which checks if the methos needs to be initialised or not */ // code = emit_imm (code, ARMREG_R0, cfg->method_index); // code = emit_call (cfg, code, MONO_PATCH_INFO_METHOD, NULL, mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD)); From 9976eaf150041610ad7c5ebb3a7868adf4c60759 Mon Sep 17 00:00:00 2001 From: Vlad - Alexandru Ionescu Date: Tue, 18 Jul 2023 13:03:24 +0200 Subject: [PATCH 06/14] Enabled for arm64 for CI purposes Signed-off-by: Vlad - Alexandru Ionescu --- src/mono/mono/cil/opcode.def | 3 +-- src/mono/mono/metadata/marshal.c | 8 ++++---- src/mono/mono/mini/aot-compiler.c | 11 ++++++++--- src/mono/mono/mini/aot-runtime.c | 10 ++++++---- src/mono/mono/mini/method-to-ir.c | 7 ------- src/mono/mono/mini/mini-arm64.c | 4 ++-- 6 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/mono/mono/cil/opcode.def b/src/mono/mono/cil/opcode.def index f3692409280fe..c420220b406db 100644 --- a/src/mono/mono/cil/opcode.def +++ b/src/mono/mono/cil/opcode.def @@ -328,8 +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_AOT_INIT_BITSET, "aot_init_bitset", Pop0, PushI, InlineI, 0, 2, 0xF0, 0x24, NEXT) -OPDEF(CEE_AOT_MODULE, "aot_module", Pop0, PushI, InlineI, 0, 2, 0xF0, 0x25, NEXT) +OPDEF(CEE_AOT_MODULE, "aot_module", Pop0, PushI, InlineI, 0, 2, 0xF0, 0x24, NEXT) #ifndef OPALIAS #define _MONO_CIL_OPALIAS_DEFINED_ #define OPALIAS(a,s,r) diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 48342fcf20767..cf08354209899 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -2977,13 +2977,13 @@ mono_marshal_get_aot_init_wrapper (MonoAotInitSubtype subtype) mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_OTHER); -// #if ENABLE_LLVM +#if !defined(ENABLE_LLVM) && defined(TARGET_ARM64) + get_marshal_cb ()->emit_method_init (mb); +#endif + // Just stub out the method with a "CEE_RET" // Our codegen backend generates other code here get_marshal_cb ()->emit_return (mb); -// #else - // get_marshal_cb ()->emit_method_init(mb); -// #endif info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_AOT_INIT); info->d.aot_init.subtype = subtype; diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index a9c3c15752dbc..298e7c1443284 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -4461,7 +4461,7 @@ add_jit_icall_wrapper (MonoAotCompile *acfg, MonoJitICallInfo *callinfo) add_method (acfg, mono_marshal_get_icall_wrapper (callinfo, TRUE)); } -#if ENABLE_LLVM +// #if ENABLE_LLVM static void add_lazy_init_wrappers (MonoAotCompile *acfg) @@ -4470,7 +4470,7 @@ add_lazy_init_wrappers (MonoAotCompile *acfg) add_method (acfg, mono_marshal_get_aot_init_wrapper ((MonoAotInitSubtype)i)); } -#endif +// #endif static MonoMethod* get_runtime_invoke_sig (MonoMethodSignature *sig) @@ -6810,8 +6810,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. * Disable this assert when nollvm init is enabled */ +#if !(!defined(ENABLE_LLVM) && defined(TARGET_ARM64)) 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); @@ -15207,6 +15208,10 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options) } #endif +#if !defined(ENABLE_LLVM) && defined(TARGET_ARM64) + add_lazy_init_wrappers (acfg); +#endif + 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); add_method (acfg, wrapper); diff --git a/src/mono/mono/mini/aot-runtime.c b/src/mono/mono/mini/aot-runtime.c index 725b388ba627c..5ad1fb5ad7fdc 100644 --- a/src/mono/mono/mini/aot-runtime.c +++ b/src/mono/mono/mini/aot-runtime.c @@ -4390,8 +4390,10 @@ load_method (MonoAotModule *amodule, MonoImage *image, MonoMethod *method, guint res = init_method (amodule, NULL, method_index, method, NULL, error); if (!res) goto cleanup; - // else - // mono_bitset_set (mono_aot_get_mono_inited(amodule), method_index); +#if !defined(ENABLE_LLVM) && defined(TARGET_ARM64) + else + mono_bitset_set (mono_aot_get_mono_inited(amodule), method_index); +#endif } } @@ -5955,10 +5957,10 @@ no_specific_trampoline (void) void mini_nollvm_init_method (MonoAotModule* amodule, guint32 method_index) { - MonoBitSet *inited_bitset = mono_aot_get_mono_inited(amodule); + MonoBitSet *inited_bitset = mono_aot_get_mono_inited (amodule); ERROR_DECL (error); - if (!mono_bitset_test(inited_bitset, method_index)) { + 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); } diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index 5710d7d6b9a3e..5865528966dc3 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -11258,13 +11258,6 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b *sp++ = ins; break; } - case MONO_CEE_AOT_INIT_BITSET: { - if (cfg->compile_aot) { - EMIT_NEW_AOTCONST (cfg, ins, MONO_PATCH_INFO_INIT_BITSET, NULL); - *sp++ = ins; - } - break; - } case MONO_CEE_AOT_MODULE: { if (cfg->compile_aot) { EMIT_NEW_AOTCONST (cfg, ins, MONO_PATCH_INFO_AOT_MODULE, NULL); diff --git a/src/mono/mono/mini/mini-arm64.c b/src/mono/mono/mini/mini-arm64.c index 619728e1d243b..04773d55bb98d 100644 --- a/src/mono/mono/mini/mini-arm64.c +++ b/src/mono/mono/mini/mini-arm64.c @@ -5925,8 +5925,8 @@ mono_arch_emit_prolog (MonoCompile *cfg) } /* Call the init wrapper which checks if the methos needs to be initialised or not */ - // code = emit_imm (code, ARMREG_R0, cfg->method_index); - // code = emit_call (cfg, code, MONO_PATCH_INFO_METHOD, NULL, mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD)); + code = emit_imm (code, ARMREG_R0, cfg->method_index); + code = emit_call (cfg, code, MONO_PATCH_INFO_METHOD, NULL, mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD)); /* Save return area addr received in R8 */ From 49dcf2e33747e63dca33267a5e2b29287f715b74 Mon Sep 17 00:00:00 2001 From: Vlad - Alexandru Ionescu Date: Tue, 18 Jul 2023 15:27:41 +0200 Subject: [PATCH 07/14] Leftover Signed-off-by: Vlad - Alexandru Ionescu --- src/mono/mono/cil/cil-opcodes.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mono/mono/cil/cil-opcodes.xml b/src/mono/mono/cil/cil-opcodes.xml index 050266e607990..e61fc80678042 100644 --- a/src/mono/mono/cil/cil-opcodes.xml +++ b/src/mono/mono/cil/cil-opcodes.xml @@ -328,6 +328,5 @@ - - + From 1dbcc282b346f65b292ea57e82b31a19957d1670 Mon Sep 17 00:00:00 2001 From: Vlad - Alexandru Ionescu Date: Fri, 21 Jul 2023 15:00:54 +0200 Subject: [PATCH 08/14] Small changes, added a flag for later use Signed-off-by: Vlad - Alexandru Ionescu --- src/mono/mono/metadata/marshal.c | 7 ++++--- src/mono/mono/mini/aot-compiler.c | 6 ++---- src/mono/mono/mini/method-to-ir.c | 7 +++---- src/mono/mono/mini/mini-arm64.c | 28 ++++++++++++++++------------ src/mono/mono/mini/mini.h | 2 ++ 5 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index cf08354209899..13d2682439acb 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -2977,9 +2977,10 @@ mono_marshal_get_aot_init_wrapper (MonoAotInitSubtype subtype) mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_OTHER); -#if !defined(ENABLE_LLVM) && defined(TARGET_ARM64) - get_marshal_cb ()->emit_method_init (mb); -#endif +/* Uncomment when working on https://github.com/dotnet/runtime/issues/82224 */ +// #ifndef ENABLE_LLVM +// get_marshal_cb ()->emit_method_init (mb); +// #endif // Just stub out the method with a "CEE_RET" // Our codegen backend generates other code here diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 298e7c1443284..a8037a6d922b0 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -6810,9 +6810,8 @@ 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. * Disable this assert when nollvm init is enabled */ -#if !(!defined(ENABLE_LLVM) && defined(TARGET_ARM64)) 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); @@ -15202,13 +15201,12 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options) flags = (LLVMModuleFlags)(flags | LLVM_MODULE_FLAG_INTERP); mono_llvm_create_aot_module (acfg->image->assembly, acfg->global_prefix, acfg->nshared_got_entries, flags); - /* This will need to be moved outside to enable nollvm init method */ add_lazy_init_wrappers (acfg); add_method (acfg, mono_marshal_get_llvm_func_wrapper (LLVM_FUNC_WRAPPER_GC_POLL)); } #endif -#if !defined(ENABLE_LLVM) && defined(TARGET_ARM64) +#if NOLLVM_AOT_METHOD_INIT add_lazy_init_wrappers (acfg); #endif diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index 5865528966dc3..721d185f175a4 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -11259,10 +11259,9 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b break; } case MONO_CEE_AOT_MODULE: { - if (cfg->compile_aot) { - EMIT_NEW_AOTCONST (cfg, ins, MONO_PATCH_INFO_AOT_MODULE, NULL); - *sp++ = ins; - } + 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: diff --git a/src/mono/mono/mini/mini-arm64.c b/src/mono/mono/mini/mini-arm64.c index 04773d55bb98d..cd07242244dd8 100644 --- a/src/mono/mono/mini/mini-arm64.c +++ b/src/mono/mono/mini/mini-arm64.c @@ -1050,14 +1050,14 @@ emit_xinsert_i8_r8 (guint8* code, MonoTypeEnum type, int dreg, int src_reg, int } static guint8* -emit_call (MonoCompile *cfg, guint8* code, MonoJumpInfoType patch_type, gconstpointer data, MonoMethod *method) +emit_call (MonoCompile *cfg, guint8* code, MonoJumpInfoType patch_type, gconstpointer data) { /* mono_add_patch_info_rel (cfg, code - cfg->native_code, patch_type, data, MONO_R_ARM64_IMM); code = emit_imm64_template (code, ARMREG_LR); arm_blrx (code, ARMREG_LR); */ - mono_add_patch_info_rel (cfg, code - cfg->native_code, patch_type, method ? method : data, MONO_R_ARM64_BL); + mono_add_patch_info_rel (cfg, code - cfg->native_code, patch_type, data, MONO_R_ARM64_BL); arm_bl (code, code); cfg->thunk_area += THUNK_SIZE; return code; @@ -3706,7 +3706,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) * So instead of emitting a trap, we emit a call a C function and place a * breakpoint there. */ - code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID, GUINT_TO_POINTER (MONO_JIT_ICALL_mono_break), NULL); + code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID, GUINT_TO_POINTER (MONO_JIT_ICALL_mono_break)); break; case OP_LOCALLOC: { guint8 *buf [16]; @@ -5073,7 +5073,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) call = (MonoCallInst*)ins; const MonoJumpInfoTarget patch = mono_call_to_patch (call); - code = emit_call (cfg, code, patch.type, patch.target, NULL); + code = emit_call (cfg, code, patch.type, patch.target); code = emit_move_return_value (cfg, code, ins); break; } @@ -5291,7 +5291,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) /* Slowpath */ g_assert (sreg1 == ARMREG_R0); code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID, - GUINT_TO_POINTER (MONO_JIT_ICALL_mono_generic_class_init), NULL); + GUINT_TO_POINTER (MONO_JIT_ICALL_mono_generic_class_init)); mono_arm_patch (jump, code, MONO_R_ARM64_CBZ); break; @@ -5312,7 +5312,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) if (sreg2 != ARMREG_R1) arm_movx (code, ARMREG_R1, sreg2); code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID, - GUINT_TO_POINTER (MONO_JIT_ICALL_mini_init_method_rgctx), NULL); + GUINT_TO_POINTER (MONO_JIT_ICALL_mini_init_method_rgctx)); mono_arm_patch (jump, code, MONO_R_ARM64_CBZ); break; @@ -5368,13 +5368,13 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) if (sreg1 != ARMREG_R0) arm_movx (code, ARMREG_R0, sreg1); code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID, - GUINT_TO_POINTER (MONO_JIT_ICALL_mono_arch_throw_exception), NULL); + GUINT_TO_POINTER (MONO_JIT_ICALL_mono_arch_throw_exception)); break; case OP_RETHROW: if (sreg1 != ARMREG_R0) arm_movx (code, ARMREG_R0, sreg1); code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID, - GUINT_TO_POINTER (MONO_JIT_ICALL_mono_arch_rethrow_exception), NULL); + GUINT_TO_POINTER (MONO_JIT_ICALL_mono_arch_rethrow_exception)); break; case OP_CALL_HANDLER: mono_add_patch_info_rel (cfg, offset, MONO_PATCH_INFO_BB, ins->inst_target_bb, MONO_R_ARM64_BL); @@ -5436,7 +5436,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) /* Call it if it is non-null */ buf [0] = code; arm_cbzx (code, ARMREG_IP1, 0); - code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID, GUINT_TO_POINTER (MONO_JIT_ICALL_mono_threads_state_poll), NULL); + code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID, GUINT_TO_POINTER (MONO_JIT_ICALL_mono_threads_state_poll)); mono_arm_patch (buf [0], code, MONO_R_ARM64_CBZ); break; } @@ -5925,9 +5925,13 @@ mono_arch_emit_prolog (MonoCompile *cfg) } /* Call the init wrapper which checks if the methos needs to be initialised or not */ - code = emit_imm (code, ARMREG_R0, cfg->method_index); - code = emit_call (cfg, code, MONO_PATCH_INFO_METHOD, NULL, mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD)); - + /* https://github.com/dotnet/runtime/pull/82711, https://github.com/dotnet/runtime/issues/83378, https://github.com/dotnet/runtime/issues/83379 */ +#if NOLLVM_AOT_METHOD_INIT + if (cfg->compile_aot) { + code = emit_imm (code, ARMREG_R0, cfg->method_index); + code = emit_call (cfg, code, MONO_PATCH_INFO_METHOD, NULL, (gconstpointer) mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD)); + } +#endif /* Save return area addr received in R8 */ if (cfg->vret_addr) { diff --git a/src/mono/mono/mini/mini.h b/src/mono/mono/mini/mini.h index 7483e028159d4..07e4dfdc2c5a5 100644 --- a/src/mono/mono/mini/mini.h +++ b/src/mono/mono/mini/mini.h @@ -87,9 +87,11 @@ typedef struct SeqPointInfo SeqPointInfo; #if ENABLE_LLVM #define COMPILE_LLVM(cfg) ((cfg)->compile_llvm) #define LLVM_ENABLED TRUE +#define NOLLVM_AOT_METHOD_INIT FALSE #else #define COMPILE_LLVM(cfg) (0) #define LLVM_ENABLED FALSE +#define NOLLVM_AOT_METHOD_INIT FALSE #endif #ifdef MONO_ARCH_SOFT_FLOAT_FALLBACK From 2bad64690b3cc7ab819ef4d44bcb702f13ef196e Mon Sep 17 00:00:00 2001 From: Vlad - Alexandru Ionescu Date: Fri, 21 Jul 2023 16:59:50 +0200 Subject: [PATCH 09/14] Added cmake flag Signed-off-by: Vlad - Alexandru Ionescu --- src/mono/cmake/config.h.in | 3 +++ src/mono/cmake/options.cmake | 1 + src/mono/mono/metadata/marshal.c | 8 +++++--- src/mono/mono/mini/aot-compiler.c | 5 +++-- src/mono/mono/mini/aot-runtime.c | 2 +- src/mono/mono/mini/mini-arm64.c | 2 +- src/mono/mono/mini/mini.h | 2 -- 7 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/mono/cmake/config.h.in b/src/mono/cmake/config.h.in index 6a12eb5338b39..b43e8718cf90f 100644 --- a/src/mono/cmake/config.h.in +++ b/src/mono/cmake/config.h.in @@ -960,6 +960,9 @@ /* define if clockgettime exists */ #cmakedefine HAVE_CLOCK_GETTIME 1 +/* work in progress: nollvm method self initialization */ +#cmakedefine ENABLE_WIP_METHOD_NOLLVM_SELF_INIT 0 + #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 f5af034cc919c..7c06b1a0060a2 100644 --- a/src/mono/cmake/options.cmake +++ b/src/mono/cmake/options.cmake @@ -57,6 +57,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/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 13d2682439acb..2a286c66208ed 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -2978,9 +2978,11 @@ mono_marshal_get_aot_init_wrapper (MonoAotInitSubtype subtype) mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_OTHER); /* Uncomment when working on https://github.com/dotnet/runtime/issues/82224 */ -// #ifndef ENABLE_LLVM -// get_marshal_cb ()->emit_method_init (mb); -// #endif +#ifdef ENABLE_WIP_METHOD_NOLLVM_SELF_INIT +#ifndef ENABLE_LLVM + get_marshal_cb ()->emit_method_init (mb); +#endif +#endif // Just stub out the method with a "CEE_RET" // Our codegen backend generates other code here diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index a8037a6d922b0..3d62ed014972a 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -6808,9 +6808,10 @@ 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. - * Disable this assert when nollvm init is enabled */ +#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); @@ -15206,7 +15207,7 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options) } #endif -#if NOLLVM_AOT_METHOD_INIT +#ifdef ENABLE_WIP_METHOD_NOLLVM_SELF_INIT add_lazy_init_wrappers (acfg); #endif diff --git a/src/mono/mono/mini/aot-runtime.c b/src/mono/mono/mini/aot-runtime.c index 5ad1fb5ad7fdc..30c5148546736 100644 --- a/src/mono/mono/mini/aot-runtime.c +++ b/src/mono/mono/mini/aot-runtime.c @@ -4390,7 +4390,7 @@ load_method (MonoAotModule *amodule, MonoImage *image, MonoMethod *method, guint res = init_method (amodule, NULL, method_index, method, NULL, error); if (!res) goto cleanup; -#if !defined(ENABLE_LLVM) && defined(TARGET_ARM64) +#ifdef ENABLE_WIP_METHOD_NOLLVM_SELF_INIT else mono_bitset_set (mono_aot_get_mono_inited(amodule), method_index); #endif diff --git a/src/mono/mono/mini/mini-arm64.c b/src/mono/mono/mini/mini-arm64.c index cd07242244dd8..76dda93e4d014 100644 --- a/src/mono/mono/mini/mini-arm64.c +++ b/src/mono/mono/mini/mini-arm64.c @@ -5926,7 +5926,7 @@ mono_arch_emit_prolog (MonoCompile *cfg) /* Call the init wrapper which checks if the methos 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 */ -#if NOLLVM_AOT_METHOD_INIT +#ifdef ENABLE_WIP_METHOD_NOLLVM_SELF_INIT if (cfg->compile_aot) { code = emit_imm (code, ARMREG_R0, cfg->method_index); code = emit_call (cfg, code, MONO_PATCH_INFO_METHOD, NULL, (gconstpointer) mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD)); diff --git a/src/mono/mono/mini/mini.h b/src/mono/mono/mini/mini.h index 07e4dfdc2c5a5..7483e028159d4 100644 --- a/src/mono/mono/mini/mini.h +++ b/src/mono/mono/mini/mini.h @@ -87,11 +87,9 @@ typedef struct SeqPointInfo SeqPointInfo; #if ENABLE_LLVM #define COMPILE_LLVM(cfg) ((cfg)->compile_llvm) #define LLVM_ENABLED TRUE -#define NOLLVM_AOT_METHOD_INIT FALSE #else #define COMPILE_LLVM(cfg) (0) #define LLVM_ENABLED FALSE -#define NOLLVM_AOT_METHOD_INIT FALSE #endif #ifdef MONO_ARCH_SOFT_FLOAT_FALLBACK From 0e4b03602dba28ed4f737119d5e7516f06245b9c Mon Sep 17 00:00:00 2001 From: Vlad - Alexandru Ionescu Date: Fri, 21 Jul 2023 17:20:50 +0200 Subject: [PATCH 10/14] Cleanup Signed-off-by: Vlad - Alexandru Ionescu --- src/mono/mono/metadata/marshal.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 2a286c66208ed..e066ae94d7002 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -2977,7 +2977,6 @@ mono_marshal_get_aot_init_wrapper (MonoAotInitSubtype subtype) mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_OTHER); -/* Uncomment when working on https://github.com/dotnet/runtime/issues/82224 */ #ifdef ENABLE_WIP_METHOD_NOLLVM_SELF_INIT #ifndef ENABLE_LLVM get_marshal_cb ()->emit_method_init (mb); From 00a9b417feea6cef65b5454f41773ef137efe9f7 Mon Sep 17 00:00:00 2001 From: Vlad-Alexandru Ionescu <114913836+LeVladIonescu@users.noreply.github.com> Date: Fri, 21 Jul 2023 17:21:53 +0200 Subject: [PATCH 11/14] Update src/mono/mono/mini/mini-arm64.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Aleksey Kliger (λgeek) --- src/mono/mono/mini/mini-arm64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/mini/mini-arm64.c b/src/mono/mono/mini/mini-arm64.c index 76dda93e4d014..34813a1d6c3d3 100644 --- a/src/mono/mono/mini/mini-arm64.c +++ b/src/mono/mono/mini/mini-arm64.c @@ -5924,7 +5924,7 @@ 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 methos needs to be initialised or not */ + /* 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) { From f5eee3e28fd077fd46dbb43dce5d7362bacb51e2 Mon Sep 17 00:00:00 2001 From: Vlad Date: Thu, 17 Aug 2023 23:32:31 +0200 Subject: [PATCH 12/14] Added flag and converting this PR to draft Signed-off-by: Vlad --- src/mono/CMakeLists.txt | 1 + src/mono/cmake/config.h.in | 2 +- src/mono/mono/metadata/marshal.c | 2 - src/mono/mono/mini/aot-compiler.c | 7 --- src/mono/mono/mini/aot-runtime.c | 2 +- src/mono/mono/mini/mini-arm64.c | 4 +- src/mono/sample/HelloWorld/HelloWorld.csproj | 4 ++ src/mono/sample/HelloWorld/Program.cs | 10 ++--- src/mono/sample/HelloWorld/README | 7 +++ src/mono/sample/HelloWorld/run.sh | 45 ++++++++++++++++++++ src/mono/sample/MyLib/Class1.cs | 25 +++++++++++ src/mono/sample/MyLib/MyLib.csproj | 9 ++++ 12 files changed, 99 insertions(+), 19 deletions(-) create mode 100644 src/mono/sample/HelloWorld/README create mode 100755 src/mono/sample/HelloWorld/run.sh create mode 100644 src/mono/sample/MyLib/Class1.cs create mode 100644 src/mono/sample/MyLib/MyLib.csproj diff --git a/src/mono/CMakeLists.txt b/src/mono/CMakeLists.txt index 922df30508e20..6fc6c23420ac8 100644 --- a/src/mono/CMakeLists.txt +++ b/src/mono/CMakeLists.txt @@ -445,6 +445,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 b43e8718cf90f..d778a046fc9bd 100644 --- a/src/mono/cmake/config.h.in +++ b/src/mono/cmake/config.h.in @@ -961,7 +961,7 @@ #cmakedefine HAVE_CLOCK_GETTIME 1 /* work in progress: nollvm method self initialization */ -#cmakedefine ENABLE_WIP_METHOD_NOLLVM_SELF_INIT 0 +#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. diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index e066ae94d7002..cfd7674f6b912 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -2978,9 +2978,7 @@ 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 -#ifndef ENABLE_LLVM get_marshal_cb ()->emit_method_init (mb); -#endif #endif // Just stub out the method with a "CEE_RET" diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 3d62ed014972a..3cf2fc4d10a8d 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -4461,8 +4461,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) { @@ -4470,8 +4468,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) { @@ -15206,10 +15202,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 - -#ifdef ENABLE_WIP_METHOD_NOLLVM_SELF_INIT add_lazy_init_wrappers (acfg); -#endif 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 30c5148546736..8e72a9d6b02bf 100644 --- a/src/mono/mono/mini/aot-runtime.c +++ b/src/mono/mono/mini/aot-runtime.c @@ -4392,7 +4392,7 @@ load_method (MonoAotModule *amodule, MonoImage *image, MonoMethod *method, guint goto cleanup; #ifdef ENABLE_WIP_METHOD_NOLLVM_SELF_INIT else - mono_bitset_set (mono_aot_get_mono_inited(amodule), method_index); + mono_bitset_set (mono_aot_get_mono_inited (amodule), method_index); #endif } } diff --git a/src/mono/mono/mini/mini-arm64.c b/src/mono/mono/mini/mini-arm64.c index 34813a1d6c3d3..733c7cee71c23 100644 --- a/src/mono/mono/mini/mini-arm64.c +++ b/src/mono/mono/mini/mini-arm64.c @@ -5927,9 +5927,9 @@ mono_arch_emit_prolog (MonoCompile *cfg) /* 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) { + 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, NULL, (gconstpointer) mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD)); + code = emit_call (cfg, code, MONO_PATCH_INFO_METHOD, (gconstpointer) mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD)); } #endif diff --git a/src/mono/sample/HelloWorld/HelloWorld.csproj b/src/mono/sample/HelloWorld/HelloWorld.csproj index ef6aa16657606..0a6d6a6aa765a 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/Program.cs b/src/mono/sample/HelloWorld/Program.cs index 6d0b31d30dc6f..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(); } } -} \ No newline at end of file +} 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 + + + From 73537b572133302d6d03506be044b4bc841fe2d3 Mon Sep 17 00:00:00 2001 From: Milos Kotlar Date: Fri, 18 Aug 2023 17:42:22 +0200 Subject: [PATCH 13/14] Fix AOT compilation to generate init wrapper code --- src/mono/mono/cil/cil-opcodes.xml | 2 +- src/mono/mono/cil/opcode.def | 2 +- src/mono/mono/metadata/marshal-lightweight.c | 6 ++---- src/mono/mono/metadata/marshal.c | 2 +- src/mono/mono/metadata/marshal.h | 2 +- src/mono/mono/mini/aot-compiler.c | 1 + src/mono/mono/mini/method-to-ir.c | 2 +- 7 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/mono/mono/cil/cil-opcodes.xml b/src/mono/mono/cil/cil-opcodes.xml index e61fc80678042..712eb72daf65e 100644 --- a/src/mono/mono/cil/cil-opcodes.xml +++ b/src/mono/mono/cil/cil-opcodes.xml @@ -328,5 +328,5 @@ - + diff --git a/src/mono/mono/cil/opcode.def b/src/mono/mono/cil/opcode.def index c420220b406db..439ebb0dd2fe6 100644 --- a/src/mono/mono/cil/opcode.def +++ b/src/mono/mono/cil/opcode.def @@ -328,7 +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_AOT_MODULE, "aot_module", Pop0, PushI, InlineI, 0, 2, 0xF0, 0x24, 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/marshal-lightweight.c b/src/mono/mono/metadata/marshal-lightweight.c index b572ab2bffdc0..8f7d4001d074a 100644 --- a/src/mono/mono/metadata/marshal-lightweight.c +++ b/src/mono/mono/metadata/marshal-lightweight.c @@ -3365,13 +3365,11 @@ static void emit_method_init_ilgen (MonoMethodBuilder *mb) { // load aot_module - mono_mb_emit_op (mb, CEE_AOT_MODULE, NULL); + 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); - - mono_mb_emit_byte (mb, CEE_RET); } void @@ -3404,7 +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 = emit_method_init_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 e6e8219b0e20d..c5b347d757aec 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -2978,7 +2978,7 @@ 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 - get_marshal_cb ()->emit_method_init (mb); + get_marshal_cb ()->emit_method_init_nollvm (mb); #endif // Just stub out the method with a "CEE_RET" diff --git a/src/mono/mono/metadata/marshal.h b/src/mono/mono/metadata/marshal.h index 03d568ea432ec..6ca9b3c2d76c7 100644 --- a/src/mono/mono/metadata/marshal.h +++ b/src/mono/mono/metadata/marshal.h @@ -349,7 +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) (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 dcf48be85f994..d1600dad9ff5d 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -14489,6 +14489,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, diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index 721d185f175a4..5575f9d8e045f 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -11258,7 +11258,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b *sp++ = ins; break; } - case MONO_CEE_AOT_MODULE: { + case MONO_CEE_MONO_AOT_MODULE: { g_assert (cfg->compile_aot); EMIT_NEW_AOTCONST (cfg, ins, MONO_PATCH_INFO_AOT_MODULE, NULL); *sp++ = ins; From 406e5bdee4401235f05a3f91f28ebdd853b79013 Mon Sep 17 00:00:00 2001 From: Vlad Date: Tue, 31 Oct 2023 01:32:59 +0100 Subject: [PATCH 14/14] Change the symbol for the init wrappers Signed-off-by: Vlad --- src/mono/mono/metadata/marshal.c | 4 +++- src/mono/mono/mini/aot-compiler.c | 9 ++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 7a71c3f138da5..e3f8603233a7a 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -2978,7 +2978,9 @@ 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 - get_marshal_cb ()->emit_method_init_nollvm (mb); + if (subtype == AOT_INIT_METHOD) { + get_marshal_cb ()->emit_method_init_nollvm (mb); + } #endif // Just stub out the method with a "CEE_RET" diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 40f439467645a..7cd6cc14e229f 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -7104,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) { /*