diff --git a/src/mono/mono/metadata/class-internals.h b/src/mono/mono/metadata/class-internals.h index e44ba4c7b49026..55067f680d1b31 100644 --- a/src/mono/mono/metadata/class-internals.h +++ b/src/mono/mono/metadata/class-internals.h @@ -952,25 +952,20 @@ mono_class_get_##shortname##_class (void) \ // GENERATE_TRY_GET_CLASS_WITH_CACHE attempts mono_class_load_from_name approximately // only once. i.e. if it fails, it will return null and not retry. -// In a race it might try a few times, but not indefinitely. -// -// FIXME This maybe has excessive volatile/barriers. -// #define GENERATE_TRY_GET_CLASS_WITH_CACHE(shortname,name_space,name) \ MonoClass* \ mono_class_try_get_##shortname##_class (void) \ { \ - static volatile MonoClass *tmp_class; \ - static volatile gboolean inited; \ - MonoClass *klass = (MonoClass *)tmp_class; \ - mono_memory_barrier (); \ - if (!inited) { \ - klass = mono_class_try_load_from_name (mono_class_generate_get_corlib_impl (), name_space, name); \ - tmp_class = klass; \ - mono_memory_barrier (); \ - inited = TRUE; \ + static MonoClass *cached_class; \ + static gboolean cached_class_inited; \ + gboolean tmp_inited; \ + mono_atomic_load_acquire(tmp_inited, gboolean, &cached_class_inited); \ + if (G_LIKELY(tmp_inited)) { \ + return (MonoClass*)cached_class; \ } \ - return klass; \ + cached_class = mono_class_try_load_from_name (mono_class_generate_get_corlib_impl (), name_space, name); \ + mono_atomic_store_release(&cached_class_inited, TRUE); \ + return (MonoClass*)cached_class; \ } GENERATE_TRY_GET_CLASS_WITH_CACHE_DECL (safehandle) diff --git a/src/mono/mono/metadata/icall.c b/src/mono/mono/metadata/icall.c index 43f3d32653f321..e326e7a7b085a0 100644 --- a/src/mono/mono/metadata/icall.c +++ b/src/mono/mono/metadata/icall.c @@ -3391,6 +3391,8 @@ static void init_io_stream_slots (void) { MonoClass* klass = mono_class_try_get_stream_class (); + g_assert(klass); + mono_class_setup_vtable (klass); MonoMethod **klass_methods = m_class_get_methods (klass); if (!klass_methods) {