>>>>"SJT" == Stephen J Turnbull
SJT> Marcus Crestani writes:
> Yeah, pretty much: I was able to nuke many finalizers by
> separately allocated data structures to Lisp objects. Some of the
> remaining finalizers are also likely to go away, as soon as I (or
> someone else) find the time to lift the remaining, separately allocated
> objects to Lisp objects.
SJT> Is this "lifting" process documented somewhere?
I wrote about it when I first introduced the incremental garbage
collector (back in November 2005). Unfortunately, the archive for
xemacs-patches does not go back that far, so here is the interesting
excerpt from my old post:
Unfortunately, the current Lisp object layout leads to holes in the
write barrier: Not all data structures that contain pointers to Lisp
objects are allocated on the Lisp heap. Some Lisp objects do not carry
all their information in the object itself. External parts are kept in
separately allocated memory blocks that are not managed by the new Lisp
allocator. Examples for these objects are hash tables and dynamic
arrays, two objects that can dynamically grow and shrink. The separate
memory blocks are not guaranteed to reside on page boundaries, and thus
cannot be watched by the write barrier.
Moreover, the separate parts can contain live pointers to other Lisp
objects. These pointers are not covered by the write barrier and
modifications by the client during garbage collection do escape. In
this case, the client changes the connectivity of the reachability
graph behind the collector's back, which eventually leads to erroneous
collection of live objects. To solve this problem, I transformed the
separately allocated parts to fully qualified Lisp objects that are
managed by the allocator and thus are covered by the write barrier.
This also removes a lot of special allocation and removal code for the
out-sourced parts. Generally, allocating all data structures that
contain pointers to Lisp objects on one heap makes the whole memory
layout more consistent.
A large part of the patch converts these data structures to Lisp
objects. The conversion of an additionally allocated data structure to
an Lisp objects includes:
- Add new object type to enum lrecord_type in lrecord.h.
- Add lrecord_header to the object's struct.
- Add DECLARE_RECORD()/XFOO/etc. below the struct definition.
- Add lrecord definition.
- Change allocation with malloc to allocation with new allocator.
- Add object to syms_of_*().
- Change memory description of parent object.
- Modify finalizer, free, or delete functions.
The initial motivation for this is the write barrier and the consistent
format for all objects that may contain Lisp pointers. That we can get
rid of finalizers this way follows naturally.
XEmacs-Beta mailing list