summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Lahdenniemi <jussi@aprikoodi.fi>2016-01-16 11:11:12 +0200
committerEli Zaretskii <eliz@gnu.org>2016-01-16 11:11:12 +0200
commit15c23aaf8368215613b0ffd02fe3bb742935f12e (patch)
tree49ef2d902791b43feff3cecaaa5b82f4ccb3d6b5
parent39afa422ad0b3cef00292e260d424b7cd589b90d (diff)
Ensure 8-byte aligned memory allocation on MS-Windows 9X
* src/w32heap.c (init_heap): Redirect malloc, realloc, and free to special functions on Windows 9X. Refuse to dump Emacs on Windows 9X. (malloc_after_dump_9x, realloc_after_dump_9x) (free_after_dump_9x): New functions. (Bug#22379) See also http://lists.gnu.org/archive/html/emacs-devel/2016-01/msg00852.html for more details about the original problem. * nt/inc/ms-w32.h (malloc_after_dump_9x, realloc_after_dump_9x) (free_after_dump_9x): Add prototypes. Copyright-paperwork-exempt: yes
-rw-r--r--nt/inc/ms-w32.h4
-rw-r--r--src/w32heap.c89
2 files changed, 87 insertions, 6 deletions
diff --git a/nt/inc/ms-w32.h b/nt/inc/ms-w32.h
index cdbfac03c6..a37510e745 100644
--- a/nt/inc/ms-w32.h
+++ b/nt/inc/ms-w32.h
@@ -457,6 +457,10 @@ extern void *malloc_after_dump(size_t);
extern void *realloc_after_dump(void *, size_t);
extern void free_after_dump(void *);
+extern void *malloc_after_dump_9x(size_t);
+extern void *realloc_after_dump_9x(void *, size_t);
+extern void free_after_dump_9x(void *);
+
extern malloc_fn the_malloc_fn;
extern realloc_fn the_realloc_fn;
extern free_fn the_free_fn;
diff --git a/src/w32heap.c b/src/w32heap.c
index 54646bfbe3..3d1c5ff50a 100644
--- a/src/w32heap.c
+++ b/src/w32heap.c
@@ -258,9 +258,18 @@ init_heap (void)
}
#endif
- the_malloc_fn = malloc_after_dump;
- the_realloc_fn = realloc_after_dump;
- the_free_fn = free_after_dump;
+ if (os_subtype == OS_9X)
+ {
+ the_malloc_fn = malloc_after_dump_9x;
+ the_realloc_fn = realloc_after_dump_9x;
+ the_free_fn = free_after_dump_9x;
+ }
+ else
+ {
+ the_malloc_fn = malloc_after_dump;
+ the_realloc_fn = realloc_after_dump;
+ the_free_fn = free_after_dump;
+ }
}
else
{
@@ -291,9 +300,18 @@ init_heap (void)
exit (-1);
}
heap = s_pfn_Rtl_Create_Heap (0, data_region_base, 0, 0, NULL, &params);
- the_malloc_fn = malloc_before_dump;
- the_realloc_fn = realloc_before_dump;
- the_free_fn = free_before_dump;
+
+ if (os_subtype == OS_9X)
+ {
+ fprintf (stderr, "Cannot dump Emacs on Windows 9X; exiting.\n");
+ exit (-1);
+ }
+ else
+ {
+ the_malloc_fn = malloc_before_dump;
+ the_realloc_fn = realloc_before_dump;
+ the_free_fn = free_before_dump;
+ }
}
/* Update system version information to match current system. */
@@ -504,6 +522,65 @@ free_before_dump (void *ptr)
}
}
+/* On Windows 9X, HeapAlloc may return pointers that are not aligned
+ on 8-byte boundary, alignment which is required by the Lisp memory
+ management. To circumvent this problem, manually enforce alignment
+ on Windows 9X. */
+
+void *
+malloc_after_dump_9x (size_t size)
+{
+ void *p = malloc_after_dump (size + 8);
+ void *pa;
+ if (p == NULL)
+ return p;
+ pa = (void*)(((intptr_t)p + 8) & ~7);
+ *((void**)pa-1) = p;
+ return pa;
+}
+
+void *
+realloc_after_dump_9x (void *ptr, size_t size)
+{
+ if (FREEABLE_P (ptr))
+ {
+ void *po = *((void**)ptr-1);
+ void *p;
+ void *pa;
+ p = realloc_after_dump (po, size + 8);
+ if (p == NULL)
+ return p;
+ pa = (void*)(((intptr_t)p + 8) & ~7);
+ if (ptr != NULL &&
+ (char*)pa - (char*)p != (char*)ptr - (char*)po)
+ {
+ /* Handle the case where alignment in pre-realloc and
+ post-realloc blocks does not match. */
+ MoveMemory (pa, (void*)((char*)p + ((char*)ptr - (char*)po)), size);
+ }
+ *((void**)pa-1) = p;
+ return pa;
+ }
+ else
+ {
+ /* Non-freeable pointers have no alignment-enforcing header
+ (since dumping is not allowed on Windows 9X). */
+ void* p = malloc_after_dump_9x (size);
+ if (p != NULL)
+ CopyMemory (p, ptr, size);
+ return p;
+ }
+}
+
+void
+free_after_dump_9x (void *ptr)
+{
+ if (FREEABLE_P (ptr))
+ {
+ free_after_dump (*((void**)ptr-1));
+ }
+}
+
#ifdef ENABLE_CHECKING
void
report_temacs_memory_usage (void)