X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=mono%2Futils%2Fmono-codeman.c;h=08b8226f61b44050928b1813e86ed6d3ddb59852;hb=f4da7083e83a69cacc69c9977e059ab8b07311a8;hp=abdcda699722247ae3ff3e2e59d2a22d82832bd5;hpb=adc40c3f99d86f885d86f081cc75d33332164051;p=mono.git diff --git a/mono/utils/mono-codeman.c b/mono/utils/mono-codeman.c index abdcda69972..08b8226f61b 100644 --- a/mono/utils/mono-codeman.c +++ b/mono/utils/mono-codeman.c @@ -26,11 +26,13 @@ #include #include #endif +#include + static uintptr_t code_memory_used = 0; -static gulong dynamic_code_alloc_count; -static gulong dynamic_code_bytes_count; -static gulong dynamic_code_frees_count; +static size_t dynamic_code_alloc_count; +static size_t dynamic_code_bytes_count; +static size_t dynamic_code_frees_count; /* * AMD64 processors maintain icache coherency only for pages which are @@ -94,6 +96,7 @@ struct _CodeChunck { struct _MonoCodeManager { int dynamic; int read_only; + int bind_size; CodeChunk *current; CodeChunk *full; CodeChunk *last; @@ -231,7 +234,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,14 +244,14 @@ 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); + mono_mutex_lock (&valloc_mutex); freelist = g_hash_table_lookup (valloc_freelists, GUINT_TO_POINTER (size)); if (freelist) { ptr = freelist->data; @@ -260,7 +263,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,7 +272,7 @@ codechunk_vfree (void *ptr, guint32 size) { GSList *freelist; - EnterCriticalSection (&valloc_mutex); + mono_mutex_lock (&valloc_mutex); freelist = 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); @@ -277,7 +280,7 @@ codechunk_vfree (void *ptr, guint32 size) } else { mono_vfree (ptr, size); } - LeaveCriticalSection (&valloc_mutex); + mono_mutex_unlock (&valloc_mutex); } static void @@ -363,14 +366,17 @@ mono_code_manager_new (void) * Creates a new code manager suitable for holding native code that can be * used for single or small methods that need to be deallocated independently * of other native code. + * BIND_SIZE is the amount of memory reserved for storing thunks. If its 0, + * the default size is used. * * Returns: the new code manager */ MonoCodeManager* -mono_code_manager_new_dynamic (void) +mono_code_manager_new_dynamic (int bind_size) { MonoCodeManager *cman = mono_code_manager_new (); cman->dynamic = 1; + cman->bind_size = bind_size; return cman; } @@ -490,11 +496,11 @@ mono_code_manager_foreach (MonoCodeManager *cman, MonoCodeManagerFunc func, void #define BIND_ROOM 8 #endif #if defined(TARGET_ARM64) -#define BIND_ROOM 8 +#define BIND_ROOM 4 #endif static CodeChunk* -new_codechunk (CodeChunk *last, int dynamic, int size) +new_codechunk (CodeChunk *last, int dynamic, int size, int bind_size) { int minsize, flags = CODE_FLAG_MMAP; int chunk_size, bsize = 0; @@ -527,15 +533,25 @@ new_codechunk (CodeChunk *last, int dynamic, int size) } } #ifdef BIND_ROOM - bsize = chunk_size / BIND_ROOM; + if (bind_size) { + bsize = bind_size; + } else { + 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 +561,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; @@ -613,7 +630,7 @@ mono_code_manager_reserve_align (MonoCodeManager *cman, int size, int alignment) } if (!cman->current) { - cman->current = new_codechunk (cman->last, cman->dynamic, size); + cman->current = new_codechunk (cman->last, cman->dynamic, size, cman->bind_size); if (!cman->current) return NULL; cman->last = cman->current; @@ -646,7 +663,7 @@ mono_code_manager_reserve_align (MonoCodeManager *cman, int size, int alignment) cman->full = chunk; break; } - chunk = new_codechunk (cman->last, cman->dynamic, size); + chunk = new_codechunk (cman->last, cman->dynamic, size, cman->bind_size); if (!chunk) return NULL; chunk->next = cman->current;