diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2012-02-09 19:56:48 +0400 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2012-02-09 19:56:48 +0400 |
commit | 1115b9a9eadf27b4db1cdf6f84957d18638faecf (patch) | |
tree | c69738698cb3a9bb6081d23df80687db6a7f554e /os_dep.c | |
parent | 1dc3ec3e1c749003e92ce11df60b6d303602b170 (diff) | |
download | bdwgc-1115b9a9eadf27b4db1cdf6f84957d18638faecf.tar.gz |
Allow to get memory via Win32 VirtualAlloc (USE_WINALLOC) on Cygwin
* README.macros (USE_WINALLOC): Document.
* include/private/gcconfig.h (USE_WINALLOC): Add comment.
* include/private/gcconfig.h (USE_MMAP): Explicitly undefine if
USE_WINALLOC.
* os_dep.c (GC_wince_get_mem): Move definition up to simplify ifdef.
* os_dep.c (GC_win32_get_mem): Test USE_WINALLOC instead of CYGWIN32;
test GLOBAL_ALLOC_TEST value only if MSWIN32.
Diffstat (limited to 'os_dep.c')
-rw-r--r-- | os_dep.c | 128 |
1 files changed, 65 insertions, 63 deletions
@@ -2193,7 +2193,62 @@ void * os2_alloc(size_t bytes) # endif /* OS2 */ -#if defined(MSWIN32) || defined(CYGWIN32) +#ifdef MSWINCE + ptr_t GC_wince_get_mem(word bytes) + { + ptr_t result = 0; /* initialized to prevent warning. */ + word i; + + /* Round up allocation size to multiple of page size */ + bytes = (bytes + GC_page_size-1) & ~(GC_page_size-1); + + /* Try to find reserved, uncommitted pages */ + for (i = 0; i < GC_n_heap_bases; i++) { + if (((word)(-(signed_word)GC_heap_lengths[i]) + & (GC_sysinfo.dwAllocationGranularity-1)) + >= bytes) { + result = GC_heap_bases[i] + GC_heap_lengths[i]; + break; + } + } + + if (i == GC_n_heap_bases) { + /* Reserve more pages */ + word res_bytes = (bytes + GC_sysinfo.dwAllocationGranularity-1) + & ~(GC_sysinfo.dwAllocationGranularity-1); + /* If we ever support MPROTECT_VDB here, we will probably need to */ + /* ensure that res_bytes is strictly > bytes, so that VirtualProtect */ + /* never spans regions. It seems to be OK for a VirtualFree */ + /* argument to span regions, so we should be OK for now. */ + result = (ptr_t) VirtualAlloc(NULL, res_bytes, + MEM_RESERVE | MEM_TOP_DOWN, + GC_pages_executable ? PAGE_EXECUTE_READWRITE : + PAGE_READWRITE); + if (HBLKDISPL(result) != 0) ABORT("Bad VirtualAlloc result"); + /* If I read the documentation correctly, this can */ + /* only happen if HBLKSIZE > 64k or not a power of 2. */ + if (GC_n_heap_bases >= MAX_HEAP_SECTS) ABORT("Too many heap sections"); + if (result == NULL) return NULL; + GC_heap_bases[GC_n_heap_bases] = result; + GC_heap_lengths[GC_n_heap_bases] = 0; + GC_n_heap_bases++; + } + + /* Commit pages */ + result = (ptr_t) VirtualAlloc(result, bytes, MEM_COMMIT, + GC_pages_executable ? PAGE_EXECUTE_READWRITE : + PAGE_READWRITE); +# undef IGNORE_PAGES_EXECUTABLE + + if (result != NULL) { + if (HBLKDISPL(result) != 0) ABORT("Bad VirtualAlloc result"); + GC_heap_lengths[i] += bytes; + } + + return(result); + } + +#elif defined(USE_WINALLOC) || defined(CYGWIN32) # ifdef USE_GLOBAL_ALLOC # define GLOBAL_ALLOC_TEST 1 @@ -2214,16 +2269,19 @@ void * os2_alloc(size_t bytes) { ptr_t result; -# ifdef CYGWIN32 +# ifndef USE_WINALLOC result = GC_unix_get_mem(bytes); # else - if (GLOBAL_ALLOC_TEST) { +# ifdef MSWIN32 + if (GLOBAL_ALLOC_TEST) { /* VirtualAlloc doesn't like PAGE_EXECUTE_READWRITE. */ /* There are also unconfirmed rumors of other */ /* problems, so we dodge the issue. */ result = (ptr_t) GlobalAlloc(0, bytes + HBLKSIZE); result = (ptr_t)(((word)result + HBLKSIZE - 1) & ~(HBLKSIZE-1)); - } else { + } else +# endif + /* else */ { /* VirtualProtect only works on regions returned by a */ /* single VirtualAlloc call. Thus we allocate one */ /* extra page, which will prevent merging of blocks */ @@ -2257,7 +2315,7 @@ void * os2_alloc(size_t bytes) PAGE_READWRITE); # undef IGNORE_PAGES_EXECUTABLE } -# endif /* !CYGWIN32 */ +# endif /* USE_WINALLOC */ if (HBLKDISPL(result) != 0) ABORT("Bad VirtualAlloc result"); /* If I read the documentation correctly, this can */ /* only happen if HBLKSIZE > 64k or not a power of 2. */ @@ -2282,7 +2340,7 @@ void * os2_alloc(size_t bytes) } } } -#endif /* MSWIN32 || CYGWIN32 */ +#endif /* USE_WINALLOC || CYGWIN32 */ #ifdef AMIGA # define GC_AMIGA_AM @@ -2290,63 +2348,6 @@ void * os2_alloc(size_t bytes) # undef GC_AMIGA_AM #endif - -#ifdef MSWINCE - ptr_t GC_wince_get_mem(word bytes) - { - ptr_t result = 0; /* initialized to prevent warning. */ - word i; - - /* Round up allocation size to multiple of page size */ - bytes = (bytes + GC_page_size-1) & ~(GC_page_size-1); - - /* Try to find reserved, uncommitted pages */ - for (i = 0; i < GC_n_heap_bases; i++) { - if (((word)(-(signed_word)GC_heap_lengths[i]) - & (GC_sysinfo.dwAllocationGranularity-1)) - >= bytes) { - result = GC_heap_bases[i] + GC_heap_lengths[i]; - break; - } - } - - if (i == GC_n_heap_bases) { - /* Reserve more pages */ - word res_bytes = (bytes + GC_sysinfo.dwAllocationGranularity-1) - & ~(GC_sysinfo.dwAllocationGranularity-1); - /* If we ever support MPROTECT_VDB here, we will probably need to */ - /* ensure that res_bytes is strictly > bytes, so that VirtualProtect */ - /* never spans regions. It seems to be OK for a VirtualFree */ - /* argument to span regions, so we should be OK for now. */ - result = (ptr_t) VirtualAlloc(NULL, res_bytes, - MEM_RESERVE | MEM_TOP_DOWN, - GC_pages_executable ? PAGE_EXECUTE_READWRITE : - PAGE_READWRITE); - if (HBLKDISPL(result) != 0) ABORT("Bad VirtualAlloc result"); - /* If I read the documentation correctly, this can */ - /* only happen if HBLKSIZE > 64k or not a power of 2. */ - if (GC_n_heap_bases >= MAX_HEAP_SECTS) ABORT("Too many heap sections"); - if (result == NULL) return NULL; - GC_heap_bases[GC_n_heap_bases] = result; - GC_heap_lengths[GC_n_heap_bases] = 0; - GC_n_heap_bases++; - } - - /* Commit pages */ - result = (ptr_t) VirtualAlloc(result, bytes, MEM_COMMIT, - GC_pages_executable ? PAGE_EXECUTE_READWRITE : - PAGE_READWRITE); -# undef IGNORE_PAGES_EXECUTABLE - - if (result != NULL) { - if (HBLKDISPL(result) != 0) ABORT("Bad VirtualAlloc result"); - GC_heap_lengths[i] += bytes; - } - - return(result); - } -#endif - #ifdef USE_MUNMAP /* For now, this only works on Win32/WinCE and some Unix-like */ @@ -2511,6 +2512,7 @@ GC_INNER void GC_unmap_gap(ptr_t start1, size_t bytes1, ptr_t start2, while (len != 0) { MEMORY_BASIC_INFORMATION mem_info; GC_word free_len; + if (VirtualQuery(start_addr, &mem_info, sizeof(mem_info)) != sizeof(mem_info)) ABORT("Weird VirtualQuery result"); |