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