+static char *
+allocate_heap (void)
+{
+ /* The base address for our GNU malloc heap is chosen in conjuction
+ with the link settings for temacs.exe which control the stack size,
+ the initial default process heap size and the executable image base
+ address. The link settings and the malloc heap base below must all
+ correspond; the relationship between these values depends on how NT
+ and Windows 95 arrange the virtual address space for a process (and on
+ the size of the code and data segments in temacs.exe).
+
+ The most important thing is to make base address for the executable
+ image high enough to leave enough room between it and the 4MB floor
+ of the process address space on Windows 95 for the primary thread stack,
+ the process default heap, and other assorted odds and ends
+ (eg. environment strings, private system dll memory etc) that are
+ allocated before temacs has a chance to grab its malloc arena. The
+ malloc heap base can then be set several MB higher than the
+ executable image base, leaving enough room for the code and data
+ segments.
+
+ Because some parts of Emacs can use rather a lot of stack space
+ (for instance, the regular expression routines can potentially
+ allocate several MB of stack space) we allow 8MB for the stack.
+
+ Allowing 1MB for the default process heap, and 1MB for odds and
+ ends, we can base the executable at 16MB and still have a generous
+ safety margin. At the moment, the executable has about 810KB of
+ code (for x86) and about 550KB of data - on RISC platforms the code
+ size could be roughly double, so if we allow 4MB for the executable
+ we will have plenty of room for expansion.
+
+ Thus we would like to set the malloc heap base to 20MB. However,
+ Windows 95 refuses to allocate the heap starting at this address, so we
+ set the base to 27MB to make it happy. Since Emacs now leaves
+ 28 bits available for pointers, this lets us use the remainder of
+ the region below the 256MB line for our malloc arena - 229MB is
+ still a pretty decent arena to play in! */
+
+ unsigned long base = 0x01B00000; /* 27MB */
+ unsigned long end = 1 << VALBITS; /* 256MB */
+ void *ptr = NULL;
+
+#define NTHEAP_PROBE_BASE 1
+#if NTHEAP_PROBE_BASE
+ /* Try various addresses looking for one the kernel will let us have. */
+ while (!ptr && (base < end))
+ {
+ reserved_heap_size = end - base;
+ ptr = VirtualAlloc ((void *) base,
+ get_reserved_heap_size (),
+ MEM_RESERVE,
+ PAGE_NOACCESS);
+ base += 0x00100000; /* 1MB increment */
+ }
+#else
+ reserved_heap_size = end - base;
+ ptr = VirtualAlloc ((void *) base,
+ get_reserved_heap_size (),
+ MEM_RESERVE,
+ PAGE_NOACCESS);
+#endif
+
+ return ptr;
+}
+
+