X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Freflection-cache.h;h=8f68929c2a376556a5f3d57f80c2302975c2882b;hb=a713a14521da8ddf992c4a3e64855d56cb7897a3;hp=ec4d722fb89cd724f960592fe0e7f303193b0ca7;hpb=6be008c409153a82e80394b98c93564e2cdb2309;p=mono.git diff --git a/mono/metadata/reflection-cache.h b/mono/metadata/reflection-cache.h index ec4d722fb89..8f68929c2a3 100644 --- a/mono/metadata/reflection-cache.h +++ b/mono/metadata/reflection-cache.h @@ -7,8 +7,10 @@ #include #include +#include #include #include +#include /* * We need to return always the same object for MethodInfo, FieldInfo etc.. @@ -38,43 +40,120 @@ reflected_hash (gconstpointer a); #define FREE_REFENTRY(entry) #endif +static inline MonoObject* +cache_object (MonoDomain *domain, MonoClass *klass, gpointer item, MonoObject* o) +{ + MonoObject *obj; + ReflectedEntry pe; + pe.item = item; + pe.refclass = klass; + mono_domain_lock (domain); + if (!domain->refobject_hash) + domain->refobject_hash = mono_g_hash_table_new_type (reflected_hash, reflected_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection objects table"); -#define CACHE_OBJECT(t,p,o,k) \ - do { \ - t _obj; \ - ReflectedEntry pe; \ - pe.item = (p); \ - pe.refclass = (k); \ - mono_domain_lock (domain); \ - if (!domain->refobject_hash) \ - domain->refobject_hash = mono_g_hash_table_new_type (reflected_hash, reflected_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection objects table"); \ - _obj = (t)mono_g_hash_table_lookup (domain->refobject_hash, &pe); \ - if (!_obj) { \ - ReflectedEntry *e = ALLOC_REFENTRY; \ - e->item = (p); \ - e->refclass = (k); \ - mono_g_hash_table_insert (domain->refobject_hash, e,o); \ - _obj = o; \ - } \ - mono_domain_unlock (domain); \ - return _obj; \ - } while (0) - -#define CHECK_OBJECT(t,p,k) \ - do { \ - t _obj; \ - ReflectedEntry e; \ - e.item = (p); \ - e.refclass = (k); \ - mono_domain_lock (domain); \ - if (!domain->refobject_hash) \ - domain->refobject_hash = mono_g_hash_table_new_type (reflected_hash, reflected_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection objects table"); \ - if ((_obj = (t)mono_g_hash_table_lookup (domain->refobject_hash, &e))) { \ - mono_domain_unlock (domain); \ - return _obj; \ - } \ - mono_domain_unlock (domain); \ - } while (0) + obj = (MonoObject*) mono_g_hash_table_lookup (domain->refobject_hash, &pe); + if (obj == NULL) { + ReflectedEntry *e = ALLOC_REFENTRY; + e->item = item; + e->refclass = klass; + mono_g_hash_table_insert (domain->refobject_hash, e, o); + obj = o; + } + mono_domain_unlock (domain); + return obj; +} + + +static inline MonoObjectHandle +cache_object_handle (MonoDomain *domain, MonoClass *klass, gpointer item, MonoObjectHandle o) +{ + ReflectedEntry pe; + pe.item = item; + pe.refclass = klass; + mono_domain_lock (domain); + if (!domain->refobject_hash) + domain->refobject_hash = mono_g_hash_table_new_type (reflected_hash, reflected_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection objects table"); + + MonoObjectHandle obj = MONO_HANDLE_NEW (MonoObject, mono_g_hash_table_lookup (domain->refobject_hash, &pe)); + if (MONO_HANDLE_IS_NULL (obj)) { + ReflectedEntry *e = ALLOC_REFENTRY; + e->item = item; + e->refclass = klass; + mono_g_hash_table_insert (domain->refobject_hash, e, MONO_HANDLE_RAW (o)); + MONO_HANDLE_ASSIGN (obj, o); + } + mono_domain_unlock (domain); + return obj; +} + + +#define CACHE_OBJECT(t,p,o,k) ((t) (cache_object (domain, (k), (p), (o)))) + + +static inline MonoObject* +check_object (MonoDomain* domain, MonoClass *klass, gpointer item) +{ + ReflectedEntry e; + e.item = item; + e.refclass = klass; + mono_domain_lock (domain); + if (!domain->refobject_hash) + domain->refobject_hash = mono_g_hash_table_new_type (reflected_hash, reflected_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection objects table"); + MonoObject *obj = (MonoObject*) mono_g_hash_table_lookup (domain->refobject_hash, &e); + mono_domain_unlock (domain); + return obj; +} + +static inline MonoObjectHandle +check_object_handle (MonoDomain* domain, MonoClass *klass, gpointer item) +{ + ReflectedEntry e; + e.item = item; + e.refclass = klass; + mono_domain_lock (domain); + if (!domain->refobject_hash) + domain->refobject_hash = mono_g_hash_table_new_type (reflected_hash, reflected_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection objects table"); + MonoObjectHandle obj = MONO_HANDLE_NEW (MonoObject, mono_g_hash_table_lookup (domain->refobject_hash, &e)); + mono_domain_unlock (domain); + return obj; +} + + +typedef MonoObject* (*ReflectionCacheConstructFunc) (MonoDomain*, MonoClass*, gpointer, gpointer, MonoError *); + +typedef MonoObjectHandle (*ReflectionCacheConstructFunc_handle) (MonoDomain*, MonoClass*, gpointer, gpointer, MonoError *); + + +static inline MonoObject* +check_or_construct (MonoDomain *domain, MonoClass *klass, gpointer item, gpointer user_data, MonoError *error, ReflectionCacheConstructFunc construct) +{ + mono_error_init (error); + MonoObject *obj = check_object (domain, klass, item); + if (obj) + return obj; + obj = construct (domain, klass, item, user_data, error); + return_val_if_nok (error, NULL); + /* note no caching if there was an error in construction */ + return cache_object (domain, klass, item, obj); +} + +static inline MonoObjectHandle +check_or_construct_handle (MonoDomain *domain, MonoClass *klass, gpointer item, gpointer user_data, MonoError *error, ReflectionCacheConstructFunc_handle construct) +{ + mono_error_init (error); + MonoObjectHandle obj = check_object_handle (domain, klass, item); + if (!MONO_HANDLE_IS_NULL (obj)) + return obj; + MONO_HANDLE_ASSIGN (obj, construct (domain, klass, item, user_data, error)); + return_val_if_nok (error, NULL); + /* note no caching if there was an error in construction */ + return cache_object_handle (domain, klass, item, obj); +} + + +#define CHECK_OR_CONSTRUCT(t,p,k,construct,ud) ((t) check_or_construct (domain, (k), (p), (ud), error, (ReflectionCacheConstructFunc) (construct))) + +#define CHECK_OR_CONSTRUCT_HANDLE(t,p,k,construct,ud) ((t) check_or_construct_handle (domain, (k), (p), (ud), error, (ReflectionCacheConstructFunc_handle) (construct))) #endif /*__MONO_METADATA_REFLECTION_CACHE_H__*/