[runtime] When attaching a tools thread, spin-wait for thread system init. Fixes...
[mono.git] / mono / utils / mono-codeman.c
index c8f746825355aff06999f7fb40de638b2f571403..30416858d9f0b868ffba274c587a7791558164eb 100644 (file)
@@ -26,6 +26,8 @@
 #include <nacl/nacl_dyncode.h>
 #include <mono/mini/mini.h>
 #endif
+#include <mono/utils/mono-mutex.h>
+
 
 static uintptr_t code_memory_used = 0;
 static size_t dynamic_code_alloc_count;
@@ -231,7 +233,7 @@ nacl_inverse_modify_patch_target (unsigned char *target)
 
 #define VALLOC_FREELIST_SIZE 16
 
-static CRITICAL_SECTION valloc_mutex;
+static mono_mutex_t valloc_mutex;
 static GHashTable *valloc_freelists;
 
 static void*
@@ -241,15 +243,15 @@ codechunk_valloc (void *preferred, guint32 size)
        GSList *freelist;
 
        if (!valloc_freelists) {
-               InitializeCriticalSection (&valloc_mutex);
+               mono_mutex_init_recursive (&valloc_mutex);
                valloc_freelists = g_hash_table_new (NULL, NULL);
        }
 
        /*
         * Keep a small freelist of memory blocks to decrease pressure on the kernel memory subsystem to avoid #3321.
         */
-       EnterCriticalSection (&valloc_mutex);
-       freelist = g_hash_table_lookup (valloc_freelists, GUINT_TO_POINTER (size));
+       mono_mutex_lock (&valloc_mutex);
+       freelist = (GSList *) g_hash_table_lookup (valloc_freelists, GUINT_TO_POINTER (size));
        if (freelist) {
                ptr = freelist->data;
                memset (ptr, 0, size);
@@ -260,7 +262,7 @@ codechunk_valloc (void *preferred, guint32 size)
                if (!ptr && preferred)
                        ptr = mono_valloc (NULL, size, MONO_PROT_RWX | ARCH_MAP_FLAGS);
        }
-       LeaveCriticalSection (&valloc_mutex);
+       mono_mutex_unlock (&valloc_mutex);
        return ptr;
 }
 
@@ -269,15 +271,15 @@ codechunk_vfree (void *ptr, guint32 size)
 {
        GSList *freelist;
 
-       EnterCriticalSection (&valloc_mutex);
-       freelist = g_hash_table_lookup (valloc_freelists, GUINT_TO_POINTER (size));
+       mono_mutex_lock (&valloc_mutex);
+       freelist = (GSList *) g_hash_table_lookup (valloc_freelists, GUINT_TO_POINTER (size));
        if (!freelist || g_slist_length (freelist) < VALLOC_FREELIST_SIZE) {
                freelist = g_slist_prepend (freelist, ptr);
                g_hash_table_insert (valloc_freelists, GUINT_TO_POINTER (size), freelist);
        } else {
                mono_vfree (ptr, size);
        }
-       LeaveCriticalSection (&valloc_mutex);
+       mono_mutex_unlock (&valloc_mutex);
 }              
 
 static void
@@ -290,7 +292,7 @@ codechunk_cleanup (void)
                return;
        g_hash_table_iter_init (&iter, valloc_freelists);
        while (g_hash_table_iter_next (&iter, &key, &value)) {
-               GSList *freelist = value;
+               GSList *freelist = (GSList *) value;
                GSList *l;
 
                for (l = freelist; l; l = l->next) {
@@ -329,7 +331,7 @@ mono_code_manager_cleanup (void)
 MonoCodeManager* 
 mono_code_manager_new (void)
 {
-       MonoCodeManager *cman = g_malloc0 (sizeof (MonoCodeManager));
+       MonoCodeManager *cman = (MonoCodeManager *) g_malloc0 (sizeof (MonoCodeManager));
        if (!cman)
                return NULL;
 #if defined(__native_client_codegen__) && defined(__native_client__)
@@ -486,11 +488,8 @@ mono_code_manager_foreach (MonoCodeManager *cman, MonoCodeManagerFunc func, void
 #if defined(__ppc__) || defined(__powerpc__)
 #define BIND_ROOM 4
 #endif
-#if defined(__arm__)
-#define BIND_ROOM 8
-#endif
 #if defined(TARGET_ARM64)
-#define BIND_ROOM 8
+#define BIND_ROOM 4
 #endif
 
 static CodeChunk*
@@ -527,15 +526,21 @@ new_codechunk (CodeChunk *last, int dynamic, int size)
                }
        }
 #ifdef BIND_ROOM
-       bsize = chunk_size / BIND_ROOM;
+       if (dynamic)
+               /* Reserve more space since there are no other chunks we might use if this one gets full */
+               bsize = (chunk_size * 2) / BIND_ROOM;
+       else
+               bsize = chunk_size / BIND_ROOM;
        if (bsize < MIN_BSIZE)
                bsize = MIN_BSIZE;
        bsize += MIN_ALIGN -1;
        bsize &= ~ (MIN_ALIGN - 1);
        if (chunk_size - size < bsize) {
                chunk_size = size + bsize;
-               chunk_size += pagesize - 1;
-               chunk_size &= ~ (pagesize - 1);
+               if (!dynamic) {
+                       chunk_size += pagesize - 1;
+                       chunk_size &= ~ (pagesize - 1);
+               }
        }
 #endif
 
@@ -545,9 +550,10 @@ new_codechunk (CodeChunk *last, int dynamic, int size)
                        return NULL;
        } else {
                /* Try to allocate code chunks next to each other to help the VM */
+               ptr = NULL;
                if (last)
                        ptr = codechunk_valloc ((guint8*)last->data + last->size, chunk_size);
-               else
+               if (!ptr)
                        ptr = codechunk_valloc (NULL, chunk_size);
                if (!ptr)
                        return NULL;
@@ -560,7 +566,7 @@ new_codechunk (CodeChunk *last, int dynamic, int size)
 #endif
        }
 
-       chunk = malloc (sizeof (CodeChunk));
+       chunk = (CodeChunk *) malloc (sizeof (CodeChunk));
        if (!chunk) {
                if (flags == CODE_FLAG_MALLOC)
                        dlfree (ptr);
@@ -570,7 +576,7 @@ new_codechunk (CodeChunk *last, int dynamic, int size)
        }
        chunk->next = NULL;
        chunk->size = chunk_size;
-       chunk->data = ptr;
+       chunk->data = (char *) ptr;
        chunk->flags = flags;
        chunk->pos = bsize;
        chunk->bsize = bsize;