number-ms.h \
object-internals.h \
opcodes.c \
+ property-bag.h \
+ property-bag.c \
socket-io.c \
socket-io.h \
w32process.c \
#include <mono/metadata/tabledefs.h>
+enum InfrequentDataKind {
+ PROP_MARSHAL_INFO = 1, /* MonoMarshalType */
+ PROP_EXT = 2, /* MonoClassExt */
+ PROP_REF_INFO_HANDLE = 3, /* gchandle */
+};
+
/* Accessors based on class kind*/
/*
break;
}
}
+
+MonoMarshalType*
+mono_class_get_marshal_info (MonoClass *class)
+{
+ return mono_property_bag_get (&class->infrequent_data, PROP_MARSHAL_INFO);
+}
+
+void
+mono_class_set_marshal_info (MonoClass *class, MonoMarshalType *marshal_info)
+{
+ marshal_info->head.tag = PROP_MARSHAL_INFO;
+ mono_property_bag_add (&class->infrequent_data, marshal_info);
+}
+
+MonoClassExt*
+mono_class_get_ext (MonoClass *class)
+{
+ return mono_property_bag_get (&class->infrequent_data, PROP_EXT);
+}
+
+void
+mono_class_set_ext (MonoClass *class, MonoClassExt *ext)
+{
+ ext->head.tag = PROP_EXT;
+ mono_property_bag_add (&class->infrequent_data, ext);
+}
+
+typedef struct {
+ MonoPropertyBagItem head;
+ guint32 value;
+} Uint32Property;
+
+guint32
+mono_class_get_ref_info_handle (MonoClass *class)
+{
+ Uint32Property *prop = mono_property_bag_get (&class->infrequent_data, PROP_REF_INFO_HANDLE);
+ return prop ? prop->value : 0;
+}
+
+guint32
+mono_class_set_ref_info_handle (MonoClass *class, guint32 value)
+{
+ if (!value) {
+ Uint32Property *prop = mono_property_bag_get (&class->infrequent_data, PROP_REF_INFO_HANDLE);
+ if (prop)
+ prop->value = 0;
+ return 0;
+ }
+
+ Uint32Property *prop = mono_class_alloc (class, sizeof (Uint32Property));
+ prop->head.tag = PROP_REF_INFO_HANDLE;
+ prop->value = value;
+ prop = mono_property_bag_add (&class->infrequent_data, prop);
+ return prop->value;
+}
#include <mono/metadata/object.h>
#include <mono/metadata/mempool.h>
#include <mono/metadata/metadata-internals.h>
+#include <mono/metadata/property-bag.h>
#include <mono/io-layer/io-layer.h>
#include "mono/utils/mono-compiler.h"
#include "mono/utils/mono-error.h"
} MonoMarshalField;
typedef struct {
+ MonoPropertyBagItem head;
+
guint32 native_size, min_align;
guint32 num_fields;
MonoMethod *ptr_to_str;
* be used for fields which are only used in like 5% of all classes.
*/
typedef struct {
+ MonoPropertyBagItem head;
+
struct {
#if MONO_SMALL_CONFIG
guint16 first, count;
int generic_param_token; /* for generic param types, both var and mvar */
} sizes;
- /* A GC handle pointing to the corresponding type builder/generic param builder */
- guint32 ref_info_handle;
-
- /* loaded on demand */
- MonoMarshalType *marshal_info;
-
/*
* Field information: Type and location from object base
*/
/* Generic vtable. Initialized by a call to mono_class_setup_vtable () */
MonoMethod **vtable;
- /* Rarely used fields of classes */
- MonoClassExt *ext;
+ /* Infrequently used items. See class-accessors.c: InfrequentDataKind for what goes into here. */
+ MonoPropertyBag infrequent_data;
};
typedef struct {
void
mono_class_set_field_count (MonoClass *klass, guint32 count);
+MonoMarshalType*
+mono_class_get_marshal_info (MonoClass *class);
+
+void
+mono_class_set_marshal_info (MonoClass *class, MonoMarshalType *marshal_info);
+
+MonoClassExt*
+mono_class_get_ext (MonoClass *class);
+
+void
+mono_class_set_ext (MonoClass *class, MonoClassExt *ext);
+
+guint32
+mono_class_get_ref_info_handle (MonoClass *class);
+
+guint32
+mono_class_set_ref_info_handle (MonoClass *class, guint32 value);
+
/*Now that everything has been defined, let's include the inline functions */
#include <mono/metadata/class-inlines.h>
enclosing = mono_class_from_typeref_checked (image, MONO_TOKEN_TYPE_REF | idx, error);
return_val_if_nok (error, NULL);
- if (enclosing->nested_classes_inited && enclosing->ext) {
+ MonoClassExt *ext = mono_class_get_ext (enclosing);
+ if (enclosing->nested_classes_inited && ext) {
/* Micro-optimization: don't scan the metadata tables if enclosing is already inited */
- for (tmp = enclosing->ext->nested_classes; tmp; tmp = tmp->next) {
+ for (tmp = ext->nested_classes; tmp; tmp = tmp->next) {
res = (MonoClass *)tmp->data;
if (strcmp (res->name, name) == 0)
return res;
guint32 last;
int first, count;
- if (klass->ext && klass->ext->properties)
+ MonoClassExt *ext = mono_class_get_ext (klass);
+ if (ext && ext->properties)
return;
if (mono_class_is_ginst (klass)) {
if (mono_class_set_type_load_failure_causedby_class (klass, gklass, "Generic type definition failed to load"))
return;
- properties = mono_class_new0 (klass, MonoProperty, gklass->ext->property.count + 1);
+ MonoClassExt *gext = mono_class_get_ext (gklass);
+ properties = mono_class_new0 (klass, MonoProperty, gext->property.count + 1);
- for (i = 0; i < gklass->ext->property.count; i++) {
+ for (i = 0; i < gext->property.count; i++) {
MonoError error;
MonoProperty *prop = &properties [i];
- *prop = gklass->ext->properties [i];
+ *prop = gext->properties [i];
if (prop->get)
prop->get = mono_class_inflate_generic_method_full_checked (
prop->parent = klass;
}
- first = gklass->ext->property.first;
- count = gklass->ext->property.count;
+ first = gext->property.first;
+ count = gext->property.count;
} else {
first = mono_metadata_properties_from_typedef (klass->image, mono_metadata_token_index (klass->type_token) - 1, &last);
count = last - first;
}
mono_class_alloc_ext (klass);
+ ext = mono_class_get_ext (klass);
mono_image_lock (klass->image);
- if (klass->ext->properties) {
+ if (ext->properties) {
/* We leak 'properties' which was allocated from the image mempool */
mono_image_unlock (klass->image);
return;
}
- klass->ext->property.first = first;
- klass->ext->property.count = count;
+ ext->property.first = first;
+ ext->property.count = count;
/* Flush any pending writes as we do double checked locking on klass->ext->properties */
mono_memory_barrier ();
/* Leave this assignment as the last op in the function */
- klass->ext->properties = properties;
+ ext->properties = properties;
mono_image_unlock (klass->image);
}
guint32 last;
MonoEvent *events;
- if (klass->ext && klass->ext->events)
+ MonoClassExt *ext = mono_class_get_ext (klass);
+ if (ext && ext->events)
return;
if (mono_class_is_ginst (klass)) {
if (mono_class_set_type_load_failure_causedby_class (klass, gklass, "Generic type definition failed to load"))
return;
- first = gklass->ext->event.first;
- count = gklass->ext->event.count;
+ MonoClassExt *gext = mono_class_get_ext (gklass);
+ first = gext->event.first;
+ count = gext->event.count;
events = mono_class_new0 (klass, MonoEvent, count);
for (i = 0; i < count; i++) {
MonoError error;
MonoEvent *event = &events [i];
- MonoEvent *gevent = &gklass->ext->events [i];
+ MonoEvent *gevent = &gext->events [i];
mono_error_init (&error); //since we do conditional calls, we must ensure the default value is ok
}
mono_class_alloc_ext (klass);
+ ext = mono_class_get_ext (klass);
mono_image_lock (klass->image);
- if (klass->ext->events) {
+ if (ext->events) {
mono_image_unlock (klass->image);
return;
}
- klass->ext->event.first = first;
- klass->ext->event.count = count;
+ ext->event.first = first;
+ ext->event.count = count;
/* Flush any pending writes as we do double checked locking on klass->ext.events */
mono_memory_barrier ();
/* Leave this assignment as the last op in the function */
- klass->ext->events = events;
+ ext->events = events;
mono_image_unlock (klass->image);
}
mono_class_set_failure (klass, mono_error_box (&prepared_error, klass->image));
mono_error_cleanup (&prepared_error);
} else if (eclass->enumtype && !mono_class_enum_basetype (eclass)) {
- if (!eclass->ref_info_handle || eclass->wastypebuilder) {
+ guint32 ref_info_handle = mono_class_get_ref_info_handle (eclass);
+ if (!ref_info_handle || eclass->wastypebuilder) {
g_warning ("Only incomplete TypeBuilder objects are allowed to be an enum without base_type");
- g_assert (eclass->ref_info_handle && !eclass->wastypebuilder);
+ g_assert (ref_info_handle && !eclass->wastypebuilder);
}
/* element_size -1 is ok as this is not an instantitable type*/
klass->sizes.element_size = -1;
g_assert (field->type->attrs & FIELD_ATTRIBUTE_HAS_DEFAULT);
- if (!klass->ext || !klass->ext->field_def_values) {
+ MonoClassExt *ext = mono_class_get_ext (klass);
+ if (!ext || !ext->field_def_values) {
MonoFieldDefaultValue *def_values;
mono_class_alloc_ext (klass);
+ ext = mono_class_get_ext (klass);
def_values = (MonoFieldDefaultValue *)mono_class_alloc0 (klass, sizeof (MonoFieldDefaultValue) * mono_class_get_field_count (klass));
mono_image_lock (klass->image);
mono_memory_barrier ();
- if (!klass->ext->field_def_values)
- klass->ext->field_def_values = def_values;
+ if (!ext->field_def_values)
+ ext->field_def_values = def_values;
mono_image_unlock (klass->image);
}
field_index = mono_field_get_index (field);
- if (!klass->ext->field_def_values [field_index].data) {
+ if (!ext->field_def_values [field_index].data) {
cindex = mono_metadata_get_constant_index (field->parent->image, mono_class_get_field_token (field), 0);
if (!cindex)
return NULL;
g_assert (!(field->type->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA));
mono_metadata_decode_row (&field->parent->image->tables [MONO_TABLE_CONSTANT], cindex - 1, constant_cols, MONO_CONSTANT_SIZE);
- klass->ext->field_def_values [field_index].def_type = (MonoTypeEnum)constant_cols [MONO_CONSTANT_TYPE];
- klass->ext->field_def_values [field_index].data = (const char *)mono_metadata_blob_heap (field->parent->image, constant_cols [MONO_CONSTANT_VALUE]);
+ ext->field_def_values [field_index].def_type = (MonoTypeEnum)constant_cols [MONO_CONSTANT_TYPE];
+ ext->field_def_values [field_index].data = (const char *)mono_metadata_blob_heap (field->parent->image, constant_cols [MONO_CONSTANT_VALUE]);
}
- *def_type = klass->ext->field_def_values [field_index].def_type;
- return klass->ext->field_def_values [field_index].data;
+ *def_type = ext->field_def_values [field_index].def_type;
+ return ext->field_def_values [field_index].data;
}
static int
mono_property_get_index (MonoProperty *prop)
{
- int index = prop - prop->parent->ext->properties;
+ MonoClassExt *ext = mono_class_get_ext (prop->parent);
+ int index = prop - ext->properties;
- g_assert (index >= 0 && index < prop->parent->ext->property.count);
+ g_assert (index >= 0 && index < ext->property.count);
return index;
}
*/
if (image_is_dynamic (klass->image)) {
+ MonoClassExt *ext = mono_class_get_ext (klass);
int prop_index = mono_property_get_index (property);
- if (klass->ext->prop_def_values && klass->ext->prop_def_values [prop_index].data) {
- *def_type = klass->ext->prop_def_values [prop_index].def_type;
- return klass->ext->prop_def_values [prop_index].data;
+ if (ext->prop_def_values && ext->prop_def_values [prop_index].data) {
+ *def_type = ext->prop_def_values [prop_index].def_type;
+ return ext->prop_def_values [prop_index].data;
}
return NULL;
}
int i;
while (klass) {
- if (klass->ext) {
- for (i = 0; i < klass->ext->event.count; ++i) {
- if (&klass->ext->events [i] == event)
- return mono_metadata_make_token (MONO_TABLE_EVENT, klass->ext->event.first + i + 1);
+ MonoClassExt *ext = mono_class_get_ext (klass);
+ if (ext) {
+ for (i = 0; i < ext->event.count; ++i) {
+ if (&ext->events [i] == event)
+ return mono_metadata_make_token (MONO_TABLE_EVENT, ext->event.first + i + 1);
}
}
klass = klass->parent;
MonoProperty* p;
int i = 0;
gpointer iter = NULL;
+ MonoClassExt *ext = mono_class_get_ext (klass);
while ((p = mono_class_get_properties (klass, &iter))) {
- if (&klass->ext->properties [i] == prop)
- return mono_metadata_make_token (MONO_TABLE_PROPERTY, klass->ext->property.first + i + 1);
+ if (&ext->properties [i] == prop)
+ return mono_metadata_make_token (MONO_TABLE_PROPERTY, ext->property.first + i + 1);
i ++;
}
}
/* interface_offsets might not be set for dynamic classes */
- if (oklass->ref_info_handle && !oklass->interface_bitmap) {
+ if (mono_class_get_ref_info_handle (oklass) && !oklass->interface_bitmap) {
/*
* oklass might be a generic type parameter but they have
* interface_offsets set.
{
mono_class_setup_properties (klass);
- return klass->ext->property.count;
+ return mono_class_get_ext (klass)->property.count;
}
/**
{
mono_class_setup_events (klass);
- return klass->ext->event.count;
+ return mono_class_get_ext (klass)->event.count;
}
/**
return NULL;
if (!*iter) {
mono_class_setup_properties (klass);
+ MonoClassExt *ext = mono_class_get_ext (klass);
/* start from the first */
- if (klass->ext->property.count) {
- *iter = &klass->ext->properties [0];
+ if (ext->property.count) {
+ *iter = &ext->properties [0];
return (MonoProperty *)*iter;
} else {
/* no fields */
}
property = (MonoProperty *)*iter;
property++;
- if (property < &klass->ext->properties [klass->ext->property.count]) {
+ MonoClassExt *ext = mono_class_get_ext (klass);
+ if (property < &ext->properties [ext->property.count]) {
*iter = property;
return (MonoProperty *)*iter;
}
return NULL;
if (!*iter) {
mono_class_setup_events (klass);
+ MonoClassExt *ext = mono_class_get_ext (klass);
/* start from the first */
- if (klass->ext->event.count) {
- *iter = &klass->ext->events [0];
+ if (ext->event.count) {
+ *iter = &ext->events [0];
return (MonoEvent *)*iter;
} else {
/* no fields */
}
event = (MonoEvent *)*iter;
event++;
- if (event < &klass->ext->events [klass->ext->event.count]) {
+ MonoClassExt *ext = mono_class_get_ext (klass);
+ if (event < &ext->events [ext->event.count]) {
*iter = event;
return (MonoEvent *)*iter;
}
mono_memory_barrier ();
if (!klass->nested_classes_inited) {
- klass->ext->nested_classes = nested_classes;
+ mono_class_get_ext (klass)->nested_classes = nested_classes;
mono_memory_barrier ();
klass->nested_classes_inited = TRUE;
}
setup_nested_types (klass);
if (!*iter) {
+ MonoClassExt *ext = mono_class_get_ext (klass);
/* start from the first */
- if (klass->ext && klass->ext->nested_classes) {
- *iter = klass->ext->nested_classes;
- return (MonoClass *)klass->ext->nested_classes->data;
+ if (ext && ext->nested_classes) {
+ *iter = ext->nested_classes;
+ return (MonoClass *)ext->nested_classes->data;
} else {
/* no nested types */
return NULL;
g_assert (field->type->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA);
- if (!klass->ext || !klass->ext->field_def_values) {
+ MonoClassExt *ext = mono_class_get_ext (klass);
+ if (!ext || !ext->field_def_values) {
mono_class_alloc_ext (klass);
+ ext = mono_class_get_ext (klass);
field_def_values = (MonoFieldDefaultValue *)mono_class_alloc0 (klass, sizeof (MonoFieldDefaultValue) * mono_class_get_field_count (klass));
mono_image_lock (klass->image);
- if (!klass->ext->field_def_values)
- klass->ext->field_def_values = field_def_values;
+ if (!ext->field_def_values)
+ ext->field_def_values = field_def_values;
mono_image_unlock (klass->image);
}
field_index = mono_field_get_index (field);
- if (!klass->ext->field_def_values [field_index].data && !image_is_dynamic (klass->image)) {
+ if (!ext->field_def_values [field_index].data && !image_is_dynamic (klass->image)) {
int first_field_idx = mono_class_get_first_field_idx (klass);
mono_metadata_field_info (field->parent->image, first_field_idx + field_index, NULL, &rva, NULL);
if (!rva)
g_warning ("field %s in %s should have RVA data, but hasn't", mono_field_get_name (field), field->parent->name);
- klass->ext->field_def_values [field_index].data = mono_image_rva_map (field->parent->image, rva);
+ ext->field_def_values [field_index].data = mono_image_rva_map (field->parent->image, rva);
}
- return klass->ext->field_def_values [field_index].data;
+ return ext->field_def_values [field_index].data;
}
/**
{
MonoClassExt *ext;
- if (klass->ext)
+ if (mono_class_get_ext (klass))
return;
ext = (MonoClassExt *)mono_class_alloc0 (klass, sizeof (MonoClassExt));
mono_image_lock (klass->image);
mono_memory_barrier ();
- if (!klass->ext)
- klass->ext = ext;
+ if (!mono_class_get_ext (klass))
+ mono_class_set_ext (klass, ext);
class_ext_size += sizeof (MonoClassExt);
++class_ext_count;
mono_image_unlock (klass->image);
static guint32
find_property_index (MonoClass *klass, MonoProperty *property) {
int i;
+ MonoClassExt *ext = mono_class_get_ext (klass);
- for (i = 0; i < klass->ext->property.count; ++i) {
- if (property == &klass->ext->properties [i])
- return klass->ext->property.first + 1 + i;
+ for (i = 0; i < ext->property.count; ++i) {
+ if (property == &ext->properties [i])
+ return ext->property.first + 1 + i;
}
return 0;
}
static guint32
find_event_index (MonoClass *klass, MonoEvent *event) {
int i;
+ MonoClassExt *ext = mono_class_get_ext (klass);
- for (i = 0; i < klass->ext->event.count; ++i) {
- if (event == &klass->ext->events [i])
- return klass->ext->event.first + 1 + i;
+ for (i = 0; i < ext->event.count; ++i) {
+ if (event == &ext->events [i])
+ return ext->event.first + 1 + i;
}
return 0;
}
if (image_is_dynamic (field->parent->image)) {
MonoClass *klass = field->parent;
int fidx = field - klass->fields;
+ MonoClassExt *ext = mono_class_get_ext (klass);
+
+ g_assert (ext);
+ g_assert (ext->field_def_values);
+ def_type = ext->field_def_values [fidx].def_type;
+ def_value = ext->field_def_values [fidx].data;
- g_assert (fidx >= 0 && fidx < mono_class_get_field_count (klass));
- g_assert (klass->ext);
- g_assert (klass->ext->field_def_values);
- def_type = klass->ext->field_def_values [fidx].def_type;
- def_value = klass->ext->field_def_values [fidx].data;
if (def_type == MONO_TYPE_END) {
mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
return NULL;
mono_marshal_load_type_info (klass);
- if (klass->marshal_info->str_to_ptr)
- return klass->marshal_info->str_to_ptr;
+ MonoMarshalType *marshal_info = mono_class_get_marshal_info (klass);
+ if (marshal_info->str_to_ptr)
+ return marshal_info->str_to_ptr;
if (!stoptr)
stoptr = mono_class_get_method_from_name (mono_defaults.marshal_class, "StructureToPtr", 3);
mono_mb_free (mb);
mono_marshal_lock ();
- if (!klass->marshal_info->str_to_ptr)
- klass->marshal_info->str_to_ptr = res;
+ if (!marshal_info->str_to_ptr)
+ marshal_info->str_to_ptr = res;
else
- res = klass->marshal_info->str_to_ptr;
+ res = marshal_info->str_to_ptr;
mono_marshal_unlock ();
return res;
}
mono_marshal_load_type_info (klass);
- if (klass->marshal_info->ptr_to_str)
- return klass->marshal_info->ptr_to_str;
+ MonoMarshalType *marshal_info = mono_class_get_marshal_info (klass);
+ if (marshal_info->ptr_to_str)
+ return marshal_info->ptr_to_str;
if (!ptostr) {
MonoMethodSignature *sig;
mono_mb_free (mb);
mono_marshal_lock ();
- if (!klass->marshal_info->ptr_to_str)
- klass->marshal_info->ptr_to_str = res;
+ if (!marshal_info->ptr_to_str)
+ marshal_info->ptr_to_str = res;
else
- res = klass->marshal_info->ptr_to_str;
+ res = marshal_info->ptr_to_str;
mono_marshal_unlock ();
return res;
}
/**
* mono_marshal_load_type_info:
*
- * Initialize klass->marshal_info using information from metadata. This function can
+ * Initialize klass::marshal_info using information from metadata. This function can
* recursively call itself, and the caller is responsible to avoid that by calling
* mono_marshal_is_loading_type_info () beforehand.
*
g_assert (klass != NULL);
- if (klass->marshal_info)
- return klass->marshal_info;
+ info = mono_class_get_marshal_info (klass);
+ if (info)
+ return info;
if (!klass->inited)
mono_class_init (klass);
- if (klass->marshal_info)
- return klass->marshal_info;
+ info = mono_class_get_marshal_info (klass);
+ if (info)
+ return info;
/*
* This function can recursively call itself, so we keep the list of classes which are
mono_native_tls_set_value (load_type_info_tls_id, loads_list);
mono_marshal_lock ();
- if (!klass->marshal_info) {
+ MonoMarshalType *info2 = mono_class_get_marshal_info (klass);
+ if (!info2) {
/*We do double-checking locking on marshal_info */
mono_memory_barrier ();
- klass->marshal_info = info;
+ mono_class_set_marshal_info (klass, info);
++class_marshal_info_count;
+ info2 = info;
}
mono_marshal_unlock ();
- return klass->marshal_info;
+ return info2;
}
/**
*/
gint32
mono_class_native_size (MonoClass *klass, guint32 *align)
-{
- if (!klass->marshal_info) {
+{
+ MonoMarshalType *info = mono_class_get_marshal_info (klass);
+ if (!info) {
if (mono_marshal_is_loading_type_info (klass)) {
if (align)
*align = 0;
} else {
mono_marshal_load_type_info (klass);
}
+ info = mono_class_get_marshal_info (klass);
}
if (align)
- *align = klass->marshal_info->min_align;
+ *align = info->min_align;
- return klass->marshal_info->native_size;
+ return info->native_size;
}
/*
return event;
gtd = mono_class_get_generic_class (event->parent)->container_class;
- offset = event - event->parent->ext->events;
- return gtd->ext->events + offset;
+ offset = event - mono_class_get_ext (event->parent)->events;
+ return mono_class_get_ext (gtd)->events + offset;
}
/*
return property;
gtd = mono_class_get_generic_class (property->parent)->container_class;
- offset = property - property->parent->ext->properties;
- return gtd->ext->properties + offset;
+ offset = property - mono_class_get_ext (property->parent)->properties;
+ return mono_class_get_ext (gtd)->properties + offset;
}
MonoWrapperCaches*
--- /dev/null
+
+/*
+ * property-bag.c: Linearizable property bag.
+ *
+ * Authors:
+ * Rodrigo Kumpera (kumpera@gmail.com)
+ *
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#include <mono/metadata/property-bag.h>
+#include <mono/utils/atomic.h>
+#include <mono/utils/mono-membar.h>
+
+void*
+mono_property_bag_get (MonoPropertyBag *bag, int tag)
+{
+ MonoPropertyBagItem *item;
+
+ for (item = bag->head; item && item->tag <= tag; item = item->next) {
+ if (item->tag == tag)
+ return item;
+ }
+ return NULL;
+}
+
+void*
+mono_property_bag_add (MonoPropertyBag *bag, void *value)
+{
+ MonoPropertyBagItem *cur, **prev, *item = value;
+ int tag = item->tag;
+ mono_memory_barrier (); //publish the values in value
+
+retry:
+ prev = &bag->head;
+ while (1) {
+ cur = *prev;
+ if (!cur || cur->tag > tag) {
+ item->next = cur;
+ if (InterlockedCompareExchangePointer ((void*)prev, item, cur) == cur)
+ return item;
+ goto retry;
+ } else if (cur->tag == tag) {
+ return cur;
+ } else {
+ prev = &cur->next;
+ }
+ }
+ return value;
+}
--- /dev/null
+/*
+ * property-bag.h: Linearizable property bag.
+ *
+ * Authors:
+ * Rodrigo Kumpera (kumpera@gmail.com)
+ *
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+#ifndef __MONO_METADATA_PROPERTY_BAG_H__
+#define __MONO_METADATA_PROPERTY_BAG_H__
+
+#include <mono/utils/mono-compiler.h>
+
+typedef struct _MonoPropertyBagItem MonoPropertyBagItem;
+
+struct _MonoPropertyBagItem {
+ MonoPropertyBagItem *next;
+ int tag;
+};
+
+typedef struct {
+ MonoPropertyBagItem *head;
+} MonoPropertyBag;
+
+void* mono_property_bag_get (MonoPropertyBag *bag, int tag);
+void* mono_property_bag_add (MonoPropertyBag *bag, void *value);
+
+#endif
mono_class_get_ref_info (MonoClass *klass)
{
MONO_REQ_GC_UNSAFE_MODE;
+ guint32 ref_info_handle = mono_class_get_ref_info_handle (klass);
- if (klass->ref_info_handle == 0)
+ if (ref_info_handle == 0)
return NULL;
else
- return mono_gchandle_get_target (klass->ref_info_handle);
+ return mono_gchandle_get_target (ref_info_handle);
}
void
{
MONO_REQ_GC_UNSAFE_MODE;
- klass->ref_info_handle = mono_gchandle_new ((MonoObject*)obj, FALSE);
+ guint32 candidate = mono_gchandle_new ((MonoObject*)obj, FALSE);
+ guint32 handle = mono_class_set_ref_info_handle (klass, candidate);
++class_ref_info_handle_count;
- g_assert (klass->ref_info_handle != 0);
+
+ if (handle != candidate)
+ mono_gchandle_free (candidate);
}
void
mono_class_free_ref_info (MonoClass *klass)
{
MONO_REQ_GC_NEUTRAL_MODE;
+ guint32 handle = mono_class_get_ref_info_handle (klass);
- if (klass->ref_info_handle) {
- mono_gchandle_free (klass->ref_info_handle);
- klass->ref_info_handle = 0;
+ if (handle) {
+ mono_gchandle_free (handle);
+ mono_class_set_ref_info_handle (klass, 0);
}
}
mono_declsec_flags_from_class (MonoClass *klass)
{
if (mono_class_get_flags (klass) & TYPE_ATTRIBUTE_HAS_SECURITY) {
- if (!klass->ext || !klass->ext->declsec_flags) {
+ MonoClassExt *ext = mono_class_get_ext (klass);
+ if (!ext || !ext->declsec_flags) {
guint32 idx;
idx = mono_metadata_token_index (klass->type_token);
idx |= MONO_HAS_DECL_SECURITY_TYPEDEF;
mono_loader_lock ();
mono_class_alloc_ext (klass);
+ ext = mono_class_get_ext (klass);
mono_loader_unlock ();
/* we cache the flags on classes */
- klass->ext->declsec_flags = mono_declsec_get_flags (klass->image, idx);
+ ext->declsec_flags = mono_declsec_get_flags (klass->image, idx);
}
- return klass->ext->declsec_flags;
+ return ext->declsec_flags;
}
return 0;
}
table->next_idx ++;
/* Emit nested types */
- if (klass->ext && klass->ext->nested_classes) {
+ MonoClassExt *ext = mono_class_get_ext (klass);
+ if (ext && ext->nested_classes) {
GList *tmp;
- for (tmp = klass->ext->nested_classes; tmp; tmp = tmp->next)
+ for (tmp = ext->nested_classes; tmp; tmp = tmp->next)
mono_image_fill_export_table_from_class (domain, (MonoClass *)tmp->data, module_index, table->next_idx - 1, assembly);
}
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
MonoReflectionFieldBuilder *fb;
MonoClassField *field;
+ MonoClassExt *ext;
MonoImage *image = klass->image;
const char *p, *p2;
int i, instance_size, packing_size = 0;
klass->fields = image_g_new0 (image, MonoClassField, fcount);
mono_class_alloc_ext (klass);
- klass->ext->field_def_values = image_g_new0 (image, MonoFieldDefaultValue, fcount);
+ ext = mono_class_get_ext (klass);
+ ext->field_def_values = image_g_new0 (image, MonoFieldDefaultValue, fcount);
/*
This is, guess what, a hack.
The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
size_t size = mono_array_length (rva_data);
char *data = (char *)mono_image_alloc (klass->image, size);
memcpy (data, base, size);
- klass->ext->field_def_values [i].data = data;
+ ext->field_def_values [i].data = data;
}
if (fb->offset != -1)
field->offset = fb->offset;
if (fb->def_value) {
MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
- idx = mono_dynimage_encode_constant (assembly, fb->def_value, &klass->ext->field_def_values [i].def_type);
+ idx = mono_dynimage_encode_constant (assembly, fb->def_value, &ext->field_def_values [i].def_type);
/* Copy the data from the blob since it might get realloc-ed */
p = assembly->blob.data + idx;
len = mono_metadata_decode_blob_size (p, &p2);
len += p2 - p;
- klass->ext->field_def_values [i].data = (const char *)mono_image_alloc (image, len);
- memcpy ((gpointer)klass->ext->field_def_values [i].data, p, len);
+ ext->field_def_values [i].data = (const char *)mono_image_alloc (image, len);
+ memcpy ((gpointer)ext->field_def_values [i].data, p, len);
}
}
MonoReflectionPropertyBuilder *pb;
MonoImage *image = klass->image;
MonoProperty *properties;
+ MonoClassExt *ext;
int i;
mono_error_init (error);
- if (!klass->ext)
- klass->ext = image_g_new0 (image, MonoClassExt, 1);
+ ext = mono_class_get_ext (klass);
+ if (!ext)
+ mono_class_set_ext (klass, ext = image_g_new0 (image, MonoClassExt, 1));
- klass->ext->property.count = tb->properties ? mono_array_length (tb->properties) : 0;
- klass->ext->property.first = 0;
+ ext->property.count = tb->properties ? mono_array_length (tb->properties) : 0;
+ ext->property.first = 0;
- properties = image_g_new0 (image, MonoProperty, klass->ext->property.count);
- klass->ext->properties = properties;
- for (i = 0; i < klass->ext->property.count; ++i) {
+ properties = image_g_new0 (image, MonoProperty, ext->property.count);
+ ext->properties = properties;
+ for (i = 0; i < ext->property.count; ++i) {
pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
properties [i].parent = klass;
properties [i].attrs = pb->attrs;
guint32 len, idx;
const char *p, *p2;
MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
- if (!klass->ext->prop_def_values)
- klass->ext->prop_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->ext->property.count);
+ if (!ext->prop_def_values)
+ ext->prop_def_values = image_g_new0 (image, MonoFieldDefaultValue, ext->property.count);
properties [i].attrs |= PROPERTY_ATTRIBUTE_HAS_DEFAULT;
- idx = mono_dynimage_encode_constant (assembly, pb->def_value, &klass->ext->prop_def_values [i].def_type);
+ idx = mono_dynimage_encode_constant (assembly, pb->def_value, &ext->prop_def_values [i].def_type);
/* Copy the data from the blob since it might get realloc-ed */
p = assembly->blob.data + idx;
len = mono_metadata_decode_blob_size (p, &p2);
len += p2 - p;
- klass->ext->prop_def_values [i].data = (const char *)mono_image_alloc (image, len);
- memcpy ((gpointer)klass->ext->prop_def_values [i].data, p, len);
+ ext->prop_def_values [i].data = (const char *)mono_image_alloc (image, len);
+ memcpy ((gpointer)ext->prop_def_values [i].data, p, len);
}
}
}
MonoReflectionEventBuilder *eb;
MonoImage *image = klass->image;
MonoEvent *events;
+ MonoClassExt *ext;
int i;
mono_error_init (error);
- if (!klass->ext)
- klass->ext = image_g_new0 (image, MonoClassExt, 1);
+ ext = mono_class_get_ext (klass);
+ if (!ext)
+ mono_class_set_ext (klass, ext = image_g_new0 (image, MonoClassExt, 1));
- klass->ext->event.count = tb->events ? mono_array_length (tb->events) : 0;
- klass->ext->event.first = 0;
+ ext->event.count = tb->events ? mono_array_length (tb->events) : 0;
+ ext->event.first = 0;
- events = image_g_new0 (image, MonoEvent, klass->ext->event.count);
- klass->ext->events = events;
- for (i = 0; i < klass->ext->event.count; ++i) {
+ events = image_g_new0 (image, MonoEvent, ext->event.count);
+ ext->events = events;
+ for (i = 0; i < ext->event.count; ++i) {
eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
events [i].parent = klass;
events [i].attrs = eb->attrs;
MonoType *subtype = mono_reflection_type_get_handle ((MonoReflectionType*)subtb, &error);
if (!is_ok (&error)) goto failure;
- klass->ext->nested_classes = g_list_prepend_image (klass->image, klass->ext->nested_classes, mono_class_from_mono_type (subtype));
+ mono_class_get_ext (klass)->nested_classes = g_list_prepend_image (klass->image, mono_class_get_ext (klass)->nested_classes, mono_class_from_mono_type (subtype));
}
}
encode_value (-1, p, &p);
} else {
encode_value (klass->vtable_size, p, &p);
- encode_value ((mono_class_is_gtd (klass) ? (1 << 8) : 0) | (no_special_static << 7) | (klass->has_static_refs << 6) | (klass->has_references << 5) | ((klass->blittable << 4) | ((klass->ext && klass->ext->nested_classes) ? 1 : 0) << 3) | (klass->has_cctor << 2) | (klass->has_finalize << 1) | klass->ghcimpl, p, &p);
+ encode_value ((mono_class_is_gtd (klass) ? (1 << 8) : 0) | (no_special_static << 7) | (klass->has_static_refs << 6) | (klass->has_references << 5) | ((klass->blittable << 4) | ((mono_class_get_ext (klass) && mono_class_get_ext (klass)->nested_classes) ? 1 : 0) << 3) | (klass->has_cctor << 2) | (klass->has_finalize << 1) | klass->ghcimpl, p, &p);
if (klass->has_cctor)
encode_method_ref (acfg, mono_class_get_cctor (klass), p, &p);
if (klass->has_finalize)