gboolean no_instances;
gboolean gnu_asm;
gboolean llvm;
+ gboolean llvm_only;
int nthreads;
int ntrampolines;
int nrgctx_trampolines;
/* Maps MonoMethod* -> blob offset */
GHashTable *method_blob_hash;
guint32 *plt_got_info_offsets;
- guint32 got_offset, llvm_got_offset, plt_offset, plt_got_offset_base;
+ guint32 got_offset, llvm_got_offset, plt_offset, plt_got_offset_base, nshared_got_entries;
/* Number of GOT entries reserved for trampolines */
guint32 num_trampoline_got_entries;
guint32 tramp_page_size;
} else {
encode_value (par->gshared_constraint ? 1 : 0, p, &p);
if (par->gshared_constraint) {
- const char *name;
-
+ MonoGSharedGenericParam *gpar = (MonoGSharedGenericParam*)par;
encode_type (acfg, par->gshared_constraint, p, &p);
-
- name = mono_generic_param_name (par);
- if (name) {
- int len = strlen (name);
-
- encode_value (len, p, &p);
- memcpy (p, name, len);
- p += len;
- } else {
- encode_value (0, p, &p);
- }
+ encode_klass_ref (acfg, mono_class_from_generic_parameter (gpar->parent, NULL, klass->byval_arg.type == MONO_TYPE_MVAR), p, &p);
}
}
} else if (klass->byval_arg.type == MONO_TYPE_PTR) {
g_assert (info);
encode_value (info->subtype, p, &p);
+ encode_value (info->d.runtime_invoke.pass_rgctx, p, &p);
if (info->subtype == WRAPPER_SUBTYPE_RUNTIME_INVOKE_DIRECT || info->subtype == WRAPPER_SUBTYPE_RUNTIME_INVOKE_VIRTUAL)
encode_method_ref (acfg, info->d.runtime_invoke.method, p, &p);
else if (info->subtype == WRAPPER_SUBTYPE_RUNTIME_INVOKE_NORMAL)
mb = mono_mb_new (mono_defaults.object_class, "FOO", MONO_WRAPPER_NONE);
m = mono_mb_create_method (mb, sig, 16);
- return mono_marshal_get_runtime_invoke (m, FALSE);
+ return mono_marshal_get_runtime_invoke (m, FALSE, FALSE);
+}
+
+static MonoMethod*
+get_runtime_invoke (MonoAotCompile *acfg, MonoMethod *method, gboolean virtual)
+{
+ return mono_marshal_get_runtime_invoke (method, virtual, acfg->aot_opts.llvm_only && mono_method_needs_static_rgctx_invoke (method, TRUE));
}
static gboolean
has_nullable = TRUE;
}
- if (info && !has_nullable) {
+ if (info && !has_nullable && !acfg->aot_opts.llvm_only) {
/* Supported by the dynamic runtime-invoke wrapper */
skip = TRUE;
}
if (!skip) {
//printf ("%s\n", mono_method_full_name (method, TRUE));
- add_method (acfg, mono_marshal_get_runtime_invoke (method, FALSE));
+ add_method (acfg, get_runtime_invoke (acfg, method, FALSE));
}
}
add_method (acfg, get_runtime_invoke_sig (csig));
/* runtime-invoke used by finalizers */
- add_method (acfg, mono_marshal_get_runtime_invoke (mono_class_get_method_from_name_flags (mono_defaults.object_class, "Finalize", 0, 0), TRUE));
+ add_method (acfg, get_runtime_invoke (acfg, mono_class_get_method_from_name_flags (mono_defaults.object_class, "Finalize", 0, 0), TRUE));
/* This is used by mono_runtime_capture_context () */
method = mono_get_context_capture_method ();
if (method)
- add_method (acfg, mono_marshal_get_runtime_invoke (method, FALSE));
+ add_method (acfg, get_runtime_invoke (acfg, method, FALSE));
#ifdef MONO_ARCH_DYN_CALL_SUPPORTED
- add_method (acfg, mono_marshal_get_runtime_invoke_dynamic ());
+ if (!acfg->aot_opts.llvm_only)
+ add_method (acfg, mono_marshal_get_runtime_invoke_dynamic ());
#endif
/* stelemref */
g_assert (m);
wrapper = mono_marshal_get_array_accessor_wrapper (m);
add_extra_method (acfg, wrapper);
- add_extra_method (acfg, mono_marshal_get_runtime_invoke (wrapper, FALSE));
+ add_extra_method (acfg, get_runtime_invoke (acfg, wrapper, FALSE));
m = mono_class_get_method_from_name (klass, "Set", -1);
g_assert (m);
wrapper = mono_marshal_get_array_accessor_wrapper (m);
add_extra_method (acfg, wrapper);
- add_extra_method (acfg, mono_marshal_get_runtime_invoke (wrapper, FALSE));
+ add_extra_method (acfg, get_runtime_invoke (acfg, wrapper, FALSE));
}
}
case MONO_PATCH_INFO_METHOD_CODE_SLOT:
encode_method_ref (acfg, patch_info->data.method, p, &p);
break;
+ case MONO_PATCH_INFO_AOT_JIT_INFO:
+ encode_value (patch_info->data.index, p, &p);
+ break;
case MONO_PATCH_INFO_INTERNAL_METHOD:
case MONO_PATCH_INFO_JIT_ICALL_ADDR: {
guint32 len = strlen (patch_info->data.name);
} else {
encode_value (0, p, &p);
}
- encode_value (patch_info->data.del_tramp->virtual, p, &p);
+ encode_value (patch_info->data.del_tramp->is_virtual, p, &p);
break;
case MONO_PATCH_INFO_FIELD:
case MONO_PATCH_INFO_SFLDA:
break;
case MONO_PATCH_INFO_INTERRUPTION_REQUEST_FLAG:
break;
- case MONO_PATCH_INFO_RGCTX_FETCH: {
+ case MONO_PATCH_INFO_RGCTX_FETCH:
+ case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
MonoJumpInfoRgctxEntry *entry = patch_info->data.rgctx_entry;
guint32 offset;
guint8 *buf2, *p2;
break;
}
case MONO_PATCH_INFO_SEQ_POINT_INFO:
+ case MONO_PATCH_INFO_AOT_MODULE:
break;
case MONO_PATCH_INFO_LLVM_IMT_TRAMPOLINE:
encode_method_ref (acfg, patch_info->data.imt_tramp->method, p, &p);
}
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_START ||
+ patch_info->type == MONO_PATCH_INFO_AOT_MODULE) {
/* Stored in a GOT slot initialized at module load time */
patch_info->type = MONO_PATCH_INFO_NONE;
continue;
}
- if (is_plt_patch (patch_info)) {
+ if (is_plt_patch (patch_info) && !(cfg->compile_llvm && acfg->aot_opts.llvm_only)) {
/* Calls are made through the PLT */
patch_info->type = MONO_PATCH_INFO_NONE;
continue;
encode_value (0, p, &p);
}
+ /* Emit the IL ranges too, since they might not be available at runtime */
+ encode_value (clause->try_offset, p, &p);
+ encode_value (clause->try_len, p, &p);
+ encode_value (clause->handler_offset, p, &p);
+ encode_value (clause->handler_len, p, &p);
+
/* Emit a list of nesting clauses */
for (i = 0; i < header->num_clauses; ++i) {
gint32 cindex1 = k;
static void
emit_plt (MonoAotCompile *acfg)
{
- char symbol [128];
int i;
+ if (acfg->aot_opts.llvm_only) {
+ g_assert (acfg->plt_offset == 1);
+ return;
+ }
+
emit_line (acfg);
- sprintf (symbol, "plt");
emit_section_change (acfg, ".text", 0);
emit_alignment_code (acfg, NACL_SIZE(16, kNaClAlignment));
- emit_info_symbol (acfg, symbol);
+ emit_info_symbol (acfg, "plt");
emit_label (acfg, acfg->plt_symbol);
for (i = 0; i < acfg->plt_offset; ++i) {
emit_symbol_size (acfg, acfg->plt_symbol, ".");
- sprintf (symbol, "plt_end");
- emit_info_symbol (acfg, symbol);
+ emit_info_symbol (acfg, "plt_end");
}
/*
int tramp_type;
#endif
- if (!mono_aot_mode_is_full (&acfg->aot_opts))
+ if (!mono_aot_mode_is_full (&acfg->aot_opts) || acfg->aot_opts.llvm_only)
return;
g_assert (acfg->image->assembly);
} else if (str_begins_with (arg, "gc-maps")) {
mini_gc_enable_gc_maps_for_aot ();
} else if (str_begins_with (arg, "dump")) {
- opts->dump_json = TRUE;
+ opts->dump_json = TRUE;
+ } else if (str_begins_with (arg, "llvmonly")) {
+ opts->mode = MONO_AOT_MODE_FULL;
+ opts->llvm = TRUE;
+ opts->llvm_only = TRUE;
} else if (str_begins_with (arg, "help") || str_begins_with (arg, "?")) {
printf ("Supported options for --aot:\n");
printf (" outfile=\n");
}
break;
}
- case MONO_PATCH_INFO_RGCTX_FETCH: {
+ case MONO_PATCH_INFO_RGCTX_FETCH:
+ case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
MonoJumpInfoRgctxEntry *entry = patch_info->data.rgctx_entry;
if (!can_encode_method (acfg, entry->method))
flags |= JIT_FLAG_FULL_AOT;
if (acfg->llvm)
flags |= JIT_FLAG_LLVM;
+ if (acfg->aot_opts.llvm_only)
+ flags |= JIT_FLAG_LLVM_ONLY | JIT_FLAG_EXPLICIT_NULL_CHECKS;
if (acfg->aot_opts.no_direct_calls)
flags |= JIT_FLAG_NO_DIRECT_ICALLS;
cfg = mini_method_compile (method, acfg->opts, mono_get_root_domain (), flags, 0, index);
for (patch_info = cfg->patch_info; patch_info; patch_info = patch_info->next) {
switch (patch_info->type) {
case MONO_PATCH_INFO_RGCTX_FETCH:
+ case MONO_PATCH_INFO_RGCTX_SLOT_INDEX:
case MONO_PATCH_INFO_METHOD: {
MonoMethod *m = NULL;
- if (patch_info->type == MONO_PATCH_INFO_RGCTX_FETCH) {
+ if (patch_info->type == MONO_PATCH_INFO_RGCTX_FETCH || patch_info->type == MONO_PATCH_INFO_RGCTX_SLOT_INDEX) {
MonoJumpInfoRgctxEntry *e = patch_info->data.rgctx_entry;
if (e->info_type == MONO_RGCTX_INFO_GENERIC_METHOD_CODE)
cfg->has_got_slots = TRUE;
break;
default:
- if (!is_plt_patch (patch_info))
+ if (!is_plt_patch (patch_info) || (cfg->compile_llvm && acfg->aot_opts.llvm_only))
cfg->has_got_slots = TRUE;
break;
}
return get_got_offset (llvm_acfg, TRUE, ji);
}
+/*
+ * mono_aot_is_shared_got_offset:
+ *
+ * Return whenever OFFSET refers to a GOT slot which is preinitialized
+ * when the AOT image is loaded.
+ */
+gboolean
+mono_aot_is_shared_got_offset (int offset)
+{
+ return offset < llvm_acfg->nshared_got_entries;
+}
+
char*
mono_aot_get_method_name (MonoCompile *cfg)
{
plt_entry->llvm_used = FALSE;
}
+char*
+mono_aot_get_direct_call_symbol (MonoJumpInfoType type, gconstpointer data)
+{
+ const char *sym = NULL;
+
+ if (llvm_acfg->aot_opts.direct_icalls) {
+ if (type == MONO_PATCH_INFO_JIT_ICALL_ADDR) {
+ /* Call to a C function implementing a jit icall */
+ sym = mono_lookup_jit_icall_symbol (data);
+ } else if (type == MONO_PATCH_INFO_ICALL_ADDR) {
+ MonoMethod *method = (gpointer)data;
+ if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
+ sym = mono_lookup_icall_symbol (method);
+ }
+ if (sym)
+ return g_strdup (sym);
+ }
+ return NULL;
+}
+
char*
mono_aot_get_plt_symbol (MonoJumpInfoType type, gconstpointer data)
{
{
char *command, *opts, *tempbc, *output_fname;
+ /* Emit the LLVM code into a .bc file */
+ if (acfg->aot_opts.llvm_only && acfg->aot_opts.asm_only) {
+ mono_llvm_emit_aot_module (acfg->aot_opts.llvm_outfile, g_path_get_basename (acfg->image->name));
+ return TRUE;
+ }
+
tempbc = g_strdup_printf ("%s.bc", acfg->tmpbasename);
mono_llvm_emit_aot_module (tempbc, g_path_get_basename (acfg->image->name));
g_free (tempbc);
+ if (acfg->aot_opts.llvm_only) {
+ /* Use the stock clang from xcode */
+ // FIXME: arch
+ // FIXME: -O2
+ // FIXME: llc/opt flags
+ command = g_strdup_printf ("clang -march=x86-64 -fpic -msse -msse2 -msse3 -msse4 -O0 -c -o \"%s\" \"%s.bc\"", acfg->llvm_ofile, acfg->tmpbasename);
+ //command = g_strdup_printf ("/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.3.sdk -Qunused-arguments -miphoneos-version-min=8.2 -arch arm64 -fpic -O0 -c -o \"%s\" \"%s.bc\"", acfg->llvm_ofile, acfg->tmpbasename);
+
+ aot_printf (acfg, "Executing clang: %s\n", command);
+ if (execute_system (command) != 0)
+ return FALSE;
+ return TRUE;
+ }
+
/*
* FIXME: Experiment with adding optimizations, the -std-compile-opts set takes
* a lot of time, and doesn't seem to save much space.
* then removing tailcallelim + the global opts.
* strip-dead-prototypes deletes unused intrinsics definitions.
*/
- opts = g_strdup ("-instcombine -simplifycfg");
//opts = g_strdup ("-simplifycfg -domtree -domfrontier -scalarrepl -instcombine -simplifycfg -domtree -domfrontier -scalarrepl -simplify-libcalls -instcombine -simplifycfg -instcombine -simplifycfg -reassociate -domtree -loops -loop-simplify -domfrontier -loop-simplify -lcssa -loop-rotate -licm -lcssa -loop-unswitch -instcombine -scalar-evolution -loop-simplify -lcssa -iv-users -indvars -loop-deletion -loop-simplify -lcssa -loop-unroll -instcombine -memdep -gvn -memdep -memcpyopt -sccp -instcombine -domtree -memdep -dse -adce -simplifycfg -domtree -verify");
/* The dse pass is disabled because of #13734 and #17616 */
/*
* Here, if 'Earlier' refers to a memset, and Later has no size info, it mistakenly thinks the memset is redundant.
*/
opts = g_strdup ("-targetlibinfo -no-aa -basicaa -notti -instcombine -simplifycfg -inline-cost -inline -sroa -domtree -early-cse -lazy-value-info -correlated-propagation -simplifycfg -instcombine -simplifycfg -reassociate -domtree -loops -loop-simplify -lcssa -loop-rotate -licm -lcssa -loop-unswitch -instcombine -scalar-evolution -loop-simplify -lcssa -indvars -loop-idiom -loop-deletion -loop-unroll -memdep -gvn -memdep -memcpyopt -sccp -instcombine -lazy-value-info -correlated-propagation -domtree -memdep -adce -simplifycfg -instcombine -strip-dead-prototypes -domtree -verify");
+ opts = g_strdup ("");
#if 1
command = g_strdup_printf ("\"%sopt\" -f %s -o \"%s.opt.bc\" \"%s.bc\"", acfg->aot_opts.llvm_path, opts, acfg->tmpbasename, acfg->tmpbasename);
aot_printf (acfg, "Executing opt: %s\n", command);
/* Verbose asm slows down llc greatly */
g_string_append (acfg->llc_args, " -asm-verbose=false");
- g_string_append (acfg->llc_args, " -disable-gnu-eh-frame -enable-mono-eh-frame");
-
if (acfg->aot_opts.mtriple)
g_string_append_printf (acfg->llc_args, " -mtriple=%s", acfg->aot_opts.mtriple);
+ g_string_append (acfg->llc_args, " -disable-gnu-eh-frame -enable-mono-eh-frame");
+
g_string_append_printf (acfg->llc_args, " -mono-eh-frame-symbol=%s%s", acfg->user_symbol_prefix, acfg->llvm_eh_frame_symbol);
#if defined(TARGET_MACH) && defined(TARGET_ARM)
gboolean saved_unbox_info = FALSE;
char symbol [256];
+ if (acfg->aot_opts.llvm_only)
+ return;
+
#if defined(TARGET_POWERPC64)
sprintf (symbol, ".Lgot_addr");
emit_section_change (acfg, ".text", 0);
method = cfg->orig_method;
/* Emit unbox trampoline */
- if (mono_aot_mode_is_full (&acfg->aot_opts) && cfg->orig_method->klass->valuetype) {
+ if (mono_aot_mode_is_full (&acfg->aot_opts) && cfg->orig_method->klass->valuetype && !(acfg->aot_opts.llvm_only && cfg->compile_llvm)) {
sprintf (symbol, "ut_%d", get_method_index (acfg, method));
emit_section_change (acfg, ".text", 0);
#ifdef MONO_ARCH_AOT_SUPPORTED
int call_size;
- if (acfg->cfgs [i])
- arch_emit_direct_call (acfg, acfg->cfgs [i]->asm_symbol, FALSE, acfg->thumb_mixed && acfg->cfgs [i]->compile_llvm, NULL, &call_size);
- else
+ if (acfg->cfgs [i]) {
+ if (acfg->aot_opts.llvm_only && acfg->cfgs [i]->compile_llvm)
+ /* Obtained by calling a generated function in the LLVM image */
+ arch_emit_direct_call (acfg, "method_addresses", FALSE, FALSE, NULL, &call_size);
+ else
+ arch_emit_direct_call (acfg, acfg->cfgs [i]->asm_symbol, FALSE, acfg->thumb_mixed && acfg->cfgs [i]->compile_llvm, NULL, &call_size);
+ } else {
arch_emit_direct_call (acfg, "method_addresses", FALSE, FALSE, NULL, &call_size);
+ }
#endif
}
method = cfg->orig_method;
- if (mono_aot_mode_is_full (&acfg->aot_opts) && cfg->orig_method->klass->valuetype) {
+ if (mono_aot_mode_is_full (&acfg->aot_opts) && cfg->orig_method->klass->valuetype && !(acfg->aot_opts.llvm_only && cfg->compile_llvm)) {
index = get_method_index (acfg, method);
emit_int32 (acfg, index);
method = cfg->orig_method;
- if (mono_aot_mode_is_full (&acfg->aot_opts) && cfg->orig_method->klass->valuetype) {
+ if (mono_aot_mode_is_full (&acfg->aot_opts) && cfg->orig_method->klass->valuetype && !(acfg->aot_opts.llvm_only && cfg->compile_llvm)) {
#ifdef MONO_ARCH_AOT_SUPPORTED
int call_size;
int i;
char symbol [128];
+ if (acfg->aot_opts.llvm_only) {
+ g_assert (acfg->unwind_ops->len == 0);
+ return;
+ }
+
/*
* The unwind info contains a lot of duplicates so we emit each unique
* entry once, and only store the offset from the start of the table in the
{
char symbol [256];
+ if (acfg->aot_opts.llvm_only)
+ return;
+
/* Don't make GOT global so accesses to it don't need relocations */
sprintf (symbol, "%s", acfg->got_symbol);
{
char symbol [128];
+ if (acfg->aot_opts.llvm_only)
+ return;
+
sprintf (symbol, "mem_end");
emit_section_change (acfg, ".text", 1);
emit_alignment_code (acfg, 8);
info->long_align = MONO_ABI_ALIGNOF (gint64);
info->generic_tramp_num = MONO_TRAMPOLINE_NUM;
info->tramp_page_size = acfg->tramp_page_size;
+ info->nshared_got_entries = acfg->nshared_got_entries;
for (i = 0; i < MONO_AOT_TRAMP_NUM; ++i)
info->tramp_page_code_offsets [i] = acfg->tramp_page_code_offsets [i];
}
symbols [sindex ++] = NULL;
symbols [sindex ++] = NULL;
}
- symbols [sindex ++] = "jit_code_start";
- symbols [sindex ++] = "jit_code_end";
- symbols [sindex ++] = "method_addresses";
+ /* llvm_get_method */
+ symbols [sindex ++] = NULL;
+ /* llvm_get_unbox_tramp */
+ symbols [sindex ++] = NULL;
+ if (!acfg->aot_opts.llvm_only) {
+ symbols [sindex ++] = "jit_code_start";
+ symbols [sindex ++] = "jit_code_end";
+ symbols [sindex ++] = "method_addresses";
+ } else {
+ symbols [sindex ++] = NULL;
+ symbols [sindex ++] = NULL;
+ symbols [sindex ++] = NULL;
+ }
symbols [sindex ++] = "blob";
symbols [sindex ++] = "class_name_table";
symbols [sindex ++] = "class_info_offsets";
symbols [sindex ++] = "plt";
symbols [sindex ++] = "plt_end";
symbols [sindex ++] = "unwind_info";
- symbols [sindex ++] = "unbox_trampolines";
- symbols [sindex ++] = "unbox_trampolines_end";
- symbols [sindex ++] = "unbox_trampoline_addresses";
+ if (!acfg->aot_opts.llvm_only) {
+ symbols [sindex ++] = "unbox_trampolines";
+ symbols [sindex ++] = "unbox_trampolines_end";
+ symbols [sindex ++] = "unbox_trampoline_addresses";
+ } else {
+ symbols [sindex ++] = NULL;
+ symbols [sindex ++] = NULL;
+ symbols [sindex ++] = NULL;
+ }
+
g_assert (sindex == MONO_AOT_FILE_INFO_NUM_SYMBOLS);
sprintf (symbol, "%smono_aot_file_info", acfg->user_symbol_prefix);
emit_int32 (acfg, info->long_align);
emit_int32 (acfg, info->generic_tramp_num);
emit_int32 (acfg, info->tramp_page_size);
+ emit_int32 (acfg, info->nshared_got_entries);
for (i = 0; i < MONO_AOT_TRAMP_NUM; ++i)
emit_int32 (acfg, info->num_trampolines [i]);
/* replace the ; flags separators with spaces */
g_strdelimit (ld_flags, ";", ' ');
+ if (acfg->aot_opts.llvm_only)
+ ld_flags = g_strdup_printf ("%s %s", ld_flags, "-lstdc++");
+
#ifdef LD_NAME
command = g_strdup_printf ("%s -o \"%s\" %s \"%s.o\" %s", LD_NAME, tmp_outfile_name, llvm_ofile, acfg->tmpfname, ld_flags);
#else
mono_json_writer_destroy (&writer);
}
+static const char *preinited_jit_icalls[] = {
+ "mono_aot_init_llvm_method",
+ "mono_aot_init_gshared_method_this",
+ "mono_aot_init_gshared_method_rgctx",
+ "mono_llvm_throw_corlib_exception",
+ "mono_resolve_vcall",
+ "mono_helper_ldstr_mscorlib"
+};
+
+static void
+add_preinit_got_slots (MonoAotCompile *acfg)
+{
+ MonoJumpInfo *ji;
+ int i;
+
+ /*
+ * Allocate the first few GOT entries to information which is needed frequently, or it is needed
+ * during method initialization etc.
+ */
+
+ ji = mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJumpInfo));
+ ji->type = MONO_PATCH_INFO_IMAGE;
+ ji->data.image = acfg->image;
+ get_got_offset (acfg, FALSE, ji);
+ get_got_offset (acfg, TRUE, ji);
+
+ ji = mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJumpInfo));
+ ji->type = MONO_PATCH_INFO_MSCORLIB_GOT_ADDR;
+ get_got_offset (acfg, FALSE, ji);
+ get_got_offset (acfg, TRUE, ji);
+
+ ji = mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJumpInfo));
+ ji->type = MONO_PATCH_INFO_GC_CARD_TABLE_ADDR;
+ get_got_offset (acfg, FALSE, ji);
+ get_got_offset (acfg, TRUE, ji);
+
+ ji = mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJumpInfo));
+ ji->type = MONO_PATCH_INFO_GC_NURSERY_START;
+ get_got_offset (acfg, FALSE, ji);
+ get_got_offset (acfg, TRUE, ji);
+
+ ji = mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJumpInfo));
+ ji->type = MONO_PATCH_INFO_JIT_TLS_ID;
+ get_got_offset (acfg, FALSE, ji);
+ get_got_offset (acfg, TRUE, ji);
+
+ ji = mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJumpInfo));
+ ji->type = MONO_PATCH_INFO_AOT_MODULE;
+ get_got_offset (acfg, FALSE, ji);
+ get_got_offset (acfg, TRUE, ji);
+
+ for (i = 0; i < sizeof (preinited_jit_icalls) / sizeof (char*); ++i) {
+ ji = mono_mempool_alloc0 (acfg->mempool, sizeof (MonoAotCompile));
+ ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
+ ji->data.name = preinited_jit_icalls [i];
+ get_got_offset (acfg, FALSE, ji);
+ get_got_offset (acfg, TRUE, ji);
+ }
+
+ acfg->nshared_got_entries = acfg->got_offset;
+}
+
int
mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options)
{
if (mono_aot_mode_is_full (&acfg->aot_opts))
acfg->flags |= MONO_AOT_FILE_FLAG_FULL_AOT;
+ if (mono_threads_is_coop_enabled ())
+ acfg->flags |= MONO_AOT_FILE_FLAG_SAFEPOINTS;
+
if (acfg->aot_opts.instances_logfile_path) {
acfg->instances_logfile = fopen (acfg->aot_opts.instances_logfile_path, "w");
if (!acfg->instances_logfile) {
if (acfg->llvm && acfg->thumb_mixed)
acfg->flags |= MONO_AOT_FILE_FLAG_LLVM_THUMB;
+ if (acfg->aot_opts.llvm_only)
+ acfg->flags |= MONO_AOT_FILE_FLAG_LLVM_ONLY;
acfg->assembly_name_sym = g_strdup (acfg->image->assembly->aname.name);
/* Get rid of characters which cannot occur in symbols */
/* PLT offset 0 is reserved for the PLT trampoline */
acfg->plt_offset = 1;
+ add_preinit_got_slots (acfg);
#ifdef ENABLE_LLVM
if (acfg->llvm) {
llvm_acfg = acfg;
- mono_llvm_create_aot_module (acfg->image->assembly, acfg->global_prefix, TRUE, acfg->aot_opts.static_link);
+ mono_llvm_create_aot_module (acfg->image->assembly, acfg->global_prefix, TRUE, acfg->aot_opts.static_link, acfg->aot_opts.llvm_only);
}
#endif
- /* GOT offset 0 is reserved for the address of the current assembly */
- {
- MonoJumpInfo *ji;
-
- ji = mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJumpInfo));
- ji->type = MONO_PATCH_INFO_IMAGE;
- ji->data.image = acfg->image;
-
- get_got_offset (acfg, FALSE, ji);
- get_got_offset (acfg, TRUE, ji);
-
- /* Slot 1 is reserved for the mscorlib got addr */
- ji = mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJumpInfo));
- ji->type = MONO_PATCH_INFO_MSCORLIB_GOT_ADDR;
- get_got_offset (acfg, FALSE, ji);
- get_got_offset (acfg, TRUE, ji);
-
- /* This is very common */
- ji = mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJumpInfo));
- ji->type = MONO_PATCH_INFO_GC_CARD_TABLE_ADDR;
- get_got_offset (acfg, FALSE, ji);
- get_got_offset (acfg, TRUE, ji);
-
- ji = mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJumpInfo));
- ji->type = MONO_PATCH_INFO_GC_NURSERY_START;
- get_got_offset (acfg, FALSE, ji);
- get_got_offset (acfg, TRUE, ji);
-
- ji = mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJumpInfo));
- ji->type = MONO_PATCH_INFO_JIT_TLS_ID;
- get_got_offset (acfg, FALSE, ji);
- get_got_offset (acfg, TRUE, ji);
- }
-
TV_GETTIME (atv);
compile_methods (acfg);
return 0;
}
+gboolean
+mono_aot_is_shared_got_offset (int offset)
+{
+ return FALSE;
+}
+
#endif