summaryrefslogtreecommitdiff
path: root/os_dep.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2012-02-09 19:56:48 +0400
committerIvan Maidanski <ivmai@mail.ru>2012-02-09 19:56:48 +0400
commit1115b9a9eadf27b4db1cdf6f84957d18638faecf (patch)
treec69738698cb3a9bb6081d23df80687db6a7f554e /os_dep.c
parent1dc3ec3e1c749003e92ce11df60b6d303602b170 (diff)
downloadbdwgc-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.c128
1 files changed, 65 insertions, 63 deletions
diff --git a/os_dep.c b/os_dep.c
index 14cb2ebf..d27f4657 100644
--- a/os_dep.c
+++ b/os_dep.c
@@ -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");