typedef struct MonoAotOptions {
char *outfile;
char *llvm_outfile;
+ char *data_outfile;
gboolean save_temps;
gboolean write_symbols;
gboolean metadata_only;
GHashTable *klass_blob_hash;
/* Maps MonoMethod* -> blob offset */
GHashTable *method_blob_hash;
+ GHashTable *gsharedvt_in_signatures;
+ GHashTable *gsharedvt_out_signatures;
guint32 *plt_got_info_offsets;
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;
+ guint32 table_offsets [MONO_AOT_TABLE_NUM];
guint32 num_trampolines [MONO_AOT_TRAMP_NUM];
guint32 trampoline_got_offset_base [MONO_AOT_TRAMP_NUM];
guint32 trampoline_size [MONO_AOT_TRAMP_NUM];
gboolean has_jitted_code;
MonoAotFileFlags flags;
MonoDynamicStream blob;
+ gboolean blob_closed;
MonoClass **typespec_classes;
GString *llc_args;
GString *as_args;
GHashTable *objc_selector_to_index;
FILE *logfile;
FILE *instances_logfile;
+ FILE *data_outfile;
+ int datafile_offset;
+ int gc_name_offset;
} MonoAotCompile;
typedef struct {
gboolean jit_used, llvm_used;
} MonoPltEntry;
-#define mono_acfg_lock(acfg) mono_mutex_lock (&((acfg)->mutex))
-#define mono_acfg_unlock(acfg) mono_mutex_unlock (&((acfg)->mutex))
+#define mono_acfg_lock(acfg) mono_os_mutex_lock (&((acfg)->mutex))
+#define mono_acfg_unlock(acfg) mono_os_mutex_unlock (&((acfg)->mutex))
/* This points to the current acfg in LLVM mode */
static MonoAotCompile *llvm_acfg;
const int kSizeOfMove = 7;
#if defined(__default_codegen__)
- code = buf = g_malloc (256);
+ code = buf = (guint8 *)g_malloc (256);
#elif defined(__native_client_codegen__)
buf_alloc = g_malloc (256 + kNaClAlignment + kSizeOfMove);
buf = ((guint)buf_alloc + kNaClAlignment) & ~kNaClAlignmentMask;
{
sh->index = 0;
sh->alloc_size = 4096;
- sh->data = g_malloc (4096);
+ sh->data = (char *)g_malloc (4096);
/* So offsets are > 0 */
sh->data [0] = 0;
stream->alloc_size *= 2;
}
- stream->data = g_realloc (stream->data, stream->alloc_size);
+ stream->data = (char *)g_realloc (stream->data, stream->alloc_size);
}
static guint32
static guint32
add_to_blob (MonoAotCompile *acfg, const guint8 *data, guint32 data_len)
{
+ g_assert (!acfg->blob_closed);
+
if (acfg->blob.alloc_size == 0)
stream_init (&acfg->blob);
return add_stream_data (&acfg->blob, (char*)data, data_len);
}
+/* Emit a table of data into the aot image */
+static void
+emit_aot_data (MonoAotCompile *acfg, MonoAotFileTable table, const char *symbol, guint8 *data, int size)
+{
+ if (acfg->data_outfile) {
+ acfg->table_offsets [(int)table] = acfg->datafile_offset;
+ fwrite (data,1, size, acfg->data_outfile);
+ acfg->datafile_offset += size;
+ // align the data to 8 bytes. Put zeros in the file (so that every build results in consistent output).
+ int align = 8 - size % 8;
+ acfg->datafile_offset += align;
+ guint8 align_buf [16];
+ memset (&align_buf, 0, sizeof (align_buf));
+ fwrite (align_buf, align, 1, acfg->data_outfile);
+ } else if (acfg->llvm) {
+ mono_llvm_emit_aot_data (symbol, data, size);
+ } else {
+ emit_section_change (acfg, RODATA_SECT, 0);
+ emit_alignment (acfg, 8);
+ emit_label (acfg, symbol);
+ emit_bytes (acfg, data, size);
+ }
+}
+
/*
* emit_offset_table:
*
* a given entry. Returns the size of the table.
*/
static guint32
-emit_offset_table (MonoAotCompile *acfg, const char *symbol, int noffsets, int group_size, gint32 *offsets)
+emit_offset_table (MonoAotCompile *acfg, const char *symbol, MonoAotFileTable table, int noffsets, int group_size, gint32 *offsets)
{
gint32 current_offset;
int i, buf_size, ngroups, index_entry_size;
index_offsets = g_new0 (guint32, ngroups);
buf_size = noffsets * 4;
- p = buf = g_malloc0 (buf_size);
+ p = buf = (guint8 *)g_malloc0 (buf_size);
current_offset = 0;
for (i = 0; i < noffsets; ++i) {
index_entry_size = 4;
buf_size = (data_p - data_buf) + (ngroups * 4) + 16;
- p = buf = g_malloc0 (buf_size);
+ p = buf = (guint8 *)g_malloc0 (buf_size);
/* Emit the header */
encode_int (noffsets, p, &p);
g_assert (p - buf <= buf_size);
- if (acfg->llvm) {
- mono_llvm_emit_aot_data (symbol, buf, p - buf);
- } else {
- emit_section_change (acfg, RODATA_SECT, 1);
- emit_alignment (acfg, 8);
- emit_label (acfg, symbol);
- emit_bytes (acfg, buf, p - buf);
- }
+ emit_aot_data (acfg, table, symbol, buf, p - buf);
g_free (buf);
g_free (data_buf);
/* FIXME: Search referenced images as well */
if (!acfg->typespec_classes) {
- acfg->typespec_classes = mono_mempool_alloc0 (acfg->mempool, sizeof (MonoClass*) * len);
+ acfg->typespec_classes = (MonoClass **)mono_mempool_alloc0 (acfg->mempool, sizeof (MonoClass*) * len);
for (i = 0; i < len; ++i) {
MonoError error;
acfg->typespec_classes [i] = mono_class_get_and_inflate_typespec_checked (acfg->image, MONO_TOKEN_TYPE_SPEC | (i + 1), NULL, &error);
MonoGenericParam *par = klass->byval_arg.data.generic_param;
encode_value (MONO_AOT_TYPEREF_VAR, p, &p);
- encode_value (klass->byval_arg.type, p, &p);
- encode_value (mono_type_get_generic_param_num (&klass->byval_arg), p, &p);
-
- encode_value (container ? 1 : 0, p, &p);
- if (container) {
- encode_value (container->is_method, p, &p);
- g_assert (!par->gshared_constraint);
- if (container->is_method)
- encode_method_ref (acfg, container->owner.method, p, &p);
- else
- encode_klass_ref (acfg, container->owner.klass, p, &p);
+
+ encode_value (par->gshared_constraint ? 1 : 0, p, &p);
+ if (par->gshared_constraint) {
+ MonoGSharedGenericParam *gpar = (MonoGSharedGenericParam*)par;
+ encode_type (acfg, par->gshared_constraint, p, &p);
+ encode_klass_ref (acfg, mono_class_from_generic_parameter (gpar->parent, NULL, klass->byval_arg.type == MONO_TYPE_MVAR), p, &p);
} else {
- encode_value (par->gshared_constraint ? 1 : 0, p, &p);
- if (par->gshared_constraint) {
- MonoGSharedGenericParam *gpar = (MonoGSharedGenericParam*)par;
- encode_type (acfg, par->gshared_constraint, p, &p);
- encode_klass_ref (acfg, mono_class_from_generic_parameter (gpar->parent, NULL, klass->byval_arg.type == MONO_TYPE_MVAR), p, &p);
+ encode_value (klass->byval_arg.type, p, &p);
+ encode_value (mono_type_get_generic_param_num (&klass->byval_arg), p, &p);
+
+ encode_value (container->is_anonymous ? 0 : 1, p, &p);
+
+ if (!container->is_anonymous) {
+ encode_value (container->is_method, p, &p);
+ if (container->is_method)
+ encode_method_ref (acfg, container->owner.method, p, &p);
+ else
+ encode_klass_ref (acfg, container->owner.klass, p, &p);
}
}
} else if (klass->byval_arg.type == MONO_TYPE_PTR) {
guint8 *buf2, *p;
if (!offset) {
- buf2 = g_malloc (1024);
+ buf2 = (guint8 *)g_malloc (1024);
p = buf2;
encode_klass_ref_inner (acfg, klass, p, &p);
encode_method_ref (acfg, info->d.synchronized_inner.method, p, &p);
else if (info->subtype == WRAPPER_SUBTYPE_ARRAY_ACCESSOR)
encode_method_ref (acfg, info->d.array_accessor.method, p, &p);
+ else if (info->subtype == WRAPPER_SUBTYPE_GSHAREDVT_IN_SIG)
+ encode_signature (acfg, info->d.gsharedvt.sig, p, &p);
+ else if (info->subtype == WRAPPER_SUBTYPE_GSHAREDVT_OUT_SIG)
+ encode_signature (acfg, info->d.gsharedvt.sig, p, &p);
break;
}
case MONO_WRAPPER_MANAGED_TO_NATIVE: {
* encode that.
* Obtain the token from information recorded by the JIT.
*/
- ji = g_hash_table_lookup (acfg->token_info_hash, method);
+ ji = (MonoJumpInfoToken *)g_hash_table_lookup (acfg->token_info_hash, method);
if (ji) {
image_index = get_image_index (acfg, ji->image);
g_assert (image_index < MAX_IMAGE_INDEX);
} else if (token == 0) {
/* This might be a method of a constructed type like int[,].Set */
/* Obtain the token from information recorded by the JIT */
- ji = g_hash_table_lookup (acfg->token_info_hash, method);
+ ji = (MonoJumpInfoToken *)g_hash_table_lookup (acfg->token_info_hash, method);
if (ji) {
image_index = get_image_index (acfg, ji->image);
g_assert (image_index < MAX_IMAGE_INDEX);
case MONO_PATCH_INFO_JIT_ICALL_ADDR:
case MONO_PATCH_INFO_ICALL_ADDR:
case MONO_PATCH_INFO_RGCTX_FETCH:
- case MONO_PATCH_INFO_LLVM_IMT_TRAMPOLINE:
return TRUE;
default:
return FALSE;
if (!acfg->patch_to_plt_entry [patch_info->type])
acfg->patch_to_plt_entry [patch_info->type] = g_hash_table_new (mono_patch_info_hash, mono_patch_info_equal);
- res = g_hash_table_lookup (acfg->patch_to_plt_entry [patch_info->type], patch_info);
+ res = (MonoPltEntry *)g_hash_table_lookup (acfg->patch_to_plt_entry [patch_info->type], patch_info);
if (!acfg->llvm && patch_info->type == MONO_PATCH_INFO_METHOD && (patch_info->data.method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)) {
/*
new_ji = mono_patch_info_dup_mp (acfg->mempool, patch_info);
- res = mono_mempool_alloc0 (acfg->mempool, sizeof (MonoPltEntry));
+ res = (MonoPltEntry *)mono_mempool_alloc0 (acfg->mempool, sizeof (MonoPltEntry));
res->plt_offset = acfg->plt_offset;
res->ji = new_ji;
res->symbol = get_plt_symbol (acfg, res->plt_offset, patch_info);
static void
add_jit_icall_wrapper (gpointer key, gpointer value, gpointer user_data)
{
- MonoAotCompile *acfg = user_data;
- MonoJitICallInfo *callinfo = value;
+ MonoAotCompile *acfg = (MonoAotCompile *)user_data;
+ MonoJitICallInfo *callinfo = (MonoJitICallInfo *)value;
MonoMethod *wrapper;
char *name;
}
static MonoMethod*
-get_runtime_invoke (MonoAotCompile *acfg, MonoMethod *method, gboolean virtual)
+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));
+ return mono_marshal_get_runtime_invoke (method, virtual_, acfg->aot_opts.llvm_only && mono_method_needs_static_rgctx_invoke (method, TRUE));
}
static gboolean
}
#endif
+ if (!skip && acfg->aot_opts.llvm_only && (acfg->opts & MONO_OPT_GSHAREDVT) && mini_gsharedvt_runtime_invoke_supported (sig))
+ /* Supported by the gsharedvt based runtime-invoke wrapper */
+ skip = TRUE;
+
if (!skip) {
//printf ("%s\n", mono_method_full_name (method, TRUE));
add_method (acfg, get_runtime_invoke (acfg, method, FALSE));
add_method (acfg, mono_marshal_get_runtime_invoke_dynamic ());
#endif
+ /* These are used by mono_jit_runtime_invoke () to calls gsharedvt out wrappers */
+ if (acfg->aot_opts.llvm_only) {
+ int variants;
+
+ /* Create simplified signatures which match the signature used by the gsharedvt out wrappers */
+ for (variants = 0; variants < 4; ++variants) {
+ for (i = 0; i < 16; ++i) {
+ sig = mini_get_gsharedvt_out_sig_wrapper_signature ((variants & 1) > 0, (variants & 2) > 0, i);
+ add_extra_method (acfg, mono_marshal_get_runtime_invoke_for_sig (sig));
+
+ g_free (sig);
+ }
+ }
+ }
+
/* stelemref */
add_method (acfg, mono_marshal_get_stelemref ());
/* From load_cattr_value () in reflection.c */
slen = mono_metadata_decode_value (p, &p);
- n = g_memdup (p, slen + 1);
+ n = (char *)g_memdup (p, slen + 1);
n [slen] = 0;
t = mono_reflection_type_from_name (n, acfg->image);
g_assert (t);
named += 1;
name_len = mono_metadata_decode_blob_size (named, &named);
- name = g_malloc (name_len + 1);
+ name = (char *)g_malloc (name_len + 1);
memcpy (name, named, name_len);
name [name_len] = 0;
named += name_len;
/* load_cattr_value (), string case */
g_assert (*named != (char)0xff);
slen = mono_metadata_decode_value (named, &named);
- export_name = g_malloc (slen + 1);
+ export_name = (char *)g_malloc (slen + 1);
memcpy (export_name, named, slen);
export_name [slen] = 0;
named += slen;
/* Add types of args/locals */
for (i = 0; i < acfg->methods->len; ++i) {
- method = g_ptr_array_index (acfg->methods, i);
+ method = (MonoMethod *)g_ptr_array_index (acfg->methods, i);
add_types_from_method_header (acfg, method);
}
if (klass)
add_instances_of (acfg, klass, insts, ninsts, TRUE);
- /* Add an instance of EnumEqualityComparer<int/uint> which is created by EqualityComparer<T> for enums */
+ /* Add instances of EnumEqualityComparer which are created by EqualityComparer<T> for enums */
{
MonoClass *enum_comparer;
- MonoGenericContext ctx;
- MonoType *args [16];
-
+ MonoType *insts [16];
+ int ninsts;
+
+ ninsts = 0;
+ insts [ninsts ++] = &mono_defaults.int32_class->byval_arg;
+ insts [ninsts ++] = &mono_defaults.uint32_class->byval_arg;
+ insts [ninsts ++] = &mono_defaults.uint16_class->byval_arg;
+ insts [ninsts ++] = &mono_defaults.byte_class->byval_arg;
enum_comparer = mono_class_from_name (mono_defaults.corlib, "System.Collections.Generic", "EnumEqualityComparer`1");
g_assert (enum_comparer);
+ add_instances_of (acfg, enum_comparer, insts, ninsts, FALSE);
- memset (&ctx, 0, sizeof (ctx));
- args [0] = &mono_defaults.int32_class->byval_arg;
- ctx.class_inst = mono_metadata_get_generic_inst (1, args);
- add_generic_class (acfg, mono_class_inflate_generic_class (enum_comparer, &ctx), FALSE, "EqualityComparer<T>");
-
- memset (&ctx, 0, sizeof (ctx));
- args [0] = &mono_defaults.uint32_class->byval_arg;
- ctx.class_inst = mono_metadata_get_generic_inst (1, args);
- add_generic_class (acfg, mono_class_inflate_generic_class (enum_comparer, &ctx), FALSE, "EqualityComparer<T>");
- }
+ ninsts = 0;
+ insts [ninsts ++] = &mono_defaults.int16_class->byval_arg;
+ enum_comparer = mono_class_from_name (mono_defaults.corlib, "System.Collections.Generic", "ShortEnumEqualityComparer`1");
+ g_assert (enum_comparer);
+ add_instances_of (acfg, enum_comparer, insts, ninsts, FALSE);
- /* Add an instance of LongEnumEqualityComparer<long/ulong> which is created by EqualityComparer<T> for enums */
- {
- MonoClass *enum_comparer;
- MonoGenericContext ctx;
- MonoType *args [16];
+ ninsts = 0;
+ insts [ninsts ++] = &mono_defaults.sbyte_class->byval_arg;
+ enum_comparer = mono_class_from_name (mono_defaults.corlib, "System.Collections.Generic", "SByteEnumEqualityComparer`1");
+ g_assert (enum_comparer);
+ add_instances_of (acfg, enum_comparer, insts, ninsts, FALSE);
enum_comparer = mono_class_from_name (mono_defaults.corlib, "System.Collections.Generic", "LongEnumEqualityComparer`1");
g_assert (enum_comparer);
-
- memset (&ctx, 0, sizeof (ctx));
- args [0] = &mono_defaults.int64_class->byval_arg;
- ctx.class_inst = mono_metadata_get_generic_inst (1, args);
- add_generic_class (acfg, mono_class_inflate_generic_class (enum_comparer, &ctx), FALSE, "EqualityComparer<T>");
-
- memset (&ctx, 0, sizeof (ctx));
- args [0] = &mono_defaults.uint64_class->byval_arg;
- ctx.class_inst = mono_metadata_get_generic_inst (1, args);
- add_generic_class (acfg, mono_class_inflate_generic_class (enum_comparer, &ctx), FALSE, "EqualityComparer<T>");
+ ninsts = 0;
+ insts [ninsts ++] = &mono_defaults.int64_class->byval_arg;
+ insts [ninsts ++] = &mono_defaults.uint64_class->byval_arg;
+ add_instances_of (acfg, enum_comparer, insts, ninsts, FALSE);
}
/* Add instances of the array generic interfaces for primitive types */
is_direct_callable (MonoAotCompile *acfg, MonoMethod *method, MonoJumpInfo *patch_info)
{
if ((patch_info->type == MONO_PATCH_INFO_METHOD) && (patch_info->data.method->klass->image == acfg->image)) {
- MonoCompile *callee_cfg = g_hash_table_lookup (acfg->method_to_cfg, patch_info->data.method);
+ MonoCompile *callee_cfg = (MonoCompile *)g_hash_table_lookup (acfg->method_to_cfg, patch_info->data.method);
if (callee_cfg) {
gboolean direct_callable = TRUE;
guint32 im_cols [MONO_IMPLMAP_SIZE];
char *import;
- import = g_hash_table_lookup (acfg->method_to_pinvoke_import, method);
+ import = (char *)g_hash_table_lookup (acfg->method_to_pinvoke_import, method);
if (import != NULL)
return import;
ln_array = g_new0 (MonoDebugLineNumberEntry, debug_info->num_line_numbers);
memcpy (ln_array, debug_info->line_numbers, debug_info->num_line_numbers * sizeof (MonoDebugLineNumberEntry));
- qsort (ln_array, debug_info->num_line_numbers, sizeof (MonoDebugLineNumberEntry), (gpointer)compare_lne);
+ qsort (ln_array, debug_info->num_line_numbers, sizeof (MonoDebugLineNumberEntry), (int (*)(const void *, const void *))compare_lne);
native_to_il_offset = g_new0 (int, code_size + 1);
for (i = 0; i < code_len; i += INST_LEN) {
patch_info = NULL;
for (pindex = start_index; pindex < patches->len; ++pindex) {
- patch_info = g_ptr_array_index (patches, pindex);
+ patch_info = (MonoJumpInfo *)g_ptr_array_index (patches, pindex);
if (patch_info->ip.i >= i)
break;
}
}
case MONO_PATCH_INFO_OBJC_SELECTOR_REF: {
int code_size, index;
- char *selector = (void*)patch_info->data.target;
+ char *selector = (char *)patch_info->data.target;
if (!acfg->objc_selector_to_index)
acfg->objc_selector_to_index = g_hash_table_new (g_str_hash, g_str_equal);
external_call = FALSE;
if ((patch_info->type == MONO_PATCH_INFO_METHOD) && (patch_info->data.method->klass->image == acfg->image)) {
if (!got_only && is_direct_callable (acfg, method, patch_info)) {
- MonoCompile *callee_cfg = g_hash_table_lookup (acfg->method_to_cfg, patch_info->data.method);
+ MonoCompile *callee_cfg = (MonoCompile *)g_hash_table_lookup (acfg->method_to_cfg, patch_info->data.method);
//printf ("DIRECT: %s %s\n", method ? mono_method_full_name (method, TRUE) : "", mono_method_full_name (callee_cfg->method, TRUE));
direct_call = TRUE;
direct_call_target = callee_cfg->asm_symbol;
/* Find next patch */
patch_info = NULL;
for (pindex = start_index; pindex < patches->len; ++pindex) {
- patch_info = g_ptr_array_index (patches, pindex);
+ patch_info = (MonoJumpInfo *)g_ptr_array_index (patches, pindex);
if (patch_info->ip.i >= i)
break;
}
#endif
len = strlen (name1);
- name2 = malloc (strlen (prefix) + len + 16);
+ name2 = (char *)malloc (strlen (prefix) + len + 16);
memcpy (name2, prefix, strlen (prefix));
j = strlen (prefix);
for (i = 0; i < len; ++i) {
count = 0;
while (TRUE) {
- cached_method = g_hash_table_lookup (cache, name2);
+ cached_method = (MonoMethod *)g_hash_table_lookup (cache, name2);
if (!(cached_method && cached_method != method))
break;
sprintf (name2 + j, "_%d", count);
emit_label (acfg, debug_sym);
}
- export_name = g_hash_table_lookup (acfg->export_names, method);
+ export_name = (char *)g_hash_table_lookup (acfg->export_names, method);
if (export_name) {
/* Emit a global symbol for the method */
emit_global_inner (acfg, export_name, TRUE);
ex_class =
mono_class_from_name (mono_defaults.exception_class->image,
- "System", patch_info->data.target);
+ "System", (const char *)patch_info->data.target);
g_assert (ex_class);
encode_klass_ref (acfg, ex_class, p, &p);
break;
*/
offset = GPOINTER_TO_UINT (g_hash_table_lookup (acfg->method_blob_hash, entry->method));
if (!offset) {
- buf2 = g_malloc (1024);
+ buf2 = (guint8 *)g_malloc (1024);
p2 = buf2;
encode_method_ref (acfg, entry->method, p2, &p2);
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);
- encode_value (patch_info->data.imt_tramp->vt_offset, p, &p);
- break;
case MONO_PATCH_INFO_SIGNATURE:
encode_signature (acfg, (MonoMethodSignature*)patch_info->data.target, p, &p);
break;
encode_method_ref (acfg, info->method, p, &p);
encode_value (info->num_entries, p, &p);
for (i = 0; i < info->num_entries; ++i) {
- MonoRuntimeGenericContextInfoTemplate *template = &info->entries [i];
+ MonoRuntimeGenericContextInfoTemplate *template_ = &info->entries [i];
- encode_value (template->info_type, p, &p);
- switch (mini_rgctx_info_type_to_patch_info_type (template->info_type)) {
+ encode_value (template_->info_type, p, &p);
+ switch (mini_rgctx_info_type_to_patch_info_type (template_->info_type)) {
case MONO_PATCH_INFO_CLASS:
- encode_klass_ref (acfg, mono_class_from_mono_type (template->data), p, &p);
+ encode_klass_ref (acfg, mono_class_from_mono_type ((MonoType *)template_->data), p, &p);
break;
case MONO_PATCH_INFO_FIELD:
- encode_field_info (acfg, template->data, p, &p);
+ encode_field_info (acfg, (MonoClassField *)template_->data, p, &p);
break;
default:
g_assert_not_reached ();
break;
}
case MONO_PATCH_INFO_LDSTR_LIT: {
- const char *s = patch_info->data.target;
+ const char *s = (const char *)patch_info->data.target;
int len = strlen (s);
encode_value (len, p, &p);
encode_value (n_patches, p, &p);
for (pindex = 0; pindex < patches->len; ++pindex) {
- patch_info = g_ptr_array_index (patches, pindex);
+ patch_info = (MonoJumpInfo *)g_ptr_array_index (patches, pindex);
if (patch_info->type == MONO_PATCH_INFO_NONE || patch_info->type == MONO_PATCH_INFO_BB)
/* Nothing to do */
/**********************/
buf_size = (patches->len < 1000) ? 40960 : 40960 + (patches->len * 64);
- p = buf = g_malloc (buf_size);
+ p = buf = (guint8 *)g_malloc (buf_size);
if (mono_class_get_cctor (method->klass))
encode_klass_ref (acfg, method->klass, p, &p);
n_patches = 0;
for (pindex = 0; pindex < patches->len; ++pindex) {
- patch_info = g_ptr_array_index (patches, pindex);
+ patch_info = (MonoJumpInfo *)g_ptr_array_index (patches, pindex);
if ((patch_info->type == MONO_PATCH_INFO_GOT_OFFSET) ||
(patch_info->type == MONO_PATCH_INFO_NONE)) {
buf_size = header->num_clauses * 256 + debug_info_size + 2048 + seq_points_size + cfg->gc_map_size;
- p = buf = g_malloc (buf_size);
+ p = buf = (guint8 *)g_malloc (buf_size);
use_unwind_ops = cfg->unwind_ops != NULL;
guint8 *buf2, *p2;
int len;
- buf2 = g_malloc (4096);
+ buf2 = (guint8 *)g_malloc (4096);
p2 = buf2;
encode_klass_ref (acfg, ei->data.catch_class, p2, &p2);
len = p2 - buf2;
* Need to encode jinfo->method too, since it is not equal to 'method'
* when using generic sharing.
*/
- buf2 = g_malloc (4096);
+ buf2 = (guint8 *)g_malloc (4096);
p2 = buf2;
encode_method_ref (acfg, jinfo->d.method, p2, &p2);
len = p2 - buf2;
buf_size = 16;
- p = buf = g_malloc (buf_size);
+ p = buf = (guint8 *)g_malloc (buf_size);
/* Mark as unusable */
encode_value (-1, p, &p);
}
buf_size = 10240 + (klass->vtable_size * 16);
- p = buf = g_malloc (buf_size);
+ p = buf = (guint8 *)g_malloc (buf_size);
g_assert (klass);
*/
continue;
- plt_entry = g_hash_table_lookup (acfg->plt_offset_to_entry, GUINT_TO_POINTER (i));
+ plt_entry = (MonoPltEntry *)g_hash_table_lookup (acfg->plt_offset_to_entry, GUINT_TO_POINTER (i));
debug_sym = plt_entry->debug_sym;
if (i == 0)
continue;
- plt_entry = g_hash_table_lookup (acfg->plt_offset_to_entry, GUINT_TO_POINTER (i));
+ plt_entry = (MonoPltEntry *)g_hash_table_lookup (acfg->plt_offset_to_entry, GUINT_TO_POINTER (i));
/* Skip plt entries not actually called by LLVM code */
if (!plt_entry->llvm_used)
g_ptr_array_sort (patches, compare_patches);
buf_size = patches->len * 128 + 128;
- buf = g_malloc (buf_size);
+ buf = (guint8 *)g_malloc (buf_size);
p = buf;
encode_patch_list (acfg, patches, patches->len, FALSE, got_offset, p, &p);
char symbol [256];
char end_symbol [256];
int i, tramp_got_offset;
- MonoAotTrampoline ntype;
+ int ntype;
#ifdef MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES
int tramp_type;
#endif
if (tramp_type == MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD)
continue;
#endif
- mono_arch_create_generic_trampoline (tramp_type, &info, acfg->aot_opts.use_trampolines_page? 2: TRUE);
+ mono_arch_create_generic_trampoline ((MonoTrampolineType)tramp_type, &info, acfg->aot_opts.use_trampolines_page? 2: TRUE);
emit_trampoline (acfg, acfg->got_offset, info);
}
GSList *l = mono_arch_get_trampolines (TRUE);
while (l) {
- MonoTrampInfo *info = l->data;
+ MonoTrampInfo *info = (MonoTrampInfo *)l->data;
emit_trampoline (acfg, acfg->got_offset, info);
l = l->next;
/* delegate_invoke_impl trampolines */
l = mono_arch_get_delegate_invoke_impls ();
while (l) {
- MonoTrampInfo *info = l->data;
+ MonoTrampInfo *info = (MonoTrampInfo *)l->data;
emit_trampoline (acfg, acfg->got_offset, info);
l = l->next;
exit (1);
}
rdv = g_new0 (ReadOnlyValue, 1);
- rdv->name = g_malloc0 (tval - val + 1);
+ rdv->name = (char *)g_malloc0 (tval - val + 1);
memcpy (rdv->name, val, tval - val);
tval++;
fval++;
args = mono_aot_split_options (aot_options ? aot_options : "");
for (int i = 0; i < args->len; ++i) {
- const char *arg = g_ptr_array_index (args, i);
+ const char *arg = (const char *)g_ptr_array_index (args, i);
if (str_begins_with (arg, "outfile=")) {
opts->outfile = g_strdup (arg + strlen ("outfile="));
opts->mode = MONO_AOT_MODE_FULL;
opts->llvm = TRUE;
opts->llvm_only = TRUE;
+ } else if (str_begins_with (arg, "data-outfile=")) {
+ opts->data_outfile = g_strdup (arg + strlen ("data-outfile="));
} else if (str_begins_with (arg, "help") || str_begins_with (arg, "?")) {
printf ("Supported options for --aot:\n");
printf (" outfile=\n");
{
MonoMethod *method = (MonoMethod*)key;
MonoJumpInfoToken *ji = (MonoJumpInfoToken*)value;
- MonoAotCompile *acfg = user_data;
+ MonoAotCompile *acfg = (MonoAotCompile *)user_data;
MonoJumpInfoToken *new_ji;
- new_ji = mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJumpInfoToken));
+ new_ji = (MonoJumpInfoToken *)mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJumpInfoToken));
new_ji->image = ji->image;
new_ji->token = ji->token;
g_hash_table_insert (acfg->token_info_hash, method, new_ji);
return TRUE;
}
+/* LOCKING: Assumes the loader lock is held */
+static void
+add_gsharedvt_wrappers (MonoAotCompile *acfg, MonoMethodSignature *sig, gboolean gsharedvt_in, gboolean gsharedvt_out)
+{
+ MonoMethod *wrapper;
+ gboolean concrete = TRUE;
+ gboolean add_in = gsharedvt_in;
+ gboolean add_out = gsharedvt_out;
+
+ if (gsharedvt_in && g_hash_table_lookup (acfg->gsharedvt_in_signatures, sig))
+ add_in = FALSE;
+ if (gsharedvt_out && g_hash_table_lookup (acfg->gsharedvt_out_signatures, sig))
+ add_out = FALSE;
+
+ if (!add_in && !add_out)
+ return;
+
+ if (mini_is_gsharedvt_variable_signature (sig))
+ return;
+
+ if (add_in)
+ g_hash_table_insert (acfg->gsharedvt_in_signatures, sig, sig);
+ if (add_out)
+ g_hash_table_insert (acfg->gsharedvt_out_signatures, sig, sig);
+
+ if (!sig->has_type_parameters) {
+ //printf ("%s\n", mono_signature_full_name (sig));
+
+ if (gsharedvt_in) {
+ wrapper = mini_get_gsharedvt_in_sig_wrapper (sig);
+ add_extra_method (acfg, wrapper);
+ }
+ if (gsharedvt_out) {
+ wrapper = mini_get_gsharedvt_out_sig_wrapper (sig);
+ add_extra_method (acfg, wrapper);
+ }
+ } else {
+ /* For signatures creared during generic sharing, convert them to a concrete signature if possible */
+ MonoMethodSignature *copy = mono_metadata_signature_dup (sig);
+ int i;
+
+ //printf ("%s\n", mono_signature_full_name (sig));
+
+ copy->ret = mini_get_underlying_type (sig->ret);
+ // FIXME: Add more cases
+ if (copy->ret->type == MONO_TYPE_VAR || copy->ret->type == MONO_TYPE_MVAR || copy->ret->type == MONO_TYPE_GENERICINST)
+ concrete = FALSE;
+ for (i = 0; i < sig->param_count; ++i) {
+ MonoType *t = mini_get_underlying_type (sig->params [i]);
+ /*
+ * Create a concrete type for Nullable<T_REF> etc.
+ * FIXME: Generalize this
+ */
+ if (t->type == MONO_TYPE_GENERICINST && mono_class_is_nullable (mono_class_from_mono_type (t))) {
+ MonoType *arg = mono_class_from_mono_type (t)->generic_class->context.class_inst->type_argv[0];
+ arg = mini_get_underlying_type (arg);
+ if (arg->type == MONO_TYPE_VAR || arg->type == MONO_TYPE_MVAR || arg->type == MONO_TYPE_GENERICINST) {
+ concrete = FALSE;
+ } else {
+ MonoGenericContext ctx;
+ MonoClass *klass;
+ MonoType *args [16];
+
+ memset (&ctx, 0, sizeof (MonoGenericContext));
+ args [0] = arg;
+ ctx.class_inst = mono_metadata_get_generic_inst (1, args);
+
+ klass = mono_class_inflate_generic_class (mono_defaults.generic_nullable_class, &ctx);
+ t = &klass->byval_arg;
+ }
+ } else {
+ if (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR || t->type == MONO_TYPE_GENERICINST)
+ concrete = FALSE;
+ }
+ copy->params [i] = t;
+ }
+ if (concrete) {
+ copy->has_type_parameters = 0;
+
+ if (gsharedvt_in) {
+ wrapper = mini_get_gsharedvt_in_sig_wrapper (copy);
+ add_extra_method (acfg, wrapper);
+ }
+
+ if (gsharedvt_out) {
+ wrapper = mini_get_gsharedvt_out_sig_wrapper (copy);
+ add_extra_method (acfg, wrapper);
+ }
+
+ //printf ("%s\n", mono_method_full_name (wrapper, 1));
+ }
+ }
+}
+
/*
* compile_method:
*
*/
flags = JIT_FLAG_AOT;
if (mono_aot_mode_is_full (&acfg->aot_opts))
- flags |= JIT_FLAG_FULL_AOT;
+ flags = (JitFlags)(flags | JIT_FLAG_FULL_AOT);
if (acfg->llvm)
- flags |= JIT_FLAG_LLVM;
+ flags = (JitFlags)(flags | JIT_FLAG_LLVM);
if (acfg->aot_opts.llvm_only)
- flags |= JIT_FLAG_LLVM_ONLY | JIT_FLAG_EXPLICIT_NULL_CHECKS;
+ flags = (JitFlags)(flags | JIT_FLAG_LLVM_ONLY | JIT_FLAG_EXPLICIT_NULL_CHECKS);
if (acfg->aot_opts.no_direct_calls)
- flags |= JIT_FLAG_NO_DIRECT_ICALLS;
+ flags = (JitFlags)(flags | JIT_FLAG_NO_DIRECT_ICALLS);
cfg = mini_method_compile (method, acfg->opts, mono_get_root_domain (), flags, 0, index);
mono_loader_clear_error ();
if (!cfg->has_got_slots)
InterlockedIncrement (&acfg->stats.methods_without_got_slots);
+ if (!cfg->method->wrapper_type)
+ /* These only need out wrappers */
+ add_gsharedvt_wrappers (acfg, mono_method_signature (cfg->method), FALSE, TRUE);
+
+ /* Add gsharedvt wrappers for signatures used by the method */
+ if (acfg->aot_opts.llvm_only && (acfg->opts & MONO_OPT_GSHAREDVT)) {
+ GSList *l;
+
+ for (l = cfg->signatures; l; l = l->next) {
+ MonoMethodSignature *sig = mono_metadata_signature_dup ((MonoMethodSignature*)l->data);
+
+ /* These only need in wrappers */
+ add_gsharedvt_wrappers (acfg, sig, TRUE, FALSE);
+ }
+ }
+
/*
* FIXME: Instead of this mess, allocate the patches from the aot mempool.
*/
unwind_ops = NULL;
for (l = cfg->unwind_ops; l; l = l->next) {
- op = mono_mempool_alloc (acfg->mempool, sizeof (MonoUnwindOp));
+ op = (MonoUnwindOp *)mono_mempool_alloc (acfg->mempool, sizeof (MonoUnwindOp));
memcpy (op, l->data, sizeof (MonoUnwindOp));
unwind_ops = g_slist_prepend_mempool (acfg->mempool, unwind_ops, op);
}
int i;
sig = mono_method_signature (method);
- args = mono_mempool_alloc (acfg->mempool, sizeof (MonoInst*) * (sig->param_count + sig->hasthis));
+ args = (MonoInst **)mono_mempool_alloc (acfg->mempool, sizeof (MonoInst*) * (sig->param_count + sig->hasthis));
for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
- args [i] = mono_mempool_alloc (acfg->mempool, sizeof (MonoInst));
+ args [i] = (MonoInst *)mono_mempool_alloc (acfg->mempool, sizeof (MonoInst));
memcpy (args [i], cfg->args [i], sizeof (MonoInst));
}
cfg->args = args;
header = mono_method_get_header (method);
- locals = mono_mempool_alloc (acfg->mempool, sizeof (MonoInst*) * header->num_locals);
+ locals = (MonoInst **)mono_mempool_alloc (acfg->mempool, sizeof (MonoInst*) * header->num_locals);
for (i = 0; i < header->num_locals; ++i) {
- locals [i] = mono_mempool_alloc (acfg->mempool, sizeof (MonoInst));
+ locals [i] = (MonoInst *)mono_mempool_alloc (acfg->mempool, sizeof (MonoInst));
memcpy (locals [i], cfg->locals [i], sizeof (MonoInst));
}
cfg->locals = locals;
static void
compile_thread_main (gpointer *user_data)
{
- MonoDomain *domain = user_data [0];
- MonoAotCompile *acfg = user_data [1];
- GPtrArray *methods = user_data [2];
+ MonoDomain *domain = (MonoDomain *)user_data [0];
+ MonoAotCompile *acfg = (MonoAotCompile *)user_data [1];
+ GPtrArray *methods = (GPtrArray *)user_data [2];
int i;
mono_thread_attach (domain);
for (i = 0; i < methods->len; ++i)
- compile_method (acfg, g_ptr_array_index (methods, i));
+ compile_method (acfg, (MonoMethod *)g_ptr_array_index (methods, i));
}
static void
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);
+ sym = mono_lookup_jit_icall_symbol ((const char *)data);
} else if (type == MONO_PATCH_INFO_ICALL_ADDR) {
- MonoMethod *method = (gpointer)data;
+ MonoMethod *method = (MonoMethod *)data;
if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
sym = mono_lookup_icall_symbol (method);
}
char*
mono_aot_get_plt_symbol (MonoJumpInfoType type, gconstpointer data)
{
- MonoJumpInfo *ji = mono_mempool_alloc (llvm_acfg->mempool, sizeof (MonoJumpInfo));
+ MonoJumpInfo *ji = (MonoJumpInfo *)mono_mempool_alloc (llvm_acfg->mempool, sizeof (MonoJumpInfo));
MonoPltEntry *plt_entry;
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);
+ sym = mono_lookup_jit_icall_symbol ((const char *)data);
} else if (type == MONO_PATCH_INFO_ICALL_ADDR) {
- MonoMethod *method = (gpointer)data;
+ MonoMethod *method = (MonoMethod *)data;
if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
sym = mono_lookup_icall_symbol (method);
}
}
}
- acfg->stats.offsets_size += emit_offset_table (acfg, "method_info_offsets", acfg->nmethods, 10, offsets);
+ acfg->stats.offsets_size += emit_offset_table (acfg, "method_info_offsets", MONO_AOT_TABLE_METHOD_INFO_OFFSETS, acfg->nmethods, 10, offsets);
g_free (offsets);
}
ginst = ((MonoMethodInflated*)method)->context.method_inst;
hashes_count = sig->param_count + 5 + (class_ginst ? class_ginst->type_argc : 0) + (ginst ? ginst->type_argc : 0);
- hashes_start = g_malloc0 (hashes_count * sizeof (guint32));
+ hashes_start = (guint32 *)g_malloc0 (hashes_count * sizeof (guint32));
hashes = hashes_start;
/* Some wrappers are assigned to random classes */
emit_extra_methods (MonoAotCompile *acfg)
{
int i, table_size, buf_size;
- char symbol [256];
guint8 *p, *buf;
guint32 *info_offsets;
guint32 hash;
/* Emit method info */
nmethods = 0;
for (i = 0; i < acfg->extra_methods->len; ++i) {
- MonoMethod *method = g_ptr_array_index (acfg->extra_methods, i);
- MonoCompile *cfg = g_hash_table_lookup (acfg->method_to_cfg, method);
+ MonoMethod *method = (MonoMethod *)g_ptr_array_index (acfg->extra_methods, i);
+ MonoCompile *cfg = (MonoCompile *)g_hash_table_lookup (acfg->method_to_cfg, method);
if (!cfg)
continue;
buf_size = 10240;
- p = buf = g_malloc (buf_size);
+ p = buf = (guint8 *)g_malloc (buf_size);
nmethods ++;
chain_lengths = g_new0 (int, table_size);
max_chain_length = 0;
for (i = 0; i < acfg->extra_methods->len; ++i) {
- MonoMethod *method = g_ptr_array_index (acfg->extra_methods, i);
- MonoCompile *cfg = g_hash_table_lookup (acfg->method_to_cfg, method);
+ MonoMethod *method = (MonoMethod *)g_ptr_array_index (acfg->extra_methods, i);
+ MonoCompile *cfg = (MonoCompile *)g_hash_table_lookup (acfg->method_to_cfg, method);
guint32 key, value;
if (!cfg)
chain_lengths [hash] ++;
max_chain_length = MAX (max_chain_length, chain_lengths [hash]);
- new_entry = mono_mempool_alloc0 (acfg->mempool, sizeof (HashEntry));
+ new_entry = (HashEntry *)mono_mempool_alloc0 (acfg->mempool, sizeof (HashEntry));
new_entry->key = key;
new_entry->value = value;
- entry = g_ptr_array_index (table, hash);
+ entry = (HashEntry *)g_ptr_array_index (table, hash);
if (entry == NULL) {
new_entry->index = hash;
g_ptr_array_index (table, hash) = new_entry;
//printf ("MAX: %d\n", max_chain_length);
buf_size = table->len * 12 + 4;
- p = buf = g_malloc (buf_size);
+ p = buf = (guint8 *)g_malloc (buf_size);
encode_int (table_size, p, &p);
for (i = 0; i < table->len; ++i) {
- HashEntry *entry = g_ptr_array_index (table, i);
+ HashEntry *entry = (HashEntry *)g_ptr_array_index (table, i);
if (entry == NULL) {
encode_int (0, p, &p);
g_assert (p - buf <= buf_size);
/* Emit the table */
- if (acfg->llvm) {
- mono_llvm_emit_aot_data ("extra_method_table", buf, p - buf);
- } else {
- sprintf (symbol, "extra_method_table");
- emit_section_change (acfg, RODATA_SECT, 0);
- emit_alignment (acfg, 8);
- emit_label (acfg, symbol);
- emit_bytes (acfg, buf, p - buf);
- }
+ emit_aot_data (acfg, MONO_AOT_TABLE_EXTRA_METHOD_TABLE, "extra_method_table", buf, p - buf);
/*
* Emit a table reverse mapping method indexes to their index in extra_method_info.
* This is used by mono_aot_find_jit_info ().
*/
buf_size = acfg->extra_methods->len * 8 + 4;
- p = buf = g_malloc (buf_size);
+ p = buf = (guint8 *)g_malloc (buf_size);
encode_int (acfg->extra_methods->len, p, &p);
for (i = 0; i < acfg->extra_methods->len; ++i) {
- MonoMethod *method = g_ptr_array_index (acfg->extra_methods, i);
+ MonoMethod *method = (MonoMethod *)g_ptr_array_index (acfg->extra_methods, i);
encode_int (get_method_index (acfg, method), p, &p);
encode_int (info_offsets [i], p, &p);
}
- if (acfg->llvm) {
- mono_llvm_emit_aot_data ("extra_method_info_offsets", buf, p - buf);
- } else {
- sprintf (symbol, "extra_method_info_offsets");
- emit_section_change (acfg, RODATA_SECT, 0);
- emit_alignment (acfg, 8);
- emit_label (acfg, symbol);
- emit_bytes (acfg, buf, p - buf);
- }
+ emit_aot_data (acfg, MONO_AOT_TABLE_EXTRA_METHOD_INFO_OFFSETS, "extra_method_info_offsets", buf, p - buf);
}
static void
g_free (seq_points_aot_file);
}
- acfg->stats.offsets_size += emit_offset_table (acfg, "ex_info_offsets", acfg->nmethods, 10, offsets);
+ acfg->stats.offsets_size += emit_offset_table (acfg, "ex_info_offsets", MONO_AOT_TABLE_EX_INFO_OFFSETS, acfg->nmethods, 10, offsets);
g_free (offsets);
}
for (i = 0; i < acfg->image->tables [MONO_TABLE_TYPEDEF].rows; ++i)
offsets [i] = emit_klass_info (acfg, MONO_TOKEN_TYPE_DEF | (i + 1));
- acfg->stats.offsets_size += emit_offset_table (acfg, "class_info_offsets", acfg->image->tables [MONO_TABLE_TYPEDEF].rows, 10, offsets);
+ acfg->stats.offsets_size += emit_offset_table (acfg, "class_info_offsets", MONO_AOT_TABLE_CLASS_INFO_OFFSETS, acfg->image->tables [MONO_TABLE_TYPEDEF].rows, 10, offsets);
g_free (offsets);
}
GPtrArray *table;
char *full_name;
guint8 *buf, *p;
- char symbol [256];
ClassNameTableEntry *entry, *new_entry;
/*
new_entry = g_new0 (ClassNameTableEntry, 1);
new_entry->token = token;
- entry = g_ptr_array_index (table, hash);
+ entry = (ClassNameTableEntry *)g_ptr_array_index (table, hash);
if (entry == NULL) {
new_entry->index = hash;
g_ptr_array_index (table, hash) = new_entry;
/* Emit the table */
buf_size = table->len * 4 + 4;
- p = buf = g_malloc0 (buf_size);
+ p = buf = (guint8 *)g_malloc0 (buf_size);
/* FIXME: Optimize memory usage */
g_assert (table_size < 65000);
encode_int16 (table_size, p, &p);
g_assert (table->len < 65000);
for (i = 0; i < table->len; ++i) {
- ClassNameTableEntry *entry = g_ptr_array_index (table, i);
+ ClassNameTableEntry *entry = (ClassNameTableEntry *)g_ptr_array_index (table, i);
if (entry == NULL) {
encode_int16 (0, p, &p);
}
g_assert (p - buf <= buf_size);
- if (acfg->llvm) {
- mono_llvm_emit_aot_data ("class_name_table", buf, p - buf);
- } else {
- sprintf (symbol, "class_name_table");
- emit_section_change (acfg, RODATA_SECT, 0);
- emit_alignment (acfg, 8);
- emit_label (acfg, symbol);
- emit_bytes (acfg, buf, p - buf);
- }
+ emit_aot_data (acfg, MONO_AOT_TABLE_CLASS_NAME, "class_name_table", buf, p - buf);
}
static void
emit_image_table (MonoAotCompile *acfg)
{
int i, buf_size;
- char symbol [256];
guint8 *buf, *p;
/*
buf_size += strlen (image->assembly_name) + strlen (image->guid) + (aname->culture ? strlen (aname->culture) : 1) + strlen ((char*)aname->public_key_token) + 4;
}
- buf = p = g_malloc0 (buf_size);
+ buf = p = (guint8 *)g_malloc0 (buf_size);
encode_int (acfg->image_table->len, p, &p);
for (i = 0; i < acfg->image_table->len; i++) {
MonoImage *image = (MonoImage*)g_ptr_array_index (acfg->image_table, i);
}
g_assert (p - buf <= buf_size);
- if (acfg->llvm) {
- mono_llvm_emit_aot_data ("image_table", buf, p - buf);
- } else {
- sprintf (symbol, "image_table");
- emit_section_change (acfg, RODATA_SECT, 1);
- emit_alignment (acfg, 8);
- emit_label (acfg, symbol);
- emit_bytes (acfg, buf, p - buf);
- }
+ emit_aot_data (acfg, MONO_AOT_TABLE_IMAGE_TABLE, "image_table", buf, p - buf);
g_free (buf);
}
acfg->plt_got_offset_base = acfg->got_offset;
first_plt_got_patch = info->got_patches->len;
for (i = 1; i < acfg->plt_offset; ++i) {
- MonoPltEntry *plt_entry = g_hash_table_lookup (acfg->plt_offset_to_entry, GUINT_TO_POINTER (i));
+ MonoPltEntry *plt_entry = (MonoPltEntry *)g_hash_table_lookup (acfg->plt_offset_to_entry, GUINT_TO_POINTER (i));
g_ptr_array_add (info->got_patches, plt_entry->ji);
/* Encode info required to decode shared GOT entries */
buf_size = info->got_patches->len * 128;
- p = buf = mono_mempool_alloc (acfg->mempool, buf_size);
- got_info_offsets = mono_mempool_alloc (acfg->mempool, info->got_patches->len * sizeof (guint32));
+ p = buf = (guint8 *)mono_mempool_alloc (acfg->mempool, buf_size);
+ got_info_offsets = (guint32 *)mono_mempool_alloc (acfg->mempool, info->got_patches->len * sizeof (guint32));
if (!llvm) {
- acfg->plt_got_info_offsets = mono_mempool_alloc (acfg->mempool, acfg->plt_offset * sizeof (guint32));
+ acfg->plt_got_info_offsets = (guint32 *)mono_mempool_alloc (acfg->mempool, acfg->plt_offset * sizeof (guint32));
/* Unused */
if (acfg->plt_offset)
acfg->plt_got_info_offsets [0] = 0;
}
for (i = 0; i < info->got_patches->len; ++i) {
- MonoJumpInfo *ji = g_ptr_array_index (info->got_patches, i);
+ MonoJumpInfo *ji = (MonoJumpInfo *)g_ptr_array_index (info->got_patches, i);
guint8 *p2;
p = buf;
/* Emit got_info_offsets table */
/* No need to emit offsets for the got plt entries, the plt embeds them directly */
- acfg->stats.offsets_size += emit_offset_table (acfg, llvm ? "llvm_got_info_offsets" : "got_info_offsets", llvm ? acfg->llvm_got_offset : first_plt_got_patch, 10, (gint32*)got_info_offsets);
+ acfg->stats.offsets_size += emit_offset_table (acfg, llvm ? "llvm_got_info_offsets" : "got_info_offsets", llvm ? MONO_AOT_TABLE_LLVM_GOT_INFO_OFFSETS : MONO_AOT_TABLE_GOT_INFO_OFFSETS, llvm ? acfg->llvm_got_offset : first_plt_got_patch, 10, (gint32*)got_info_offsets);
}
static void
for (i = 0; i < table_size; ++i)
g_ptr_array_add (table, NULL);
for (i = 0; i < acfg->globals->len; ++i) {
- char *name = g_ptr_array_index (acfg->globals, i);
+ char *name = (char *)g_ptr_array_index (acfg->globals, i);
hash = mono_metadata_str_hash (name) % table_size;
new_entry = g_new0 (GlobalsTableEntry, 1);
new_entry->value = i;
- entry = g_ptr_array_index (table, hash);
+ entry = (GlobalsTableEntry *)g_ptr_array_index (table, hash);
if (entry == NULL) {
new_entry->index = hash;
g_ptr_array_index (table, hash) = new_entry;
g_assert (table_size < 65000);
emit_int16 (acfg, table_size);
for (i = 0; i < table->len; ++i) {
- GlobalsTableEntry *entry = g_ptr_array_index (table, i);
+ GlobalsTableEntry *entry = (GlobalsTableEntry *)g_ptr_array_index (table, i);
if (entry == NULL) {
emit_int16 (acfg, 0);
/* Emit the names */
for (i = 0; i < acfg->globals->len; ++i) {
- char *name = g_ptr_array_index (acfg->globals, i);
+ char *name = (char *)g_ptr_array_index (acfg->globals, i);
sprintf (symbol, "name_%d", i);
emit_section_change (acfg, RODATA_SECT, 1);
emit_pointer (acfg, symbol);
for (i = 0; i < acfg->globals->len; ++i) {
- char *name = g_ptr_array_index (acfg->globals, i);
+ char *name = (char *)g_ptr_array_index (acfg->globals, i);
sprintf (symbol, "name_%d", i);
emit_pointer (acfg, symbol);
}
static void
-init_aot_file_info (MonoAotCompile *acfg, MonoAotFileInfo *info, int gc_name_offset)
+init_aot_file_info (MonoAotCompile *acfg, MonoAotFileInfo *info)
{
int i;
info->flags = acfg->flags;
info->opts = acfg->opts;
info->simd_opts = acfg->simd_opts;
- info->gc_name_index = gc_name_offset;
+ info->gc_name_index = acfg->gc_name_offset;
+ info->datafile_size = acfg->datafile_offset;
+ for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
+ info->table_offsets [i] = acfg->table_offsets [i];
for (i = 0; i < MONO_AOT_TRAMP_NUM; ++i)
info->num_trampolines [i] = acfg->num_trampolines [i];
for (i = 0; i < MONO_AOT_TRAMP_NUM; ++i)
symbols [sindex ++] = NULL;
symbols [sindex ++] = NULL;
}
- symbols [sindex ++] = "blob";
- symbols [sindex ++] = "class_name_table";
- symbols [sindex ++] = "class_info_offsets";
- symbols [sindex ++] = "method_info_offsets";
- symbols [sindex ++] = "ex_info_offsets";
- symbols [sindex ++] = "extra_method_info_offsets";
- symbols [sindex ++] = "extra_method_table";
- symbols [sindex ++] = "got_info_offsets";
- if (acfg->llvm)
- symbols [sindex ++] = "llvm_got_info_offsets";
- else
- symbols [sindex ++] = NULL;
+ if (acfg->data_outfile) {
+ for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
+ symbols [sindex ++] = NULL;
+ } else {
+ symbols [sindex ++] = "blob";
+ symbols [sindex ++] = "class_name_table";
+ symbols [sindex ++] = "class_info_offsets";
+ symbols [sindex ++] = "method_info_offsets";
+ symbols [sindex ++] = "ex_info_offsets";
+ symbols [sindex ++] = "extra_method_info_offsets";
+ symbols [sindex ++] = "extra_method_table";
+ symbols [sindex ++] = "got_info_offsets";
+ if (acfg->llvm)
+ symbols [sindex ++] = "llvm_got_info_offsets";
+ else
+ symbols [sindex ++] = NULL;
+ symbols [sindex ++] = "image_table";
+ }
symbols [sindex ++] = "mem_end";
- symbols [sindex ++] = "image_table";
symbols [sindex ++] = "assembly_guid";
symbols [sindex ++] = "runtime_version";
if (acfg->num_trampoline_got_entries) {
emit_int32 (acfg, info->generic_tramp_num);
emit_int32 (acfg, info->tramp_page_size);
emit_int32 (acfg, info->nshared_got_entries);
+ emit_int32 (acfg, info->datafile_size);
+ for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
+ emit_int32 (acfg, info->table_offsets [i]);
for (i = 0; i < MONO_AOT_TRAMP_NUM; ++i)
emit_int32 (acfg, info->num_trampolines [i]);
for (i = 0; i < MONO_AOT_TRAMP_NUM; ++i)
static void
emit_file_info (MonoAotCompile *acfg)
{
- int gc_name_offset;
- const char *gc_name;
char *build_info;
MonoAotFileInfo *info;
/* Emit a string holding the assembly name */
emit_string_symbol (acfg, "assembly_name", acfg->image->assembly->aname.name);
- /*
- * The managed allocators are GC specific, so can't use an AOT image created by one GC
- * in another.
- */
- gc_name = mono_gc_get_gc_name ();
- gc_name_offset = add_to_blob (acfg, (guint8*)gc_name, strlen (gc_name) + 1);
-
info = g_new0 (MonoAotFileInfo, 1);
- init_aot_file_info (acfg, info, gc_name_offset);
+ init_aot_file_info (acfg, info);
if (acfg->llvm)
mono_llvm_emit_aot_file_info (info, acfg->has_jitted_code);
static void
emit_blob (MonoAotCompile *acfg)
{
- char symbol [128];
-
- if (acfg->llvm) {
- mono_llvm_emit_aot_data ("blob", (guint8*)acfg->blob.data, acfg->blob.index);
- return;
- }
+ acfg->blob_closed = TRUE;
- sprintf (symbol, "blob");
- emit_section_change (acfg, RODATA_SECT, 1);
- emit_alignment (acfg, 8);
- emit_label (acfg, symbol);
-
- emit_bytes (acfg, (guint8*)acfg->blob.data, acfg->blob.index);
+ emit_aot_data (acfg, MONO_AOT_TABLE_BLOB, "blob", (guint8*)acfg->blob.data, acfg->blob.index);
}
static void
sprintf (symbol2, "%sme_%x", acfg->temp_prefix, i);
- mono_dwarf_writer_emit_method (acfg->dwarf, cfg, cfg->method, cfg->asm_symbol, symbol2, cfg->asm_debug_symbol, cfg->jit_info->code_start, cfg->jit_info->code_size, cfg->args, cfg->locals, cfg->unwind_ops, mono_debug_find_method (cfg->jit_info->d.method, mono_domain_get ()));
+ mono_dwarf_writer_emit_method (acfg->dwarf, cfg, cfg->method, cfg->asm_symbol, symbol2, cfg->asm_debug_symbol, (guint8 *)cfg->jit_info->code_start, cfg->jit_info->code_size, cfg->args, cfg->locals, cfg->unwind_ops, mono_debug_find_method (cfg->jit_info->d.method, mono_domain_get ()));
}
#endif
}
methods = g_new0 (MonoMethod*, methods_len);
//memcpy (methods, g_ptr_array_index (acfg->methods, 0), sizeof (MonoMethod*) * methods_len);
for (i = 0; i < methods_len; ++i)
- methods [i] = g_ptr_array_index (acfg->methods, i);
+ methods [i] = (MonoMethod *)g_ptr_array_index (acfg->methods, i);
i = 0;
while (i < methods_len) {
frag = g_ptr_array_new ();
user_data [1] = acfg;
user_data [2] = frag;
- handle = mono_threads_create_thread ((gpointer)compile_thread_main, user_data, 0, 0, NULL);
+ handle = mono_threads_create_thread ((LPTHREAD_START_ROUTINE)compile_thread_main, user_data, 0, 0, NULL);
g_ptr_array_add (threads, handle);
}
g_free (methods);
/* Compile methods added by compile_method () or all methods if nthreads == 0 */
for (i = methods_len; i < acfg->methods->len; ++i) {
/* This can new methods to acfg->methods */
- compile_method (acfg, g_ptr_array_index (acfg->methods, i));
+ compile_method (acfg, (MonoMethod *)g_ptr_array_index (acfg->methods, i));
}
}
acfg->klass_blob_hash = g_hash_table_new (NULL, NULL);
acfg->method_blob_hash = g_hash_table_new (NULL, NULL);
acfg->plt_entry_debug_sym_cache = g_hash_table_new (g_str_hash, g_str_equal);
- mono_mutex_init_recursive (&acfg->mutex);
+ acfg->gsharedvt_in_signatures = g_hash_table_new ((GHashFunc)mono_signature_hash, (GEqualFunc)mono_metadata_signature_equal);
+ acfg->gsharedvt_out_signatures = g_hash_table_new ((GHashFunc)mono_signature_hash, (GEqualFunc)mono_metadata_signature_equal);
+ mono_os_mutex_init_recursive (&acfg->mutex);
init_got_info (&acfg->got_info);
init_got_info (&acfg->llvm_got_info);
"mono_aot_init_gshared_method_this",
"mono_aot_init_gshared_method_rgctx",
"mono_llvm_throw_corlib_exception",
- "mono_resolve_vcall",
+ "mono_init_vtable_slot",
"mono_helper_ldstr_mscorlib"
};
* during method initialization etc.
*/
- ji = mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJumpInfo));
+ ji = (MonoJumpInfo *)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 = (MonoJumpInfo *)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 = (MonoJumpInfo *)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 = (MonoJumpInfo *)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 = (MonoJumpInfo *)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 = (MonoJumpInfo *)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);
- ji = mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJumpInfo));
+ ji = (MonoJumpInfo *)mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJumpInfo));
ji->type = MONO_PATCH_INFO_GC_NURSERY_BITS;
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 = (MonoJumpInfo *)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);
acfg->logfile = fopen (acfg->aot_opts.logfile, "a+");
}
+ if (acfg->aot_opts.data_outfile) {
+ acfg->data_outfile = fopen (acfg->aot_opts.data_outfile, "w+");
+ if (!acfg->data_outfile) {
+ aot_printerrf (acfg, "Unable to create file '%s': %s\n", acfg->aot_opts.data_outfile, strerror (errno));
+ return 1;
+ }
+ acfg->flags = (MonoAotFileFlags)(acfg->flags | MONO_AOT_FILE_FLAG_SEPARATE_DATA);
+ }
+
//acfg->aot_opts.print_skipped_methods = TRUE;
-#if !defined(MONO_ARCH_GSHAREDVT_SUPPORTED) || !defined(ENABLE_GSHAREDVT)
+#if !defined(ENABLE_GSHAREDVT)
if (opts & MONO_OPT_GSHAREDVT) {
aot_printerrf (acfg, "-O=gsharedvt not supported on this platform.\n");
return 1;
}
#endif
+#if !defined(MONO_ARCH_GSHAREDVT_SUPPORTED)
+ if (!acfg->aot_opts.llvm_only && (opts & MONO_OPT_GSHAREDVT)) {
+ aot_printerrf (acfg, "-O=gsharedvt not supported on this platform.\n");
+ return 1;
+ }
+#endif
+
+#if defined(ENABLE_GSHAREDVT)
+ if (acfg->aot_opts.llvm_only) {
+ acfg->opts |= MONO_OPT_GSHAREDVT;
+ opts |= MONO_OPT_GSHAREDVT;
+ }
+#endif
+
+ if (opts & MONO_OPT_GSHAREDVT)
+ mono_set_generic_sharing_vt_supported (TRUE);
+
aot_printf (acfg, "Mono Ahead of Time compiler - compiling assembly %s\n", image->name);
#ifndef MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES
aot_printerrf (acfg, "The soft-debug AOT option requires the --debug option.\n");
return 1;
}
- acfg->flags |= MONO_AOT_FILE_FLAG_DEBUG;
+ acfg->flags = (MonoAotFileFlags)(acfg->flags | MONO_AOT_FILE_FLAG_DEBUG);
}
if (mono_use_llvm || acfg->aot_opts.llvm) {
acfg->llvm = TRUE;
acfg->aot_opts.asm_writer = TRUE;
- acfg->flags |= MONO_AOT_FILE_FLAG_WITH_LLVM;
+ acfg->flags = (MonoAotFileFlags)(acfg->flags | MONO_AOT_FILE_FLAG_WITH_LLVM);
if (acfg->aot_opts.soft_debug) {
aot_printerrf (acfg, "The 'soft-debug' option is not supported when compiling with LLVM.\n");
}
if (mono_aot_mode_is_full (&acfg->aot_opts))
- acfg->flags |= MONO_AOT_FILE_FLAG_FULL_AOT;
+ acfg->flags = (MonoAotFileFlags)(acfg->flags | MONO_AOT_FILE_FLAG_FULL_AOT);
if (mono_threads_is_coop_enabled ())
- acfg->flags |= MONO_AOT_FILE_FLAG_SAFEPOINTS;
+ acfg->flags = (MonoAotFileFlags)(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");
arch_init (acfg);
if (acfg->llvm && acfg->thumb_mixed)
- acfg->flags |= MONO_AOT_FILE_FLAG_LLVM_THUMB;
+ acfg->flags = (MonoAotFileFlags)(acfg->flags | MONO_AOT_FILE_FLAG_LLVM_THUMB);
if (acfg->aot_opts.llvm_only)
- acfg->flags |= MONO_AOT_FILE_FLAG_LLVM_ONLY;
+ acfg->flags = (MonoAotFileFlags)(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 */
emit_got (acfg);
- emit_file_info (acfg);
+ {
+ /*
+ * The managed allocators are GC specific, so can't use an AOT image created by one GC
+ * in another.
+ */
+ const char *gc_name = mono_gc_get_gc_name ();
+ acfg->gc_name_offset = add_to_blob (acfg, (guint8*)gc_name, strlen (gc_name) + 1);
+ }
emit_blob (acfg);
emit_globals (acfg);
+ emit_file_info (acfg);
+
if (acfg->dwarf) {
emit_dwarf_info (acfg);
mono_dwarf_writer_close (acfg->dwarf);
fprintf (acfg->fp, "\n.section .note.GNU-stack,\"\",@progbits\n");
}
+ if (acfg->aot_opts.data_outfile)
+ fclose (acfg->data_outfile);
+
#ifdef ENABLE_LLVM
if (acfg->llvm) {
gboolean res;