static char*
get_plt_entry_debug_sym (MonoAotCompile *acfg, MonoJumpInfo *ji, GHashTable *cache);
+static void
+add_gsharedvt_wrappers (MonoAotCompile *acfg, MonoMethodSignature *sig, gboolean gsharedvt_in, gboolean gsharedvt_out);
+
static void
aot_printf (MonoAotCompile *acfg, const gchar *format, ...)
{
#elif defined(TARGET_POWERPC)
{
guint8 buf [32];
- guint8 *code;
emit_bytes (acfg, code, mono_arch_get_patch_offset (code));
code = buf;
for (i = 0; i < klass->field.count; ++i) {
if (field == &klass->fields [i])
- return MONO_TOKEN_FIELD_DEF | (klass->field.first + 1 + i);
+ return MONO_TOKEN_FIELD_DEF | (mono_class_get_first_field_idx (klass) + 1 + i);
}
g_assert_not_reached ();
* information.
*/
- if (klass->generic_class) {
+ if (mono_class_is_ginst (klass)) {
guint32 token;
g_assert (klass->type_token);
encode_value (MONO_AOT_TYPEREF_TYPESPEC_TOKEN, p, &p);
encode_value (token, p, &p);
} else {
- MonoClass *gclass = klass->generic_class->container_class;
- MonoGenericInst *inst = klass->generic_class->context.class_inst;
+ MonoClass *gclass = mono_class_get_generic_class (klass)->container_class;
+ MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
static int count = 0;
guint8 *p1 = p;
/*
* The encoding of generic instances is large so emit them only once.
*/
- if (klass->generic_class) {
+ if (mono_class_is_ginst (klass)) {
guint32 token;
g_assert (klass->type_token);
MonoMarshalType *info;
int i;
- if ((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT)
+ if (mono_class_is_auto_layout (klass))
return FALSE;
info = mono_marshal_load_type_info (klass);
memset (ctx, 0, sizeof (MonoGenericContext));
- if (method->klass->generic_container) {
- shared_context = method->klass->generic_container->context;
+ if (mono_class_is_gtd (method->klass)) {
+ shared_context = mono_class_get_generic_container (method->klass)->context;
inst = shared_context.class_inst;
args = g_new0 (MonoType*, inst->type_argc);
if (!klass->delegate || klass == mono_defaults.delegate_class || klass == mono_defaults.multicastdelegate_class)
continue;
- if (!klass->generic_container) {
+ if (!mono_class_is_gtd (klass)) {
method = mono_get_delegate_invoke (klass);
m = mono_marshal_get_delegate_invoke (method, NULL);
add_method (acfg, del_invoke);
}
}
- } else if ((acfg->opts & MONO_OPT_GSHAREDVT) && klass->generic_container) {
+ } else if ((acfg->opts & MONO_OPT_GSHAREDVT) && mono_class_is_gtd (klass)) {
MonoError error;
MonoGenericContext ctx;
MonoMethod *inst, *gshared;
if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED) {
if (method->is_generic) {
// FIXME:
- } else if ((acfg->opts & MONO_OPT_GSHAREDVT) && method->klass->generic_container) {
+ } else if ((acfg->opts & MONO_OPT_GSHAREDVT) && mono_class_is_gtd (method->klass)) {
MonoError error;
MonoGenericContext ctx;
MonoMethod *inst, *gshared, *m;
(method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)) {
add_method (acfg, mono_marshal_get_native_wrapper (method, TRUE, TRUE));
}
+
+ if (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
+ if (acfg->aot_opts.llvm_only) {
+ /* The wrappers have a different signature (hasthis is not set) so need to add this too */
+ add_gsharedvt_wrappers (acfg, mono_method_signature (method), FALSE, TRUE);
+ }
+ }
}
/* native-to-managed wrappers */
continue;
}
- if (klass->valuetype && !klass->generic_container && can_marshal_struct (klass) &&
+ if (klass->valuetype && !mono_class_is_gtd (klass) && can_marshal_struct (klass) &&
!(klass->nested_in && strstr (klass->nested_in->name, "<PrivateImplementationDetails>") == klass->nested_in->name)) {
add_method (acfg, mono_marshal_get_struct_to_ptr (klass));
add_method (acfg, mono_marshal_get_ptr_to_struct (klass));
return TRUE;
if (klass->rank)
return has_type_vars (klass->element_class);
- if (klass->generic_class) {
- MonoGenericContext *context = &klass->generic_class->context;
+ if (mono_class_is_ginst (klass)) {
+ MonoGenericContext *context = &mono_class_get_generic_class (klass)->context;
if (context->class_inst) {
int i;
return TRUE;
}
}
- if (klass->generic_container)
+ if (mono_class_is_gtd (klass))
return TRUE;
return FALSE;
}
mono_class_init (klass);
- if (klass->generic_class && klass->generic_class->context.class_inst->is_open)
+ if (mono_class_is_ginst (klass) && mono_class_get_generic_class (klass)->context.class_inst->is_open)
return;
if (has_type_vars (klass))
return;
- if (!klass->generic_class && !klass->rank)
+ if (!mono_class_is_ginst (klass) && !klass->rank)
return;
if (mono_class_has_failure (klass))
* Use gsharedvt for generic collections with vtype arguments to avoid code blowup.
* Enable this only for some classes since gsharedvt might not support all methods.
*/
- if ((acfg->opts & MONO_OPT_GSHAREDVT) && klass->image == mono_defaults.corlib && klass->generic_class && klass->generic_class->context.class_inst && is_vt_inst (klass->generic_class->context.class_inst) &&
+ if ((acfg->opts & MONO_OPT_GSHAREDVT) && klass->image == mono_defaults.corlib && mono_class_is_ginst (klass) && mono_class_get_generic_class (klass)->context.class_inst && is_vt_inst (mono_class_get_generic_class (klass)->context.class_inst) &&
(!strcmp (klass->name, "Dictionary`2") || !strcmp (klass->name, "List`1") || !strcmp (klass->name, "ReadOnlyCollection`1")))
use_gsharedvt = TRUE;
*/
if (klass->image == mono_defaults.corlib && !strcmp (klass->name_space, "System.Collections.Generic") &&
(!strcmp(klass->name, "ICollection`1") || !strcmp (klass->name, "IEnumerable`1") || !strcmp (klass->name, "IList`1") || !strcmp (klass->name, "IEnumerator`1") || !strcmp (klass->name, "IReadOnlyList`1"))) {
- MonoClass *tclass = mono_class_from_mono_type (klass->generic_class->context.class_inst->type_argv [0]);
+ MonoClass *tclass = mono_class_from_mono_type (mono_class_get_generic_class (klass)->context.class_inst->type_argv [0]);
MonoClass *array_class = mono_bounded_array_class_get (tclass, 1, FALSE);
gpointer iter;
char *name_prefix;
break;
}
g_assert (nclass);
- nclass = mono_class_inflate_generic_class_checked (nclass, mono_generic_class_get_context (klass->generic_class), &error);
+ nclass = mono_class_inflate_generic_class_checked (nclass, mono_generic_class_get_context (mono_class_get_generic_class (klass)), &error);
mono_error_assert_ok (&error); /* FIXME don't swallow the error */
add_generic_class (acfg, nclass, FALSE, "ICollection<T>");
}
/* Add an instance of GenericComparer<T> which is created dynamically by Comparer<T> */
if (klass->image == mono_defaults.corlib && !strcmp (klass->name_space, "System.Collections.Generic") && !strcmp (klass->name, "Comparer`1")) {
MonoError error;
- MonoClass *tclass = mono_class_from_mono_type (klass->generic_class->context.class_inst->type_argv [0]);
+ MonoClass *tclass = mono_class_from_mono_type (mono_class_get_generic_class (klass)->context.class_inst->type_argv [0]);
MonoClass *icomparable, *gcomparer, *icomparable_inst;
MonoGenericContext ctx;
MonoType *args [16];
/* Add an instance of GenericEqualityComparer<T> which is created dynamically by EqualityComparer<T> */
if (klass->image == mono_defaults.corlib && !strcmp (klass->name_space, "System.Collections.Generic") && !strcmp (klass->name, "EqualityComparer`1")) {
MonoError error;
- MonoClass *tclass = mono_class_from_mono_type (klass->generic_class->context.class_inst->type_argv [0]);
+ MonoClass *tclass = mono_class_from_mono_type (mono_class_get_generic_class (klass)->context.class_inst->type_argv [0]);
MonoClass *iface, *gcomparer, *iface_inst;
MonoGenericContext ctx;
MonoType *args [16];
/* Add an instance of EnumComparer<T> which is created dynamically by EqualityComparer<T> for enums */
if (klass->image == mono_defaults.corlib && !strcmp (klass->name_space, "System.Collections.Generic") && !strcmp (klass->name, "EqualityComparer`1")) {
MonoClass *enum_comparer;
- MonoClass *tclass = mono_class_from_mono_type (klass->generic_class->context.class_inst->type_argv [0]);
+ MonoClass *tclass = mono_class_from_mono_type (mono_class_get_generic_class (klass)->context.class_inst->type_argv [0]);
MonoGenericContext ctx;
MonoType *args [16];
/* Add an instance of ObjectComparer<T> which is created dynamically by Comparer<T> for enums */
if (klass->image == mono_defaults.corlib && !strcmp (klass->name_space, "System.Collections.Generic") && !strcmp (klass->name, "Comparer`1")) {
MonoClass *comparer;
- MonoClass *tclass = mono_class_from_mono_type (klass->generic_class->context.class_inst->type_argv [0]);
+ MonoClass *tclass = mono_class_from_mono_type (mono_class_get_generic_class (klass)->context.class_inst->type_argv [0]);
MonoGenericContext ctx;
MonoType *args [16];
g_free (type_argv);
}
- if (method->is_generic || method->klass->generic_container)
+ if (method->is_generic || mono_class_is_gtd (method->klass))
declaring_method = method;
else
declaring_method = mono_method_get_declaring_generic_method (method);
if (callee_cfg) {
gboolean direct_callable = TRUE;
- if (direct_callable && !(!callee_cfg->has_got_slots && (callee_cfg->method->klass->flags & TYPE_ATTRIBUTE_BEFORE_FIELD_INIT)))
+ if (direct_callable && !(!callee_cfg->has_got_slots && mono_class_is_before_field_init (callee_cfg->method->klass)))
direct_callable = FALSE;
if ((callee_cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED) && (!method || method->wrapper_type != MONO_WRAPPER_SYNCHRONIZED))
// FIXME: Maybe call the wrapper directly ?
encode_method_ref (acfg, patch_info->data.virt_method->method, p, &p);
break;
case MONO_PATCH_INFO_GC_SAFE_POINT_FLAG:
+ case MONO_PATCH_INFO_GET_TLS_TRAMP:
break;
default:
g_warning ("unable to handle jump info %d", patch_info->type);
mono_class_has_finalizer (klass);
- if (klass->generic_container || cant_encode) {
+ if (mono_class_is_gtd (klass) || cant_encode) {
encode_value (-1, p, &p);
} else {
encode_value (klass->vtable_size, p, &p);
- encode_value ((klass->generic_container ? (1 << 8) : 0) | (no_special_static << 7) | (klass->has_static_refs << 6) | (klass->has_references << 5) | ((klass->blittable << 4) | ((klass->ext && klass->ext->nested_classes) ? 1 : 0) << 3) | (klass->has_cctor << 2) | (klass->has_finalize << 1) | klass->ghcimpl, p, &p);
+ encode_value ((mono_class_is_gtd (klass) ? (1 << 8) : 0) | (no_special_static << 7) | (klass->has_static_refs << 6) | (klass->has_references << 5) | ((klass->blittable << 4) | ((klass->ext && klass->ext->nested_classes) ? 1 : 0) << 3) | (klass->has_cctor << 2) | (klass->has_finalize << 1) | klass->ghcimpl, p, &p);
if (klass->has_cctor)
encode_method_ref (acfg, mono_class_get_cctor (klass), p, &p);
if (klass->has_finalize)
if (!MONO_TYPE_ISSTRUCT (t))
return TRUE;
klass = mono_class_from_mono_type (t);
- orig_ctx = &klass->generic_class->context;
+ orig_ctx = &mono_class_get_generic_class (klass)->context;
inst = orig_ctx->class_inst;
if (inst) {
InterlockedIncrement (&acfg->stats.mcount);
#if 0
- if (method->is_generic || method->klass->generic_container) {
+ if (method->is_generic || mono_class_is_gtd (method->klass)) {
InterlockedIncrement (&acfg->stats.genericcount);
return;
}
case MONO_PATCH_INFO_VTABLE: {
MonoClass *klass = patch_info->data.klass;
- if (klass->generic_class && !mini_class_is_generic_sharable (klass))
+ if (mono_class_is_ginst (klass) && !mini_class_is_generic_sharable (klass))
add_generic_class_with_depth (acfg, klass, depth + 5, "vtable");
break;
}
MonoClass *klass = patch_info->data.field->parent;
/* The .cctor needs to run at runtime. */
- if (klass->generic_class && !mono_generic_context_is_sharable_full (&klass->generic_class->context, FALSE, FALSE) && mono_class_get_cctor (klass))
+ if (mono_class_is_ginst (klass) && !mono_generic_context_is_sharable_full (&mono_class_get_generic_class (klass)->context, FALSE, FALSE) && mono_class_get_cctor (klass))
add_extra_method_with_depth (acfg, mono_class_get_cctor (klass), depth + 1);
break;
}
static int
execute_system (const char * command)
{
- int status;
+ int status = 0;
#if _WIN32
// We need an extra set of quotes around the whole command to properly handle commands
sig = mono_method_signature (method);
- if (method->klass->generic_class)
- class_ginst = method->klass->generic_class->context.class_inst;
+ if (mono_class_is_ginst (method->klass))
+ class_ginst = mono_class_get_generic_class (method->klass)->context.class_inst;
if (method->is_inflated)
ginst = ((MonoMethodInflated*)method)->context.method_inst;
if (!method->wrapper_type) {
char *full_name;
- if (klass->generic_class)
- full_name = mono_type_full_name (&klass->generic_class->container_class->byval_arg);
+ if (mono_class_is_ginst (klass))
+ full_name = mono_type_full_name (&mono_class_get_generic_class (klass)->container_class->byval_arg);
else
full_name = mono_type_full_name (&klass->byval_arg);
}
*/
- if (method->is_generic || method->klass->generic_container)
+ if (method->is_generic || mono_class_is_gtd (method->klass))
/* Compile the ref shared version instead */
method = mini_get_shared_method (method);
method = mono_get_method_checked (acfg->image, token, NULL, NULL, &error);
report_loader_error (acfg, &error, "Failed to load method token 0x%x due to %s\n", i, mono_error_get_message (&error));
- if (method->is_generic || method->klass->generic_container) {
+ if (method->is_generic || mono_class_is_gtd (method->klass)) {
MonoMethod *gshared;
gshared = mini_get_shared_method_full (method, TRUE, TRUE);
GPtrArray *frag;
int len, j;
GPtrArray *threads;
- HANDLE handle;
+ MonoThreadHandle *thread_handle;
gpointer *user_data;
MonoMethod **methods;
user_data [1] = acfg;
user_data [2] = frag;
- handle = mono_threads_create_thread (compile_thread_main, (gpointer) user_data, 0, NULL);
- g_ptr_array_add (threads, handle);
+ thread_handle = mono_threads_create_thread (compile_thread_main, (gpointer) user_data, NULL, NULL);
+ g_ptr_array_add (threads, thread_handle);
}
g_free (methods);
for (i = 0; i < threads->len; ++i) {
- WaitForSingleObjectEx (g_ptr_array_index (threads, i), INFINITE, FALSE);
+ mono_thread_info_wait_one_handle (g_ptr_array_index (threads, i), INFINITE, FALSE);
mono_threads_close_thread_handle (g_ptr_array_index (threads, i));
}
} else {
get_got_offset (acfg, FALSE, ji);
get_got_offset (acfg, TRUE, ji);
+ ji = (MonoJumpInfo *)mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJumpInfo));
+ ji->type = MONO_PATCH_INFO_GET_TLS_TRAMP;
+ get_got_offset (acfg, FALSE, ji);
+ get_got_offset (acfg, TRUE, ji);
+
for (i = 0; i < sizeof (preinited_jit_icalls) / sizeof (char*); ++i) {
ji = (MonoJumpInfo *)mono_mempool_alloc0 (acfg->mempool, sizeof (MonoAotCompile));
ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
//acfg->aot_opts.print_skipped_methods = TRUE;
#if !defined(MONO_ARCH_GSHAREDVT_SUPPORTED)
- if (opts & MONO_OPT_GSHAREDVT) {
+ if (acfg->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");
+ if (acfg->aot_opts.llvm_only) {
+ aot_printerrf (acfg, "--aot=llvmonly requires a runtime that supports gsharedvt.\n");
return 1;
}
+#else
+ if (acfg->aot_opts.llvm_only || mono_aot_mode_is_full (&acfg->aot_opts) || mono_aot_mode_is_hybrid (&acfg->aot_opts))
+ acfg->opts |= MONO_OPT_GSHAREDVT;
#endif
+#if !defined(ENABLE_LLVM)
if (acfg->aot_opts.llvm_only) {
-#ifndef MONO_ARCH_GSHAREDVT_SUPPORTED
- aot_printerrf (acfg, "--aot=llvmonly requires a runtime that supports gsharedvt.\n");
- return 1;
-#endif
-#ifndef ENABLE_LLVM
aot_printerrf (acfg, "--aot=llvmonly requires a runtime compiled with llvm support.\n");
return 1;
-#endif
- }
-
-#if defined(MONO_ARCH_GSHAREDVT_SUPPORTED)
- if (acfg->aot_opts.llvm_only || mono_aot_mode_is_full (&acfg->aot_opts) || mono_aot_mode_is_hybrid (&acfg->aot_opts)) {
- acfg->opts |= MONO_OPT_GSHAREDVT;
- opts |= MONO_OPT_GSHAREDVT;
}
#endif
- if (opts & MONO_OPT_GSHAREDVT)
+ if (acfg->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);
mini_llvm_init ();
if (acfg->aot_opts.asm_only && !acfg->aot_opts.llvm_outfile) {
- aot_printerrf (acfg, "Compiling with LLVM and the asm-only option requires the llvm-outputfile= option.");
+ aot_printerrf (acfg, "Compiling with LLVM and the asm-only option requires the llvm-outfile= option.\n");
return 1;
}
}
acfg->method_index = 1;
- if (mono_aot_mode_is_full (&acfg->aot_opts))
+ if (mono_aot_mode_is_full (&acfg->aot_opts) || mono_aot_mode_is_hybrid (&acfg->aot_opts))
mono_set_partial_sharing_supported (TRUE);
res = collect_methods (acfg);
acfg->tmpfname = g_strdup_printf ("%s", acfg->aot_opts.outfile);
else
acfg->tmpfname = g_strdup_printf ("%s.s", acfg->image->name);
- acfg->fp = fopen (acfg->tmpfname, "w+");
+ acfg->fp = fopen (acfg->tmpfname, "w+");
} else {
int i = g_file_open_tmp ("mono_aot_XXXXXX", &acfg->tmpfname, NULL);
acfg->fp = fdopen (i, "w+");