if (recursive) {
MonoGenericClass *gclass = type->data.generic_class;
- g_assert (gclass->container_class->generic_container);
+ g_assert (mono_class_is_gtd (gclass->container_class));
return mono_generic_context_check_used (&gclass->context);
} else {
return 0;
context_used |= type_check_context_used (&klass->this_arg, FALSE);
context_used |= type_check_context_used (&klass->byval_arg, FALSE);
- if (klass->generic_class)
- context_used |= mono_generic_context_check_used (&klass->generic_class->context);
- else if (klass->generic_container)
- context_used |= mono_generic_context_check_used (&klass->generic_container->context);
+ if (mono_class_is_ginst (klass))
+ context_used |= mono_generic_context_check_used (&mono_class_get_generic_class (klass)->context);
+ else if (mono_class_is_gtd (klass))
+ context_used |= mono_generic_context_check_used (&mono_class_get_generic_container (klass)->context);
return context_used;
}
g_assert (rgctx_template);
- if (parent->generic_class)
- parent = parent->generic_class->container_class;
+ if (mono_class_is_ginst (parent))
+ parent = mono_class_get_generic_class (parent)->container_class;
if (!generic_subclass_hash)
generic_subclass_hash = g_hash_table_new (mono_aligned_addr_hash, NULL);
declaring = method;
m = NULL;
- if (klass->generic_class)
+ if (mono_class_is_ginst (klass))
m = mono_class_get_inflated_method (klass, declaring);
if (!m) {
mono_class_setup_methods (klass);
if (mono_class_has_failure (klass))
return NULL;
- for (i = 0; i < klass->method.count; ++i) {
+ int mcount = mono_class_get_method_count (klass);
+ for (i = 0; i < mcount; ++i) {
m = klass->methods [i];
if (m == declaring)
break;
if (m->is_inflated && mono_method_get_declaring_generic_method (m) == declaring)
break;
}
- if (i >= klass->method.count)
+ if (i >= mcount)
return NULL;
}
MonoMethod *inflated_method;
MonoType *inflated_type = mono_class_inflate_generic_type_checked (&method->klass->byval_arg, context, &error);
mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+ WrapperInfo *winfo = NULL;
MonoClass *inflated_class = mono_class_from_mono_type (inflated_type);
MonoJumpInfoGSharedVtCall *res;
mono_class_init (inflated_class);
- g_assert (!method->wrapper_type);
+ if (method->wrapper_type) {
+ winfo = mono_marshal_get_wrapper_info (method);
+
+ g_assert (winfo);
+ g_assert (winfo->subtype == WRAPPER_SUBTYPE_SYNCHRONIZED_INNER);
+ method = winfo->d.synchronized_inner.method;
+ }
if (inflated_class->byval_arg.type == MONO_TYPE_ARRAY ||
inflated_class->byval_arg.type == MONO_TYPE_SZARRAY) {
}
mono_class_init (inflated_method->klass);
g_assert (inflated_method->klass == inflated_class);
+
+ if (winfo) {
+ g_assert (winfo->subtype == WRAPPER_SUBTYPE_SYNCHRONIZED_INNER);
+ inflated_method = mono_marshal_get_synchronized_inner_wrapper (inflated_method);
+ }
+
res->method = inflated_method;
return res;
static MonoClass*
class_uninstantiated (MonoClass *klass)
{
- if (klass->generic_class)
- return klass->generic_class->container_class;
+ if (mono_class_is_ginst (klass))
+ return mono_class_get_generic_class (klass)->container_class;
return klass;
}
DEBUG (printf ("get slot: %s %d\n", mono_type_full_name (&class->byval_arg), slot));
- if (klass->generic_class && !shared) {
+ if (mono_class_is_ginst (klass) && !shared) {
MonoRuntimeGenericContextInfoTemplate oti;
gboolean tmp_do_free;
- oti = class_get_rgctx_template_oti (klass->generic_class->container_class,
+ oti = class_get_rgctx_template_oti (mono_class_get_generic_class (klass)->container_class,
type_argc, slot, TRUE, FALSE, &tmp_do_free);
if (oti.data) {
gpointer info = oti.data;
- oti.data = inflate_info (&oti, &klass->generic_class->context, klass, temporary);
+ oti.data = inflate_info (&oti, &mono_class_get_generic_class (klass)->context, klass, temporary);
if (tmp_do_free)
free_inflated_info (oti.info_type, info);
}
case MONO_RGCTX_INFO_STATIC_DATA: {
MonoVTable *vtable = mono_class_vtable (domain, klass);
if (!vtable) {
- mono_error_set_exception_instance (error, mono_class_get_exception_for_failure (klass));
+ mono_error_set_for_class_failure (error, klass);
return NULL;
}
return mono_vtable_get_static_field_data (vtable);
case MONO_RGCTX_INFO_VTABLE: {
MonoVTable *vtable = mono_class_vtable (domain, klass);
if (!vtable) {
- mono_error_set_exception_instance (error, mono_class_get_exception_for_failure (klass));
+ mono_error_set_for_class_failure (error, klass);
return NULL;
}
return vtable;
memcpy_method [size] = m;
}
if (!domain_info->memcpy_addr [size]) {
- gpointer addr = mono_compile_method (memcpy_method [size]);
+ gpointer addr = mono_compile_method_checked (memcpy_method [size], error);
mono_memory_barrier ();
domain_info->memcpy_addr [size] = (gpointer *)addr;
+ mono_error_assert_ok (error);
}
return domain_info->memcpy_addr [size];
} else {
bzero_method [size] = m;
}
if (!domain_info->bzero_addr [size]) {
- gpointer addr = mono_compile_method (bzero_method [size]);
+ gpointer addr = mono_compile_method_checked (bzero_method [size], error);
mono_memory_barrier ();
domain_info->bzero_addr [size] = (gpointer *)addr;
+ mono_error_assert_ok (error);
}
return domain_info->bzero_addr [size];
}
int i;
if (!MONO_TYPE_ISSTRUCT (t))
- return &mono_defaults.int_class->byval_arg;
+ return get_wrapper_shared_type (&mono_defaults.object_class->byval_arg);
klass = mono_class_from_mono_type (t);
- orig_ctx = &klass->generic_class->context;
+ orig_ctx = &mono_class_get_generic_class (klass)->context;
memset (&ctx, 0, sizeof (MonoGenericContext));
args [i] = get_wrapper_shared_type (inst->type_argv [i]);
ctx.method_inst = mono_metadata_get_generic_inst (inst->type_argc, args);
}
- klass = mono_class_inflate_generic_class_checked (klass->generic_class->container_class, &ctx, &error);
+ klass = mono_class_inflate_generic_class_checked (mono_class_get_generic_class (klass)->container_class, &ctx, &error);
mono_error_assert_ok (&error); /* FIXME don't swallow the error */
return &klass->byval_arg;
}
MonoMethod *res, *cached;
WrapperInfo *info;
MonoMethodSignature *csig, *gsharedvt_sig;
- int i, pindex, retval_var;
+ int i, pindex, retval_var = 0;
static GHashTable *cache;
// FIXME: Memory management
{
static gboolean inited = FALSE;
static int num_trampolines;
+ MonoError error;
gpointer res, info;
MonoDomain *domain = mono_domain_get ();
MonoJitDomainInfo *domain_info;
wrapper = mini_get_gsharedvt_in_sig_wrapper (normal_sig);
else
wrapper = mini_get_gsharedvt_out_sig_wrapper (normal_sig);
- res = mono_compile_method (wrapper);
+ res = mono_compile_method_checked (wrapper, &error);
+ mono_error_assert_ok (&error);
return res;
}
if (!tramp_addr) {
wrapper = mono_marshal_get_gsharedvt_in_wrapper ();
- addr = mono_compile_method (wrapper);
+ addr = mono_compile_method_checked (wrapper, &error);
mono_memory_barrier ();
+ mono_error_assert_ok (&error);
tramp_addr = addr;
}
addr = tramp_addr;
if (!tramp_addr) {
wrapper = mono_marshal_get_gsharedvt_out_wrapper ();
- addr = mono_compile_method (wrapper);
+ addr = mono_compile_method_checked (wrapper, &error);
mono_memory_barrier ();
+ mono_error_assert_ok (&error);
tramp_addr = addr;
}
addr = tramp_addr;
gpointer arg = NULL;
if (mono_llvm_only) {
- addr = mono_compile_method (m);
+ addr = mono_compile_method_checked (m, error);
+ return_val_if_nok (error, NULL);
addr = mini_add_method_wrappers_llvmonly (m, addr, FALSE, FALSE, &arg);
/* Returns an ftndesc */
return mini_create_llvmonly_ftndesc (domain, addr, arg);
} else {
- addr = mono_compile_method ((MonoMethod *)data);
+ addr = mono_compile_method_checked ((MonoMethod *)data, error);
+ return_val_if_nok (error, NULL);
return mini_add_method_trampoline ((MonoMethod *)data, addr, mono_method_needs_static_rgctx_invoke ((MonoMethod *)data, FALSE), FALSE);
}
}
g_assert (mono_llvm_only);
- addr = mono_compile_method (m);
+ addr = mono_compile_method_checked (m, error);
+ return_val_if_nok (error, NULL);
MonoJitInfo *ji;
gboolean callee_gsharedvt;
mono_class_setup_vtable (info->klass);
// FIXME: Check type load
- if (iface_class->flags & TYPE_ATTRIBUTE_INTERFACE) {
+ if (mono_class_is_interface (iface_class)) {
ioffset = mono_class_interface_offset (info->klass, iface_class);
g_assert (ioffset != -1);
} else {
method = info->klass->vtable [ioffset + slot];
method = mono_class_inflate_generic_method_checked (method, context, error);
- if (!mono_error_ok (error))
- return NULL;
- addr = mono_compile_method (method);
+ return_val_if_nok (error, NULL);
+ addr = mono_compile_method_checked (method, error);
+ return_val_if_nok (error, NULL);
return mini_add_method_trampoline (method, addr, mono_method_needs_static_rgctx_invoke (method, FALSE), FALSE);
}
case MONO_RGCTX_INFO_VIRT_METHOD_BOX_TYPE: {
mono_class_setup_vtable (info->klass);
// FIXME: Check type load
- if (iface_class->flags & TYPE_ATTRIBUTE_INTERFACE) {
+ if (mono_class_is_interface (iface_class)) {
ioffset = mono_class_interface_offset (info->klass, iface_class);
g_assert (ioffset != -1);
} else {
}
#ifndef DISABLE_REMOTING
case MONO_RGCTX_INFO_REMOTING_INVOKE_WITH_CHECK:
- return mono_compile_method (mono_marshal_get_remoting_invoke_with_check ((MonoMethod *)data));
+ return mono_compile_method_checked (mono_marshal_get_remoting_invoke_with_check ((MonoMethod *)data), error);
#endif
case MONO_RGCTX_INFO_METHOD_DELEGATE_CODE:
return mono_domain_alloc0 (domain, sizeof (gpointer));
vtable = mono_class_vtable (domain, method->method.method.klass);
if (!vtable) {
- mono_error_set_exception_instance (error, mono_class_get_exception_for_failure (method->method.method.klass));
+ mono_error_set_for_class_failure (error, method->method.method.klass);
return NULL;
}
g_assert (method->is_inflated);
- if (!virtual_)
- addr = mono_compile_method (method);
- else
+ if (mono_llvm_only && (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED))
+ method = mono_marshal_get_synchronized_wrapper (method);
+
+ if (!virtual_) {
+ addr = mono_compile_method_checked (method, error);
+ return_val_if_nok (error, NULL);
+ } else
addr = NULL;
if (virtual_) {
/* See mono_emit_method_call_full () */
/* The gsharedvt trampoline will recognize this constant */
vcall_offset = MONO_GSHAREDVT_DEL_INVOKE_VT_OFFSET;
- } else if (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+ } else if (mono_class_is_interface (method->klass)) {
guint32 imt_slot = mono_method_get_imt_slot (method);
vcall_offset = ((gint32)imt_slot - MONO_IMT_SIZE) * SIZEOF_VOID_P;
} else {
MonoRuntimeGenericContextTemplate *parent_template;
MonoRuntimeGenericContextInfoTemplate *oti;
- if (parent->generic_class)
- parent = parent->generic_class->container_class;
+ if (mono_class_is_ginst (parent))
+ parent = mono_class_get_generic_class (parent)->container_class;
parent_template = mono_class_get_runtime_generic_context_template (parent);
oti = rgctx_template_get_other_slot (parent_template, type_argc, i);
int i, first_slot, size;
MonoDomain *domain = class_vtable->domain;
MonoClass *klass = class_vtable->klass;
- MonoGenericContext *class_context = klass->generic_class ? &klass->generic_class->context : NULL;
+ MonoGenericContext *class_context = mono_class_is_ginst (klass) ? &mono_class_get_generic_class (klass)->context : NULL;
MonoRuntimeGenericContextInfoTemplate oti;
MonoGenericContext context = { class_context ? class_context->class_inst : NULL, method_inst };
int rgctx_index;
method_inst ? method_inst->type_argc : 0, slot, TRUE, TRUE, &do_free);
/* This might take the loader lock */
info = instantiate_info (domain, &oti, &context, klass, error);
+ return_val_if_nok (error, NULL);
g_assert (info);
/*
MonoMethodRuntimeGenericContext *mrgctx;
MonoMethodRuntimeGenericContext key;
- g_assert (!class_vtable->klass->generic_container);
+ g_assert (!mono_class_is_gtd (class_vtable->klass));
g_assert (!method_inst->is_open);
mono_domain_lock (domain);
if not compiled with sharing. */
if (method->wrapper_type != MONO_WRAPPER_NONE)
return FALSE;
- if (method->klass->generic_container)
+ if (mono_class_is_gtd (method->klass))
return TRUE;
return FALSE;
}
}
}
- if (method->klass->generic_class) {
- if (!mono_generic_context_is_sharable_full (&method->klass->generic_class->context, allow_type_vars, allow_partial))
+ if (mono_class_is_ginst (method->klass)) {
+ if (!mono_generic_context_is_sharable_full (&mono_class_get_generic_class (method->klass)->context, allow_type_vars, allow_partial))
return FALSE;
- g_assert (method->klass->generic_class->container_class &&
- method->klass->generic_class->container_class->generic_container);
+ g_assert (mono_class_get_generic_class (method->klass)->container_class &&
+ mono_class_is_gtd (mono_class_get_generic_class (method->klass)->container_class));
- if (has_constraints (method->klass->generic_class->container_class->generic_container))
+ if (has_constraints (mono_class_get_generic_container (mono_class_get_generic_class (method->klass)->container_class)))
return FALSE;
}
- if (method->klass->generic_container && !allow_type_vars)
+ if (mono_class_is_gtd (method->klass) && !allow_type_vars)
return FALSE;
/* This does potentially expensive cattr checks, so do it at the end */
return ((method->flags & METHOD_ATTRIBUTE_STATIC) ||
method->klass->valuetype) &&
- (method->klass->generic_class || method->klass->generic_container);
+ (mono_class_is_ginst (method->klass) || mono_class_is_gtd (method->klass));
}
static MonoGenericInst*
{
MonoGenericContext object_context;
- g_assert (!method->klass->generic_class);
- if (method->klass->generic_container) {
- int type_argc = method->klass->generic_container->type_argc;
+ g_assert (!mono_class_is_ginst (method->klass));
+ if (mono_class_is_gtd (method->klass)) {
+ int type_argc = mono_class_get_generic_container (method->klass)->type_argc;
object_context.class_inst = get_object_generic_inst (type_argc);
} else {
MonoClass*
mini_class_get_container_class (MonoClass *klass)
{
- if (klass->generic_class)
- return klass->generic_class->container_class;
+ if (mono_class_is_ginst (klass))
+ return mono_class_get_generic_class (klass)->container_class;
- g_assert (klass->generic_container);
+ g_assert (mono_class_is_gtd (klass));
return klass;
}
MonoGenericContext*
mini_class_get_context (MonoClass *klass)
{
- if (klass->generic_class)
- return &klass->generic_class->context;
+ if (mono_class_is_ginst (klass))
+ return &mono_class_get_generic_class (klass)->context;
- g_assert (klass->generic_container);
- return &klass->generic_container->context;
+ g_assert (mono_class_is_gtd (klass));
+ return &mono_class_get_generic_container (klass)->context;
}
/*
gboolean
mini_class_is_generic_sharable (MonoClass *klass)
{
- if (klass->generic_class && is_async_state_machine_class (klass))
+ if (mono_class_is_ginst (klass) && is_async_state_machine_class (klass))
return FALSE;
- return (klass->generic_class && mono_generic_context_is_sharable (&klass->generic_class->context, FALSE));
+ return (mono_class_is_ginst (klass) && mono_generic_context_is_sharable (&mono_class_get_generic_class (klass)->context, FALSE));
}
gboolean
memset (&context, 0, sizeof (context));
if (gclass->context.class_inst)
- context.class_inst = get_shared_inst (gclass->context.class_inst, gclass->container_class->generic_container->context.class_inst, NULL, FALSE, FALSE, TRUE);
+ context.class_inst = get_shared_inst (gclass->context.class_inst, mono_class_get_generic_container (gclass->container_class)->context.class_inst, NULL, FALSE, FALSE, TRUE);
if (gclass->context.method_inst)
- context.method_inst = get_shared_inst (gclass->context.method_inst, gclass->container_class->generic_container->context.method_inst, NULL, FALSE, FALSE, TRUE);
+ context.method_inst = get_shared_inst (gclass->context.method_inst, mono_class_get_generic_container (gclass->container_class)->context.method_inst, NULL, FALSE, FALSE, TRUE);
k = mono_class_inflate_generic_class_checked (gclass->container_class, &context, &error);
mono_error_assert_ok (&error); /* FIXME don't swallow the error */
MonoGenericContext *context = mono_method_get_context (method);
MonoGenericInst *inst;
- if (method->is_generic || (method->klass->generic_container && !method->is_inflated)) {
+ /*
+ * Instead of creating a shared version of the wrapper, create a shared version of the original
+ * method and construct a wrapper for it. Otherwise, we could end up with two copies of the
+ * same wrapper, breaking AOT which assumes wrappers are unique.
+ * FIXME: Add other cases.
+ */
+ if (method->wrapper_type == MONO_WRAPPER_SYNCHRONIZED) {
+ MonoMethod *wrapper = mono_marshal_method_from_wrapper (method);
+
+ return mono_marshal_get_synchronized_wrapper (mini_get_shared_method_full (wrapper, all_vt, is_gsharedvt));
+ }
+ if (method->wrapper_type == MONO_WRAPPER_DELEGATE_INVOKE) {
+ WrapperInfo *info = mono_marshal_get_wrapper_info (method);
+
+ if (info->subtype == WRAPPER_SUBTYPE_NONE) {
+ MonoMethod *m = mono_marshal_get_delegate_invoke (mini_get_shared_method_full (info->d.delegate_invoke.method, all_vt, is_gsharedvt), NULL);
+ return m;
+ }
+ }
+
+ if (method->is_generic || (mono_class_is_gtd (method->klass) && !method->is_inflated)) {
declaring_method = method;
} else {
declaring_method = mono_method_get_declaring_generic_method (method);
if (declaring_method->is_generic)
shared_context = mono_method_get_generic_container (declaring_method)->context;
else
- shared_context = declaring_method->klass->generic_container->context;
+ shared_context = mono_class_get_generic_container (declaring_method->klass)->context;
if (!is_gsharedvt)
partial = mono_method_is_generic_sharable_full (method, FALSE, TRUE, FALSE);
gsharedvt = is_gsharedvt || (!partial && mini_is_gsharedvt_sharable_method (method));
- class_container = declaring_method->klass->generic_container;
+ class_container = mono_class_try_get_generic_container (declaring_method->klass); //FIXME is this a case for a try_get?
method_container = mono_method_get_generic_container (declaring_method);
/*
void
mono_set_generic_sharing_vt_supported (gboolean supported)
{
- gsharedvt_supported = supported;
+ /* ensure we do not disable gsharedvt once it's been enabled */
+ if (!gsharedvt_supported && supported)
+ gsharedvt_supported = TRUE;
}
#ifdef MONO_ARCH_GSHAREDVT_SUPPORTED