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 }