Memory that you want to allocate directly should be allocated using
xmalloc() rather than
malloc(). This implements
error-checking on the return value, and once upon a time did some more
vital stuff (i.e.
BLOCK_INPUT, which is no longer necessary).
xfree(), and realloc using
xmalloc() will do a non-local exit if the memory can’t be
allocated. (Many functions, however, do not expect this, and thus SXEmacs
will likely crash if this happens. This is a bug. If you can,
you should strive to make your function handle this OK. However, it’s
difficult in the general circumstance, perhaps requiring extra
unwind-protects and such.)
Note that SXEmacs provides two separate replacements for the standard
malloc() library function. These are called old GNU malloc
(malloc.c) and new GNU malloc (gmalloc.c),
respectively. New GNU malloc is better in pretty much every way than
old GNU malloc, and should be used if possible. (It used to be that on
some systems, the old one worked but the new one didn’t. I think this
was due specifically to a bug in SunOS, which the new one now works
around; so I don’t think the old one ever has to be used any more.) The
primary difference between both of these mallocs and the standard system
malloc is that they are much faster, at the expense of increased space.
The basic idea is that memory is allocated in fixed chunks of powers of
two. This allows for basically constant malloc time, since the various
chunks can just be kept on a number of free lists. (The standard system
malloc typically allocates arbitrary-sized chunks and has to spend some
time, sometimes a significant amount of time, walking the heap looking
for a free block to use and cleaning things up.) The new GNU malloc
improves on things by allocating large objects in chunks of 4096 bytes
rather than in ever larger powers of two, which results in ever larger
wastage. There is a slight speed loss here, but it’s of doubtful
NOTE: Apparently there is a third-generation GNU malloc that is significantly better than the new GNU malloc, and should probably be included in SXEmacs.
There is also the relocating allocator, ralloc.c. This actually
moves blocks of memory around so that the
sbrk() pointer shrunk
and virtual memory released back to the system. On some systems,
this is a big win. On all systems, it causes a noticeable (and
sometimes huge) speed penalty, so I turn it off by default.
ralloc.c only works with the new GNU malloc in gmalloc.c.
There are also two versions of ralloc.c, one that uses
rather than block copies to move data around. This purports to
be faster, although that depends on the amount of data that would
have had to be block copied and the system-call overhead for
mmap(). I don’t know exactly how this works, except that the
relocating-allocation routines are pretty much used only for
the memory allocated for a buffer, which is the biggest consumer
of space, esp. of space that may get freed later.
Note that the GNU mallocs have some “memory warning” facilities. SXEmacs taps into them and issues a warning through the standard warning system, when memory gets to 75%, 85%, and 95% full. (On some systems, the memory warnings are not functional.)
Allocated memory that is going to be used to make a Lisp object
is created using
allocate_lisp_storage(). This just calls
xmalloc(). It used to verify that the pointer to the memory can
fit into a Lisp word, before the current Lisp object representation was
allocate_lisp_storage() is called by
ALLOCATE_FIXED_TYPE(), and the vector
and bit-vector creation routines. These routines also call
INCREMENT_CONS_COUNTER() at the appropriate times; this keeps
statistics on how much memory is allocated, so that garbage-collection
can be invoked when the threshold is reached.