]> code.delx.au - gnu-emacs/blobdiff - src/w32heap.c
Don't install keyboard hook when debugged on MS-Windows
[gnu-emacs] / src / w32heap.c
index 3d1c5ff50a252bb4b269f17bc11b989dbd6ac402..658a8a5d691b08aebefaadd9ead4f2394179e0d7 100644 (file)
@@ -73,12 +73,11 @@ typedef PVOID (WINAPI * RtlCreateHeap_Proc) (
 
 typedef LONG NTSTATUS;
 
-typedef NTSTATUS
-(NTAPI * PRTL_HEAP_COMMIT_ROUTINE)(
-                                   IN PVOID Base,
-                                   IN OUT PVOID *CommitAddress,
-                                   IN OUT PSIZE_T CommitSize
-                                   );
+typedef NTSTATUS (NTAPI *PRTL_HEAP_COMMIT_ROUTINE) (
+                                                   IN PVOID Base,
+                                                   IN OUT PVOID *CommitAddress,
+                                                   IN OUT PSIZE_T CommitSize
+                                                   );
 
 typedef struct _RTL_HEAP_PARAMETERS {
   ULONG Length;
@@ -100,8 +99,8 @@ typedef struct _RTL_HEAP_PARAMETERS {
    special segment to the executable.  In order to be able to do this
    without losing too much space, we need to create a Windows heap at
    the specific address of the static array.  The RtlCreateHeap
-   available inside the NT kernel since XP will do this.  It allows to
-   create a non-growable heap at a specific address.  So before
+   available inside the NT kernel since XP will do this.  It allows the
+   creation of a non-growable heap at a specific address.  So before
    dumping, we create a non-growable heap at the address of the
    dumped_data[] array.  After dumping, we reuse memory allocated
    there without being able to free it (but most of it is not meant to
@@ -190,7 +189,7 @@ free_fn the_free_fn;
    claims for new memory.  Before dumping, we allocate space
    from the fixed size dumped_data[] array.
 */
-NTSTATUS NTAPI
+static NTSTATUS NTAPI
 dumped_data_commit (PVOID Base, PVOID *CommitAddress, PSIZE_T CommitSize)
 {
   /* This is used before dumping.
@@ -324,9 +323,9 @@ init_heap (void)
 
 /* FREEABLE_P checks if the block can be safely freed.  */
 #define FREEABLE_P(addr)                                               \
-    ((unsigned char *)(addr) > 0                                       \
-     && ((unsigned char *)(addr) < dumped_data                         \
-        || (unsigned char *)(addr) >= dumped_data + DUMPED_HEAP_SIZE))
+  ((DWORD_PTR)(unsigned char *)(addr) > 0                              \
+   && ((unsigned char *)(addr) < dumped_data                           \
+       || (unsigned char *)(addr) >= dumped_data + DUMPED_HEAP_SIZE))
 
 void *
 malloc_after_dump (size_t size)
@@ -641,26 +640,32 @@ mmap_alloc (void **var, size_t nbytes)
      advance, and the buffer is enlarged several times as the data is
      decompressed on the fly.  */
   if (nbytes < MAX_BUFFER_SIZE)
-    p = VirtualAlloc (NULL, (nbytes * 2), MEM_RESERVE, PAGE_READWRITE);
+    p = VirtualAlloc (NULL, ROUND_UP (nbytes * 2, get_allocation_unit ()),
+                     MEM_RESERVE, PAGE_READWRITE);
 
   /* If it fails, or if the request is above 512MB, try with the
      requested size.  */
   if (p == NULL)
-    p = VirtualAlloc (NULL, nbytes, MEM_RESERVE, PAGE_READWRITE);
+    p = VirtualAlloc (NULL, ROUND_UP (nbytes, get_allocation_unit ()),
+                     MEM_RESERVE, PAGE_READWRITE);
 
   if (p != NULL)
     {
       /* Now, commit pages for NBYTES.  */
       *var = VirtualAlloc (p, nbytes, MEM_COMMIT, PAGE_READWRITE);
+      if (*var == NULL)
+       p = *var;
     }
 
   if (!p)
     {
-      if (GetLastError () == ERROR_NOT_ENOUGH_MEMORY)
+      DWORD e = GetLastError ();
+
+      if (e == ERROR_NOT_ENOUGH_MEMORY)
        errno = ENOMEM;
       else
        {
-         DebPrint (("mmap_alloc: error %ld\n", GetLastError ()));
+         DebPrint (("mmap_alloc: error %ld\n", e));
          errno = EINVAL;
        }
     }
@@ -683,6 +688,7 @@ void *
 mmap_realloc (void **var, size_t nbytes)
 {
   MEMORY_BASIC_INFORMATION memInfo, m2;
+  void *old_ptr;
 
   if (*var == NULL)
     return mmap_alloc (var, nbytes);
@@ -694,52 +700,54 @@ mmap_realloc (void **var, size_t nbytes)
       return mmap_alloc (var, nbytes);
     }
 
+  memset (&memInfo, 0, sizeof (memInfo));
   if (VirtualQuery (*var, &memInfo, sizeof (memInfo)) == 0)
     DebPrint (("mmap_realloc: VirtualQuery error = %ld\n", GetLastError ()));
 
   /* We need to enlarge the block.  */
   if (memInfo.RegionSize < nbytes)
     {
-      if (VirtualQuery (*var + memInfo.RegionSize, &m2, sizeof(m2)) == 0)
+      memset (&m2, 0, sizeof (m2));
+      if (VirtualQuery ((char *)*var + memInfo.RegionSize, &m2, sizeof(m2)) == 0)
         DebPrint (("mmap_realloc: VirtualQuery error = %ld\n",
                   GetLastError ()));
       /* If there is enough room in the current reserved area, then
         commit more pages as needed.  */
       if (m2.State == MEM_RESERVE
+         && m2.AllocationBase == memInfo.AllocationBase
          && nbytes <= memInfo.RegionSize + m2.RegionSize)
        {
          void *p;
 
-         p = VirtualAlloc (*var + memInfo.RegionSize,
-                           nbytes - memInfo.RegionSize,
-                           MEM_COMMIT, PAGE_READWRITE);
+         p = VirtualAlloc (*var, nbytes, MEM_COMMIT, PAGE_READWRITE);
          if (!p /* && GetLastError() != ERROR_NOT_ENOUGH_MEMORY */)
            {
-             DebPrint (("realloc enlarge: VirtualAlloc error %ld\n",
+             DebPrint (("realloc enlarge: VirtualAlloc (%p + %I64x, %I64x) error %ld\n",
+                        *var, (uint64_t)memInfo.RegionSize,
+                        (uint64_t)(nbytes - memInfo.RegionSize),
                         GetLastError ()));
-             errno = ENOMEM;
+             DebPrint (("next region: %p %p %I64x %x\n", m2.BaseAddress,
+                        m2.AllocationBase, (uint64_t)m2.RegionSize,
+                        m2.AllocationProtect));
            }
+         else
+           return *var;
+       }
+      /* Else we must actually enlarge the block by allocating a new
+        one and copying previous contents from the old to the new one.  */
+      old_ptr = *var;
+
+      if (mmap_alloc (var, nbytes))
+       {
+         CopyMemory (*var, old_ptr, memInfo.RegionSize);
+         mmap_free (&old_ptr);
          return *var;
        }
       else
        {
-         /* Else we must actually enlarge the block by allocating a
-            new one and copying previous contents from the old to the
-            new one.  */
-         void *old_ptr = *var;
-
-         if (mmap_alloc (var, nbytes))
-           {
-             CopyMemory (*var, old_ptr, memInfo.RegionSize);
-             mmap_free (&old_ptr);
-             return *var;
-           }
-         else
-           {
-             /* We failed to enlarge the buffer.  */
-             *var = old_ptr;
-             return NULL;
-           }
+         /* We failed to reallocate the buffer.  */
+         *var = old_ptr;
+         return NULL;
        }
     }
 
@@ -751,7 +759,7 @@ mmap_realloc (void **var, size_t nbytes)
         {
           /* Let's give some memory back to the system and release
             some pages.  */
-          void *old_ptr = *var;
+          old_ptr = *var;
 
          if (mmap_alloc (var, nbytes))
             {
@@ -770,7 +778,7 @@ mmap_realloc (void **var, size_t nbytes)
         }
 
       /* We still can decommit pages.  */
-      if (VirtualFree (*var + nbytes + get_page_size(),
+      if (VirtualFree ((char *)*var + nbytes + get_page_size(),
                       memInfo.RegionSize - nbytes - get_page_size(),
                       MEM_DECOMMIT) == 0)
         DebPrint (("mmap_realloc: VirtualFree error %ld\n", GetLastError ()));