Merge pull request #4727 from BrzVlad/fix-xamarin-studio
authorVlad Brezae <brezaevlad@gmail.com>
Mon, 24 Apr 2017 15:37:00 +0000 (18:37 +0300)
committerGitHub <noreply@github.com>
Mon, 24 Apr 2017 15:37:00 +0000 (18:37 +0300)
[metadata] Fix special static field access

mono/metadata/domain-internals.h
mono/metadata/domain.c
mono/metadata/object.c
mono/mini/jit-icalls.c
mono/mini/mini-amd64.h
mono/tests/Makefile.am
mono/tests/generic-special2.2.cs [new file with mode: 0644]
msvc/mono.def
msvc/monosgen.def

index 3cfa02246127b652ccfd974b097451047642283f..bdab742092f8c75340cf6bbaf3054bcbe9582356 100644 (file)
@@ -337,11 +337,6 @@ struct _MonoDomain {
        /* hashtables for Reflection handles */
        MonoGHashTable     *type_hash;
        MonoGHashTable     *refobject_hash;
-       /*
-        * A GC-tracked array to keep references to the static fields of types.
-        * See note [Domain Static Data Array].
-        */
-       gpointer           *static_data_array;
        /* maps class -> type initialization exception object */
        MonoGHashTable    *type_init_exception_hash;
        /* maps delegate trampoline addr -> delegate object */
@@ -579,9 +574,6 @@ MonoImage *mono_assembly_open_from_bundle (const char *filename,
                                           MonoImageOpenStatus *status,
                                           gboolean refonly);
 
-MONO_API void
-mono_domain_add_class_static_data (MonoDomain *domain, MonoClass *klass, gpointer data, guint32 *bitmap);
-
 MonoAssembly *
 mono_try_assembly_resolve (MonoDomain *domain, const char *fname, MonoAssembly *requesting, gboolean refonly, MonoError *error);
 
index fb2f414570f1c2ef90362d120f9fd6603f84bd89..2e6a52170078f5487e79fb00c2df5e32508b741b 100644 (file)
@@ -409,7 +409,6 @@ mono_domain_create (void)
        domain->assembly_bindings_parsed = FALSE;
        domain->class_vtable_array = g_ptr_array_new ();
        domain->proxy_vtable_hash = g_hash_table_new ((GHashFunc)mono_ptrarray_hash, (GCompareFunc)mono_ptrarray_equal);
-       domain->static_data_array = NULL;
        mono_jit_code_hash_init (&domain->jit_code_hash);
        domain->ldstr_table = mono_g_hash_table_new_type ((GHashFunc)mono_string_hash, (GCompareFunc)mono_string_equal, MONO_HASH_KEY_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain string constants table");
        domain->num_jit_info_tables = 1;
@@ -1150,10 +1149,6 @@ mono_domain_free (MonoDomain *domain, gboolean force)
        domain->class_vtable_array = NULL;
        g_hash_table_destroy (domain->proxy_vtable_hash);
        domain->proxy_vtable_hash = NULL;
-       if (domain->static_data_array) {
-               mono_gc_free_fixed (domain->static_data_array);
-               domain->static_data_array = NULL;
-       }
        mono_internal_hash_table_destroy (&domain->jit_code_hash);
 
        /*
@@ -1453,40 +1448,6 @@ mono_context_get_domain_id (MonoAppContext *context)
        return context->domain_id;
 }
 
-/* LOCKING: the caller holds the lock for this domain */
-void
-mono_domain_add_class_static_data (MonoDomain *domain, MonoClass *klass, gpointer data, guint32 *bitmap)
-{
-       /* Note [Domain Static Data Array]:
-        *
-        * Entry 0 in the array is the index of the next free slot.
-        * Entry 1 is the total size of the array.
-        */
-       int next;
-       if (domain->static_data_array) {
-               int size = GPOINTER_TO_INT (domain->static_data_array [1]);
-               next = GPOINTER_TO_INT (domain->static_data_array [0]);
-               if (next >= size) {
-                       /* 'data' is allocated by alloc_fixed */
-                       gpointer *new_array = (gpointer *)mono_gc_alloc_fixed (sizeof (gpointer) * (size * 2), MONO_GC_ROOT_DESCR_FOR_FIXED (size * 2), MONO_ROOT_SOURCE_DOMAIN, "static field list");
-                       mono_gc_memmove_aligned (new_array, domain->static_data_array, sizeof (gpointer) * size);
-                       size *= 2;
-                       new_array [1] = GINT_TO_POINTER (size);
-                       mono_gc_free_fixed (domain->static_data_array);
-                       domain->static_data_array = new_array;
-               }
-       } else {
-               int size = 32;
-               gpointer *new_array = (gpointer *)mono_gc_alloc_fixed (sizeof (gpointer) * size, MONO_GC_ROOT_DESCR_FOR_FIXED (size), MONO_ROOT_SOURCE_DOMAIN, "static field list");
-               next = 2;
-               new_array [0] = GINT_TO_POINTER (next);
-               new_array [1] = GINT_TO_POINTER (size);
-               domain->static_data_array = new_array;
-       }
-       domain->static_data_array [next++] = data;
-       domain->static_data_array [0] = GINT_TO_POINTER (next);
-}
-
 /**
  * mono_get_corlib:
  * Use this function to get the \c MonoImage* for the \c mscorlib.dll assembly
index ae6b5d774e3ecca34d6c374cff2e2b70fbdd3975..c23c56bafb87838a93505e21cb009b262b8edace 100644 (file)
@@ -1968,7 +1968,6 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *klass, MonoErro
                        /*g_print ("bitmap 0x%x for %s.%s (size: %d)\n", bitmap [0], klass->name_space, klass->name, class_size);*/
                        statics_gc_descr = mono_gc_make_descr_from_bitmap (bitmap, max_set + 1);
                        vt->vtable [klass->vtable_size] = mono_gc_alloc_fixed (class_size, statics_gc_descr, MONO_ROOT_SOURCE_STATIC, "managed static variables");
-                       mono_domain_add_class_static_data (domain, klass, vt->vtable [klass->vtable_size], NULL);
                        if (bitmap != default_bitmap)
                                g_free (bitmap);
                } else {
index b52edd4e404bf1fadba2233bdb25834d92dcf840..401ac247e2a0569fb100aa530f9df08cb1682c03 100644 (file)
@@ -888,11 +888,16 @@ mono_class_static_field_address (MonoDomain *domain, MonoClassField *field)
 
        //printf ("SFLDA1 %p\n", (char*)vtable->data + field->offset);
 
-       if (domain->special_static_fields && (addr = g_hash_table_lookup (domain->special_static_fields, field)))
+       if (field->offset == -1) {
+               /* Special static */
+               g_assert (domain->special_static_fields);
+               mono_domain_lock (domain);
+               addr = g_hash_table_lookup (domain->special_static_fields, field);
+               mono_domain_unlock (domain);
                addr = mono_get_special_static_data (GPOINTER_TO_UINT (addr));
-       else
+       } else {
                addr = (char*)mono_vtable_get_static_field_data (vtable) + field->offset;
-       
+       }
        return addr;
 }
 
index ace42c42331376aa3963e919f8a60b06dc6ead45..d13bca95ee1aa08a09ac3cde6c6ec05c3bbc4f13 100644 (file)
@@ -595,7 +595,7 @@ mono_arch_code_chunk_destroy (void *chunk);
 #define MONO_TRAMPOLINE_UNWINDINFO_SIZE(max_code_count) (mono_arch_unwindinfo_get_size (max_code_count))
 #define MONO_MAX_TRAMPOLINE_UNWINDINFO_SIZE (MONO_TRAMPOLINE_UNWINDINFO_SIZE(3))
 
-inline gboolean
+static inline gboolean
 mono_arch_unwindinfo_validate_size (GSList *unwind_ops, guint max_size)
 {
        guint current_size = mono_arch_unwindinfo_get_size (mono_arch_unwindinfo_get_code_count (unwind_ops));
@@ -607,7 +607,7 @@ mono_arch_unwindinfo_validate_size (GSList *unwind_ops, guint max_size)
 #define MONO_TRAMPOLINE_UNWINDINFO_SIZE(max_code_count) 0
 #define MONO_MAX_TRAMPOLINE_UNWINDINFO_SIZE 0
 
-inline gboolean
+static inline gboolean
 mono_arch_unwindinfo_validate_size (GSList *unwind_ops, guint max_size)
 {
        return TRUE;
index d4a62c67992d28561131c580018721bd68cea88c..abdbce8bd9d002dfed0fa40056d3adaf5507e3c1 100644 (file)
@@ -344,6 +344,7 @@ TESTS_CS_SRC=               \
        generic-static-methods.2.cs     \
        generic-null-call.2.cs  \
        generic-special.2.cs    \
+       generic-special2.2.cs   \
        generic-exceptions.2.cs \
        generic-virtual2.2.cs   \
        generic-valuetype-interface.2.cs        \
@@ -616,6 +617,7 @@ TESTS_GSHARED_SRC = \
        generic-tailcall2.2.cs                  \
        generic-array-exc.2.cs  \
        generic-special.2.cs                    \
+       generic-special2.2.cs   \
        generic-exceptions.2.cs \
        generic-delegate2.2.cs          \
        generic-virtual2.2.cs   \
diff --git a/mono/tests/generic-special2.2.cs b/mono/tests/generic-special2.2.cs
new file mode 100644 (file)
index 0000000..625d873
--- /dev/null
@@ -0,0 +1,54 @@
+using System;
+using System.Reflection;
+using System.IO;
+using System.Collections.Generic;
+using System.Threading;
+
+internal class GenericType<T> {
+       [ThreadStatic]
+       internal static object static_var;
+
+       public static void AccessStaticVar ()
+       {
+               if (static_var != null && static_var.GetType () != typeof (List<T>))
+                       throw new Exception ("Corrupted static var");
+               GenericType<T>.static_var = new List<T> ();
+       }
+}
+
+public static class Program {
+       private static bool stress;
+
+       /* Create a lot of static vars */
+       private static void CreateVTables ()
+       {
+               Type[] nullArgs = new Type[0];
+               Assembly ass = Assembly.GetAssembly (typeof (int));
+               foreach (Type type in ass.GetTypes ()) {
+                       try {
+                               Type inst = typeof (GenericType<>).MakeGenericType (type);
+                               Activator.CreateInstance (inst);
+                       } catch {
+                       }
+               }
+       }
+
+       private static void StressStaticFieldAddr ()
+       {
+               while (stress) {
+                       GenericType<object>.AccessStaticVar ();
+               }
+       }
+
+       public static void Main (string[] args)
+       {
+               Thread thread = new Thread (StressStaticFieldAddr);
+
+               stress = true;
+               thread.Start ();
+               CreateVTables ();
+               stress = false;
+
+               thread.Join ();
+       }
+}
index 52e1b14888e7ec27f5e4e52003bd6254949ce1b5..11039d6b3f92c91c1623bf1b8320dfb78ea17e7c 100644 (file)
@@ -243,7 +243,6 @@ mono_dl_fallback_register
 mono_dl_fallback_unregister
 mono_dl_open
 mono_dllmap_insert
-mono_domain_add_class_static_data
 mono_domain_assembly_open
 mono_domain_create
 mono_domain_create_appdomain
index 5c238113281f6de1c55010c93701817d63d81c24..35df803f15aab6025e95ea2fa45abf1a397402ca 100644 (file)
@@ -243,7 +243,6 @@ mono_dl_fallback_register
 mono_dl_fallback_unregister
 mono_dl_open
 mono_dllmap_insert
-mono_domain_add_class_static_data
 mono_domain_assembly_open
 mono_domain_create
 mono_domain_create_appdomain