MonoClass *parent = class->parent;
MonoClass *subclass;
MonoRuntimeGenericContextTemplate *rgctx_template = class_lookup_rgctx_template (class);
- static gboolean hook_installed;
-
- if (!hook_installed) {
- mono_install_image_unload_hook (mono_class_unregister_image_generic_subclasses, NULL);
- hook_installed = TRUE;
- }
g_assert (rgctx_template);
#define MONO_RGCTX_SLOT_USED_MARKER ((gpointer)&mono_defaults.object_class->byval_arg)
+/*
+ * Return true if this info type has the notion of identify.
+ *
+ * Some info types expect that each insert results in a new slot been assigned.
+ */
+static int
+other_info_has_identity (int info_type)
+{
+ return info_type != MONO_RGCTX_INFO_CAST_CACHE;
+}
+
/*
* LOCKING: loader lock
*/
case MONO_RGCTX_INFO_KLASS:
case MONO_RGCTX_INFO_VTABLE:
case MONO_RGCTX_INFO_TYPE:
- case MONO_RGCTX_INFO_REFLECTION_TYPE: {
+ case MONO_RGCTX_INFO_REFLECTION_TYPE:
+ case MONO_RGCTX_INFO_CAST_CACHE: {
gpointer result = mono_class_inflate_generic_type_with_mempool (temporary ? NULL : class->image,
data, context, &error);
g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
case MONO_RGCTX_INFO_VTABLE:
case MONO_RGCTX_INFO_TYPE:
case MONO_RGCTX_INFO_REFLECTION_TYPE:
+ case MONO_RGCTX_INFO_CAST_CACHE:
mono_metadata_free_type (info);
break;
default:
generic_inst_is_sharable (MonoGenericInst *inst, gboolean allow_type_vars,
gboolean allow_partial)
{
- gboolean has_refs;
int i;
- has_refs = FALSE;
- for (i = 0; i < inst->type_argc; ++i) {
- MonoType *type = inst->type_argv [i];
-
- if (MONO_TYPE_IS_REFERENCE (type) || (allow_type_vars && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)))
- has_refs = TRUE;
- }
-
for (i = 0; i < inst->type_argc; ++i) {
MonoType *type = inst->type_argv [i];
mono_raise_exception (mono_class_get_exception_for_failure (class));
return vtable;
}
+ case MONO_RGCTX_INFO_CAST_CACHE: {
+ /*First slot is the cache itself, the second the vtable.*/
+ gpointer **cache_data = mono_domain_alloc0 (domain, sizeof (gpointer) * 2);
+ cache_data [1] = (gpointer)class;
+ return cache_data;
+ }
default:
g_assert_not_reached ();
}
case MONO_RGCTX_INFO_STATIC_DATA:
case MONO_RGCTX_INFO_KLASS:
case MONO_RGCTX_INFO_VTABLE:
+ case MONO_RGCTX_INFO_CAST_CACHE:
temporary = TRUE;
break;
default:
switch (oti->info_type) {
case MONO_RGCTX_INFO_STATIC_DATA:
case MONO_RGCTX_INFO_KLASS:
- case MONO_RGCTX_INFO_VTABLE: {
+ case MONO_RGCTX_INFO_VTABLE:
+ case MONO_RGCTX_INFO_CAST_CACHE: {
MonoClass *arg_class = mono_class_from_mono_type (data);
free_inflated_info (oti->info_type, data);
case MONO_RGCTX_INFO_VTABLE:
case MONO_RGCTX_INFO_TYPE:
case MONO_RGCTX_INFO_REFLECTION_TYPE:
+ case MONO_RGCTX_INFO_CAST_CACHE:
return mono_class_from_mono_type (data1) == mono_class_from_mono_type (data2);
case MONO_RGCTX_INFO_METHOD:
case MONO_RGCTX_INFO_GENERIC_METHOD_CODE:
mono_loader_lock ();
- oti_list = get_other_info_templates (rgctx_template, type_argc);
+ if (other_info_has_identity (info_type)) {
+ oti_list = get_other_info_templates (rgctx_template, type_argc);
- for (oti = oti_list, i = 0; oti; oti = oti->next, ++i) {
- gpointer inflated_data;
+ for (oti = oti_list, i = 0; oti; oti = oti->next, ++i) {
+ gpointer inflated_data;
- if (oti->info_type != info_type || !oti->data)
- continue;
+ if (oti->info_type != info_type || !oti->data)
+ continue;
- inflated_data = inflate_other_info (oti, generic_context, class, TRUE);
+ inflated_data = inflate_other_info (oti, generic_context, class, TRUE);
- if (other_info_equal (data, inflated_data, info_type)) {
+ if (other_info_equal (data, inflated_data, info_type)) {
+ free_inflated_info (info_type, inflated_data);
+ mono_loader_unlock ();
+ return i;
+ }
free_inflated_info (info_type, inflated_data);
- mono_loader_unlock ();
- return i;
}
- free_inflated_info (info_type, inflated_data);
}
/* We haven't found the info */
void
mono_generic_sharing_init (void)
{
+ mono_install_image_unload_hook (mono_class_unregister_image_generic_subclasses, NULL);
+}
+
+void
+mono_generic_sharing_cleanup (void)
+{
+ mono_remove_image_unload_hook (mono_class_unregister_image_generic_subclasses, NULL);
+
+ if (generic_subclass_hash)
+ g_hash_table_destroy (generic_subclass_hash);
+}
+
+gboolean
+mini_type_is_reference (MonoCompile *cfg, MonoType *type)
+{
+ if (mono_type_is_reference (type))
+ return TRUE;
+ if (!cfg->generic_sharing_context)
+ return FALSE;
+ /*FIXME the probably needs better handle under partial sharing*/
+ return type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR;
}