From: Bernhard Urban Date: Tue, 15 Nov 2016 07:31:10 +0000 (+0100) Subject: Merge pull request #3961 from akoeplinger/ppc-parallelism X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=957d4804ab58d99538589cc58a3375298d675d92;hp=f53186653caea2cdbc21c892bdb1dcb667d449eb;p=mono.git Merge pull request #3961 from akoeplinger/ppc-parallelism [ci] Reduce make parallelism on ppc64 --- diff --git a/mono/metadata/Makefile.am b/mono/metadata/Makefile.am index a48d586713f..bc369533a3f 100644 --- a/mono/metadata/Makefile.am +++ b/mono/metadata/Makefile.am @@ -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 \ diff --git a/mono/metadata/class-accessors.c b/mono/metadata/class-accessors.c index 53e67682d53..1ea2597599f 100644 --- a/mono/metadata/class-accessors.c +++ b/mono/metadata/class-accessors.c @@ -6,6 +6,12 @@ #include +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; +} diff --git a/mono/metadata/class-internals.h b/mono/metadata/class-internals.h index afbae43bff6..40a8780dbbd 100644 --- a/mono/metadata/class-internals.h +++ b/mono/metadata/class-internals.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #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 diff --git a/mono/metadata/class.c b/mono/metadata/class.c index 163e3b9b2af..3f54ba7397c 100644 --- a/mono/metadata/class.c +++ b/mono/metadata/class.c @@ -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); diff --git a/mono/metadata/custom-attrs.c b/mono/metadata/custom-attrs.c index 600a27e0765..8e56148ab1c 100644 --- a/mono/metadata/custom-attrs.c +++ b/mono/metadata/custom-attrs.c @@ -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; } diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index 9b5686568da..29ee725a4db 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -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; diff --git a/mono/metadata/marshal.c b/mono/metadata/marshal.c index 11b688dbea3..148f5bc2517 100644 --- a/mono/metadata/marshal.c +++ b/mono/metadata/marshal.c @@ -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; } /* diff --git a/mono/metadata/metadata.c b/mono/metadata/metadata.c index 36a954cd8b0..e8a19188a75 100644 --- a/mono/metadata/metadata.c +++ b/mono/metadata/metadata.c @@ -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 index 00000000000..28e81138065 --- /dev/null +++ b/mono/metadata/property-bag.c @@ -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 +#include +#include + +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 index 00000000000..8f3f0ee26c2 --- /dev/null +++ b/mono/metadata/property-bag.h @@ -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 + +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 diff --git a/mono/metadata/reflection.c b/mono/metadata/reflection.c index 88ecb5fddfd..c0c334a0f23 100644 --- a/mono/metadata/reflection.c +++ b/mono/metadata/reflection.c @@ -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; } diff --git a/mono/metadata/sre-save.c b/mono/metadata/sre-save.c index 2f32e315a42..b52ff6c6df9 100644 --- a/mono/metadata/sre-save.c +++ b/mono/metadata/sre-save.c @@ -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); } diff --git a/mono/metadata/sre.c b/mono/metadata/sre.c index 5b411fd05fe..3d73c756133 100644 --- a/mono/metadata/sre.c +++ b/mono/metadata/sre.c @@ -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)); } } diff --git a/mono/mini/aot-compiler.c b/mono/mini/aot-compiler.c index b581dc35e4a..08ce2f06701 100644 --- a/mono/mini/aot-compiler.c +++ b/mono/mini/aot-compiler.c @@ -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) diff --git a/scripts/ci/run-test-default.sh b/scripts/ci/run-test-default.sh index 02097b59a0f..5f0767219f8 100755 --- a/scripts/ci/run-test-default.sh +++ b/scripts/ci/run-test-default.sh @@ -3,7 +3,9 @@ export TESTCMD=`dirname "${BASH_SOURCE[0]}"`/run-step.sh ${TESTCMD} --label=mini --timeout=5m make -w -C mono/mini -k check check-seq-points EMIT_NUNIT=1 +${TESTCMD} --label=compile-runtime-tests --timeout=20m make -w -C mono/tests -j4 tests ${TESTCMD} --label=runtime --timeout=160m make -w -C mono/tests -k test-wrench V=1 CI=1 CI_PR=${ghprbPullId} +${TESTCMD} --label=runtime-unit-tests --timeout=5m make -w -C mono/unit-tests -k check ${TESTCMD} --label=corlib --timeout=30m make -w -C mcs/class/corlib run-test ${TESTCMD} --label=verify --timeout=15m make -w -C runtime mcs-compileall ${TESTCMD} --label=profiler --timeout=30m make -w -C mono/profiler -k check @@ -23,6 +25,7 @@ then ${TESTCMD} --label=Windows.Forms --skip; else ${TESTCMD} --label=Windows.Forms --timeout=5m make -w -C mcs/class/System.Windows.Forms run-test fi ${TESTCMD} --label=System.Data --timeout=5m make -w -C mcs/class/System.Data run-test +if [[ ${label} == w* ]]; then ${TESTCMD} --label=Mono.Data.Sqlite --skip; else ${TESTCMD} --label=Mono.Data.Sqlite --timeout=5m make -w -C mcs/class/Mono.Data.Sqlite run-test; fi ${TESTCMD} --label=System.Data.OracleClient --timeout=5m make -w -C mcs/class/System.Data.OracleClient run-test; ${TESTCMD} --label=System.Design --timeout=5m make -w -C mcs/class/System.Design run-test; if [[ -n "${ghprbPullId}" ]] && [[ ${label} == w* ]]; then ${TESTCMD} --label=Mono.Posix --skip; else ${TESTCMD} --label=Mono.Posix --timeout=5m make -w -C mcs/class/Mono.Posix run-test; fi @@ -84,6 +87,7 @@ ${TESTCMD} --label=Microsoft.Build.Engine-14 --timeout=60m make -w -C mcs/class/ ${TESTCMD} --label=Microsoft.Build.Framework-14 --timeout=60m make -w -C mcs/class/Microsoft.Build.Framework run-test PROFILE=xbuild_14 ${TESTCMD} --label=Microsoft.Build.Tasks-14 --timeout=60m make -w -C mcs/class/Microsoft.Build.Tasks run-test PROFILE=xbuild_14 ${TESTCMD} --label=Microsoft.Build.Utilities-14 --timeout=60m make -w -C mcs/class/Microsoft.Build.Utilities run-test PROFILE=xbuild_14 +${TESTCMD} --label=System.IO.Compression --timeout=5m make -w -C mcs/class/System.IO.Compression run-test if [[ ${label} == osx-* ]] then ${TESTCMD} --label=ms-test-suite --timeout=15m make -w -C acceptance-tests check-ms-test-suite else ${TESTCMD} --label=ms-test-suite --skip;