From: monojenkins Date: Mon, 6 Apr 2020 22:14:07 +0000 (-0400) Subject: [llvm] Define a separate symbol for the aot method info for every method. Pass this... X-Git-Tag: submit/tizen/20210909.063632~8731 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=aa5341b2bbd1a5bfba3572cdc88ef3cf3a1645dc;p=platform%2Fupstream%2Fdotnet%2Fruntime.git [llvm] Define a separate symbol for the aot method info for every method. Pass this symbol to the init functions instead of the method index. (#34009) This removes a dependency the generated code has on the method index, hopefully allowing separate compilation etc. in the future. Co-authored-by: vargaz --- diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 768a009..a83aa8b 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -6865,7 +6865,10 @@ emit_method_info (MonoAotCompile *acfg, MonoCompile *cfg) flags |= MONO_AOT_METHOD_FLAG_HAS_PATCHES; if (needs_ctx && ctx) flags |= MONO_AOT_METHOD_FLAG_HAS_CTX; - encode_value (flags, p, &p); + /* Saved into another table so it can be accessed without having access to this data */ + cfg->aot_method_flags = flags; + + encode_int (cfg->method_index, p, &p); if (flags & MONO_AOT_METHOD_FLAG_HAS_CCTOR) encode_klass_ref (acfg, method->klass, p, &p); if (needs_ctx && ctx) @@ -6884,7 +6887,15 @@ emit_method_info (MonoAotCompile *acfg, MonoCompile *cfg) g_assert (p - buf < buf_size); - cfg->method_info_offset = add_to_blob (acfg, buf, p - buf); + if (cfg->compile_llvm) { + char *symbol = g_strdup_printf ("info_%s", cfg->llvm_method_name); + cfg->llvm_info_var = mono_llvm_emit_aot_data_aligned (symbol, buf, p - buf, 1); + g_free (symbol); + /* aot-runtime.c will use this to check whenever this is an llvm method */ + cfg->method_info_offset = 0; + } else { + cfg->method_info_offset = add_to_blob (acfg, buf, p - buf); + } g_free (buf); } @@ -10356,10 +10367,11 @@ emit_code (MonoAotCompile *acfg) } static void -emit_info (MonoAotCompile *acfg) +emit_method_info_table (MonoAotCompile *acfg) { int oindex, i; gint32 *offsets; + guint8 *method_flags; offsets = g_new0 (gint32, acfg->nmethods); @@ -10377,6 +10389,14 @@ emit_info (MonoAotCompile *acfg) acfg->stats.offsets_size += emit_offset_table (acfg, "method_info_offsets", MONO_AOT_TABLE_METHOD_INFO_OFFSETS, acfg->nmethods, 10, offsets); g_free (offsets); + + /* Emit a separate table for method flags, its needed at runtime */ + method_flags = g_new0 (guint8, acfg->nmethods); + for (i = 0; i < acfg->nmethods; ++i) { + if (acfg->cfgs [i]) + method_flags [acfg->cfgs [i]->method_index] = acfg->cfgs [i]->aot_method_flags; + } + emit_aot_data (acfg, MONO_AOT_TABLE_FLAGS_TABLE, "method_flags_table", method_flags, acfg->nmethods); } #endif /* #if !defined(DISABLE_AOT) && !defined(DISABLE_JIT) */ @@ -11397,6 +11417,7 @@ emit_aot_file_info (MonoAotCompile *acfg, MonoAotFileInfo *info) symbols [sindex ++] = NULL; symbols [sindex ++] = "image_table"; symbols [sindex ++] = "weak_field_indexes"; + symbols [sindex ++] = "method_flags_table"; } symbols [sindex ++] = "mem_end"; @@ -14161,7 +14182,7 @@ emit_aot_image (MonoAotCompile *acfg) emit_code (acfg); - emit_info (acfg); + emit_method_info_table (acfg); emit_extra_methods (acfg); diff --git a/src/mono/mono/mini/aot-runtime.c b/src/mono/mono/mini/aot-runtime.c index 97423e4..43dda8c 100644 --- a/src/mono/mono/mini/aot-runtime.c +++ b/src/mono/mono/mini/aot-runtime.c @@ -250,7 +250,7 @@ static void compute_llvm_code_range (MonoAotModule *amodule, guint8 **code_start, guint8 **code_end); static gboolean -init_method (MonoAotModule *amodule, guint32 method_index, MonoMethod *method, MonoClass *init_class, MonoError *error); +init_method (MonoAotModule *amodule, gpointer info, guint32 method_index, MonoMethod *method, MonoClass *init_class, MonoError *error); static MonoJumpInfo* decode_patches (MonoAotModule *amodule, MonoMemPool *mp, int n_patches, gboolean llvm, guint32 *got_offsets); @@ -4321,9 +4321,12 @@ load_method (MonoDomain *domain, MonoAotModule *amodule, MonoImage *image, MonoM if (!(is_llvm_code (amodule, code) && (amodule->info.flags & MONO_AOT_FILE_FLAG_LLVM_ONLY)) || (mono_llvm_only && method && method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED)) { - res = init_method (amodule, method_index, method, NULL, error); - if (!res) - goto cleanup; + /* offset == 0 means its llvm code */ + if (mono_aot_get_offset (amodule->method_info_offsets, method_index) != 0) { + res = init_method (amodule, NULL, method_index, method, NULL, error); + if (!res) + goto cleanup; + } } if (mono_trace_is_traced (G_LOG_LEVEL_DEBUG, MONO_TRACE_AOT)) { @@ -4345,11 +4348,7 @@ load_method (MonoDomain *domain, MonoAotModule *amodule, MonoImage *image, MonoM } if (mono_llvm_only) { - guint8 *info, *p; - - info = &amodule->blob [mono_aot_get_offset (amodule->method_info_offsets, method_index)]; - p = info; - guint8 flags = decode_value (p, &p); + guint8 flags = amodule->info.method_flags_table [method_index]; /* The caller needs to looks this up, but its hard to do without constructing the full MonoJitInfo, so save it here */ if (flags & MONO_AOT_METHOD_FLAG_GSHAREDVT_VARIABLE) { mono_aot_lock (); @@ -4600,7 +4599,7 @@ mono_aot_find_method_index (MonoMethod *method) } static gboolean -init_method (MonoAotModule *amodule, guint32 method_index, MonoMethod *method, MonoClass *init_class, MonoError *error) +init_method (MonoAotModule *amodule, gpointer info, guint32 method_index, MonoMethod *method, MonoClass *init_class, MonoError *error) { MonoDomain *domain = mono_domain_get (); MonoMemPool *mp; @@ -4609,7 +4608,7 @@ init_method (MonoAotModule *amodule, guint32 method_index, MonoMethod *method, M int pindex, n_patches; guint8 *p; MonoJitInfo *jinfo = NULL; - guint8 *code, *info; + guint8 *code; MonoGenericContext *context; MonoGenericContext ctx; @@ -4621,12 +4620,21 @@ init_method (MonoAotModule *amodule, guint32 method_index, MonoMethod *method, M error_init (error); - code = (guint8 *)amodule->methods [method_index]; - info = &amodule->blob [mono_aot_get_offset (amodule->method_info_offsets, method_index)]; + if (!info) + info = &amodule->blob [mono_aot_get_offset (amodule->method_info_offsets, method_index)]; - p = info; + p = (guint8*)info; + + // FIXME: Is this aligned ? + guint32 encoded_method_index = *(guint32*)p; + if (method_index) + g_assert (method_index == encoded_method_index); + method_index = encoded_method_index; + p += 4; + + code = (guint8 *)amodule->methods [method_index]; + guint8 flags = amodule->info.method_flags_table [method_index]; - guint8 flags = decode_value (p, &p); if (flags & MONO_AOT_METHOD_FLAG_HAS_CCTOR) klass_to_run_ctor = decode_klass_ref (amodule, p, &p, error); if (!is_ok (error)) @@ -4756,17 +4764,16 @@ init_method (MonoAotModule *amodule, guint32 method_index, MonoMethod *method, M } /* - * mono_aot_init_llvmonly_method: + * mono_aot_init_llvm_method: * - * Initialize the method identified by METHOD_INDEX in llvmonly mode. + * Initialize the LLVM method identified by METHOD_INFO. */ gboolean -mono_aot_init_llvmonly_method (gpointer aot_module, guint32 method_index, MonoClass *init_class, MonoError *error) +mono_aot_init_llvm_method (gpointer aot_module, gpointer method_info, MonoClass *init_class, MonoError *error) { MonoAotModule *amodule = (MonoAotModule*)aot_module; - MonoMethod *method = NULL; - return init_method (amodule, method_index, method, init_class, error); + return init_method (amodule, method_info, 0, NULL, init_class, error); } /* diff --git a/src/mono/mono/mini/aot-runtime.h b/src/mono/mono/mini/aot-runtime.h index 91ea7ac..57dd480 100644 --- a/src/mono/mono/mini/aot-runtime.h +++ b/src/mono/mono/mini/aot-runtime.h @@ -97,6 +97,7 @@ typedef enum { MONO_AOT_TABLE_EXTRA_METHOD_INFO_OFFSETS, MONO_AOT_TABLE_EXTRA_METHOD_TABLE, MONO_AOT_TABLE_WEAK_FIELD_INDEXES, + MONO_AOT_TABLE_FLAGS_TABLE, MONO_AOT_TABLE_NUM } MonoAotFileTable; @@ -144,6 +145,7 @@ typedef struct MonoAotFileInfo gpointer image_table; /* Points to an array of weak field indexes */ gpointer weak_field_indexes; + guint8 *method_flags_table; gpointer mem_end; /* The GUID of the assembly which the AOT image was generated from */ @@ -271,7 +273,7 @@ gboolean mono_aot_is_pagefault (void *ptr); void mono_aot_handle_pagefault (void *ptr); guint32 mono_aot_find_method_index (MonoMethod *method); -gboolean mono_aot_init_llvmonly_method (gpointer amodule, guint32 method_index, MonoClass *init_class, MonoError *error); +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); MonoAotMethodFlags mono_aot_get_method_flags (guint8 *code); diff --git a/src/mono/mono/mini/llvmonly-runtime.c b/src/mono/mono/mini/llvmonly-runtime.c index 3104e29..100cffb 100644 --- a/src/mono/mono/mini/llvmonly-runtime.c +++ b/src/mono/mono/mini/llvmonly-runtime.c @@ -768,13 +768,16 @@ mini_llvmonly_resolve_iface_call_gsharedvt (MonoObject *this_obj, int imt_slot, return res; } -static void -init_llvmonly_method (MonoAotModule *amodule, guint32 method_index, MonoClass *init_class) +/* Called from LLVM code to initialize a method */ +// FIXME: This should be somewhere else +void +mini_llvm_init_method (MonoAotFileInfo *info, gpointer aot_module, gpointer method_info, MonoVTable *vtable) { - ERROR_DECL (error); gboolean res; + MonoAotModule *amodule = (MonoAotModule *)aot_module; + ERROR_DECL (error); - res = mono_aot_init_llvmonly_method (amodule, method_index, init_class, error); + res = mono_aot_init_llvm_method (amodule, method_info, vtable ? vtable->klass : NULL, error); if (!res || !is_ok (error)) { MonoException *ex = mono_error_convert_to_exception (error); if (ex) { @@ -788,15 +791,6 @@ init_llvmonly_method (MonoAotModule *amodule, guint32 method_index, MonoClass *i } } -/* Called from generated code to initialize a method */ -void -mini_llvm_init_method (MonoAotFileInfo *info, gpointer aot_module, guint32 method_index, MonoVTable *vtable) -{ - MonoAotModule *amodule = (MonoAotModule *)aot_module; - - init_llvmonly_method (amodule, method_index, vtable ? vtable->klass : NULL); -} - static GENERATE_GET_CLASS_WITH_CACHE (nullref, "System", "NullReferenceException") void diff --git a/src/mono/mono/mini/llvmonly-runtime.h b/src/mono/mono/mini/llvmonly-runtime.h index f939916..35aa4dc 100644 --- a/src/mono/mono/mini/llvmonly-runtime.h +++ b/src/mono/mono/mini/llvmonly-runtime.h @@ -29,7 +29,7 @@ G_EXTERN_C void mini_llvmonly_init_delegate (MonoDelegate *del); G_EXTERN_C void mini_llvmonly_init_delegate_virtual (MonoDelegate *del, MonoObject *target, MonoMethod *method); /* Used for regular llvm as well */ -G_EXTERN_C void mini_llvm_init_method (MonoAotFileInfo *info, gpointer aot_module, guint32 method_index, MonoVTable *vtable); +G_EXTERN_C void mini_llvm_init_method (MonoAotFileInfo *info, gpointer aot_module, gpointer method_info, MonoVTable *vtable); G_EXTERN_C void mini_llvmonly_throw_nullref_exception (void); diff --git a/src/mono/mono/mini/mini-llvm.c b/src/mono/mono/mini/mini-llvm.c index 25f58b7..4392f33 100644 --- a/src/mono/mono/mini/mini-llvm.c +++ b/src/mono/mono/mini/mini-llvm.c @@ -3000,37 +3000,37 @@ emit_llvm_code_start (MonoLLVMModule *module) } /* - * emit_init_icall_wrapper: + * emit_init_func: * - * Emit wrappers around the mini_llvm_init_method () JIT icall. + * Emit functions to initialize LLVM methods. + * These are wrappers around the mini_llvm_init_method () JIT icall. * The wrappers handle adding the 'amodule' argument, loading the vtable from different locations, and they have * a cold calling convention. */ static LLVMValueRef -emit_init_icall_wrapper (MonoLLVMModule *module, MonoAotInitSubtype subtype) +emit_init_func (MonoLLVMModule *module, MonoAotInitSubtype subtype) { LLVMModuleRef lmodule = module->lmodule; - LLVMValueRef func, indexes [2], args [16], callee, inited_var, cmp; + LLVMValueRef func, indexes [2], args [16], callee, info_var, index_var, inited_var, cmp; LLVMBasicBlockRef entry_bb, inited_bb, notinited_bb; LLVMBuilderRef builder; LLVMTypeRef icall_sig; const char *wrapper_name = mono_marshal_get_aot_init_wrapper_name (subtype); LLVMTypeRef func_type = NULL; + LLVMTypeRef arg_type = module->ptr_type; char *name = g_strdup_printf ("%s_%s", module->global_prefix, wrapper_name); switch (subtype) { case AOT_INIT_METHOD: - func_type = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE); + func_type = LLVMFunctionType1 (LLVMVoidType (), arg_type, FALSE); break; case AOT_INIT_METHOD_GSHARED_MRGCTX: - func_type = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE); - break; case AOT_INIT_METHOD_GSHARED_VTABLE: - func_type = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE); + func_type = LLVMFunctionType2 (LLVMVoidType (), arg_type, IntPtrType (), FALSE); break; case AOT_INIT_METHOD_GSHARED_THIS: - func_type = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE); + func_type = LLVMFunctionType2 (LLVMVoidType (), arg_type, ObjRefType (), FALSE); break; default: g_assert_not_reached (); @@ -3038,6 +3038,8 @@ emit_init_icall_wrapper (MonoLLVMModule *module, MonoAotInitSubtype subtype) func = LLVMAddFunction (lmodule, name, func_type); + info_var = LLVMGetParam (func, 0); + LLVMSetLinkage (func, LLVMInternalLinkage); mono_llvm_add_func_attr (func, LLVM_ATTR_NO_INLINE); @@ -3049,9 +3051,15 @@ emit_init_icall_wrapper (MonoLLVMModule *module, MonoAotInitSubtype subtype) builder = LLVMCreateBuilder (); LLVMPositionBuilderAtEnd (builder, entry_bb); + /* Load method_index which is emitted at the start of the method info */ + indexes [0] = const_int32 (0); + indexes [1] = const_int32 (0); + // FIXME: Make sure its aligned + index_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, LLVMBuildBitCast (builder, info_var, LLVMPointerType (LLVMInt32Type (), 0), ""), indexes, 1, ""), "method_index"); + /* Check for is_inited here as well, since this can be called from JITted code which might not check it */ - indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE); - indexes [1] = LLVMGetParam (func, 0); + indexes [0] = const_int32 (0); + indexes [1] = index_var; inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""), "is_inited"); cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), ""); @@ -3067,7 +3075,7 @@ emit_init_icall_wrapper (MonoLLVMModule *module, MonoAotInitSubtype subtype) args [0] = LLVMBuildPtrToInt (builder, module->info_var, IntPtrType (), ""); args [1] = LLVMBuildPtrToInt (builder, amodule_var, IntPtrType (), ""); - args [2] = LLVMGetParam (func, 0); + args [2] = info_var; switch (subtype) { case AOT_INIT_METHOD: @@ -3093,13 +3101,17 @@ emit_init_icall_wrapper (MonoLLVMModule *module, MonoAotInitSubtype subtype) break; } - icall_sig = LLVMFunctionType4 (LLVMVoidType (), IntPtrType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE); + /* Call the mini_llvm_init_method JIT icall */ + icall_sig = LLVMFunctionType4 (LLVMVoidType (), IntPtrType (), IntPtrType (), arg_type, IntPtrType (), FALSE); callee = get_aotconst_module (module, builder, MONO_PATCH_INFO_JIT_ICALL_ID, GINT_TO_POINTER (MONO_JIT_ICALL_mini_llvm_init_method), LLVMPointerType (icall_sig, 0), NULL, NULL); LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (icall_sig), ""); - // Set the inited flag - indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE); - indexes [1] = LLVMGetParam (func, 0); + /* + * Set the inited flag + * This is already done by the LLVM methods themselves, but its needed by JITted methods. + */ + indexes [0] = const_int32 (0); + indexes [1] = index_var; LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, "")); LLVMBuildBr (builder, inited_bb); @@ -3107,7 +3119,7 @@ emit_init_icall_wrapper (MonoLLVMModule *module, MonoAotInitSubtype subtype) LLVMPositionBuilderAtEnd (builder, inited_bb); LLVMBuildRetVoid (builder); - LLVMVerifyFunction(func, LLVMAbortProcessAction); + LLVMVerifyFunction (func, LLVMAbortProcessAction); LLVMDisposeBuilder (builder); g_free (name); @@ -3162,16 +3174,16 @@ emit_icall_cold_wrapper (MonoLLVMModule *module, LLVMModuleRef lmodule, MonoJitI * cold calling convention. */ static void -emit_init_icall_wrappers (MonoLLVMModule *module) +emit_init_funcs (MonoLLVMModule *module) { - module->init_method = emit_init_icall_wrapper (module, AOT_INIT_METHOD); - module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, AOT_INIT_METHOD_GSHARED_MRGCTX); - module->init_method_gshared_this = emit_init_icall_wrapper (module, AOT_INIT_METHOD_GSHARED_THIS); - module->init_method_gshared_vtable = emit_init_icall_wrapper (module, AOT_INIT_METHOD_GSHARED_VTABLE); + module->init_method = emit_init_func (module, AOT_INIT_METHOD); + module->init_method_gshared_mrgctx = emit_init_func (module, AOT_INIT_METHOD_GSHARED_MRGCTX); + module->init_method_gshared_this = emit_init_func (module, AOT_INIT_METHOD_GSHARED_THIS); + module->init_method_gshared_vtable = emit_init_func (module, AOT_INIT_METHOD_GSHARED_VTABLE); } static LLVMValueRef -get_init_icall_wrapper (MonoLLVMModule *module, MonoAotInitSubtype subtype) +get_init_func (MonoLLVMModule *module, MonoAotInitSubtype subtype) { switch (subtype) { case AOT_INIT_METHOD: @@ -3335,12 +3347,12 @@ emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, Mo } /* - * emit_init_method: + * emit_method_init: * * Emit code to initialize the GOT slots used by the method. */ static void -emit_init_method (EmitContext *ctx) +emit_method_init (EmitContext *ctx) { LLVMValueRef indexes [16], args [16], callee; LLVMValueRef inited_var, cmp, call; @@ -3350,8 +3362,8 @@ emit_init_method (EmitContext *ctx) ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index); - indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE); - indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE); + indexes [0] = const_int32 (0); + indexes [1] = const_int32 (cfg->method_index); inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited"); args [0] = inited_var; @@ -3368,26 +3380,30 @@ emit_init_method (EmitContext *ctx) builder = ctx->builder = create_builder (ctx); LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb); + LLVMTypeRef type = LLVMArrayType (LLVMInt8Type (), 0); + char *symbol = g_strdup_printf ("info_dummy_%s", cfg->llvm_method_name); + LLVMValueRef info_var = LLVMAddGlobal (ctx->lmodule, type, symbol); + g_free (symbol); + cfg->llvm_dummy_info_var = info_var; + + args [0] = convert (ctx, info_var, ctx->module->ptr_type); + // FIXME: Cache if (ctx->rgctx_arg && ((cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) || mini_method_is_default_method (cfg->method))) { - args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0); args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ()); callee = ctx->module->init_method_gshared_mrgctx; call = LLVMBuildCall (builder, callee, args, 2, ""); } else if (ctx->rgctx_arg) { /* A vtable is passed as the rgctx argument */ - args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0); args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ()); callee = ctx->module->init_method_gshared_vtable; call = LLVMBuildCall (builder, callee, args, 2, ""); } else if (cfg->gshared) { - args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0); args [1] = convert (ctx, ctx->this_arg, ObjRefType ()); callee = ctx->module->init_method_gshared_this; call = LLVMBuildCall (builder, callee, args, 2, ""); } else { - args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0); callee = ctx->module->init_method; call = LLVMBuildCall (builder, callee, args, 1, ""); } @@ -3398,6 +3414,11 @@ emit_init_method (EmitContext *ctx) */ set_call_cold_cconv (call); + // Set the inited flag + indexes [0] = const_int32 (0); + indexes [1] = const_int32 (cfg->method_index); + LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, "")); + LLVMBuildBr (builder, inited_bb); ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb; @@ -9214,7 +9235,7 @@ emit_method_inner (EmitContext *ctx) if (cfg->method->wrapper_type == MONO_WRAPPER_OTHER) { WrapperInfo *info = mono_marshal_get_wrapper_info (cfg->method); if (info->subtype == WRAPPER_SUBTYPE_AOT_INIT) { - method = get_init_icall_wrapper (ctx->module, info->d.aot_init.subtype); + method = get_init_func (ctx->module, info->d.aot_init.subtype); ctx->lmethod = method; ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index); @@ -9754,7 +9775,7 @@ after_codegen_1: if (cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED) needs_init = FALSE; if (needs_init) - emit_init_method (ctx); + emit_method_init (ctx); else LLVMBuildBr (ctx->builder, ctx->inited_bb); @@ -9769,9 +9790,8 @@ after_codegen_1: mono_llvm_add_func_attr (method, LLVM_ATTR_NO_INLINE); after_codegen: + g_ptr_array_add (ctx->module->cfgs, cfg); if (cfg->llvm_only) { - g_ptr_array_add (ctx->module->cfgs, cfg); - /* * Add the contents of ctx->callsite_list to module->callsite_list. * We can't do this earlier, as it contains llvm instructions which can be @@ -9820,7 +9840,7 @@ after_codegen: } //LLVMDumpValue (ctx->lmethod); - //int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction); + //int err = LLVMVerifyFunction (ctx->lmethod, LLVMPrintMessageAction); //g_assert (err == 0); } else { //LLVMVerifyFunction (method, 0); @@ -10282,6 +10302,16 @@ mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, module->cfgs = g_ptr_array_new (); module->intrins_by_id = g_new0 (LLVMValueRef, INTRINS_NUM); module->aotconst_vars = g_hash_table_new (NULL, NULL); + module->llvm_types = g_hash_table_new (NULL, NULL); + module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal); + module->plt_entries_ji = g_hash_table_new (NULL, NULL); + module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal); + module->idx_to_lmethod = g_hash_table_new (NULL, NULL); + module->method_to_lmethod = g_hash_table_new (NULL, NULL); + module->method_to_call_info = g_hash_table_new (NULL, NULL); + module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL); + module->no_method_table_lmethods = g_hash_table_new (NULL, NULL); + module->callsite_list = g_ptr_array_new (); if (llvm_only) /* clang ignores our debug info because it has an invalid version */ @@ -10370,7 +10400,7 @@ mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, emit_llvm_code_start (module); // Needs idx_to_lmethod - emit_init_icall_wrappers (module); + emit_init_funcs (module); /* Add a dummy personality function */ if (!use_mono_personality_debug) { @@ -10390,17 +10420,6 @@ mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage); mono_llvm_set_is_constant (module->sentinel_exception); } - - module->llvm_types = g_hash_table_new (NULL, NULL); - module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal); - module->plt_entries_ji = g_hash_table_new (NULL, NULL); - module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal); - module->idx_to_lmethod = g_hash_table_new (NULL, NULL); - module->method_to_lmethod = g_hash_table_new (NULL, NULL); - module->method_to_call_info = g_hash_table_new (NULL, NULL); - module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL); - module->no_method_table_lmethods = g_hash_table_new (NULL, NULL); - module->callsite_list = g_ptr_array_new (); } void @@ -10552,9 +10571,10 @@ mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code) * mono_llvm_emit_aot_data: * * Emit the binary data DATA pointed to by symbol SYMBOL. + * Return the LLVM variable for the data. */ -void -mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len) +gpointer +mono_llvm_emit_aot_data_aligned (const char *symbol, guint8 *data, int data_len, int align) { MonoLLVMModule *module = &aot_module; LLVMTypeRef type; @@ -10565,8 +10585,16 @@ mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len) LLVMSetVisibility (d, LLVMHiddenVisibility); LLVMSetLinkage (d, LLVMInternalLinkage); LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len)); - LLVMSetAlignment (d, 8); + if (align != 1) + LLVMSetAlignment (d, align); mono_llvm_set_is_constant (d); + return d; +} + +gpointer +mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len) +{ + return mono_llvm_emit_aot_data_aligned (symbol, data, data_len, 8); } /* Add a reference to a global defined in JITted code */ @@ -10709,6 +10737,7 @@ emit_aot_file_info (MonoLLVMModule *module) fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets"); fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table"); fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "weak_field_indexes"); + fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_flags_table"); } /* Not needed (mem_end) */ fields [tindex ++] = LLVMConstNull (eltype); @@ -10989,6 +11018,24 @@ mono_llvm_emit_aot_module (const char *filename, const char *cu_name) mono_llvm_replace_uses_of (module->inited_var, real_inited); LLVMDeleteGlobal (module->inited_var); + /* Replace the dummy info_ variables with the real ones */ + for (int i = 0; i < module->cfgs->len; ++i) { + MonoCompile *cfg = (MonoCompile *)g_ptr_array_index (module->cfgs, i); + + // FIXME: Eliminate unused vars + + // FIXME: Speed this up + if (cfg->llvm_dummy_info_var) { + if (cfg->llvm_info_var) { + mono_llvm_replace_uses_of (cfg->llvm_dummy_info_var, cfg->llvm_info_var); + LLVMDeleteGlobal (cfg->llvm_dummy_info_var); + } else { + // FIXME: How can this happen ? + LLVMSetInitializer (cfg->llvm_dummy_info_var, mono_llvm_create_constant_data_array (NULL, 0)); + } + } + } + if (module->llvm_only) { emit_get_method (&aot_module); emit_get_unbox_tramp (&aot_module); diff --git a/src/mono/mono/mini/mini-llvm.h b/src/mono/mono/mini/mini-llvm.h index 6662764..ad23192 100644 --- a/src/mono/mono/mini/mini-llvm.h +++ b/src/mono/mono/mini/mini-llvm.h @@ -25,7 +25,8 @@ void mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call); void mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, int initial_got_size, LLVMModuleFlags flags); void mono_llvm_emit_aot_module (const char *filename, const char *cu_name); void mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code); -void mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len); +gpointer mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len); +gpointer mono_llvm_emit_aot_data_aligned (const char *symbol, guint8 *data, int data_len, int align); void mono_llvm_check_method_supported (MonoCompile *cfg); void mono_llvm_free_domain_info (MonoDomain *domain); MONO_API void mono_personality (void); diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index 1fe5b7c..1d217a6 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -4844,7 +4844,7 @@ register_icalls (void) register_dyn_icall (mini_get_dbg_callbacks ()->user_break, mono_debugger_agent_user_break, mono_icall_sig_void, FALSE); - register_icall (mini_llvm_init_method, mono_icall_sig_void_ptr_ptr_int_ptr, TRUE); + register_icall (mini_llvm_init_method, mono_icall_sig_void_ptr_ptr_ptr_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_generic_virtual_call, mono_icall_sig_ptr_ptr_int_ptr); diff --git a/src/mono/mono/mini/mini.c b/src/mono/mono/mini/mini.c index c734426..8fb697c 100644 --- a/src/mono/mono/mini/mini.c +++ b/src/mono/mono/mini/mini.c @@ -4244,7 +4244,14 @@ mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code) g_assert_not_reached (); } -void mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len) +gpointer +mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len) +{ + g_assert_not_reached (); +} + +gpointer +mono_llvm_emit_aot_data_aligned (const char *symbol, guint8 *data, int data_len, int align) { g_assert_not_reached (); } diff --git a/src/mono/mono/mini/mini.h b/src/mono/mono/mini/mini.h index 8ebb1a2..b9321bc 100644 --- a/src/mono/mono/mini/mini.h +++ b/src/mono/mono/mini/mini.h @@ -1539,9 +1539,11 @@ typedef struct { /* Used by AOT */ guint32 got_offset, ex_info_offset, method_info_offset, method_index; + guint32 aot_method_flags; /* For llvm */ guint32 got_access_count; gpointer llvmonly_init_cond; + gpointer llvm_dummy_info_var, llvm_info_var; /* Symbol used to refer to this method in generated assembly */ char *asm_symbol; char *asm_debug_symbol;