- Note that there are only eight types that the tag can represent, but
-many more actual types than this. This is handled by having one of the
-tag types specify a meta-type called a "record"; for all such objects,
-the first four bytes of the pointed-to structure indicate what the
-actual type is.
-
- Note also that having 28 bits for pointers and integers restricts a
-lot of things to 256 megabytes of memory. (Basically, enough pointers
-and indices and whatnot get stuffed into Lisp objects that the total
-amount of memory used by XEmacs can't grow above 256 megabytes. In
-older versions of XEmacs and GNU Emacs, the tag was 5 bits wide,
-allowing for 32 types, which was more than the actual number of types
-that existed at the time, and no "record" type was necessary. However,
-this limited the editor to 64 megabytes total, which some users who
-edited large files might conceivably exceed.)
-
- Also, note that there is an implicit assumption here that all
-pointers are low enough that the top bits are all zero and can just be
-chopped off. On standard machines that allocate memory from the bottom
-up (and give each process its own address space), this works fine. Some
-machines, however, put the data space somewhere else in memory (e.g.
-beginning at 0x80000000). Those machines cope by defining
-`DATA_SEG_BITS' in the corresponding `m/' or `s/' file to the proper
-mask. Then, pointers retrieved from Lisp objects are automatically
-OR'ed with this value prior to being used.
-
- A corollary of the previous paragraph is that *(pointers to)
-stack-allocated structures cannot be put into Lisp objects*. The stack
-is generally located near the top of memory; if you put such a pointer
-into a Lisp object, it will get its top bits chopped off, and you will
-lose.
-
- Actually, there's an alternative representation of a `Lisp_Object',
-invented by Kyle Jones, that is used when the `--use-minimal-tagbits'
-option to `configure' is used. In this case the 2 lower bits are used
-for the tag bits. This representation assumes that pointers to structs
-are always aligned to multiples of 4, so the lower 2 bits are always
-zero.
-
- [ 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 ]
- [ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 ]
-
- <---------------------------------------------------------> <->
- a pointer to a structure, or an integer tag
-
- A tag of 00 is used for all pointer object types, a tag of 10 is used
-for characters, and the other two tags 01 and 11 are joined together to
-form the integer object type. The markbit is moved to part of the
-structure being pointed at (integers and chars do not need to be marked,
-since no memory is allocated). This representation has these
-advantages:
-
- 1. 31 bits can be used for Lisp Integers.
-
- 2. _Any_ pointer can be represented directly, and no bit masking
- operations are necessary.
-
- The disadvantages are:
-
- 1. An extra level of indirection is needed when accessing the object
- types that were not record types. So checking whether a Lisp
- object is a cons cell becomes a slower operation.
-
- 2. Mark bits can no longer be stored directly in Lisp objects, so
- another place for them must be found. This means that a cons cell
- requires more memory than merely room for 2 lisp objects, leading
- to extra memory use.
-
- Various macros are used to construct Lisp objects and extract the
-components. Macros of the form `XINT()', `XCHAR()', `XSTRING()',
-`XSYMBOL()', etc. mask out the pointer/integer field and cast it to the
-appropriate type. All of the macros that construct pointers will `OR'
-with `DATA_SEG_BITS' if necessary. `XINT()' needs to be a bit tricky
-so that negative numbers are properly sign-extended: Usually it does
-this by shifting the number four bits to the left and then four bits to
-the right. This assumes that the right-shift operator does an
-arithmetic shift (i.e. it leaves the most-significant bit as-is rather
-than shifting in a zero, so that it mimics a divide-by-two even for
-negative numbers). Not all machines/compilers do this, and on the ones
-that don't, a more complicated definition is selected by defining
-`EXPLICIT_SIGN_EXTEND'.
-
- Note that when `ERROR_CHECK_TYPECHECK' is defined, the extractor
+ Various macros are used to convert between Lisp_Objects and the
+corresponding C type. Macros of the form `XINT()', `XCHAR()',
+`XSTRING()', `XSYMBOL()', do any required bit shifting and/or masking
+and cast it to the appropriate type. `XINT()' needs to be a bit tricky
+so that negative numbers are properly sign-extended. Since integers
+are stored left-shifted, if the right-shift operator does an arithmetic
+shift (i.e. it leaves the most-significant bit as-is rather than
+shifting in a zero, so that it mimics a divide-by-two even for negative
+numbers) the shift to remove the tag bit is enough. This is the case
+on all the systems we support.
+
+ Note that when `ERROR_CHECK_TYPECHECK' is defined, the converter