-/* Heap management routines for GNU Emacs on the Microsoft Windows
- API. Copyright (C) 1994, 2001-2014 Free Software Foundation, Inc.
+/* Heap management routines for GNU Emacs on the Microsoft Windows API.
+ Copyright (C) 1994, 2001-2016 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <sys/mman.h>
#include "w32common.h"
#include "w32heap.h"
-#include "lisp.h" /* for VALMASK */
+#include "lisp.h"
/* We chose to leave those declarations here. They are used only in
this file. The RtlCreateHeap is available since XP. It is located
than half of the size stated below. It would be nice to find a way
to build only the first bootstrap-emacs.exe with the large size,
and reset that to a lower value afterwards. */
-#ifdef _WIN64
-# define DUMPED_HEAP_SIZE (18*1024*1024)
+#if defined _WIN64 || defined WIDE_EMACS_INT
+# define DUMPED_HEAP_SIZE (20*1024*1024)
#else
-# define DUMPED_HEAP_SIZE (11*1024*1024)
+# define DUMPED_HEAP_SIZE (12*1024*1024)
#endif
static unsigned char dumped_data[DUMPED_HEAP_SIZE];
as requests arrive. */
*CommitAddress = data_region_base + committed;
committed += *CommitSize;
+ /* Check that the private heap area does not overlap the big chunks area. */
if (((unsigned char *)(*CommitAddress)) + *CommitSize >= bc_limit)
{
- /* Check that the private heap area does not overlap the big
- chunks area. */
- fprintf(stderr,
- "dumped_data_commit: memory exhausted.\nEnlarge dumped_data[]!\n");
+ fprintf (stderr,
+ "dumped_data_commit: memory exhausted.\nEnlarge dumped_data[]!\n");
exit (-1);
}
return 0;
/* We want to turn on Low Fragmentation Heap for XP and older systems.
MinGW32 lacks those definitions. */
-#ifndef _W64
+#ifndef MINGW_W64
typedef enum _HEAP_INFORMATION_CLASS {
HeapCompatibilityInformation
} HEAP_INFORMATION_CLASS;
data_region_end = data_region_base;
/* Create the private heap. */
- heap = HeapCreate(0, 0, 0);
+ heap = HeapCreate (0, 0, 0);
-#ifndef _W64
+#ifndef MINGW_W64
/* Set the low-fragmentation heap for OS before Vista. */
- HMODULE hm_kernel32dll = LoadLibrary("kernel32.dll");
- HeapSetInformation_Proc s_pfn_Heap_Set_Information = (HeapSetInformation_Proc) GetProcAddress(hm_kernel32dll, "HeapSetInformation");
+ HMODULE hm_kernel32dll = LoadLibrary ("kernel32.dll");
+ HeapSetInformation_Proc s_pfn_Heap_Set_Information = (HeapSetInformation_Proc) GetProcAddress (hm_kernel32dll, "HeapSetInformation");
if (s_pfn_Heap_Set_Information != NULL)
- if (s_pfn_Heap_Set_Information ((PVOID) heap,
- HeapCompatibilityInformation,
- &enable_lfh, sizeof(enable_lfh)) == 0)
- DebPrint (("Enabling Low Fragmentation Heap failed: error %ld\n",
- GetLastError ()));
+ {
+ if (s_pfn_Heap_Set_Information ((PVOID) heap,
+ HeapCompatibilityInformation,
+ &enable_lfh, sizeof(enable_lfh)) == 0)
+ DebPrint (("Enabling Low Fragmentation Heap failed: error %ld\n",
+ GetLastError ()));
+ }
#endif
the_malloc_fn = malloc_after_dump;
= (RtlCreateHeap_Proc) GetProcAddress (hm_ntdll, "RtlCreateHeap");
/* Specific parameters for the private heap. */
RTL_HEAP_PARAMETERS params;
- ZeroMemory(¶ms, sizeof(params));
+ ZeroMemory (¶ms, sizeof(params));
params.Length = sizeof(RTL_HEAP_PARAMETERS);
data_region_base = (unsigned char *)ROUND_UP (dumped_data, 0x1000);
params.CommitRoutine = &dumped_data_commit;
/* Create the private heap. */
+ if (s_pfn_Rtl_Create_Heap == NULL)
+ {
+ fprintf (stderr, "Cannot build Emacs without RtlCreateHeap being available; exiting.\n");
+ exit (-1);
+ }
heap = s_pfn_Rtl_Create_Heap (0, data_region_base, 0, 0, NULL, ¶ms);
the_malloc_fn = malloc_before_dump;
the_realloc_fn = realloc_before_dump;
#undef free
/* FREEABLE_P checks if the block can be safely freed. */
-#define FREEABLE_P(addr) \
- ((unsigned char *)(addr) < dumped_data \
- || (unsigned char *)(addr) >= dumped_data + DUMPED_HEAP_SIZE)
+#define FREEABLE_P(addr) \
+ ((unsigned char *)(addr) > 0 \
+ && ((unsigned char *)(addr) < dumped_data \
+ || (unsigned char *)(addr) >= dumped_data + DUMPED_HEAP_SIZE))
void *
malloc_after_dump (size_t size)
array. */
if (blocks_number >= MAX_BLOCKS)
{
- fprintf(stderr,
- "malloc_before_dump: no more big chunks available.\nEnlarge MAX_BLOCKS!\n");
+ fprintf (stderr,
+ "malloc_before_dump: no more big chunks available.\nEnlarge MAX_BLOCKS!\n");
exit (-1);
}
bc_limit -= size;
blocks[blocks_number].size = size;
blocks[blocks_number].occupied = TRUE;
blocks_number++;
+ /* Check that areas do not overlap. */
if (bc_limit < dumped_data + committed)
{
- /* Check that areas do not overlap. */
- fprintf(stderr,
- "malloc_before_dump: memory exhausted.\nEnlarge dumped_data[]!\n");
+ fprintf (stderr,
+ "malloc_before_dump: memory exhausted.\nEnlarge dumped_data[]!\n");
exit (-1);
}
}
/* If the block lies in the dumped data, do not free it. Only
allocate a new one. */
p = HeapAlloc (heap, 0, size);
- if (p)
- CopyMemory (p, ptr, size);
- else
+ if (!p)
errno = ENOMEM;
+ else if (ptr)
+ CopyMemory (p, ptr, size);
}
/* After dump, keep track of the "brk value" for sbrk(0). */
if (p)
of failing the call as below. But this doesn't seem to be
worth the added complexity, as loadup allocates only a very
small number of large blocks, and never reallocates them. */
- if (p)
+ if (p && ptr)
{
CopyMemory (p, ptr, size);
free_before_dump (ptr);
void
free_before_dump (void *ptr)
{
+ if (!ptr)
+ return;
+
/* Before dumping. */
if (dumped_data < (unsigned char *)ptr
&& (unsigned char *)ptr < bc_limit)