[gnu.emacs.bug] emacs memory use limitation

shep@ALLSPICE.LCS.MIT.EDU (Tim Shepard) (07/09/89)

I'm using emacs-18.54 on a BSD4.3 VAX.

As distributed, emacs can only use the first 16 megabytes of data
memory on most architectures.  This is because VALBITS is defined to
be 24 in lisp.h and only the low VALBITS bits of a pointer are
actually saved.  The upper 8 bits are quietly ignored.  This causes
emacs to become very confused when malloc() starts returning pointers
which do not fit in 24 bits.  If you've seen a looping and
unresponsive emacs which ps shows to be about 16 or 17 megabytes big,
then you've likely been bitten by this.

The malloc distributed with emacs does check to make sure you have not
exceeded the BSD {get,set}rlimit() imposed memory limits and does
invoke callback routines to the program to warn of the approaching
exhaustion of memory.  Emacs does use these callbacks to show the user
the *Danger* buffers, but neither emacs nor the emacs malloc() checks
to make sure that the pointers have not exceeded this 16 megabyte
limit.  I quickly made the changes shown in the diff below to the
emacs malloc.c which in my particular case (BSD4.3, Vax) causes malloc
to make sure the pointers will be usable by emacs and uses
(1<<VALBITS) for lim_data if it is less than the limit returned from
getrlimit(). I'm not sure how hard it would be to put this checking in
for all architectures because I do not understand the memory layout or
memory limits of all the other machines and operating systems.

Note that you can fiddle around with the VALBITS and GCBITS
definitions and get up to 64 megabytes of usable space in emacs.

I believe future releases of gnu-emacs should at least contain a note
describing this problem so that maintainers of gnu-emacs at various
sites will at least be aware of this limitation.  (It took me quite a
while to figure out what was causing emacs to wedge.)

			-Tim Shepard


*** malloc.c.DIST	Fri Apr  7 22:12:10 1989
--- malloc.c	Thu Jun  1 11:24:15 1989
***************
*** 144,149 ****
--- 144,150 ----
  #ifdef emacs
  /* config.h specifies which kind of system this is.  */
  #include "config.h"
+ #include "lisp.h"
  #else
  
  /* Determine which kind of system this is.  */
***************
*** 385,391 ****
    if ((siz = nu) < 8)
      nblks = 1 << ((siz = 8) - nu);
  
!   if ((cp = sbrk (1 << (siz + 3))) == (char *) -1)
      {
  #ifdef BSD
  #ifndef BSD4_1
--- 386,401 ----
    if ((siz = nu) < 8)
      nblks = 1 << ((siz = 8) - nu);
  
!   if (
! #ifdef emacs
! #ifdef vax
! #ifdef VALBITS
!       ((cp + (1 << siz + 3)) > (1 << VALBITS)) ||
! #endif
! #endif
! #endif
!       ((cp = sbrk (1 << (siz + 3))) == (char *) -1)
!       )
      {
  #ifdef BSD
  #ifndef BSD4_1
***************
*** 792,797 ****
--- 802,815 ----
  get_lim_data ()
  {
    lim_data = vlimit (LIM_DATA, -1);
+ #ifdef emacs
+ #ifdef vax
+ #ifdef VALBITS
+   if ((1<<VALBITS) < lim_data)
+     lim_data = 1 << VALBITS;
+ #endif
+ #endif
+ #endif
  }
  
  #else /* BSD4_2 */
***************
*** 805,810 ****
--- 823,836 ----
    lim_data = XXrlimit.rlim_cur & RLIM_INFINITY; /* soft limit */
  #else
    lim_data = XXrlimit.rlim_cur;	/* soft limit */
+ #endif
+ #ifdef emacs
+ #ifdef vax
+ #ifdef VALBITS
+   if ((1<<VALBITS) < lim_data)
+     lim_data = 1 << VALBITS;
+ #endif
+ #endif
  #endif
  }