Alexandre Julliard : ntdll: Release some address space after the process initialization is done.

Alexandre Julliard julliard at winehq.org
Thu Jun 25 08:13:58 CDT 2009


Module: wine
Branch: master
Commit: 09712593c8496be5e952b7316099f9eed5043203
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=09712593c8496be5e952b7316099f9eed5043203

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Jun 25 14:18:53 2009 +0200

ntdll: Release some address space after the process initialization is done.

---

 dlls/ntdll/loader.c     |    2 +-
 dlls/ntdll/ntdll_misc.h |    2 +-
 dlls/ntdll/virtual.c    |   79 ++++++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 76 insertions(+), 7 deletions(-)

diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 2f9b41e..aa9395e 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -2477,11 +2477,11 @@ void WINAPI LdrInitializeThunk( ULONG unknown1, ULONG unknown2, ULONG unknown3,
     if ((status = fixup_imports( wm, load_path )) != STATUS_SUCCESS) goto error;
     if ((status = alloc_process_tls()) != STATUS_SUCCESS) goto error;
     if ((status = alloc_thread_tls()) != STATUS_SUCCESS) goto error;
-    if (nt->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE) VIRTUAL_UseLargeAddressSpace();
 
     status = wine_call_on_stack( attach_process_dlls, wm, NtCurrentTeb()->Tib.StackBase );
     if (status != STATUS_SUCCESS) goto error;
 
+    virtual_release_address_space( nt->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE );
     virtual_clear_thread_stack();
     return;
 
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 34ae2d6..b6a3d88 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -150,7 +150,7 @@ extern NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err );
 extern BOOL virtual_check_buffer_for_read( const void *ptr, SIZE_T size );
 extern BOOL virtual_check_buffer_for_write( void *ptr, SIZE_T size );
 extern void VIRTUAL_SetForceExec( BOOL enable );
-extern void VIRTUAL_UseLargeAddressSpace(void);
+extern void virtual_release_address_space( BOOL free_high_mem );
 extern struct _KUSER_SHARED_DATA *user_shared_data;
 
 /* completion */
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 33918ca..bacfa32 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -370,6 +370,36 @@ static void add_reserved_area( void *addr, size_t size )
 
 
 /***********************************************************************
+ *           remove_reserved_area
+ *
+ * Remove a reserved area from the list maintained by libwine.
+ * The csVirtual section must be held by caller.
+ */
+static void remove_reserved_area( void *addr, size_t size )
+{
+    struct file_view *view;
+
+    TRACE( "removing %p-%p\n", addr, (char *)addr + size );
+    wine_mmap_remove_reserved_area( addr, size, 0 );
+
+    /* unmap areas not covered by an existing view */
+    LIST_FOR_EACH_ENTRY( view, &views_list, struct file_view, entry )
+    {
+        if ((char *)view->base >= (char *)addr + size)
+        {
+            munmap( addr, size );
+            break;
+        }
+        if ((char *)view->base + view->size <= (char *)addr) continue;
+        if (view->base > addr) munmap( addr, (char *)view->base - (char *)addr );
+        if ((char *)view->base + view->size > (char *)addr + size) break;
+        size = (char *)addr + size - ((char *)view->base + view->size);
+        addr = (char *)view->base + view->size;
+    }
+}
+
+
+/***********************************************************************
  *           is_beyond_limit
  *
  * Check if an address range goes beyond a given limit.
@@ -1615,17 +1645,56 @@ void VIRTUAL_SetForceExec( BOOL enable )
     server_leave_uninterrupted_section( &csVirtual, &sigset );
 }
 
+struct free_range
+{
+    char *base;
+    char *limit;
+};
+
+/* free reserved areas above the limit; callback for wine_mmap_enum_reserved_areas */
+static int free_reserved_memory( void *base, size_t size, void *arg )
+{
+    struct free_range *range = arg;
+
+    if ((char *)base >= range->limit) return 0;
+    if ((char *)base + size <= range->base) return 0;
+    if ((char *)base < range->base)
+    {
+        size -= range->base - (char *)base;
+        base = range->base;
+    }
+    if ((char *)base + size > range->limit) size = range->limit - (char *)base;
+    remove_reserved_area( base, size );
+    return 1;  /* stop enumeration since the list has changed */
+}
 
 /***********************************************************************
- *           VIRTUAL_UseLargeAddressSpace
+ *           virtual_release_address_space
  *
- * Increase the address space size for apps that support it.
+ * Release some address space once we have loaded and initialized the app.
  */
-void VIRTUAL_UseLargeAddressSpace(void)
+void virtual_release_address_space( BOOL free_high_mem )
 {
+#ifdef __i386__
+    struct free_range range;
+    sigset_t sigset;
+
+    server_enter_uninterrupted_section( &csVirtual, &sigset );
+
+    range.base  = (char *)0x20000000;
+    range.limit = (char *)0x7f000000;
+    while (wine_mmap_enum_reserved_areas( free_reserved_memory, &range, 0 )) /* nothing */;
+
     /* no large address space on win9x */
-    if (NtCurrentTeb()->Peb->OSPlatformId != VER_PLATFORM_WIN32_NT) return;
-    user_space_limit = working_set_limit = address_space_limit;
+    if (free_high_mem && NtCurrentTeb()->Peb->OSPlatformId == VER_PLATFORM_WIN32_NT)
+    {
+        range.base  = (char *)0x80000000;
+        range.limit = address_space_limit;
+        while (wine_mmap_enum_reserved_areas( free_reserved_memory, &range, 1 )) /* nothing */;
+        user_space_limit = working_set_limit = address_space_limit;
+    }
+    server_leave_uninterrupted_section( &csVirtual, &sigset );
+#endif
 }
 
 




More information about the wine-cvs mailing list