{
MonoClass *klass, *gklass;
+ if (gclass->cached_class)
+ return gclass->cached_class;
+
mono_loader_lock ();
if (gclass->cached_class) {
mono_loader_unlock ();
return gclass->cached_class;
}
- gclass->cached_class = mono_image_set_alloc0 (gclass->owner, sizeof (MonoClass));
- klass = gclass->cached_class;
+ klass = mono_image_set_alloc0 (gclass->owner, sizeof (MonoClass));
gklass = gclass->container_class;
}
}
+ mono_memory_barrier ();
+ gclass->cached_class = klass;
+
mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
inflated_classes ++;
}
#define FAST_CACHE_SIZE 16
-static MonoClass *var_cache_fast [FAST_CACHE_SIZE];
-static MonoClass *mvar_cache_fast [FAST_CACHE_SIZE];
-static GHashTable *var_cache_slow;
-static GHashTable *mvar_cache_slow;
static MonoClass *
get_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar)
{
int n = mono_generic_param_num (param);
+ MonoImage *image = param->image;
GHashTable *ht;
- if (n < FAST_CACHE_SIZE)
- return (is_mvar ? mvar_cache_fast : var_cache_fast) [n];
- ht = is_mvar ? mvar_cache_slow : var_cache_slow;
- return ht ? g_hash_table_lookup (ht, GINT_TO_POINTER (n)) : NULL;
+ g_assert (image);
+
+ if (n < FAST_CACHE_SIZE) {
+ if (is_mvar)
+ return image->mvar_cache_fast ? image->mvar_cache_fast [n] : NULL;
+ else
+ return image->var_cache_fast ? image->var_cache_fast [n] : NULL;
+ } else {
+ ht = is_mvar ? image->mvar_cache_slow : image->var_cache_slow;
+ return ht ? g_hash_table_lookup (ht, GINT_TO_POINTER (n)) : NULL;
+ }
}
+/*
+ * LOCKING: Acquires the loader lock.
+ */
static void
set_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar, MonoClass *klass)
{
int n = mono_generic_param_num (param);
+ MonoImage *image = param->image;
GHashTable *ht;
+ g_assert (image);
+
if (n < FAST_CACHE_SIZE) {
- (is_mvar ? mvar_cache_fast : var_cache_fast) [n] = klass;
+ if (is_mvar) {
+ /* No locking needed */
+ if (!image->mvar_cache_fast)
+ image->mvar_cache_fast = mono_image_alloc0 (image, sizeof (MonoClass*) * FAST_CACHE_SIZE);
+ image->mvar_cache_fast [n] = klass;
+ } else {
+ if (!image->var_cache_fast)
+ image->var_cache_fast = mono_image_alloc0 (image, sizeof (MonoClass*) * FAST_CACHE_SIZE);
+ image->var_cache_fast [n] = klass;
+ }
return;
}
- ht = is_mvar ? mvar_cache_slow : var_cache_slow;
+ ht = is_mvar ? image->mvar_cache_slow : image->var_cache_slow;
if (!ht) {
- ht = g_hash_table_new (NULL, NULL);
- if (is_mvar)
- mvar_cache_slow = ht;
- else
- var_cache_slow = ht;
+ mono_loader_lock ();
+ ht = is_mvar ? image->mvar_cache_slow : image->var_cache_slow;
+ if (!ht) {
+ ht = g_hash_table_new (NULL, NULL);
+ mono_memory_barrier ();
+ if (is_mvar)
+ image->mvar_cache_slow = ht;
+ else
+ image->var_cache_slow = ht;
+ }
+ mono_loader_unlock ();
}
g_hash_table_insert (ht, GINT_TO_POINTER (n), klass);
name = buf;
}
- if (get_class_from_name) {
+ /* FIXME: get_class_from_name () can't handle types in the EXPORTEDTYPE table */
+ if (get_class_from_name && image->tables [MONO_TABLE_EXPORTEDTYPE].rows == 0) {
gboolean res = get_class_from_name (image, name_space, name, &class);
if (res) {
if (!class)
MonoGenericContainer *container = klass_gtd->generic_container;
/*Viable candidates are instances of the same generic interface*/
- if (mono_class_get_generic_type_definition (oklass) != klass_gtd)
+ if (mono_class_get_generic_type_definition (oklass) != klass_gtd || oklass == klass_gtd)
return FALSE;
klass_argv = &klass->generic_class->context.class_inst->type_argv [0];
MonoGenericContainer *container = klass_gtd->generic_container;
/*Viable candidates are instances of the same generic interface*/
- if (mono_class_get_generic_type_definition (oklass) != klass_gtd)
+ if (mono_class_get_generic_type_definition (oklass) != klass_gtd || oklass == klass_gtd)
return FALSE;
klass_argv = &klass->generic_class->context.class_inst->type_argv [0];
if (!klass->inited)
mono_class_init (klass);
- if (!klass->has_finalize)
+ if (!mono_class_has_finalizer (klass))
return NULL;
if (mono_class_get_cached_class_info (klass, &cached_info))
{
int access_level;
+ if (access_klass->image->assembly && access_klass->image->assembly->corlib_internal)
+ return TRUE;
+
if (access_klass->element_class && !access_klass->enumtype)
access_klass = access_klass->element_class;
can_access_member (MonoClass *access_klass, MonoClass *member_klass, MonoClass* context_klass, int access_level)
{
MonoClass *member_generic_def;
+ if (access_klass->image->assembly && access_klass->image->assembly->corlib_internal)
+ return TRUE;
+
if (((access_klass->generic_class && access_klass->generic_class->container_class) ||
access_klass->generic_container) &&
(member_generic_def = get_generic_definition_class (member_klass))) {