Next: , Previous: , Up: Allocation of Objects in SXEmacs Lisp   [Contents][Index]


11.8 Low-level allocation

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). Free using xfree(), and realloc using xrealloc(). Note that 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 significance.

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 mmap() 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 introduced. allocate_lisp_storage() is called by alloc_lcrecord(), 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.


Next: , Previous: , Up: Allocation of Objects in SXEmacs Lisp   [Contents][Index]