Hi,
I'm currently working on a new Representation for ELisp data objects
in order to get them more abstract and have GC and the other XEmacs
modules decoupled.
With the new representation, data objects are either binary or contain
only descriptors (a descriptor is a tagged datum, in XEmacs source its
C type is Lisp_Object). This gives the GC the information needed to
traverse the reachability graph of live objects. The mark_object
method of a class of objects will be obsolete.
Outside the GC objects should be only accessed through provided
selector and mutator macros/functions. This will help to implement a
write barrier, needed for the generational GC.
An example is the new representation of Lisp_Compiled_Function:
The structure contains only tagged data. The Information is accessed
through selectors and mutators.
struct Lisp_Compiled_Function
{
struct lrecord_header lheader;
Lisp_Object stack_depth;
Lisp_Object specpdl_depth;
Lisp_Object flags;
Lisp_Object instructions;
Lisp_Object constants;
Lisp_Object arglist;
Lisp_Object doc_and_interactive;
#ifdef COMPILED_FUNCTION_ANNOTATION_HACK
Lisp_Object annotated;
#endif
};
/* selectors */
#define XCF_STACK_DEPTH(f) \
(unsigned) XINT (XCOMPILED_FUNCTION (f)->stack_depth)
#define XCF_SPECPDL_DEPTH(f) \
(unsigned) XINT (XCOMPILED_FUNCTION (f)->specpdl_depth)
#define XCF_DOCUMENTATIONP(f) \
((((unsigned int) XINT (XCOMPILED_FUNCTION (f)->flags)) & 1U) == 1U)
#define XCF_INTERACTIVEP(f)\
((((unsigned int) XINT (XCOMPILED_FUNCTION (f)->flags)) & 2U) == 2U)
#define XCF_DOMAINP(f)\
((((unsigned int) XINT (XCOMPILED_FUNCTION (f)->flags)) & 4U) == 4U)
#define XCF_EBOLIFIED(f)\
((((unsigned int) XINT (XCOMPILED_FUNCTION (f)->flags)) & 8U) == 8U)
#define XCF_INSTRUCTIONS(f) XCOMPILED_FUNCTION (f)->instructions
#define XCF_CONSTANTS(f) XCOMPILED_FUNCTION (f)->constants
#define XCF_ARGLIST(f) XCOMPILED_FUNCTION (f)->arglist
#define XCF_DOC_AND_INTERACTIVE(f) XCOMPILED_FUNCTION (f)->doc_and_interactive
#ifdef COMPILED_FUNCTION_ANNOTATION_HACK
#define XCF_ANNOTATION(f) XCOMPILED_FUNCTION (f)->annotated
#endif
Lisp_Object compiled_function_instructions (Lisp_Object f);
Lisp_Object compiled_function_documentation (Lisp_Object f);
Lisp_Object compiled_function_domain (Lisp_Object f);
Lisp_Object compiled_function_interactive (Lisp_Object f);
/* mutators */
#define XSET_CF_STACK_DEPTH(f, d) \
XSETINT (XCOMPILED_FUNCTION (f)->stack_depth, (unsigned) d)
#define XSET_CF_SPECPDL_DEPTH(f, d) \
XSETINT (XCOMPILED_FUNCTION (f)->specpdl_depth, (unsigned) d)
#define XSET_CF_DOCUMENTATIONP(f, p) \
XSETINT (XCOMPILED_FUNCTION (f)->flags, \
((XINT (XCOMPILED_FUNCTION (f)->flags)) & 14U) | p)
#define XSET_CF_INTERACTIVEP(f, p) \
XSETINT (XCOMPILED_FUNCTION (f)->flags, \
((XINT (XCOMPILED_FUNCTION (f)->flags)) & 13U) | (p << 1))
#define XSET_CF_DOMAINP(f, p) \
XSETINT (XCOMPILED_FUNCTION (f)->flags, \
((XINT (XCOMPILED_FUNCTION (f)->flags)) & 11U) | (p << 2))
#define XSET_CF_EBOLIFIED(f, p) \
XSETINT (XCOMPILED_FUNCTION (f)->flags, \
((XINT (XCOMPILED_FUNCTION (f)->flags)) & 7U) | (p << 3))
#define XSET_CF_INSTRUCTIONS(f, i) XCOMPILED_FUNCTION (f)->instructions = i
#define XSET_CF_CONSTANTS(f, c) XCOMPILED_FUNCTION (f)->constants = c
#define XSET_CF_ARGLIST(f, args) XCOMPILED_FUNCTION (f)->arglist = args
#define XSET_CF_DOC_AND_INTERACTIVE(f, dai) \
XCOMPILED_FUNCTION (f)->doc_and_interactive = dai
#ifdef COMPILED_FUNCTION_ANNOTATION_HACK
#define XSET_CF_ANNOTATED(f, a) (XCOMPILED_FUNCTION (f)->annotated = a)
#endif
compare it to the old representation:
struct Lisp_Compiled_Function
{
struct lrecord_header lheader;
unsigned short stack_depth;
unsigned short specpdl_depth;
struct
{
unsigned int documentationp: 1;
unsigned int interactivep: 1;
unsigned int domainp: 1;
unsigned int ebolified: 1;
} flags;
Lisp_Object instructions;
Lisp_Object constants;
Lisp_Object arglist;
Lisp_Object doc_and_interactive;
#ifdef COMPILED_FUNCTION_ANNOTATION_HACK
Lisp_Object annotated;
#endif
};
Richard