From 222e406deb878a6312b3c4bf3bcd0e185fa2ff2c Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 31 Oct 2008 13:00:59 +0100 Subject: [PATCH] ntdll: Create a separate heap for allocating memory views instead of using malloc. --- dlls/ntdll/heap.c | 2 +- dlls/ntdll/virtual.c | 38 ++++++++++++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index 7abe85dac1c..d94e1f0bed0 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -1253,7 +1253,7 @@ HANDLE WINAPI RtlCreateHeap( ULONG flags, PVOID addr, SIZE_T totalSize, SIZE_T c list_add_head( &processHeap->entry, &heapPtr->entry ); RtlLeaveCriticalSection( &processHeap->critSection ); } - else + else if (!addr) { processHeap = subheap->heap; /* assume the first heap we create is the process main heap */ list_init( &processHeap->entry ); diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index 812d3510061..50b794cc87e 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -141,6 +141,9 @@ static void * const user_space_limit = 0; /* no limit needed on other platfo #define VIRTUAL_DEBUG_DUMP_VIEW(view) \ do { if (TRACE_ON(virtual)) VIRTUAL_DumpView(view); } while (0) +#define VIRTUAL_HEAP_SIZE (4*1024*1024) + +static HANDLE virtual_heap; static void *preload_reserve_start; static void *preload_reserve_end; static int use_locks; @@ -401,7 +404,7 @@ static void delete_view( struct file_view *view ) /* [in] View */ if (!(view->flags & VFLAG_SYSTEM)) unmap_area( view->base, view->size ); list_remove( &view->entry ); if (view->mapping) NtClose( view->mapping ); - free( view ); + RtlFreeHeap( virtual_heap, 0, view ); } @@ -421,7 +424,11 @@ static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t siz /* Create the view structure */ - if (!(view = malloc( sizeof(*view) + (size >> page_shift) - 1 ))) return STATUS_NO_MEMORY; + if (!(view = RtlAllocateHeap( virtual_heap, 0, sizeof(*view) + (size >> page_shift) - 1 ))) + { + FIXME( "out of memory in virtual heap for %p-%p\n", base, (char *)base + size ); + return STATUS_NO_MEMORY; + } view->base = base; view->size = size; @@ -1167,11 +1174,16 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz } -static int get_address_space_limit( void *base, size_t size, void *arg ) +/* callback for wine_mmap_enum_reserved_areas to allocate space for the virtual heap */ +static int alloc_virtual_heap( void *base, size_t size, void *arg ) { - void **limit = arg; - if ((char *)base + size > (char *)*limit) *limit = (char *)base + size; - return 1; + void **heap_base = arg; + + if (address_space_limit) address_space_limit = max( (char *)address_space_limit, (char *)base + size ); + if (size < VIRTUAL_HEAP_SIZE) return 0; + *heap_base = wine_anon_mmap( (char *)base + size - VIRTUAL_HEAP_SIZE, + VIRTUAL_HEAP_SIZE, PROT_READ|PROT_WRITE, MAP_FIXED ); + return (*heap_base != (void *)-1); } /*********************************************************************** @@ -1180,6 +1192,9 @@ static int get_address_space_limit( void *base, size_t size, void *arg ) void virtual_init(void) { const char *preload; + void *heap_base; + struct file_view *heap_view; + #ifndef page_mask page_size = getpagesize(); page_mask = page_size - 1; @@ -1197,8 +1212,15 @@ void virtual_init(void) preload_reserve_end = (void *)end; } } - if (address_space_limit) - wine_mmap_enum_reserved_areas( get_address_space_limit, &address_space_limit, 1 ); + + /* try to find space in a reserved area for the virtual heap */ + if (!wine_mmap_enum_reserved_areas( alloc_virtual_heap, &heap_base, 1 )) + heap_base = wine_anon_mmap( NULL, VIRTUAL_HEAP_SIZE, PROT_READ|PROT_WRITE, 0 ); + + assert( heap_base != (void *)-1 ); + virtual_heap = RtlCreateHeap( HEAP_NO_SERIALIZE, heap_base, VIRTUAL_HEAP_SIZE, + VIRTUAL_HEAP_SIZE, NULL, NULL ); + create_view( &heap_view, heap_base, VIRTUAL_HEAP_SIZE, VPROT_COMMITTED | VPROT_READ | VPROT_WRITE ); } -- 2.11.4.GIT