Merge pull request #3936 from kumpera/monoclass_reorg2
authorRodrigo Kumpera <kumpera@users.noreply.github.com>
Tue, 15 Nov 2016 01:18:26 +0000 (17:18 -0800)
committerGitHub <noreply@github.com>
Tue, 15 Nov 2016 01:18:26 +0000 (17:18 -0800)
More MonoClass reorg, replace 3 fields with a property bag

14 files changed:
mono/metadata/Makefile.am
mono/metadata/class-accessors.c
mono/metadata/class-internals.h
mono/metadata/class.c
mono/metadata/custom-attrs.c
mono/metadata/icall.c
mono/metadata/marshal.c
mono/metadata/metadata.c
mono/metadata/property-bag.c [new file with mode: 0644]
mono/metadata/property-bag.h [new file with mode: 0644]
mono/metadata/reflection.c
mono/metadata/sre-save.c
mono/metadata/sre.c
mono/mini/aot-compiler.c

index a48d586713f751a7f02520017476835819ec8c35..bc369533a3f86bdc79f4d09e1c21cce51c292667 100644 (file)
@@ -201,6 +201,8 @@ common_sources = \
        number-ms.h             \
        object-internals.h      \
        opcodes.c               \
+       property-bag.h  \
+       property-bag.c  \
        socket-io.c             \
        socket-io.h             \
        w32process.c            \
index 53e67682d53604ac205868943fada78ad4fc51b2..1ea2597599fba3ee870715c18c4dfadc4a086d20 100644 (file)
@@ -6,6 +6,12 @@
 #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*/
 
 /*
@@ -222,3 +228,58 @@ mono_class_set_field_count (MonoClass *klass, guint32 count)
                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;
+}
index afbae43bff65bd721ac8c95acd74a26aa17808c0..40a8780dbbdd228d24efcaba92c53aa823c47779 100644 (file)
@@ -9,6 +9,7 @@
 #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"
@@ -164,6 +165,8 @@ typedef struct {
 } MonoMarshalField;
 
 typedef struct {
+       MonoPropertyBagItem head;
+
        guint32 native_size, min_align;
        guint32 num_fields;
        MonoMethod *ptr_to_str;
@@ -232,6 +235,8 @@ typedef struct {
  * 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;
@@ -362,12 +367,6 @@ struct _MonoClass {
                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
         */
@@ -386,8 +385,8 @@ struct _MonoClass {
        /* 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 {
@@ -1494,6 +1493,24 @@ mono_class_get_field_count (MonoClass *klass);
 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>
 
index 163e3b9b2aff4c21655371a6cbc1a2bc9bd7378e..3f54ba7397c04d4e32e998a530b0d2a32b7bfd1c 100644 (file)
@@ -245,9 +245,10 @@ mono_class_from_typeref_checked (MonoImage *image, guint32 type_token, MonoError
                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;
@@ -2523,7 +2524,8 @@ mono_class_setup_properties (MonoClass *klass)
        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)) {
@@ -2534,13 +2536,14 @@ mono_class_setup_properties (MonoClass *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 (
@@ -2553,8 +2556,8 @@ mono_class_setup_properties (MonoClass *klass)
                        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;
@@ -2603,23 +2606,24 @@ mono_class_setup_properties (MonoClass *klass)
        }
 
        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);
 }
@@ -2655,7 +2659,8 @@ mono_class_setup_events (MonoClass *klass)
        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)) {
@@ -2666,8 +2671,9 @@ mono_class_setup_events (MonoClass *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);
 
@@ -2677,7 +2683,7 @@ mono_class_setup_events (MonoClass *klass)
                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
 
@@ -2766,22 +2772,23 @@ mono_class_setup_events (MonoClass *klass)
        }
 
        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);
 }
@@ -6765,9 +6772,10 @@ mono_bounded_array_class_get (MonoClass *eclass, guint32 rank, gboolean bounded)
                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;
@@ -7135,23 +7143,25 @@ mono_class_get_field_default_value (MonoClassField *field, MonoTypeEnum *def_typ
 
        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;
@@ -7159,20 +7169,21 @@ mono_class_get_field_default_value (MonoClassField *field, MonoTypeEnum *def_typ
                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;
 }
@@ -7197,10 +7208,11 @@ mono_class_get_property_default_value (MonoProperty *property, MonoTypeEnum *def
         */
 
        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;
        }
@@ -7220,10 +7232,11 @@ mono_class_get_event_token (MonoEvent *event)
        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;
@@ -7271,9 +7284,10 @@ mono_class_get_property_token (MonoProperty *prop)
                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 ++;
                }
@@ -8370,7 +8384,7 @@ mono_class_is_assignable_from (MonoClass *klass, MonoClass *oklass)
                }
 
                /* 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.
@@ -9117,7 +9131,7 @@ mono_class_num_properties (MonoClass *klass)
 {
        mono_class_setup_properties (klass);
 
-       return klass->ext->property.count;
+       return mono_class_get_ext (klass)->property.count;
 }
 
 /**
@@ -9131,7 +9145,7 @@ mono_class_num_events (MonoClass *klass)
 {
        mono_class_setup_events (klass);
 
-       return klass->ext->event.count;
+       return mono_class_get_ext (klass)->event.count;
 }
 
 /**
@@ -9316,9 +9330,10 @@ mono_class_get_properties (MonoClass* klass, gpointer *iter)
                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 */
@@ -9327,7 +9342,8 @@ mono_class_get_properties (MonoClass* klass, gpointer *iter)
        }
        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;
        }
