提交 3f8e97c1 编写于 作者: J Jonathan Chambers

Cache class custom attributes on MonoClass rather than domain and make caching...

Cache class custom attributes on MonoClass rather than domain and make caching operation thread safe
上级 de3cbfd2
......@@ -4,6 +4,7 @@
#include <mono/metadata/class.h>
#include <mono/metadata/object.h>
#include <mono/metadata/mempool.h>
#include <mono/metadata/reflection.h>
#include <mono/io-layer/io-layer.h>
#include "mono/utils/mono-compiler.h"
#include "mono/utils/mono-error.h"
......@@ -357,6 +358,9 @@ struct _MonoClass {
MonoClass *parent;
MonoClass *nested_in;
/* cached custom attributes for the class */
MonoCustomAttrInfo* cattrs;
MonoImage *image;
const char *name;
const char *name_space;
......
......@@ -254,9 +254,6 @@ struct _MonoDomain {
GHashTable *generic_virtual_cases;
MonoThunkFreeList **thunk_free_lists;
/* Hashing class attributes as a lookup optimization */
GHashTable *class_custom_attributes;
/* Information maintained by the JIT engine */
gpointer runtime_info;
......
......@@ -1199,7 +1199,6 @@ mono_domain_create (void)
domain->jit_info_table = jit_info_table_new (domain);
domain->jit_info_free_queue = NULL;
domain->finalizable_objects_hash = g_hash_table_new (mono_aligned_addr_hash, NULL);
domain->class_custom_attributes = g_hash_table_new_full (mono_aligned_addr_hash, NULL, NULL, mono_custom_attrs_free_cached);
#ifndef HAVE_SGEN_GC
domain->track_resurrection_handles_hash = g_hash_table_new (mono_aligned_addr_hash, NULL);
#endif
......@@ -1988,10 +1987,8 @@ mono_domain_free (MonoDomain *domain, gboolean force)
#endif
g_hash_table_destroy (domain->finalizable_objects_hash);
g_hash_table_destroy (domain->class_custom_attributes);
domain->finalizable_objects_hash = NULL;
domain->class_custom_attributes = NULL;
#ifndef HAVE_SGEN_GC
if (domain->track_resurrection_objects_hash) {
......
......@@ -1228,15 +1228,6 @@ mono_custom_attrs_free (MonoCustomAttrInfo *ainfo)
g_free (ainfo);
}
void
mono_custom_attrs_free_cached (MonoCustomAttrInfo *ainfo)
{
if (ainfo) {
g_assert (ainfo->cached);
g_free (ainfo);
}
}
/*
* idx is the table index of the object
* type is one of MONO_CUSTOM_ATTR_*
......@@ -8393,19 +8384,16 @@ MonoCustomAttrInfo*
mono_custom_attrs_from_class (MonoClass *klass)
{
MonoDomain* domain = mono_domain_get();
// Hashing attributes as a lookup optimization.
MonoCustomAttrInfo* hashed_attribute_info = (MonoCustomAttrInfo*)g_hash_table_lookup(domain->class_custom_attributes, klass);
MonoCustomAttrInfo* cattrs;
guint32 idx;
if(hashed_attribute_info != NULL)
{
return hashed_attribute_info;
}
if (klass->generic_class)
klass = klass->generic_class->container_class;
cattrs = InterlockedCompareExchangePointer(&klass->cattrs, NULL, NULL);
if (cattrs)
return cattrs;
if (klass->image->dynamic)
return lookup_custom_attr (klass->image, klass);
......@@ -8419,13 +8407,33 @@ mono_custom_attrs_from_class (MonoClass *klass)
idx |= MONO_CUSTOM_ATTR_TYPEDEF;
}
hashed_attribute_info = mono_custom_attrs_from_index (klass->image, idx);
cattrs = mono_custom_attrs_from_index (klass->image, idx);
if (cattrs) {
size_t cattrs_size;
MonoCustomAttrInfo* cattrs_orig;
MonoCustomAttrInfo* cattr_cached;
/* make copy from image mempool that is cached */
cattrs_size = MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * cattrs->num_attrs;
cattr_cached = mono_image_alloc (klass->image, cattrs_size);
memcpy (cattr_cached, cattrs, cattrs_size);
cattr_cached->cached = 1;
/* free non-cached version */
mono_custom_attrs_free (cattrs);
cattrs = cattr_cached;
cattrs_orig = InterlockedCompareExchangePointer(&klass->cattrs, cattrs, NULL);
if (cattrs_orig) {
/* Race to cache and another thread won.
* No need to free as we used image mempool for allocation. */
cattrs = cattrs_orig;
}
}
g_hash_table_insert(domain->class_custom_attributes, klass, hashed_attribute_info);
/* Tell users not to free hashed_attribute_info */
if (hashed_attribute_info != NULL)
hashed_attribute_info->cached = 1;
return hashed_attribute_info;
return cattrs;
}
MonoCustomAttrInfo*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册