From 6c7518f4e04fad66acdff7d02d38adbf38ceaeb6 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 12 Aug 2006 12:14:27 +0000 Subject: [PATCH] record Windows experiments svn: r4039 --- src/mzscheme/gc2/protect_range.c | 3 ++ src/mzscheme/gc2/vm_win.c | 78 ++++++++++++++++++++++++++++++-- 2 files changed, 78 insertions(+), 3 deletions(-) diff --git a/src/mzscheme/gc2/protect_range.c b/src/mzscheme/gc2/protect_range.c index f3a6ecbc6e..a6dfe285d8 100644 --- a/src/mzscheme/gc2/protect_range.c +++ b/src/mzscheme/gc2/protect_range.c @@ -7,6 +7,9 @@ #ifdef _WIN32 +/* VirtualProtect can be used only on pages allocated at the same + time, so we can't collapse ranges. */ + # define initialize_protect_page_ranges(b, s) /* */ # define add_protect_page_range(s, l, a, w) protect_pages(s, l, w) # define flush_protect_page_ranges(w) /* */ diff --git a/src/mzscheme/gc2/vm_win.c b/src/mzscheme/gc2/vm_win.c index 90cd4115db..a9de82e3c9 100644 --- a/src/mzscheme/gc2/vm_win.c +++ b/src/mzscheme/gc2/vm_win.c @@ -22,12 +22,46 @@ # define CHECK_USED_AGAINST_MAX(x) /* empty */ #endif +/* Cache doesn't seem to help in Windows: */ +#define CACHE_SLOTS 0 + +#if CACHE_SLOTS +typedef struct { + size_t len; + void *page; +} alloc_cache_entry; + +/* First dimension is age: */ +static alloc_cache_entry cache[2][CACHE_SLOTS]; +#endif + static void *malloc_pages(size_t len, size_t alignment) { CHECK_USED_AGAINST_MAX(len); - ACTUALLY_ALLOCATING_PAGES(len); LOGICALLY_ALLOCATING_PAGES(len); +#if CACHE_SLOTS + { + int i, j; + + for (j = 0; j < 2; j++) { + for (i = 0; i < CACHE_SLOTS; i++) { + if (cache[j][i].len == len) { + if (cache[j][i].page) { + void *result = cache[j][i].page; + cache[j][i].page = *(void **)result; + memset(result, 0, len); + return result; + } + break; + } + } + } + } +#endif + + ACTUALLY_ALLOCATING_PAGES(len); + return (void *)VirtualAlloc(NULL, len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); @@ -35,14 +69,49 @@ static void *malloc_pages(size_t len, size_t alignment) static void free_pages(void *p, size_t len) { - VirtualFree(p, 0, MEM_RELEASE); - LOGICALLY_FREEING_PAGES(len); + +#if CACHE_SLOTS + { + int i; + + for (i = 0; i < CACHE_SLOTS; i++) { + if (!cache[0][i].len) + cache[0][i].len = len; + if (cache[0][i].len == len) { + *(void **)p = cache[0][i].page; + cache[0][i].page = p; + return; + } + } + } +#endif + ACTUALLY_FREEING_PAGES(len); + + VirtualFree(p, 0, MEM_RELEASE); } static void flush_freed_pages(void) { +#if CACHE_SLOTS + int i; + void *p, *next; + + for (i = 0; i < CACHE_SLOTS; i++) { + if (cache[1][i].len) { + for (p = cache[1][i].page; p; p = next) { + next = *(void **)p; + ACTUALLY_FREEING_PAGES(cache[i].len); + VirtualFree(p, 0, MEM_RELEASE); + } + } + cache[1][i].len = cache[0][i].len; + cache[1][i].page = cache[0][i].page; + cache[0][i].len = 0; + cache[0][i].page = NULL; + } +#endif } static void protect_pages(void *p, size_t len, int writeable) @@ -56,8 +125,11 @@ typedef unsigned long size_type; static size_type determine_max_heap_size(void) { + /* FIXME: should use QueryInformationJobObject() */ +#if 0 GCPRINT(GCOUTF, "Don't know how to get heap size for Windows: assuming 1GB\n"); +#endif return (1 * 1024 * 1024 * 1024); } #endif