@@ -9354,9 +9370,10 @@ mono_class_get_events (MonoClass* klass, gpointer *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 */
@@ -9365,7 +9382,8 @@ mono_class_get_events (MonoClass* klass, gpointer *iter)
        }
        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;
        }
@@ -9463,7 +9481,7 @@ setup_nested_types (MonoClass *klass)
 
        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;
        }
@@ -9495,10 +9513,11 @@ mono_class_get_nested_types (MonoClass* klass, gpointer *iter)
                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;
@@ -9637,28 +9656,30 @@ mono_field_get_rva (MonoClassField *field)
 
        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;
 }
 
 /**
@@ -10631,14 +10652,14 @@ mono_class_alloc_ext (MonoClass *klass)
 {
        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);
index 600a27e0765ba20e8109fb7678ec505053d6e17d..8e56148ab1cb8fd8994f2233b11deb542b1df47d 100644 (file)
@@ -134,10 +134,11 @@ find_field_index (MonoClass *klass, MonoClassField *field) {
 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;
 }
@@ -148,10 +149,11 @@ find_property_index (MonoClass *klass, MonoProperty *property) {
 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;
 }
index 9b5686568da3491507fa7ea5ff90469edea9dd81..29ee725a4db5e926d61af3cec194340f836c58a7 100644 (file)
@@ -2098,12 +2098,13 @@ ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *rfield)
        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;
index 11b688dbea39934fbf45e03c95b4a219d89a5edb..148f5bc251743e9d26bf104a8fc70b9c9c41d7cb 100644 (file)
@@ -9128,8 +9128,9 @@ mono_marshal_get_struct_to_ptr (MonoClass *klass)
 
        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);
@@ -9175,10 +9176,10 @@ mono_marshal_get_struct_to_ptr (MonoClass *klass)
        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;
 }
@@ -9201,8 +9202,9 @@ mono_marshal_get_ptr_to_struct (MonoClass *klass)
 
        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;
@@ -9253,10 +9255,10 @@ mono_marshal_get_ptr_to_struct (MonoClass *klass)
        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;
 }
@@ -11233,7 +11235,7 @@ mono_marshal_is_loading_type_info (MonoClass *klass)
 /**
  * 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.
  *
@@ -11252,14 +11254,16 @@ mono_marshal_load_type_info (MonoClass* klass)
 
        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
@@ -11381,15 +11385,17 @@ mono_marshal_load_type_info (MonoClass* klass)
        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;
 }
 
 /**
@@ -11401,8 +11407,9 @@ mono_marshal_load_type_info (MonoClass* klass)
  */
 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;
@@ -11410,12 +11417,13 @@ mono_class_native_size (MonoClass *klass, guint32 *align)
                } 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;
 }
 
 /*
index 36a954cd8b036e73716d1d806fd2a83a465f7098..e8a19188a757201581b562a6ce7309af31b420d5 100644 (file)
@@ -6634,8 +6634,8 @@ mono_metadata_get_corresponding_event_from_generic_type_definition (MonoEvent *e
                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;
 }
 
 /*
@@ -6652,8 +6652,8 @@ mono_metadata_get_corresponding_property_from_generic_type_definition (MonoPrope
                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*
diff --git a/mono/metadata/property-bag.c b/mono/metadata/property-bag.c
new file mode 100644 (file)
index 0000000..28e8113
--- /dev/null
@@ -0,0 +1,49 @@
+
+/*
+ * 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;
+}
diff --git a/mono/metadata/property-bag.h b/mono/metadata/property-bag.h
new file mode 100644 (file)
index 0000000..8f3f0ee
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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
index 88ecb5fddfdf84bb216c4259845dbc865569cf3e..c0c334a0f23e3b0671c51336e7144180378d7774 100644 (file)
@@ -89,11 +89,12 @@ gpointer
 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
@@ -101,19 +102,23 @@ mono_class_set_ref_info (MonoClass *klass, gpointer obj)
 {
        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);
        }
 }
 
@@ -2363,7 +2368,8 @@ guint32
 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);
@@ -2371,11 +2377,12 @@ mono_declsec_flags_from_class (MonoClass *klass)
                        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;
 }
index 2f32e315a429ce58d78d7d89f304bc1f491dc5d0..b52ff6c6df9543e60c7386f0af3b70cc829f9840 100644 (file)
@@ -1217,10 +1217,11 @@ mono_image_fill_export_table_from_class (MonoDomain *domain, MonoClass *klass,
        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);
        }
 
index 5b411fd05fe962e5a20dd28d65b86a2d49b360c5..3d73c7561332b5efbf78b0ed01f3c6b7f1240560 100644 (file)
@@ -3190,6 +3190,7 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
        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;
@@ -3215,7 +3216,8 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
        
        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.
@@ -3248,7 +3250,7 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
                        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;
@@ -3258,13 +3260,13 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
                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);
                }
        }
 
@@ -3278,19 +3280,21 @@ typebuilder_setup_properties (MonoClass *klass, MonoError *error)
        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;
@@ -3307,16 +3311,16 @@ typebuilder_setup_properties (MonoClass *klass, MonoError *error)
                        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);
                }
        }
 }
@@ -3328,19 +3332,21 @@ typebuilder_setup_events (MonoClass *klass, MonoError *error)
        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;
@@ -3467,7 +3473,7 @@ ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
 
                        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));
                }
        }
 
index b581dc35e4a9c19048a55e459b1e2ef039edcfb9..08ce2f067011cbd3024c0e9945fd235b803cf5fd 100644 (file)
@@ -6314,7 +6314,7 @@ emit_klass_info (MonoAotCompile *acfg, guint32 token)
                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)