"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "mono/mini/aot-compiler.c" between
mono-6.10.0.104.tar.xz and mono-6.12.0.90.tar.xz

About: Mono is an open source implementation of Microsoft's .NET Framework based on the ECMA standards for C# and the Common Language Runtime.

aot-compiler.c  (mono-6.10.0.104.tar.xz):aot-compiler.c  (mono-6.12.0.90.tar.xz)
skipping to change at line 82 skipping to change at line 82
static MonoMethod* static MonoMethod*
try_get_method_nofail (MonoClass *klass, const char *method_name, int param_coun t, int flags) try_get_method_nofail (MonoClass *klass, const char *method_name, int param_coun t, int flags)
{ {
MonoMethod *result; MonoMethod *result;
ERROR_DECL (error); ERROR_DECL (error);
result = mono_class_get_method_from_name_checked (klass, method_name, par am_count, flags, error); result = mono_class_get_method_from_name_checked (klass, method_name, par am_count, flags, error);
mono_error_assert_ok (error); mono_error_assert_ok (error);
return result; return result;
} }
// FIXME Consolidate the multiple functions named get_method_nofail.
static MonoMethod* static MonoMethod*
get_method_nofail (MonoClass *klass, const char *method_name, int param_count, i nt flags) get_method_nofail (MonoClass *klass, const char *method_name, int param_count, i nt flags)
{ {
MonoMethod *result = try_get_method_nofail (klass, method_name, param_cou nt, flags); MonoMethod *result = try_get_method_nofail (klass, method_name, param_cou nt, flags);
g_assertf (result, "Expected to find method %s in klass %s", method_name, m_class_get_name (klass)); g_assertf (result, "Expected to find method %s in klass %s", method_name, m_class_get_name (klass));
return result; return result;
} }
#if !defined(DISABLE_AOT) && !defined(DISABLE_JIT) #if !defined(DISABLE_AOT) && !defined(DISABLE_JIT)
skipping to change at line 205 skipping to change at line 206
gboolean asm_writer; gboolean asm_writer;
gboolean nodebug; gboolean nodebug;
gboolean dwarf_debug; gboolean dwarf_debug;
gboolean soft_debug; gboolean soft_debug;
gboolean log_generics; gboolean log_generics;
gboolean log_instances; gboolean log_instances;
gboolean gen_msym_dir; gboolean gen_msym_dir;
char *gen_msym_dir_path; char *gen_msym_dir_path;
gboolean direct_pinvoke; gboolean direct_pinvoke;
gboolean direct_icalls; gboolean direct_icalls;
gboolean direct_extern_calls;
gboolean no_direct_calls; gboolean no_direct_calls;
gboolean use_trampolines_page; gboolean use_trampolines_page;
gboolean no_instances; gboolean no_instances;
// We are collecting inflated methods and emitting non-inflated // We are collecting inflated methods and emitting non-inflated
gboolean dedup; gboolean dedup;
// The name of the assembly for which the AOT module is going to have all deduped methods moved to. // The name of the assembly for which the AOT module is going to have all deduped methods moved to.
// When set, we are emitting inflated methods only // When set, we are emitting inflated methods only
char *dedup_include; char *dedup_include;
gboolean gnu_asm; gboolean gnu_asm;
gboolean try_llvm; gboolean try_llvm;
skipping to change at line 533 skipping to change at line 535
if (acfg->is_full_aot && fatal) { if (acfg->is_full_aot && fatal) {
fprintf (output, "FullAOT cannot continue if there are loader err ors.\n"); fprintf (output, "FullAOT cannot continue if there are loader err ors.\n");
exit (1); exit (1);
} }
} }
/* Wrappers around the image writer functions */ /* Wrappers around the image writer functions */
#define MAX_SYMBOL_SIZE 256 #define MAX_SYMBOL_SIZE 256
#if defined(TARGET_WIN32) && defined(TARGET_X86)
static const char * static const char *
mangle_symbol (const char * symbol, char * mangled_symbol, gsize length) mangle_symbol (const char * symbol, char * mangled_symbol, gsize length)
{ {
gsize needed_size = length; gsize needed_size = length;
g_assert (NULL != symbol); g_assert (NULL != symbol);
g_assert (NULL != mangled_symbol); g_assert (NULL != mangled_symbol);
g_assert (0 != length); g_assert (0 != length);
#if defined(TARGET_WIN32) && defined(TARGET_X86)
if (symbol && '_' != symbol [0]) { if (symbol && '_' != symbol [0]) {
needed_size = g_snprintf (mangled_symbol, length, "_%s", symbol); needed_size = g_snprintf (mangled_symbol, length, "_%s", symbol);
} else { } else {
needed_size = g_snprintf (mangled_symbol, length, "%s", symbol); needed_size = g_snprintf (mangled_symbol, length, "%s", symbol);
} }
#else
needed_size = g_snprintf (mangled_symbol, length, "%s", symbol);
#endif
g_assert (0 <= needed_size && needed_size < length); g_assert (0 <= needed_size && needed_size < length);
return mangled_symbol; return mangled_symbol;
} }
static char * static char *
mangle_symbol_alloc (const char * symbol) mangle_symbol_alloc (const char * symbol)
{ {
g_assert (NULL != symbol); g_assert (NULL != symbol);
#if defined(TARGET_WIN32) && defined(TARGET_X86)
if (symbol && '_' != symbol [0]) { if (symbol && '_' != symbol [0]) {
return g_strdup_printf ("_%s", symbol); return g_strdup_printf ("_%s", symbol);
} }
else { else {
return g_strdup_printf ("%s", symbol); return g_strdup_printf ("%s", symbol);
} }
#else
return g_strdup_printf ("%s", symbol);
#endif
} }
#endif
static void static void
emit_section_change (MonoAotCompile *acfg, const char *section_name, int subsect ion_index) emit_section_change (MonoAotCompile *acfg, const char *section_name, int subsect ion_index)
{ {
mono_img_writer_emit_section_change (acfg->w, section_name, subsection_in dex); mono_img_writer_emit_section_change (acfg->w, section_name, subsection_in dex);
} }
#if defined(TARGET_WIN32) && defined(TARGET_X86) #if defined(TARGET_WIN32) && defined(TARGET_X86)
static void static void
skipping to change at line 751 skipping to change at line 747
#else #else
static G_GNUC_UNUSED void static G_GNUC_UNUSED void
emit_global_inner (MonoAotCompile *acfg, const char *name, gboolean func) emit_global_inner (MonoAotCompile *acfg, const char *name, gboolean func)
{ {
mono_img_writer_emit_global (acfg->w, name, func); mono_img_writer_emit_global (acfg->w, name, func);
} }
#endif #endif
#ifdef TARGET_WIN32_MSVC
static gboolean static gboolean
link_shared_library (MonoAotCompile *acfg) link_shared_library (MonoAotCompile *acfg)
{ {
return !acfg->aot_opts.static_link && !acfg->aot_opts.asm_only; return !acfg->aot_opts.static_link && !acfg->aot_opts.asm_only;
} }
#endif
static gboolean static gboolean
add_to_global_symbol_table (MonoAotCompile *acfg) add_to_global_symbol_table (MonoAotCompile *acfg)
{ {
#ifdef TARGET_WIN32_MSVC #ifdef TARGET_WIN32_MSVC
return acfg->aot_opts.no_dlsym || link_shared_library (acfg); return acfg->aot_opts.no_dlsym || link_shared_library (acfg);
#else #else
return acfg->aot_opts.no_dlsym; return acfg->aot_opts.no_dlsym;
#endif #endif
} }
skipping to change at line 5306 skipping to change at line 5304
g_free (name_prefix); g_free (name_prefix);
} }
/* Add an instance of GenericComparer<T> which is created dynamically by Comparer<T> */ /* Add an instance of GenericComparer<T> which is created dynamically by Comparer<T> */
if (in_corlib && !strcmp (klass_name_space, "System.Collections.Generic") && !strcmp (klass_name, "Comparer`1")) { if (in_corlib && !strcmp (klass_name_space, "System.Collections.Generic") && !strcmp (klass_name, "Comparer`1")) {
ERROR_DECL (error); ERROR_DECL (error);
MonoClass *tclass = mono_class_from_mono_type_internal (mono_clas s_get_generic_class (klass)->context.class_inst->type_argv [0]); MonoClass *tclass = mono_class_from_mono_type_internal (mono_clas s_get_generic_class (klass)->context.class_inst->type_argv [0]);
MonoClass *icomparable, *gcomparer, *icomparable_inst; MonoClass *icomparable, *gcomparer, *icomparable_inst;
MonoGenericContext ctx; MonoGenericContext ctx;
MonoType *args [16];
memset (&ctx, 0, sizeof (ctx)); memset (&ctx, 0, sizeof (ctx));
icomparable = mono_class_load_from_name (mono_defaults.corlib, "S ystem", "IComparable`1"); icomparable = mono_class_load_from_name (mono_defaults.corlib, "S ystem", "IComparable`1");
args [0] = m_class_get_byval_arg (tclass); MonoType *args [ ] = { m_class_get_byval_arg (tclass) };
ctx.class_inst = mono_metadata_get_generic_inst (1, args); ctx.class_inst = mono_metadata_get_generic_inst (1, args);
icomparable_inst = mono_class_inflate_generic_class_checked (icom parable, &ctx, error); icomparable_inst = mono_class_inflate_generic_class_checked (icom parable, &ctx, error);
mono_error_assert_ok (error); /* FIXME don't swallow the error */ mono_error_assert_ok (error); /* FIXME don't swallow the error */
if (mono_class_is_assignable_from_internal (icomparable_inst, tcl ass)) { if (mono_class_is_assignable_from_internal (icomparable_inst, tcl ass)) {
MonoClass *gcomparer_inst; MonoClass *gcomparer_inst;
gcomparer = mono_class_load_from_name (mono_defaults.corl ib, "System.Collections.Generic", "GenericComparer`1"); gcomparer = mono_class_load_from_name (mono_defaults.corl ib, "System.Collections.Generic", "GenericComparer`1");
gcomparer_inst = mono_class_inflate_generic_class_checked (gcomparer, &ctx, error); gcomparer_inst = mono_class_inflate_generic_class_checked (gcomparer, &ctx, error);
mono_error_assert_ok (error); /* FIXME don't swallow the error */ mono_error_assert_ok (error); /* FIXME don't swallow the error */
skipping to change at line 5334 skipping to change at line 5331
add_generic_class (acfg, gcomparer_inst, FALSE, "Comparer <T>"); add_generic_class (acfg, gcomparer_inst, FALSE, "Comparer <T>");
} }
} }
/* Add an instance of GenericEqualityComparer<T> which is created dynamic ally by EqualityComparer<T> */ /* Add an instance of GenericEqualityComparer<T> which is created dynamic ally by EqualityComparer<T> */
if (in_corlib && !strcmp (klass_name_space, "System.Collections.Generic") && !strcmp (klass_name, "EqualityComparer`1")) { if (in_corlib && !strcmp (klass_name_space, "System.Collections.Generic") && !strcmp (klass_name, "EqualityComparer`1")) {
ERROR_DECL (error); ERROR_DECL (error);
MonoClass *tclass = mono_class_from_mono_type_internal (mono_clas s_get_generic_class (klass)->context.class_inst->type_argv [0]); MonoClass *tclass = mono_class_from_mono_type_internal (mono_clas s_get_generic_class (klass)->context.class_inst->type_argv [0]);
MonoClass *iface, *gcomparer, *iface_inst; MonoClass *iface, *gcomparer, *iface_inst;
MonoGenericContext ctx; MonoGenericContext ctx;
MonoType *args [16];
memset (&ctx, 0, sizeof (ctx)); memset (&ctx, 0, sizeof (ctx));
iface = mono_class_load_from_name (mono_defaults.corlib, "System" , "IEquatable`1"); iface = mono_class_load_from_name (mono_defaults.corlib, "System" , "IEquatable`1");
g_assert (iface); g_assert (iface);
args [0] = m_class_get_byval_arg (tclass); MonoType *args [ ] = { m_class_get_byval_arg (tclass) };
ctx.class_inst = mono_metadata_get_generic_inst (1, args); ctx.class_inst = mono_metadata_get_generic_inst (1, args);
iface_inst = mono_class_inflate_generic_class_checked (iface, &ct x, error); iface_inst = mono_class_inflate_generic_class_checked (iface, &ct x, error);
mono_error_assert_ok (error); /* FIXME don't swallow the error */ mono_error_assert_ok (error); /* FIXME don't swallow the error */
if (mono_class_is_assignable_from_internal (iface_inst, tclass)) { if (mono_class_is_assignable_from_internal (iface_inst, tclass)) {
MonoClass *gcomparer_inst; MonoClass *gcomparer_inst;
ERROR_DECL (error); ERROR_DECL (error);
gcomparer = mono_class_load_from_name (mono_defaults.corl ib, "System.Collections.Generic", "GenericEqualityComparer`1"); gcomparer = mono_class_load_from_name (mono_defaults.corl ib, "System.Collections.Generic", "GenericEqualityComparer`1");
skipping to change at line 5362 skipping to change at line 5358
mono_error_assert_ok (error); /* FIXME don't swallow the error */ mono_error_assert_ok (error); /* FIXME don't swallow the error */
add_generic_class (acfg, gcomparer_inst, FALSE, "Equality Comparer<T>"); add_generic_class (acfg, gcomparer_inst, FALSE, "Equality Comparer<T>");
} }
} }
/* Add an instance of EnumComparer<T> which is created dynamically by Equ alityComparer<T> for enums */ /* Add an instance of EnumComparer<T> which is created dynamically by Equ alityComparer<T> for enums */
if (in_corlib && !strcmp (klass_name_space, "System.Collections.Generic") && !strcmp (klass_name, "EqualityComparer`1")) { if (in_corlib && !strcmp (klass_name_space, "System.Collections.Generic") && !strcmp (klass_name, "EqualityComparer`1")) {
MonoClass *enum_comparer; MonoClass *enum_comparer;
MonoClass *tclass = mono_class_from_mono_type_internal (mono_clas s_get_generic_class (klass)->context.class_inst->type_argv [0]); MonoClass *tclass = mono_class_from_mono_type_internal (mono_clas s_get_generic_class (klass)->context.class_inst->type_argv [0]);
MonoGenericContext ctx; MonoGenericContext ctx;
MonoType *args [16];
if (m_class_is_enumtype (tclass)) { if (m_class_is_enumtype (tclass)) {
MonoClass *enum_comparer_inst; MonoClass *enum_comparer_inst;
ERROR_DECL (error); ERROR_DECL (error);
memset (&ctx, 0, sizeof (ctx)); memset (&ctx, 0, sizeof (ctx));
args [0] = m_class_get_byval_arg (tclass); MonoType *args [ ] = { m_class_get_byval_arg (tclass) };
ctx.class_inst = mono_metadata_get_generic_inst (1, args) ; ctx.class_inst = mono_metadata_get_generic_inst (1, args) ;
enum_comparer = mono_class_load_from_name (mono_defaults. corlib, "System.Collections.Generic", "EnumEqualityComparer`1"); enum_comparer = mono_class_load_from_name (mono_defaults. corlib, "System.Collections.Generic", "EnumEqualityComparer`1");
enum_comparer_inst = mono_class_inflate_generic_class_che cked (enum_comparer, &ctx, error); enum_comparer_inst = mono_class_inflate_generic_class_che cked (enum_comparer, &ctx, error);
mono_error_assert_ok (error); /* FIXME don't swallow the error */ mono_error_assert_ok (error); /* FIXME don't swallow the error */
add_generic_class (acfg, enum_comparer_inst, FALSE, "Equa lityComparer<T>"); add_generic_class (acfg, enum_comparer_inst, FALSE, "Equa lityComparer<T>");
} }
} }
/* Add an instance of ObjectComparer<T> which is created dynamically by C omparer<T> for enums */ /* Add an instance of ObjectComparer<T> which is created dynamically by C omparer<T> for enums */
if (in_corlib && !strcmp (klass_name_space, "System.Collections.Generic") && !strcmp (klass_name, "Comparer`1")) { if (in_corlib && !strcmp (klass_name_space, "System.Collections.Generic") && !strcmp (klass_name, "Comparer`1")) {
MonoClass *comparer; MonoClass *comparer;
MonoClass *tclass = mono_class_from_mono_type_internal (mono_clas s_get_generic_class (klass)->context.class_inst->type_argv [0]); MonoClass *tclass = mono_class_from_mono_type_internal (mono_clas s_get_generic_class (klass)->context.class_inst->type_argv [0]);
MonoGenericContext ctx; MonoGenericContext ctx;
MonoType *args [16];
if (m_class_is_enumtype (tclass)) { if (m_class_is_enumtype (tclass)) {
MonoClass *comparer_inst; MonoClass *comparer_inst;
ERROR_DECL (error); ERROR_DECL (error);
memset (&ctx, 0, sizeof (ctx)); memset (&ctx, 0, sizeof (ctx));
args [0] = m_class_get_byval_arg (tclass); MonoType *args [ ] = { m_class_get_byval_arg (tclass) };
ctx.class_inst = mono_metadata_get_generic_inst (1, args) ; ctx.class_inst = mono_metadata_get_generic_inst (1, args) ;
comparer = mono_class_load_from_name (mono_defaults.corli b, "System.Collections.Generic", "ObjectComparer`1"); comparer = mono_class_load_from_name (mono_defaults.corli b, "System.Collections.Generic", "ObjectComparer`1");
comparer_inst = mono_class_inflate_generic_class_checked (comparer, &ctx, error); comparer_inst = mono_class_inflate_generic_class_checked (comparer, &ctx, error);
mono_error_assert_ok (error); /* FIXME don't swallow the error */ mono_error_assert_ok (error); /* FIXME don't swallow the error */
add_generic_class (acfg, comparer_inst, FALSE, "Comparer< T>"); add_generic_class (acfg, comparer_inst, FALSE, "Comparer< T>");
} }
} }
} }
static void static void
add_instances_of (MonoAotCompile *acfg, MonoClass *klass, MonoType **insts, int ninsts, gboolean force) add_instances_of (MonoAotCompile *acfg, MonoClass *klass, MonoType **insts, int ninsts, gboolean force)
{ {
int i; int i;
MonoGenericContext ctx; MonoGenericContext ctx;
MonoType *args [16];
if (acfg->aot_opts.no_instances) if (acfg->aot_opts.no_instances)
return; return;
memset (&ctx, 0, sizeof (ctx)); memset (&ctx, 0, sizeof (ctx));
for (i = 0; i < ninsts; ++i) { for (i = 0; i < ninsts; ++i) {
ERROR_DECL (error); ERROR_DECL (error);
MonoClass *generic_inst; MonoClass *generic_inst;
args [0] = insts [i]; MonoType *args [ ] = { insts [i] };
ctx.class_inst = mono_metadata_get_generic_inst (1, args); ctx.class_inst = mono_metadata_get_generic_inst (1, args);
generic_inst = mono_class_inflate_generic_class_checked (klass, & ctx, error); generic_inst = mono_class_inflate_generic_class_checked (klass, & ctx, error);
mono_error_assert_ok (error); /* FIXME don't swallow the error */ mono_error_assert_ok (error); /* FIXME don't swallow the error */
add_generic_class (acfg, generic_inst, force, ""); add_generic_class (acfg, generic_inst, force, "");
} }
} }
static void static void
add_types_from_method_header (MonoAotCompile *acfg, MonoMethod *method) add_types_from_method_header (MonoAotCompile *acfg, MonoMethod *method)
{ {
skipping to change at line 5807 skipping to change at line 5800
gboolean enable_icall = FALSE; gboolean enable_icall = FALSE;
if (cfg->compile_aot) if (cfg->compile_aot)
enable_icall = lookup_external_icall_symbol_name_aot (method) ? T RUE : FALSE; enable_icall = lookup_external_icall_symbol_name_aot (method) ? T RUE : FALSE;
else else
enable_icall = FALSE; enable_icall = FALSE;
return enable_icall; return enable_icall;
} }
/* /*
* method_is_externally_callable:
*
* Return whenever METHOD can be directly called from other AOT images
* without going through a PLT.
*/
static gboolean
method_is_externally_callable (MonoAotCompile *acfg, MonoMethod *method)
{
// FIXME: Unify
if (acfg->aot_opts.llvm_only) {
if (!acfg->aot_opts.static_link)
return FALSE;
if (method->wrapper_type == MONO_WRAPPER_ALLOC)
return TRUE;
if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE)
return TRUE;
if (method->string_ctor)
return FALSE;
if (method->wrapper_type)
return FALSE;
if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) || (method->i
flags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
return FALSE;
if (method->is_inflated)
return FALSE;
if (!((mono_class_get_flags (method->klass) & TYPE_ATTRIBUTE_PUBL
IC) && (method->flags & METHOD_ATTRIBUTE_PUBLIC)))
return FALSE;
/* Can't enable this as the callee might fail llvm compilation */
//return TRUE;
return FALSE;
} else {
if (!acfg->aot_opts.direct_extern_calls)
return FALSE;
if (!acfg->llvm || acfg->aot_opts.llvm_disable_self_init)
return FALSE;
if (acfg->aot_opts.soft_debug || acfg->aot_opts.no_direct_calls)
return FALSE;
if (method->wrapper_type == MONO_WRAPPER_ALLOC)
return FALSE;
if (method->string_ctor)
return FALSE;
if (method->wrapper_type)
return FALSE;
if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) || (method->i
flags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
return FALSE;
if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
return FALSE;
if (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)
return FALSE;
if (method->is_inflated)
return FALSE;
if (!((mono_class_get_flags (method->klass) & TYPE_ATTRIBUTE_PUBL
IC) && (method->flags & METHOD_ATTRIBUTE_PUBLIC)))
return FALSE;
return TRUE;
}
}
/*
* is_direct_callable: * is_direct_callable:
* *
* Return whenever the method identified by JI is directly callable without * Return whenever the method identified by JI is directly callable without
* going through the PLT. * going through the PLT.
*/ */
static gboolean static gboolean
is_direct_callable (MonoAotCompile *acfg, MonoMethod *method, MonoJumpInfo *patc h_info) is_direct_callable (MonoAotCompile *acfg, MonoMethod *method, MonoJumpInfo *patc h_info)
{ {
if ((patch_info->type == MONO_PATCH_INFO_METHOD) && (m_class_get_image (p atch_info->data.method->klass) == acfg->image)) { if ((patch_info->type == MONO_PATCH_INFO_METHOD) && (m_class_get_image (p atch_info->data.method->klass) == acfg->image)) {
MonoCompile *callee_cfg = (MonoCompile *)g_hash_table_lookup (acf g->method_to_cfg, patch_info->data.method); MonoCompile *callee_cfg = (MonoCompile *)g_hash_table_lookup (acf g->method_to_cfg, patch_info->data.method);
skipping to change at line 5858 skipping to change at line 5908
if (direct_callable && (callee_cfg->method->wrapper_type == MONO_WRAPPER_ALLOC)) if (direct_callable && (callee_cfg->method->wrapper_type == MONO_WRAPPER_ALLOC))
/* sgen does some initialization when the allocat or method is created */ /* sgen does some initialization when the allocat or method is created */
direct_callable = FALSE; direct_callable = FALSE;
if (direct_callable && (callee_cfg->method->wrapper_type == MONO_WRAPPER_WRITE_BARRIER)) if (direct_callable && (callee_cfg->method->wrapper_type == MONO_WRAPPER_WRITE_BARRIER))
/* we don't know at compile time whether sgen is concurrent or not */ /* we don't know at compile time whether sgen is concurrent or not */
direct_callable = FALSE; direct_callable = FALSE;
if (direct_callable) if (direct_callable)
return TRUE; return TRUE;
} }
} else if ((patch_info->type == MONO_PATCH_INFO_METHOD) && (m_class_get_i
mage (patch_info->data.method->klass) != acfg->image)) {
/* Cross assembly calls */
return method_is_externally_callable (acfg, patch_info->data.meth
od);
} else if ((patch_info->type == MONO_PATCH_INFO_ICALL_ADDR_CALL && patch_ info->data.method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) { } else if ((patch_info->type == MONO_PATCH_INFO_ICALL_ADDR_CALL && patch_ info->data.method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) {
if (acfg->aot_opts.direct_pinvoke) if (acfg->aot_opts.direct_pinvoke)
return TRUE; return TRUE;
} else if (patch_info->type == MONO_PATCH_INFO_ICALL_ADDR_CALL) { } else if (patch_info->type == MONO_PATCH_INFO_ICALL_ADDR_CALL) {
if (acfg->aot_opts.direct_icalls) if (acfg->aot_opts.direct_icalls)
return TRUE; return TRUE;
return FALSE; return FALSE;
} }
return FALSE; return FALSE;
skipping to change at line 6139 skipping to change at line 6192
break; break;
} }
default: { default: {
/* /*
* If this patch is a call, try emitting a direct call instead of * If this patch is a call, try emitting a direct call instead of
* through a PLT entry. This is possible if the c alled method is in * through a PLT entry. This is possible if the c alled method is in
* the same assembly and requires no initializati on. * the same assembly and requires no initializati on.
*/ */
direct_call = FALSE; direct_call = FALSE;
external_call = FALSE; external_call = FALSE;
if ((patch_info->type == MONO_PATCH_INFO_METHOD) if (patch_info->type == MONO_PATCH_INFO_METHOD) {
&& (m_class_get_image (patch_info->data.method->klass) == acfg->image)) { MonoMethod *cmethod = patch_info->data.me
if (!got_only && is_direct_callable (acfg thod;
, method, patch_info)) { if (cmethod->wrapper_type == MONO_WRAPPER
MonoCompile *callee_cfg = (MonoCo _OTHER && mono_marshal_get_wrapper_info (cmethod)->subtype == WRAPPER_SUBTYPE_AO
mpile *)g_hash_table_lookup (acfg->method_to_cfg, patch_info->data.method); T_INIT) {
WrapperInfo *info = mono_marshal_
get_wrapper_info (cmethod);
/*
* This is a call from a JITted m
ethod to the init wrapper emitted by LLVM.
*/
g_assert (acfg->aot_opts.llvm &&
acfg->aot_opts.direct_extern_calls);
const char *init_name = mono_mars
hal_get_aot_init_wrapper_name (info->d.aot_init.subtype);
char *symbol = g_strdup_printf ("
%s%s_%s", acfg->user_symbol_prefix, acfg->global_prefix, init_name);
direct_call = TRUE;
direct_call_target = symbol;
patch_info->type = MONO_PATCH_INF
O_NONE;
} else if ((m_class_get_image (patch_info
->data.method->klass) == acfg->image) && !got_only && is_direct_callable (acfg,
method, patch_info)) {
MonoCompile *callee_cfg = (MonoCo
mpile *)g_hash_table_lookup (acfg->method_to_cfg, cmethod);
// Don't compile inflated methods if we're doing dedup // Don't compile inflated methods if we're doing dedup
if (acfg->aot_opts.dedup && !mono if (acfg->aot_opts.dedup && !mono
_aot_can_dedup (patch_info->data.method)) { _aot_can_dedup (cmethod)) {
char *name = mono_aot_get char *name = mono_aot_get
_mangled_method_name (patch_info->data.method); _mangled_method_name (cmethod);
mono_trace (G_LOG_LEVEL_D EBUG, MONO_TRACE_AOT, "DIRECT CALL: %s by %s", name, method ? mono_method_full_n ame (method, TRUE) : ""); mono_trace (G_LOG_LEVEL_D EBUG, MONO_TRACE_AOT, "DIRECT CALL: %s by %s", name, method ? mono_method_full_n ame (method, TRUE) : "");
g_free (name); g_free (name);
direct_call = TRUE; direct_call = TRUE;
direct_call_target = call ee_cfg->asm_symbol; direct_call_target = call ee_cfg->asm_symbol;
patch_info->type = MONO_P ATCH_INFO_NONE; patch_info->type = MONO_P ATCH_INFO_NONE;
acfg->stats.direct_calls ++; acfg->stats.direct_calls ++;
} }
} }
skipping to change at line 7475 skipping to change at line 7543
static G_GNUC_UNUSED void static G_GNUC_UNUSED void
emit_trampoline (MonoAotCompile *acfg, MonoTrampInfo *info) emit_trampoline (MonoAotCompile *acfg, MonoTrampInfo *info)
{ {
emit_trampoline_full (acfg, info, TRUE); emit_trampoline_full (acfg, info, TRUE);
} }
static void static void
emit_trampolines (MonoAotCompile *acfg) emit_trampolines (MonoAotCompile *acfg)
{ {
char symbol [MAX_SYMBOL_SIZE]; char symbol [MAX_SYMBOL_SIZE];
char end_symbol [MAX_SYMBOL_SIZE]; char end_symbol [MAX_SYMBOL_SIZE + 2];
int i, tramp_got_offset; int i, tramp_got_offset;
int ntype; int ntype;
#ifdef MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES #ifdef MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES
int tramp_type; int tramp_type;
#endif #endif
if (!mono_aot_mode_is_full (&acfg->aot_opts) && !mono_aot_mode_is_interp (&acfg->aot_opts)) if (!mono_aot_mode_is_full (&acfg->aot_opts) && !mono_aot_mode_is_interp (&acfg->aot_opts))
return; return;
if (acfg->aot_opts.llvm_only) if (acfg->aot_opts.llvm_only)
return; return;
skipping to change at line 8098 skipping to change at line 8166
} else if (str_begins_with (arg, "gen-seq-points-file")) { } else if (str_begins_with (arg, "gen-seq-points-file")) {
fprintf (stderr, "Mono Warning: aot option gen-seq-points -file is deprecated.\n"); fprintf (stderr, "Mono Warning: aot option gen-seq-points -file is deprecated.\n");
} else if (str_begins_with (arg, "msym-dir=")) { } else if (str_begins_with (arg, "msym-dir=")) {
mini_debug_options.no_seq_points_compact_data = FALSE; mini_debug_options.no_seq_points_compact_data = FALSE;
opts->gen_msym_dir = TRUE; opts->gen_msym_dir = TRUE;
opts->gen_msym_dir_path = g_strdup (arg + strlen ("msym_d ir=")); opts->gen_msym_dir_path = g_strdup (arg + strlen ("msym_d ir="));
} else if (str_begins_with (arg, "direct-pinvoke")) { } else if (str_begins_with (arg, "direct-pinvoke")) {
opts->direct_pinvoke = TRUE; opts->direct_pinvoke = TRUE;
} else if (str_begins_with (arg, "direct-icalls")) { } else if (str_begins_with (arg, "direct-icalls")) {
opts->direct_icalls = TRUE; opts->direct_icalls = TRUE;
} else if (str_begins_with (arg, "direct-extern-calls")) {
opts->direct_extern_calls = TRUE;
} else if (str_begins_with (arg, "no-direct-calls")) { } else if (str_begins_with (arg, "no-direct-calls")) {
opts->no_direct_calls = TRUE; opts->no_direct_calls = TRUE;
} else if (str_begins_with (arg, "print-skipped")) { } else if (str_begins_with (arg, "print-skipped")) {
opts->print_skipped_methods = TRUE; opts->print_skipped_methods = TRUE;
} else if (str_begins_with (arg, "stats")) { } else if (str_begins_with (arg, "stats")) {
opts->stats = TRUE; opts->stats = TRUE;
// Intentionally undocumented-- has no known function other than to debug the compiler // Intentionally undocumented-- has no known function other than to debug the compiler
} else if (str_begins_with (arg, "no-instances")) { } else if (str_begins_with (arg, "no-instances")) {
opts->no_instances = TRUE; opts->no_instances = TRUE;
// Intentionally undocumented x4-- Used for internal debugging of compiler // Intentionally undocumented x4-- Used for internal debugging of compiler
skipping to change at line 8616 skipping to change at line 8686
if (acfg->aot_opts.llvm_only) if (acfg->aot_opts.llvm_only)
flags = (JitFlags)(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) if (acfg->aot_opts.no_direct_calls)
flags = (JitFlags)(flags | JIT_FLAG_NO_DIRECT_ICALLS); flags = (JitFlags)(flags | JIT_FLAG_NO_DIRECT_ICALLS);
if (acfg->aot_opts.direct_pinvoke) if (acfg->aot_opts.direct_pinvoke)
flags = (JitFlags)(flags | JIT_FLAG_DIRECT_PINVOKE); flags = (JitFlags)(flags | JIT_FLAG_DIRECT_PINVOKE);
if (acfg->aot_opts.interp) if (acfg->aot_opts.interp)
flags = (JitFlags)(flags | JIT_FLAG_INTERP); flags = (JitFlags)(flags | JIT_FLAG_INTERP);
if (acfg->aot_opts.use_current_cpu) if (acfg->aot_opts.use_current_cpu)
flags = (JitFlags)(flags | JIT_FLAG_USE_CURRENT_CPU); flags = (JitFlags)(flags | JIT_FLAG_USE_CURRENT_CPU);
if (method_is_externally_callable (acfg, method))
flags = (JitFlags)(flags | JIT_FLAG_SELF_INIT);
jit_time_start = mono_time_track_start (); jit_time_start = mono_time_track_start ();
cfg = mini_method_compile (method, acfg->opts, mono_get_root_domain (), f lags, 0, index); cfg = mini_method_compile (method, acfg->opts, mono_get_root_domain (), f lags, 0, index);
mono_time_track_end (&mono_jit_stats.jit_time, jit_time_start); mono_time_track_end (&mono_jit_stats.jit_time, jit_time_start);
if (cfg->exception_type == MONO_EXCEPTION_GENERIC_SHARING_FAILED) { if (cfg->exception_type == MONO_EXCEPTION_GENERIC_SHARING_FAILED) {
if (acfg->aot_opts.print_skipped_methods) if (acfg->aot_opts.print_skipped_methods)
printf ("Skip (gshared failure): %s (%s)\n", mono_method_ get_full_name (method), cfg->exception_message); printf ("Skip (gshared failure): %s (%s)\n", mono_method_ get_full_name (method), cfg->exception_message);
mono_atomic_inc_i32 (&acfg->stats.genericcount); mono_atomic_inc_i32 (&acfg->stats.genericcount);
return; return;
skipping to change at line 8846 skipping to change at line 8918
} }
} else if (mono_aot_mode_is_full (&acfg->aot_opts) && mono_aot_mode_is_in terp (&acfg->aot_opts)) { } else if (mono_aot_mode_is_full (&acfg->aot_opts) && mono_aot_mode_is_in terp (&acfg->aot_opts)) {
/* The interpreter uses these wrappers to call aot-ed code */ /* The interpreter uses these wrappers to call aot-ed code */
if (!cfg->method->wrapper_type || cfg->method->wrapper_type == MO NO_WRAPPER_DELEGATE_INVOKE) if (!cfg->method->wrapper_type || cfg->method->wrapper_type == MO NO_WRAPPER_DELEGATE_INVOKE)
add_gsharedvt_wrappers (acfg, mono_method_signature_inter nal (cfg->method), FALSE, TRUE, TRUE); add_gsharedvt_wrappers (acfg, mono_method_signature_inter nal (cfg->method), FALSE, TRUE, TRUE);
} }
if (cfg->llvm_only) if (cfg->llvm_only)
acfg->stats.llvm_count ++; acfg->stats.llvm_count ++;
if (acfg->llvm && !cfg->compile_llvm && method_is_externally_callable (ac
fg, cfg->method)) {
/*
* This is a JITted fallback method for a method which failed LLV
M compilation, emit a global
* symbol for it with the same name the LLVM method would get.
*/
char *name = mono_aot_get_mangled_method_name (cfg->method);
char *export_name = g_strdup_printf ("%s%s", acfg->user_symbol_pr
efix, name);
g_hash_table_insert (acfg->export_names, cfg->method, export_name
);
}
/* /*
* FIXME: Instead of this mess, allocate the patches from the aot mempool . * FIXME: Instead of this mess, allocate the patches from the aot mempool .
*/ */
/* Make a copy of the patch info which is in the mempool */ /* Make a copy of the patch info which is in the mempool */
{ {
MonoJumpInfo *patches = NULL, *patches_end = NULL; MonoJumpInfo *patches = NULL, *patches_end = NULL;
for (patch_info = cfg->patch_info; patch_info; patch_info = patch _info->next) { for (patch_info = cfg->patch_info; patch_info; patch_info = patch _info->next) {
MonoJumpInfo *new_patch_info = mono_patch_info_dup_mp (ac fg->mempool, patch_info); MonoJumpInfo *new_patch_info = mono_patch_info_dup_mp (ac fg->mempool, patch_info);
skipping to change at line 8971 skipping to change at line 9053
* *
* Return whenever OFFSET refers to a GOT slot which is preinitialized * Return whenever OFFSET refers to a GOT slot which is preinitialized
* when the AOT image is loaded. * when the AOT image is loaded.
*/ */
gboolean gboolean
mono_aot_is_shared_got_offset (int offset) mono_aot_is_shared_got_offset (int offset)
{ {
return offset < llvm_acfg->nshared_got_entries; return offset < llvm_acfg->nshared_got_entries;
} }
gboolean
mono_aot_is_externally_callable (MonoMethod *cmethod)
{
return method_is_externally_callable (llvm_acfg, cmethod);
}
char* char*
mono_aot_get_method_name (MonoCompile *cfg) mono_aot_get_method_name (MonoCompile *cfg)
{ {
MonoMethod *method = cfg->orig_method; MonoMethod *method = cfg->orig_method;
/* Use the mangled name if possible */ /* Use the mangled name if possible */
if (method->wrapper_type == MONO_WRAPPER_OTHER) { if (method->wrapper_type == MONO_WRAPPER_OTHER) {
WrapperInfo *info = mono_marshal_get_wrapper_info (method); WrapperInfo *info = mono_marshal_get_wrapper_info (method);
if (info->subtype == WRAPPER_SUBTYPE_GSHAREDVT_IN_SIG || info->su btype == WRAPPER_SUBTYPE_GSHAREDVT_OUT_SIG) if (info->subtype == WRAPPER_SUBTYPE_GSHAREDVT_IN_SIG || info->su btype == WRAPPER_SUBTYPE_GSHAREDVT_OUT_SIG)
return mono_aot_get_mangled_method_name (method); return mono_aot_get_mangled_method_name (method);
skipping to change at line 9337 skipping to change at line 9425
break; break;
case ')': case ')':
g_string_append (s, "_rparen_"); g_string_append (s, "_rparen_");
break; break;
case ',': case ',':
g_string_append (s, "_comma_"); g_string_append (s, "_comma_");
break; break;
case ':': case ':':
g_string_append (s, "_colon_"); g_string_append (s, "_colon_");
break; break;
case '|':
g_string_append (s, "_verbar_");
break;
default: default:
g_string_append_c (s, c); g_string_append_c (s, c);
} }
} }
return g_string_free (s, FALSE); return g_string_free (s, FALSE);
} }
static gboolean static gboolean
append_mangled_klass (GString *s, MonoClass *klass) append_mangled_klass (GString *s, MonoClass *klass)
skipping to change at line 9813 skipping to change at line 9904
* // we know that the store is safe. * // we know that the store is safe.
* if (AA.getDataLayout() == 0 && * if (AA.getDataLayout() == 0 &&
* Later.Ptr->getType() == Earlier.Ptr->getType()) { * Later.Ptr->getType() == Earlier.Ptr->getType()) {
* return OverwriteComplete; * return OverwriteComplete;
* Here, if 'Earlier' refers to a memset, and Later has no size info, it mistakenly thinks the memset is redundant. * Here, if 'Earlier' refers to a memset, and Later has no size info, it mistakenly thinks the memset is redundant.
*/ */
if (acfg->aot_opts.llvm_only) { if (acfg->aot_opts.llvm_only) {
// FIXME: This doesn't work yet // FIXME: This doesn't work yet
opts = g_strdup (""); opts = g_strdup ("");
} else { } else {
opts = g_strdup ("-O2 -disable-tail-calls -place-safepoints -spp- all-backedges"); opts = g_strdup ("-disable-tail-calls -place-safepoints -spp-all- backedges");
} }
if (acfg->aot_opts.llvm_opts) { if (acfg->aot_opts.llvm_opts) {
opts = g_strdup_printf ("%s %s", opts, acfg->aot_opts.llvm_opts); opts = g_strdup_printf ("%s %s", acfg->aot_opts.llvm_opts, opts);
} else if (!acfg->aot_opts.llvm_only) {
opts = g_strdup_printf ("-O2 %s", opts);
} }
if (acfg->aot_opts.use_current_cpu) { if (acfg->aot_opts.use_current_cpu) {
opts = g_strdup_printf ("%s -mcpu=native", opts); opts = g_strdup_printf ("%s -mcpu=native", opts);
} }
if (acfg->aot_opts.llvm_cpu_attr) { if (acfg->aot_opts.llvm_cpu_attr) {
opts = g_strdup_printf ("%s -mattr=%s", opts, acfg->aot_opts.llvm _cpu_attr); opts = g_strdup_printf ("%s -mattr=%s", opts, acfg->aot_opts.llvm _cpu_attr);
} }
skipping to change at line 10380 skipping to change at line 10473
* mono_aot_get_array_helper_from_wrapper; * mono_aot_get_array_helper_from_wrapper;
* *
* Get the helper method in Array called by an array wrapper method. * Get the helper method in Array called by an array wrapper method.
*/ */
MonoMethod* MonoMethod*
mono_aot_get_array_helper_from_wrapper (MonoMethod *method) mono_aot_get_array_helper_from_wrapper (MonoMethod *method)
{ {
MonoMethod *m; MonoMethod *m;
const char *prefix; const char *prefix;
MonoGenericContext ctx; MonoGenericContext ctx;
MonoType *args [16];
char *mname, *iname, *s, *s2, *helper_name = NULL; char *mname, *iname, *s, *s2, *helper_name = NULL;
prefix = "System.Collections.Generic"; prefix = "System.Collections.Generic";
s = g_strdup_printf ("%s", method->name + strlen (prefix) + 1); s = g_strdup_printf ("%s", method->name + strlen (prefix) + 1);
s2 = strstr (s, "`1."); s2 = strstr (s, "`1.");
g_assert (s2); g_assert (s2);
s2 [0] = '\0'; s2 [0] = '\0';
iname = s; iname = s;
mname = s2 + 3; mname = s2 + 3;
skipping to change at line 10405 skipping to change at line 10497
else else
helper_name = g_strdup_printf ("InternalArray__%s_%s", iname, mna me); helper_name = g_strdup_printf ("InternalArray__%s_%s", iname, mna me);
m = get_method_nofail (mono_defaults.array_class, helper_name, mono_metho d_signature_internal (method)->param_count, 0); m = get_method_nofail (mono_defaults.array_class, helper_name, mono_metho d_signature_internal (method)->param_count, 0);
g_assert (m); g_assert (m);
g_free (helper_name); g_free (helper_name);
g_free (s); g_free (s);
if (m->is_generic) { if (m->is_generic) {
ERROR_DECL (error); ERROR_DECL (error);
memset (&ctx, 0, sizeof (ctx)); memset (&ctx, 0, sizeof (ctx));
args [0] = m_class_get_byval_arg (m_class_get_element_class (meth od->klass)); MonoType *args [ ] = { m_class_get_byval_arg (m_class_get_element _class (method->klass)) };
ctx.method_inst = mono_metadata_get_generic_inst (1, args); ctx.method_inst = mono_metadata_get_generic_inst (1, args);
m = mono_class_inflate_generic_method_checked (m, &ctx, error); m = mono_class_inflate_generic_method_checked (m, &ctx, error);
g_assert (is_ok (error)); /* FIXME don't swallow the error */ g_assert (is_ok (error)); /* FIXME don't swallow the error */
} }
return m; return m;
} }
#if !defined(DISABLE_AOT) && !defined(DISABLE_JIT) #if !defined(DISABLE_AOT) && !defined(DISABLE_JIT)
skipping to change at line 12192 skipping to change at line 12284
g_strdelimit (ld_flags, ';', ' '); g_strdelimit (ld_flags, ';', ' ');
if (acfg->aot_opts.llvm_only) if (acfg->aot_opts.llvm_only)
ld_flags = g_strdup_printf ("%s %s", ld_flags, "-lstdc++"); ld_flags = g_strdup_printf ("%s %s", ld_flags, "-lstdc++");
#ifdef TARGET_WIN32_MSVC #ifdef TARGET_WIN32_MSVC
g_assert (tmp_outfile_name != NULL); g_assert (tmp_outfile_name != NULL);
g_assert (objfile != NULL); g_assert (objfile != NULL);
command = g_strdup_printf ("\"%s%s\" %s %s /OUT:%s %s %s", tool_prefix, L D_NAME, command = g_strdup_printf ("\"%s%s\" %s %s /OUT:%s %s %s", tool_prefix, L D_NAME,
acfg->aot_opts.nodebug ? LD_OPTIONS : LD_DEBUG_OPTIONS, l d_flags, wrap_path (tmp_outfile_name), wrap_path (objfile), wrap_path (llvm_ofil e)); acfg->aot_opts.nodebug ? LD_OPTIONS : LD_DEBUG_OPTIONS, l d_flags, wrap_path (tmp_outfile_name), wrap_path (objfile), wrap_path (llvm_ofil e));
#elif defined(LD_NAME) #else
command = g_strdup_printf ("%s%s %s -o %s %s %s %s", tool_prefix, LD_NAME GString *str;
, LD_OPTIONS,
wrap_path (tmp_outfile_name), wrap_path (llvm_ofile), str = g_string_new ("");
wrap_path (g_strdup_printf ("%s." AS_OBJECT_FILE_SUFFIX, acfg->tm #if defined(LD_NAME)
pfname)), ld_flags); g_string_append_printf (str, "%s%s %s", tool_prefix, LD_NAME, LD_OPTIONS)
;
#else #else
// Default (linux) // Default (linux)
if (acfg->aot_opts.tool_prefix) { if (acfg->aot_opts.tool_prefix)
/* Cross compiling */ /* Cross compiling */
command = g_strdup_printf ("\"%sld\" %s -shared -o %s %s %s %s", g_string_append_printf (str, "\"%sld\" %s", tool_prefix, LD_OPTIO
tool_prefix, LD_OPTIONS, NS);
wrap_path (tmp else if (acfg->aot_opts.llvm_only)
_outfile_name), wrap_path (llvm_ofile), g_string_append_printf (str, "%s", acfg->aot_opts.clangxx);
wrap_path (g_s else
trdup_printf ("%s." AS_OBJECT_FILE_SUFFIX, acfg->tmpfname)), ld_flags); g_string_append_printf (str, "\"%sld\"", tool_prefix);
} else { g_string_append_printf (str, " -shared");
char *args = g_strdup_printf ("%s -shared -o %s %s %s %s", LD_OPT #endif
IONS, g_string_append_printf (str, " -o %s %s %s %s",
wrap_pa wrap_path (tmp_outfile_na
th (tmp_outfile_name), wrap_path (llvm_ofile), me), wrap_path (llvm_ofile),
wrap_pa wrap_path (g_strdup_print
th (g_strdup_printf ("%s." AS_OBJECT_FILE_SUFFIX, acfg->tmpfname)), ld_flags); f ("%s." AS_OBJECT_FILE_SUFFIX, acfg->tmpfname)), ld_flags);
if (acfg->aot_opts.llvm_only) { #if defined(TARGET_MACH)
command = g_strdup_printf ("%s %s", acfg->aot_opts.clangx g_string_append_printf (str, " -Wl,-install_name,%s%s", g_path_get_basena
x, args); me (acfg->image->name), MONO_SOLIB_EXT);
} else { #endif
command = g_strdup_printf ("\"%sld\" %s", tool_prefix, ar
gs); command = g_string_free (str, FALSE);
}
g_free (args);
}
#endif #endif
aot_printf (acfg, "Executing the native linker: %s\n", command); aot_printf (acfg, "Executing the native linker: %s\n", command);
if (execute_system (command) != 0) { if (execute_system (command) != 0) {
g_free (tmp_outfile_name); g_free (tmp_outfile_name);
g_free (outfile_name); g_free (outfile_name);
g_free (command); g_free (command);
g_free (objfile); g_free (objfile);
g_free (ld_flags); g_free (ld_flags);
return 1; return 1;
} }
skipping to change at line 13032 skipping to change at line 13127
static void static void
add_preinit_got_slots (MonoAotCompile *acfg) add_preinit_got_slots (MonoAotCompile *acfg)
{ {
MonoJumpInfo *ji; MonoJumpInfo *ji;
int i; int i;
/* /*
* Allocate the first few GOT entries to information which is needed freq uently, or it is needed * Allocate the first few GOT entries to information which is needed freq uently, or it is needed
* during method initialization etc. * during method initialization etc.
*/ */
ji = (MonoJumpInfo *)mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJump Info)); ji = (MonoJumpInfo *)mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJump Info));
ji->type = MONO_PATCH_INFO_IMAGE; ji->type = MONO_PATCH_INFO_IMAGE;
ji->data.image = acfg->image; ji->data.image = acfg->image;
add_preinit_slot (acfg, ji); add_preinit_slot (acfg, ji);
ji = (MonoJumpInfo *)mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJump Info)); ji = (MonoJumpInfo *)mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJump Info));
ji->type = MONO_PATCH_INFO_MSCORLIB_GOT_ADDR; ji->type = MONO_PATCH_INFO_MSCORLIB_GOT_ADDR;
add_preinit_slot (acfg, ji); add_preinit_slot (acfg, ji);
ji = (MonoJumpInfo *)mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJump Info)); ji = (MonoJumpInfo *)mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJump Info));
skipping to change at line 13149 skipping to change at line 13243
if (method->wrapper_type != MONO_WRAPPER_NONE) { if (method->wrapper_type != MONO_WRAPPER_NONE) {
wrappers_saved ++; wrappers_saved ++;
wrappers_size_saved += dcfg->code_len * count; wrappers_size_saved += dcfg->code_len * count;
} else { } else {
instances_saved ++; instances_saved ++;
inflated_size_saved += dcfg->code_len * count; inflated_size_saved += dcfg->code_len * count;
} }
} }
} }
aot_printf (acfg, "Dedup Pass: Size Saved From Deduped Wrappers:\t%d meth aot_printf (acfg, "Dedup Pass: Size Saved From Deduped Wrappers:\t%d meth
ods, %zu bytes\n", wrappers_saved, wrappers_size_saved); ods, %" G_GSIZE_FORMAT "u bytes\n", wrappers_saved, wrappers_size_saved);
aot_printf (acfg, "Dedup Pass: Size Saved From Inflated Methods:\t%d meth aot_printf (acfg, "Dedup Pass: Size Saved From Inflated Methods:\t%d meth
ods, %zu bytes\n", instances_saved, inflated_size_saved); ods, %" G_GSIZE_FORMAT "u bytes\n", instances_saved, inflated_size_saved);
if (acfg->dedup_emit_mode) if (acfg->dedup_emit_mode)
aot_printf (acfg, "Dedup Pass: Size of Moved But Not Deduped (onl y 1 copy) Methods:\t%d methods, %zu bytes\n", copied, copied_singles); aot_printf (acfg, "Dedup Pass: Size of Moved But Not Deduped (onl y 1 copy) Methods:\t%d methods, %" G_GSIZE_FORMAT "u bytes\n", copied, copied_si ngles);
g_hash_table_destroy (acfg->dedup_stats); g_hash_table_destroy (acfg->dedup_stats);
acfg->dedup_stats = NULL; acfg->dedup_stats = NULL;
} }
// Flush the cache to tell future calls what to skip // Flush the cache to tell future calls what to skip
static void static void
mono_flush_method_cache (MonoAotCompile *acfg) mono_flush_method_cache (MonoAotCompile *acfg)
{ {
GHashTable *method_cache = acfg->dedup_cache; GHashTable *method_cache = acfg->dedup_cache;
skipping to change at line 13477 skipping to change at line 13571
if (!acfg->aot_opts.llvm_path) if (!acfg->aot_opts.llvm_path)
acfg->aot_opts.llvm_path = g_strdup (""); acfg->aot_opts.llvm_path = g_strdup ("");
acfg->aot_opts.temp_path = g_strdup (""); acfg->aot_opts.temp_path = g_strdup ("");
#ifdef MONOTOUCH #ifdef MONOTOUCH
acfg->aot_opts.use_trampolines_page = TRUE; acfg->aot_opts.use_trampolines_page = TRUE;
#endif #endif
acfg->aot_opts.clangxx = g_strdup ("clang++"); acfg->aot_opts.clangxx = g_strdup ("clang++");
mono_aot_parse_options (aot_options, &acfg->aot_opts); mono_aot_parse_options (aot_options, &acfg->aot_opts);
if (acfg->aot_opts.direct_extern_calls && !(acfg->aot_opts.llvm && acfg->
aot_opts.static_link)) {
aot_printerrf (acfg, "The 'direct-extern-calls' option requires t
he 'llvm' and 'static' options.\n");
return 1;
}
// start dedup // start dedup
MonoAotState *astate = NULL; MonoAotState *astate = NULL;
gboolean is_dedup_dummy = FALSE; gboolean is_dedup_dummy = FALSE;
mono_setup_dedup_state (acfg, (MonoAotState **) global_aot_state, ass, &a state, &is_dedup_dummy); mono_setup_dedup_state (acfg, (MonoAotState **) global_aot_state, ass, &a state, &is_dedup_dummy);
// Process later // Process later
if (is_dedup_dummy && astate && !astate->emit_inflated_methods) if (is_dedup_dummy && astate && !astate->emit_inflated_methods)
return 0; return 0;
if (acfg->aot_opts.dedup_include && !is_dedup_dummy) if (acfg->aot_opts.dedup_include && !is_dedup_dummy)
skipping to change at line 14136 skipping to change at line 14235
{ {
return 0; return 0;
} }
gboolean gboolean
mono_aot_is_shared_got_offset (int offset) mono_aot_is_shared_got_offset (int offset)
{ {
return FALSE; return FALSE;
} }
gboolean
mono_aot_is_externally_callable (MonoMethod *cmethod)
{
return FALSE;
}
int int
mono_compile_deferred_assemblies (guint32 opts, const char *aot_options, gpointe r **aot_state) mono_compile_deferred_assemblies (guint32 opts, const char *aot_options, gpointe r **aot_state)
{ {
g_assert_not_reached (); g_assert_not_reached ();
return 0; return 0;
} }
gboolean gboolean
mono_aot_direct_icalls_enabled_for_method (MonoCompile *cfg, MonoMethod *method) mono_aot_direct_icalls_enabled_for_method (MonoCompile *cfg, MonoMethod *method)
{ {
g_assert_not_reached (); g_assert_not_reached ();
return 0; return 0;
} }
gboolean gboolean
mono_aot_can_enter_interp (MonoMethod *method) mono_aot_can_enter_interp (MonoMethod *method)
{ {
return FALSE; return FALSE;
} }
int
mono_aot_get_method_index (MonoMethod *method)
{
g_assert_not_reached ();
return 0;
}
#endif #endif
 End of changes. 44 change blocks. 
68 lines changed or deleted 196 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)