X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Futils%2Fmono-mmap.c;h=62266d34d25eac954dd6aa1c5ccf6cf551c7b0c2;hb=f704d56c378b28e252572db4730a6e13edc14aa0;hp=7fa483ce593747f586e4842fed1a720ffeff2dee;hpb=58e8a9f85176c9607e605b888ef45db01a0f6997;p=mono.git diff --git a/mono/utils/mono-mmap.c b/mono/utils/mono-mmap.c index 7fa483ce593..62266d34d25 100644 --- a/mono/utils/mono-mmap.c +++ b/mono/utils/mono-mmap.c @@ -1,5 +1,6 @@ -/* - * mono-mmap.c: Support for mapping code into the process address space +/** + * \file + * Support for mapping code into the process address space * * Author: * Mono Team (mono-list@lists.ximian.com) @@ -8,12 +9,9 @@ * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ -#include "config.h" +#include -#ifdef HOST_WIN32 -#include -#include -#else +#ifndef HOST_WIN32 #include #if HAVE_SYS_STAT_H #include @@ -29,13 +27,14 @@ #include #include #include -#endif +#endif /* !HOST_WIN32 */ #include "mono-mmap.h" #include "mono-mmap-internals.h" #include "mono-proclib.h" #include - +#include +#include #define BEGIN_CRITICAL_SECTION do { \ MonoThreadInfo *__info = mono_thread_info_current_unchecked (); \ @@ -61,9 +60,7 @@ typedef struct { short stats_end; } SAreaHeader; -static void* malloced_shared_area = NULL; - -static void* +void* malloc_shared_area (int pid) { int size = mono_pagesize (); @@ -76,7 +73,7 @@ malloc_shared_area (int pid) return sarea; } -static char* +char* aligned_address (char *mem, size_t size, size_t alignment) { char *aligned = (char*)((size_t)(mem + (alignment - 1)) & ~(alignment - 1)); @@ -84,180 +81,61 @@ aligned_address (char *mem, size_t size, size_t alignment) return aligned; } -#ifdef HOST_WIN32 - -int -mono_pagesize (void) -{ - SYSTEM_INFO info; - static int saved_pagesize = 0; - if (saved_pagesize) - return saved_pagesize; - GetSystemInfo (&info); - saved_pagesize = info.dwAllocationGranularity; - return saved_pagesize; -} - -static int -prot_from_flags (int flags) -{ - int prot = flags & (MONO_MMAP_READ|MONO_MMAP_WRITE|MONO_MMAP_EXEC); - switch (prot) { - case 0: prot = PAGE_NOACCESS; break; - case MONO_MMAP_READ: prot = PAGE_READONLY; break; - case MONO_MMAP_READ|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READ; break; - case MONO_MMAP_READ|MONO_MMAP_WRITE: prot = PAGE_READWRITE; break; - case MONO_MMAP_READ|MONO_MMAP_WRITE|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READWRITE; break; - case MONO_MMAP_WRITE: prot = PAGE_READWRITE; break; - case MONO_MMAP_WRITE|MONO_MMAP_EXEC: prot = PAGE_EXECUTE_READWRITE; break; - case MONO_MMAP_EXEC: prot = PAGE_EXECUTE; break; - default: - g_assert_not_reached (); - } - return prot; -} - -void* -mono_valloc (void *addr, size_t length, int flags) -{ - void *ptr; - int mflags = MEM_RESERVE|MEM_COMMIT; - int prot = prot_from_flags (flags); - /* translate the flags */ - - ptr = VirtualAlloc (addr, length, mflags, prot); - return ptr; -} - -void* -mono_valloc_aligned (size_t length, size_t alignment, int flags) -{ - int prot = prot_from_flags (flags); - char *mem = VirtualAlloc (NULL, length + alignment, MEM_RESERVE, prot); - char *aligned; - - if (!mem) - return NULL; - - aligned = aligned_address (mem, length, alignment); - - aligned = VirtualAlloc (aligned, length, MEM_COMMIT, prot); - g_assert (aligned); - - return aligned; -} - -#define HAVE_VALLOC_ALIGNED - -int -mono_vfree (void *addr, size_t length) -{ - MEMORY_BASIC_INFORMATION mbi; - SIZE_T query_result = VirtualQuery (addr, &mbi, sizeof (mbi)); - BOOL res; - - g_assert (query_result); - - res = VirtualFree (mbi.AllocationBase, 0, MEM_RELEASE); - - g_assert (res); - - return 0; -} - -void* -mono_file_map (size_t length, int flags, int fd, guint64 offset, void **ret_handle) -{ - void *ptr; - int mflags = 0; - HANDLE file, mapping; - int prot = prot_from_flags (flags); - /* translate the flags */ - /*if (flags & MONO_MMAP_PRIVATE) - mflags |= MAP_PRIVATE; - if (flags & MONO_MMAP_SHARED) - mflags |= MAP_SHARED; - if (flags & MONO_MMAP_ANON) - mflags |= MAP_ANONYMOUS; - if (flags & MONO_MMAP_FIXED) - mflags |= MAP_FIXED; - if (flags & MONO_MMAP_32BIT) - mflags |= MAP_32BIT;*/ - - mflags = FILE_MAP_READ; - if (flags & MONO_MMAP_WRITE) - mflags = FILE_MAP_COPY; - - file = (HANDLE) _get_osfhandle (fd); - mapping = CreateFileMapping (file, NULL, prot, 0, 0, NULL); - if (mapping == NULL) - return NULL; - ptr = MapViewOfFile (mapping, mflags, 0, offset, length); - if (ptr == NULL) { - CloseHandle (mapping); - return NULL; - } - *ret_handle = (void*)mapping; - return ptr; -} - -int -mono_file_unmap (void *addr, void *handle) -{ - UnmapViewOfFile (addr); - CloseHandle ((HANDLE)handle); - return 0; -} - -int -mono_mprotect (void *addr, size_t length, int flags) -{ - DWORD oldprot; - int prot = prot_from_flags (flags); - - if (flags & MONO_MMAP_DISCARD) { - VirtualFree (addr, length, MEM_DECOMMIT); - VirtualAlloc (addr, length, MEM_COMMIT, prot); - return 0; - } - return VirtualProtect (addr, length, prot, &oldprot) == 0; -} - -void* -mono_shared_area (void) -{ - if (!malloced_shared_area) - malloced_shared_area = malloc_shared_area (0); - /* get the pid here */ - return malloced_shared_area; -} +static volatile size_t allocation_count [MONO_MEM_ACCOUNT_MAX]; void -mono_shared_area_remove (void) +account_mem (MonoMemAccountType type, ssize_t size) { - if (malloced_shared_area) - g_free (malloced_shared_area); - malloced_shared_area = NULL; +#if SIZEOF_VOID_P == 4 + InterlockedAdd ((volatile gint32*)&allocation_count [type], (gint32)size); +#else + InterlockedAdd64 ((volatile gint64*)&allocation_count [type], (gint64)size); +#endif } -void* -mono_shared_area_for_pid (void *pid) +const char* +mono_mem_account_type_name (MonoMemAccountType type) { - return NULL; + static const char *names[] = { + "code", + "hazard pointers", + "domain", + "SGen internal", + "SGen nursery", + "SGen LOS", + "SGen mark&sweep", + "SGen card table", + "SGen shadow card table", + "SGen debugging", + "SGen binary protocol", + "exceptions", + "profiler", + "other" + }; + + return names [type]; } void -mono_shared_area_unload (void *area) -{ +mono_mem_account_register_counters (void) +{ + for (int i = 0; i < MONO_MEM_ACCOUNT_MAX; ++i) { + const char *prefix = "Valloc "; + const char *name = mono_mem_account_type_name (i); + char descr [128]; + g_assert (strlen (prefix) + strlen (name) < sizeof (descr)); + sprintf (descr, "%s%s", prefix, name); + mono_counters_register (descr, MONO_COUNTER_WORD | MONO_COUNTER_RUNTIME | MONO_COUNTER_BYTES | MONO_COUNTER_VARIABLE, (void*)&allocation_count [i]); + } } -int -mono_shared_area_instances (void **array, int count) -{ - return 0; -} +#ifdef HOST_WIN32 +// Windows specific implementation in mono-mmap-windows.c +#define HAVE_VALLOC_ALIGNED #else + +static void* malloced_shared_area = NULL; #if defined(HAVE_MMAP) /** @@ -278,6 +156,12 @@ mono_pagesize (void) return saved_pagesize; } +int +mono_valloc_granule (void) +{ + return mono_pagesize (); +} + static int prot_from_flags (int flags) { @@ -294,20 +178,18 @@ prot_from_flags (int flags) /** * mono_valloc: - * @addr: memory address - * @length: memory area size - * @flags: protection flags - * - * Allocates @length bytes of virtual memory with the @flags - * protection. @addr can be a preferred memory address or a - * mandatory one if MONO_MMAP_FIXED is set in @flags. - * @addr must be pagesize aligned and can be NULL. - * @length must be a multiple of pagesize. - * - * Returns: NULL on failure, the address of the memory area otherwise + * \param addr memory address + * \param length memory area size + * \param flags protection flags + * Allocates \p length bytes of virtual memory with the \p flags + * protection. \p addr can be a preferred memory address or a + * mandatory one if MONO_MMAP_FIXED is set in \p flags. + * \p addr must be pagesize aligned and can be NULL. + * \p length must be a multiple of pagesize. + * \returns NULL on failure, the address of the memory area otherwise */ void* -mono_valloc (void *addr, size_t length, int flags) +mono_valloc (void *addr, size_t length, int flags, MonoMemAccountType type) { void *ptr; int mflags = 0; @@ -334,43 +216,45 @@ mono_valloc (void *addr, size_t length, int flags) if (ptr == MAP_FAILED) return NULL; + + account_mem (type, (ssize_t)length); + return ptr; } /** * mono_vfree: - * @addr: memory address returned by mono_valloc () - * @length: size of memory area - * - * Remove the memory mapping at the address @addr. - * - * Returns: 0 on success. + * \param addr memory address returned by mono_valloc () + * \param length size of memory area + * Remove the memory mapping at the address \p addr. + * \returns \c 0 on success. */ int -mono_vfree (void *addr, size_t length) +mono_vfree (void *addr, size_t length, MonoMemAccountType type) { int res; BEGIN_CRITICAL_SECTION; res = munmap (addr, length); END_CRITICAL_SECTION; + + account_mem (type, -(ssize_t)length); + return res; } /** * mono_file_map: - * @length: size of data to map - * @flags: protection flags - * @fd: file descriptor - * @offset: offset in the file - * @ret_handle: pointer to storage for returning a handle for the map - * - * Map the area of the file pointed to by the file descriptor @fd, at offset - * @offset and of size @length in memory according to the protection flags - * @flags. - * @offset and @length must be multiples of the page size. - * @ret_handle must point to a void*: this value must be used when unmapping - * the memory area using mono_file_unmap (). - * + * \param length size of data to map + * \param flags protection flags + * \param fd file descriptor + * \param offset offset in the file + * \param ret_handle pointer to storage for returning a handle for the map + * Map the area of the file pointed to by the file descriptor \p fd, at offset + * \p offset and of size \p length in memory according to the protection flags + * \p flags. + * \p offset and \p length must be multiples of the page size. + * \p ret_handle must point to a void*: this value must be used when unmapping + * the memory area using \c mono_file_unmap(). */ void* mono_file_map (size_t length, int flags, int fd, guint64 offset, void **ret_handle) @@ -399,13 +283,11 @@ mono_file_map (size_t length, int flags, int fd, guint64 offset, void **ret_hand /** * mono_file_unmap: - * @addr: memory address returned by mono_file_map () - * @handle: handle of memory map - * - * Remove the memory mapping at the address @addr. - * @handle must be the value returned in ret_handle by mono_file_map (). - * - * Returns: 0 on success. + * \param addr memory address returned by mono_file_map () + * \param handle handle of memory map + * Remove the memory mapping at the address \p addr. + * \p handle must be the value returned in ret_handle by \c mono_file_map(). + * \returns \c 0 on success. */ int mono_file_unmap (void *addr, void *handle) @@ -421,18 +303,16 @@ mono_file_unmap (void *addr, void *handle) /** * mono_mprotect: - * @addr: memory address - * @length: size of memory area - * @flags: new protection flags - * - * Change the protection for the memory area at @addr for @length bytes - * to matche the supplied @flags. - * If @flags includes MON_MMAP_DISCARD the pages are discarded from memory + * \param addr memory address + * \param length size of memory area + * \param flags new protection flags + * Change the protection for the memory area at \p addr for \p length bytes + * to matche the supplied \p flags. + * If \p flags includes MON_MMAP_DISCARD the pages are discarded from memory * and the area is cleared to zero. - * @addr must be aligned to the page size. - * @length must be a multiple of the page size. - * - * Returns: 0 on success. + * \p addr must be aligned to the page size. + * \p length must be a multiple of the page size. + * \returns \c 0 on success. */ #if defined(__native_client__) int @@ -481,14 +361,20 @@ mono_pagesize (void) return 4096; } +int +mono_valloc_granule (void) +{ + return mono_pagesize (); +} + void* -mono_valloc (void *addr, size_t length, int flags) +mono_valloc (void *addr, size_t length, int flags, MonoMemAccountType type) { - return malloc (length); + return g_malloc (length); } void* -mono_valloc_aligned (size_t length, size_t alignment, int flags) +mono_valloc_aligned (size_t size, size_t alignment, int flags, MonoMemAccountType type) { g_assert_not_reached (); } @@ -496,9 +382,9 @@ mono_valloc_aligned (size_t length, size_t alignment, int flags) #define HAVE_VALLOC_ALIGNED int -mono_vfree (void *addr, size_t length) +mono_vfree (void *addr, size_t length, MonoMemAccountType type) { - free (addr); + g_free (addr); return 0; } @@ -521,7 +407,7 @@ static gboolean shared_area_disabled (void) { if (!use_shared_area) { - if (g_getenv ("MONO_DISABLE_SHARED_AREA")) + if (g_hasenv ("MONO_DISABLE_SHARED_AREA")) use_shared_area = -1; else use_shared_area = 1; @@ -747,10 +633,10 @@ mono_shared_area_instances (void **array, int count) #ifndef HAVE_VALLOC_ALIGNED void* -mono_valloc_aligned (size_t size, size_t alignment, int flags) +mono_valloc_aligned (size_t size, size_t alignment, int flags, MonoMemAccountType type) { /* Allocate twice the memory to be able to put the block on an aligned address */ - char *mem = (char *) mono_valloc (NULL, size + alignment, flags); + char *mem = (char *) mono_valloc (NULL, size + alignment, flags, type); char *aligned; if (!mem) @@ -759,9 +645,9 @@ mono_valloc_aligned (size_t size, size_t alignment, int flags) aligned = aligned_address (mem, size, alignment); if (aligned > mem) - mono_vfree (mem, aligned - mem); + mono_vfree (mem, aligned - mem, type); if (aligned + size < mem + size + alignment) - mono_vfree (aligned + size, (mem + size + alignment) - (aligned + size)); + mono_vfree (aligned + size, (mem + size + alignment) - (aligned + size), type); return aligned; }