Merge r21-4-11-chise-0_20-=ucs.
[chise/xemacs-chise.git.1] / info / internals.info-5
diff --git a/info/internals.info-5 b/info/internals.info-5
deleted file mode 100644 (file)
index cbb9a34..0000000
+++ /dev/null
@@ -1,1006 +0,0 @@
-This is Info file ../../info/internals.info, produced by Makeinfo
-version 1.68 from the input file internals.texi.
-
-INFO-DIR-SECTION XEmacs Editor
-START-INFO-DIR-ENTRY
-* Internals: (internals).      XEmacs Internals Manual.
-END-INFO-DIR-ENTRY
-
-   Copyright (C) 1992 - 1996 Ben Wing.  Copyright (C) 1996, 1997 Sun
-Microsystems.  Copyright (C) 1994 - 1998 Free Software Foundation.
-Copyright (C) 1994, 1995 Board of Trustees, University of Illinois.
-
-   Permission is granted to make and distribute verbatim copies of this
-manual provided the copyright notice and this permission notice are
-preserved on all copies.
-
-   Permission is granted to copy and distribute modified versions of
-this manual under the conditions for verbatim copying, provided that the
-entire resulting derived work is distributed under the terms of a
-permission notice identical to this one.
-
-   Permission is granted to copy and distribute translations of this
-manual into another language, under the above conditions for modified
-versions, except that this permission notice may be stated in a
-translation approved by the Foundation.
-
-   Permission is granted to copy and distribute modified versions of
-this manual under the conditions for verbatim copying, provided also
-that the section entitled "GNU General Public License" is included
-exactly as in the original, and provided that the entire resulting
-derived work is distributed under the terms of a permission notice
-identical to this one.
-
-   Permission is granted to copy and distribute translations of this
-manual into another language, under the above conditions for modified
-versions, except that the section entitled "GNU General Public License"
-may be included in a translation approved by the Free Software
-Foundation instead of in the original English.
-
-\1f
-File: internals.info,  Node: garbage_collect_1,  Next: mark_object,  Prev: Invocation,  Up: Garbage Collection - Step by Step
-
-`garbage_collect_1'
--------------------
-
-   We can now describe exactly what happens after the invocation takes
-place.
-  1. There are several cases in which the garbage collector is left
-     immediately: when we are already garbage collecting
-     (`gc_in_progress'), when the garbage collection is somehow
-     forbidden (`gc_currently_forbidden'), when we are currently
-     displaying something (`in_display') or when we are preparing for
-     the armageddon of the whole system (`preparing_for_armageddon').
-
-  2. Next the correct frame in which to put all the output occurring
-     during garbage collecting is determined. In order to be able to
-     restore the old display's state after displaying the message, some
-     data about the current cursor position has to be saved. The
-     variables `pre_gc_curser' and `cursor_changed' take care of that.
-
-  3. The state of `gc_currently_forbidden' must be restored after the
-     garbage collection, no matter what happens during the process. We
-     accomplish this by `record_unwind_protect'ing the suitable function
-     `restore_gc_inhibit' together with the current value of
-     `gc_currently_forbidden'.
-
-  4. If we are concurrently running an interactive xemacs session, the
-     next step is simply to show the garbage collector's cursor/message.
-
-  5. The following steps are the intrinsic steps of the garbage
-     collector, therefore `gc_in_progress' is set.
-
-  6. For debugging purposes, it is possible to copy the current C stack
-     frame. However, this seems to be a currently unused feature.
-
-  7. Before actually starting to go over all live objects, references to
-     objects that are no longer used are pruned. We only have to do
-     this for events (`clear_event_resource') and for specifiers
-     (`cleanup_specifiers').
-
-  8. Now the mark phase begins and marks all accessible elements. In
-     order to start from all slots that serve as roots of
-     accessibility, the function `mark_object' is called for each root
-     individually to go out from there to mark all reachable objects.
-     All roots that are traversed are shown in their processed order:
-        * all constant symbols and static variables that are registered
-          via `staticpro' in the array `staticvec'.  *Note Adding
-          Global Lisp Variables::.
-
-        * all Lisp objects that are created in C functions and that
-          must be protected from freeing them. They are registered in
-          the global list `gcprolist'.  *Note GCPROing::.
-
-        * all local variables (i.e. their name fields `symbol' and old
-          values `old_values') that are bound during the evaluation by
-          the Lisp engine. They are stored in `specbinding' structs
-          pushed on a stack called `specpdl'.  *Note Dynamic Binding;
-          The specbinding Stack; Unwind-Protects::.
-
-        * all catch blocks that the Lisp engine encounters during the
-          evaluation cause the creation of structs `catchtag' inserted
-          in the list `catchlist'. Their tag (`tag') and value (`val'
-          fields are freshly created objects and therefore have to be
-          marked.  *Note Catch and Throw::.
-
-        * every function application pushes new structs `backtrace' on
-          the call stack of the Lisp engine (`backtrace_list'). The
-          unique parts that have to be marked are the fields for each
-          function (`function') and all their arguments (`args').
-          *Note Evaluation::.
-
-        * all objects that are used by the redisplay engine that must
-          not be freed are marked by a special function called
-          `mark_redisplay' (in `redisplay.c').
-
-        * all objects created for profiling purposes are allocated by C
-          functions instead of using the lisp allocation mechanisms. In
-          order to receive the right ones during the sweep phase, they
-          also have to be marked manually. That is done by the function
-          `mark_profiling_info'
-
-  9. Hash tables in Xemacs belong to a kind of special objects that
-     make use of a concept often called 'weak pointers'.  To make a
-     long story short, these kind of pointers are not followed during
-     the estimation of the live objects during garbage collection.  Any
-     object referenced only by weak pointers is collected anyway, and
-     the reference to it is cleared. In hash tables there are different
-     usage patterns of them, manifesting in different types of hash
-     tables, namely 'non-weak', 'weak', 'key-weak' and 'value-weak'
-     (internally also 'key-car-weak' and 'value-car-weak') hash tables,
-     each clearing entries depending on different conditions. More
-     information can be found in the documentation to the function
-     `make-hash-table'.
-
-     Because there are complicated dependency rules about when and what
-     to mark while processing weak hash tables, the standard `marker'
-     method is only active if it is marking non-weak hash tables. As
-     soon as a weak component is in the table, the hash table entries
-     are ignored while marking. Instead their marking is done each
-     separately by the function `finish_marking_weak_hash_tables'. This
-     function iterates over each hash table entry `hentries' for each
-     weak hash table in `Vall_weak_hash_tables'. Depending on the type
-     of a table, the appropriate action is performed.  If a table is
-     acting as `HASH_TABLE_KEY_WEAK', and a key already marked,
-     everything reachable from the `value' component is marked. If it is
-     acting as a `HASH_TABLE_VALUE_WEAK' and the value component is
-     already marked, the marking starts beginning only from the `key'
-     component.  If it is a `HASH_TABLE_KEY_CAR_WEAK' and the car of
-     the key entry is already marked, we mark both the `key' and
-     `value' components.  Finally, if the table is of the type
-     `HASH_TABLE_VALUE_CAR_WEAK' and the car of the value components is
-     already marked, again both the `key' and the `value' components
-     get marked.
-
-     Again, there are lists with comparable properties called weak
-     lists. There exist different peculiarities of their types called
-     `simple', `assoc', `key-assoc' and `value-assoc'. You can find
-     further details about them in the description to the function
-     `make-weak-list'. The scheme of their marking is similar: all weak
-     lists are listed in `Qall_weak_lists', therefore we iterate over
-     them. The marking is advanced until we hit an already marked pair.
-     Then we know that during a former run all the rest has been marked
-     completely. Again, depending on the special type of the weak list,
-     our jobs differ. If it is a `WEAK_LIST_SIMPLE' and the elem is
-     marked, we mark the `cons' part. If it is a `WEAK_LIST_ASSOC' and
-     not a pair or a pair with both marked car and cdr, we mark the
-     `cons' and the `elem'. If it is a `WEAK_LIST_KEY_ASSOC' and not a
-     pair or a pair with a marked car of the elem, we mark the `cons'
-     and the `elem'. Finally, if it is a `WEAK_LIST_VALUE_ASSOC' and
-     not a pair or a pair with a marked cdr of the elem, we mark both
-     the `cons' and the `elem'.
-
-     Since, by marking objects in reach from weak hash tables and weak
-     lists, other objects could get marked, this perhaps implies
-     further marking of other weak objects, both finishing functions
-     are redone as long as yet unmarked objects get freshly marked.
-
- 10. After completing the special marking for the weak hash tables and
-     for the weak lists, all entries that point to objects that are
-     going to be swept in the further process are useless, and
-     therefore have to be removed from the table or the list.
-
-     The function `prune_weak_hash_tables' does the job for weak hash
-     tables. Totally unmarked hash tables are removed from the list
-     `Vall_weak_hash_tables'. The other ones are treated more carefully
-     by scanning over all entries and removing one as soon as one of
-     the components `key' and `value' is unmarked.
-
-     The same idea applies to the weak lists. It is accomplished by
-     `prune_weak_lists': An unmarked list is pruned from
-     `Vall_weak_lists' immediately. A marked list is treated more
-     carefully by going over it and removing just the unmarked pairs.
-
- 11. The function `prune_specifiers' checks all listed specifiers held
-     in `Vall_speficiers' and removes the ones from the lists that are
-     unmarked.
-
- 12. All syntax tables are stored in a list called
-     `Vall_syntax_tables'. The function `prune_syntax_tables' walks
-     through it and unlinks the tables that are unmarked.
-
- 13. Next, we will attack the complete sweeping - the function
-     `gc_sweep' which holds the predominance.
-
- 14. First, all the variables with respect to garbage collection are
-     reset. `consing_since_gc' - the counter of the created cells since
-     the last garbage collection - is set back to 0, and
-     `gc_in_progress' is not `true' anymore.
-
- 15. In case the session is interactive, the displayed cursor and
-     message are removed again.
-
- 16. The state of `gc_inhibit' is restored to the former value by
-     unwinding the stack.
-
- 17. A small memory reserve is always held back that can be reached by
-     `breathing_space'. If nothing more is left, we create a new reserve
-     and exit.
-
-\1f
-File: internals.info,  Node: mark_object,  Next: gc_sweep,  Prev: garbage_collect_1,  Up: Garbage Collection - Step by Step
-
-`mark_object'
--------------
-
-   The first thing that is checked while marking an object is whether
-the object is a real Lisp object `Lisp_Type_Record' or just an integer
-or a character. Integers and characters are the only two types that are
-stored directly - without another level of indirection, and therefore
-they don´t have to be marked and collected.  *Note How Lisp Objects Are
-Represented in C::.
-
-   The second case is the one we have to handle. It is the one when we
-are dealing with a pointer to a Lisp object. But, there exist also three
-possibilities, that prevent us from doing anything while marking: The
-object is read only which prevents it from being garbage collected,
-i.e. marked (`C_READONLY_RECORD_HEADER'). The object in question is
-already marked, and need not be marked for the second time (checked by
-`MARKED_RECORD_HEADER_P'). If it is a special, unmarkable object
-(`UNMARKABLE_RECORD_HEADER_P', apparently, these are objects that sit
-in some CONST space, and can therefore not be marked, see
-`this_one_is_unmarkable' in `alloc.c').
-
-   Now, the actual marking is feasible. We do so by once using the macro
-`MARK_RECORD_HEADER' to mark the object itself (actually the special
-flag in the lrecord header), and calling its special marker "method"
-`marker' if available. The marker method marks every other object that
-is in reach from our current object. Note, that these marker methods
-should not call `mark_object' recursively, but instead should return
-the next object from where further marking has to be performed.
-
-   In case another object was returned, as mentioned before, we
-reiterate the whole `mark_object' process beginning with this next
-object.
-
-\1f
-File: internals.info,  Node: gc_sweep,  Next: sweep_lcrecords_1,  Prev: mark_object,  Up: Garbage Collection - Step by Step
-
-`gc_sweep'
-----------
-
-   The job of this function is to free all unmarked records from
-memory. As we know, there are different types of objects implemented
-and managed, and consequently different ways to free them from memory.
-*Note Introduction to Allocation::.
-
-   We start with all objects stored through `lcrecords'. All bulkier
-objects are allocated and handled using that scheme of `lcrecords'.
-Each object is `malloc'ed separately instead of placing it in one of
-the contiguous frob blocks. All types that are currently stored using
-`lcrecords'´s  `alloc_lcrecord' and `make_lcrecord_list' are the types:
-vectors, buffers, char-table, char-table-entry, console, weak-list,
-database, device, ldap, hash-table, command-builder, extent-auxiliary,
-extent-info, face, coding-system, frame, image-instance, glyph,
-popup-data, gui-item, keymap, charset, color_instance, font_instance,
-opaque, opaque-list, process, range-table, specifier,
-symbol-value-buffer-local, symbol-value-lisp-magic,
-symbol-value-varalias, toolbar-button, tooltalk-message,
-tooltalk-pattern, window, and window-configuration. We take care of
-them in the fist place in order to be able to handle and to finalize
-items stored in them more easily. The function `sweep_lcrecords_1' as
-described below is doing the whole job for us.  For a description about
-the internals: *Note lrecords::.
-
-   Our next candidates are the other objects that behave quite
-differently than everything else: the strings. They consists of two
-parts, a fixed-size portion (`struct Lisp_string') holding the string's
-length, its property list and a pointer to the second part, and the
-actual string data, which is stored in string-chars blocks comparable to
-frob blocks. In this block, the data is not only freed, but also a
-compression of holes is made, i.e. all strings are relocated together.
-*Note String::. This compacting phase is performed by the function
-`compact_string_chars', the actual sweeping by the function
-`sweep_strings' is described below.
-
-   After that, the other types are swept step by step using functions
-`sweep_conses', `sweep_bit_vectors_1', `sweep_compiled_functions',
-`sweep_floats', `sweep_symbols', `sweep_extents', `sweep_markers' and
-`sweep_extents'.  They are the fixed-size types cons, floats,
-compiled-functions, symbol, marker, extent, and event stored in
-so-called "frob blocks", and therefore we can basically do the same on
-every type objects, using the same macros, especially defined only to
-handle everything with respect to fixed-size blocks. The only fixed-size
-type that is not handled here are the fixed-size portion of strings,
-because we took special care of them earlier.
-
-   The only big exceptions are bit vectors stored differently and
-therefore treated differently by the function `sweep_bit_vectors_1'
-described later.
-
-   At first, we need some brief information about how these fixed-size
-types are managed in general, in order to understand how the sweeping
-is done. They have all a fixed size, and are therefore stored in big
-blocks of memory - allocated at once - that can hold a certain amount
-of objects of one type. The macro `DECLARE_FIXED_TYPE_ALLOC' creates
-the suitable structures for every type. More precisely, we have the
-block struct (holding a pointer to the previous block `prev' and the
-objects in `block[]'), a pointer to current block
-(`current_..._block)') and its last index (`current_..._block_index'),
-and a pointer to the free list that will be created. Also a macro
-`FIXED_TYPE_FROM_BLOCK' plus some related macros exists that are used
-to obtain a new object, either from the free list
-`ALLOCATE_FIXED_TYPE_1' if there is an unused object of that type
-stored or by allocating a completely new block using
-`ALLOCATE_FIXED_TYPE_FROM_BLOCK'.
-
-   The rest works as follows: all of them define a macro `UNMARK_...'
-that is used to unmark the object. They define a macro
-`ADDITIONAL_FREE_...' that defines additional work that has to be done
-when converting an object from in use to not in use (so far, only
-markers use it in order to unchain them). Then, they all call the macro
-`SWEEP_FIXED_TYPE_BLOCK' instantiated with their type name and their
-struct name.
-
-   This call in particular does the following: we go over all blocks
-starting with the current moving towards the oldest.  For each block,
-we look at every object in it. If the object already freed (checked
-with `FREE_STRUCT_P' using the first pointer of the object), or if it is
-set to read only (`C_READONLY_RECORD_HEADER_P', nothing must be done.
-If it is unmarked (checked with `MARKED_RECORD_HEADER_P'), it is put in
-the free list and set free (using the macro `FREE_FIXED_TYPE',
-otherwise it stays in the block, but is unmarked (by `UNMARK_...').
-While going through one block, we note if the whole block is empty. If
-so, the whole block is freed (using `xfree') and the free list state is
-set to the state it had before handling this block.
-
-\1f
-File: internals.info,  Node: sweep_lcrecords_1,  Next: compact_string_chars,  Prev: gc_sweep,  Up: Garbage Collection - Step by Step
-
-`sweep_lcrecords_1'
--------------------
-
-   After nullifying the complete lcrecord statistics, we go over all
-lcrecords two separate times. They are all chained together in a list
-with a head called `all_lcrecords'.
-
-   The first loop calls for each object its `finalizer' method, but only
-in the case that it is not read only (`C_READONLY_RECORD_HEADER_P)', it
-is not already marked (`MARKED_RECORD_HEADER_P'), it is not already in
-a free list (list of freed objects, field `free') and finally it owns a
-finalizer method.
-
-   The second loop actually frees the appropriate objects again by
-iterating through the whole list. In case an object is read only or
-marked, it has to persist, otherwise it is manually freed by calling
-`xfree'. During this loop, the lcrecord statistics are kept up to date
-by calling `tick_lcrecord_stats' with the right arguments,
-
-\1f
-File: internals.info,  Node: compact_string_chars,  Next: sweep_strings,  Prev: sweep_lcrecords_1,  Up: Garbage Collection - Step by Step
-
-`compact_string_chars'
-----------------------
-
-   The purpose of this function is to compact all the data parts of the
-strings that are held in so-called `string_chars_block', i.e. the
-strings that do not exceed a certain maximal length.
-
-   The procedure with which this is done is as follows. We are keeping
-two positions in the `string_chars_block's using two pointer/integer
-pairs, namely `from_sb'/`from_pos' and `to_sb'/`to_pos'. They stand for
-the actual positions, from where to where, to copy the actually handled
-string.
-
-   While going over all chained `string_char_block's and their held
-strings, staring at `first_string_chars_block', both pointers are
-advanced and eventually a string is copied from `from_sb' to `to_sb',
-depending on the status of the pointed at strings.
-
-   More precisely, we can distinguish between the following actions.
-   * The string at `from_sb''s position could be marked as free, which
-     is indicated by an invalid pointer to the pointer that should
-     point back to the fixed size string object, and which is checked by
-     `FREE_STRUCT_P'. In this case, the `from_sb'/`from_pos' is
-     advanced to the next string, and nothing has to be copied.
-
-   * Also, if a string object itself is unmarked, nothing has to be
-     copied. We likewise advance the `from_sb'/`from_pos' pair as
-     described above.
-
-   * In all other cases, we have a marked string at hand. The string
-     data must be moved from the from-position to the to-position. In
-     case there is not enough space in the actual `to_sb'-block, we
-     advance this pointer to the beginning of the next block before
-     copying. In case the from and to positions are different, we
-     perform the actual copying using the library function `memmove'.
-
-   After compacting, the pointer to the current `string_chars_block',
-sitting in `current_string_chars_block', is reset on the last block to
-which we moved a string, i.e. `to_block', and all remaining blocks (we
-know that they just carry garbage) are explicitly `xfree'd.
-
-\1f
-File: internals.info,  Node: sweep_strings,  Next: sweep_bit_vectors_1,  Prev: compact_string_chars,  Up: Garbage Collection - Step by Step
-
-`sweep_strings'
----------------
-
-   The sweeping for the fixed sized string objects is essentially
-exactly the same as it is for all other fixed size types. As before,
-the freeing into the suitable free list is done by using the macro
-`SWEEP_FIXED_SIZE_BLOCK' after defining the right macros
-`UNMARK_string' and `ADDITIONAL_FREE_string'. These two definitions are
-a little bit special compared to the ones used for the other fixed size
-types.
-
-   `UNMARK_string' is defined the same way except some additional code
-used for updating the bookkeeping information.
-
-   For strings, `ADDITIONAL_FREE_string' has to do something in
-addition: in case, the string was not allocated in a
-`string_chars_block' because it exceeded the maximal length, and
-therefore it was `malloc'ed separately, we know also `xfree' it
-explicitly.
-
-\1f
-File: internals.info,  Node: sweep_bit_vectors_1,  Prev: sweep_strings,  Up: Garbage Collection - Step by Step
-
-`sweep_bit_vectors_1'
----------------------
-
-   Bit vectors are also one of the rare types that are `malloc'ed
-individually. Consequently, while sweeping, all further needless bit
-vectors must be freed by hand. This is done, as one might imagine, the
-expected way: since they are all registered in a list called
-`all_bit_vectors', all elements of that list are traversed, all
-unmarked bit vectors are unlinked by calling `xfree' and all of them
-become unmarked.  In addition, the bookkeeping information used for
-garbage collector's output purposes is updated.
-
-\1f
-File: internals.info,  Node: Integers and Characters,  Next: Allocation from Frob Blocks,  Prev: Garbage Collection - Step by Step,  Up: Allocation of Objects in XEmacs Lisp
-
-Integers and Characters
-=======================
-
-   Integer and character Lisp objects are created from integers using
-the macros `XSETINT()' and `XSETCHAR()' or the equivalent functions
-`make_int()' and `make_char()'. (These are actually macros on most
-systems.)  These functions basically just do some moving of bits
-around, since the integral value of the object is stored directly in
-the `Lisp_Object'.
-
-   `XSETINT()' and the like will truncate values given to them that are
-too big; i.e. you won't get the value you expected but the tag bits
-will at least be correct.
-
-\1f
-File: internals.info,  Node: Allocation from Frob Blocks,  Next: lrecords,  Prev: Integers and Characters,  Up: Allocation of Objects in XEmacs Lisp
-
-Allocation from Frob Blocks
-===========================
-
-   The uninitialized memory required by a `Lisp_Object' of a particular
-type is allocated using `ALLOCATE_FIXED_TYPE()'.  This only occurs
-inside of the lowest-level object-creating functions in `alloc.c':
-`Fcons()', `make_float()', `Fmake_byte_code()', `Fmake_symbol()',
-`allocate_extent()', `allocate_event()', `Fmake_marker()', and
-`make_uninit_string()'.  The idea is that, for each type, there are a
-number of frob blocks (each 2K in size); each frob block is divided up
-into object-sized chunks.  Each frob block will have some of these
-chunks that are currently assigned to objects, and perhaps some that are
-free. (If a frob block has nothing but free chunks, it is freed at the
-end of the garbage collection cycle.)  The free chunks are stored in a
-free list, which is chained by storing a pointer in the first four bytes
-of the chunk. (Except for the free chunks at the end of the last frob
-block, which are handled using an index which points past the end of the
-last-allocated chunk in the last frob block.)  `ALLOCATE_FIXED_TYPE()'
-first tries to retrieve a chunk from the free list; if that fails, it
-calls `ALLOCATE_FIXED_TYPE_FROM_BLOCK()', which looks at the end of the
-last frob block for space, and creates a new frob block if there is
-none. (There are actually two versions of these macros, one of which is
-more defensive but less efficient and is used for error-checking.)
-
-\1f
-File: internals.info,  Node: lrecords,  Next: Low-level allocation,  Prev: Allocation from Frob Blocks,  Up: Allocation of Objects in XEmacs Lisp
-
-lrecords
-========
-
-   [see `lrecord.h']
-
-   All lrecords have at the beginning of their structure a `struct
-lrecord_header'.  This just contains a pointer to a `struct
-lrecord_implementation', which is a structure containing method pointers
-and such.  There is one of these for each type, and it is a global,
-constant, statically-declared structure that is declared in the
-`DEFINE_LRECORD_IMPLEMENTATION()' macro. (This macro actually declares
-an array of two `struct lrecord_implementation' structures.  The first
-one contains all the standard method pointers, and is used in all
-normal circumstances.  During garbage collection, however, the lrecord
-is "marked" by bumping its implementation pointer by one, so that it
-points to the second structure in the array.  This structure contains a
-special indication in it that it's a "marked-object" structure: the
-finalize method is the special function `this_marks_a_marked_record()',
-and all other methods are null pointers.  At the end of garbage
-collection, all lrecords will either be reclaimed or unmarked by
-decrementing their implementation pointers, so this second structure
-pointer will never remain past garbage collection.
-
-   Simple lrecords (of type (c) above) just have a `struct
-lrecord_header' at their beginning.  lcrecords, however, actually have a
-`struct lcrecord_header'.  This, in turn, has a `struct lrecord_header'
-at its beginning, so sanity is preserved; but it also has a pointer
-used to chain all lcrecords together, and a special ID field used to
-distinguish one lcrecord from another. (This field is used only for
-debugging and could be removed, but the space gain is not significant.)
-
-   Simple lrecords are created using `ALLOCATE_FIXED_TYPE()', just like
-for other frob blocks.  The only change is that the implementation
-pointer must be initialized correctly. (The implementation structure for
-an lrecord, or rather the pointer to it, is named `lrecord_float',
-`lrecord_extent', `lrecord_buffer', etc.)
-
-   lcrecords are created using `alloc_lcrecord()'.  This takes a size
-to allocate and an implementation pointer. (The size needs to be passed
-because some lcrecords, such as window configurations, are of variable
-size.) This basically just `malloc()'s the storage, initializes the
-`struct lcrecord_header', and chains the lcrecord onto the head of the
-list of all lcrecords, which is stored in the variable `all_lcrecords'.
-The calls to `alloc_lcrecord()' generally occur in the lowest-level
-allocation function for each lrecord type.
-
-   Whenever you create an lrecord, you need to call either
-`DEFINE_LRECORD_IMPLEMENTATION()' or
-`DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION()'.  This needs to be specified
-in a C file, at the top level.  What this actually does is define and
-initialize the implementation structure for the lrecord. (And possibly
-declares a function `error_check_foo()' that implements the `XFOO()'
-macro when error-checking is enabled.)  The arguments to the macros are
-the actual type name (this is used to construct the C variable name of
-the lrecord implementation structure and related structures using the
-`##' macro concatenation operator), a string that names the type on the
-Lisp level (this may not be the same as the C type name; typically, the
-C type name has underscores, while the Lisp string has dashes), various
-method pointers, and the name of the C structure that contains the
-object.  The methods are used to encapsulate type-specific information
-about the object, such as how to print it or mark it for garbage
-collection, so that it's easy to add new object types without having to
-add a specific case for each new type in a bunch of different places.
-
-   The difference between `DEFINE_LRECORD_IMPLEMENTATION()' and
-`DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION()' is that the former is used
-for fixed-size object types and the latter is for variable-size object
-types.  Most object types are fixed-size; some complex types, however
-(e.g. window configurations), are variable-size.  Variable-size object
-types have an extra method, which is called to determine the actual
-size of a particular object of that type.  (Currently this is only used
-for keeping allocation statistics.)
-
-   For the purpose of keeping allocation statistics, the allocation
-engine keeps a list of all the different types that exist.  Note that,
-since `DEFINE_LRECORD_IMPLEMENTATION()' is a macro that is specified at
-top-level, there is no way for it to add to the list of all existing
-types.  What happens instead is that each implementation structure
-contains in it a dynamically assigned number that is particular to that
-type. (Or rather, it contains a pointer to another structure that
-contains this number.  This evasiveness is done so that the
-implementation structure can be declared const.) In the sweep stage of
-garbage collection, each lrecord is examined to see if its
-implementation structure has its dynamically-assigned number set.  If
-not, it must be a new type, and it is added to the list of known types
-and a new number assigned.  The number is used to index into an array
-holding the number of objects of each type and the total memory
-allocated for objects of that type.  The statistics in this array are
-also computed during the sweep stage.  These statistics are returned by
-the call to `garbage-collect' and are printed out at the end of the
-loadup phase.
-
-   Note that for every type defined with a `DEFINE_LRECORD_*()' macro,
-there needs to be a `DECLARE_LRECORD_IMPLEMENTATION()' somewhere in a
-`.h' file, and this `.h' file needs to be included by `inline.c'.
-
-   Furthermore, there should generally be a set of `XFOOBAR()',
-`FOOBARP()', etc. macros in a `.h' (or occasionally `.c') file.  To
-create one of these, copy an existing model and modify as necessary.
-
-   The various methods in the lrecord implementation structure are:
-
-  1. A "mark" method.  This is called during the marking stage and
-     passed a function pointer (usually the `mark_object()' function),
-     which is used to mark an object.  All Lisp objects that are
-     contained within the object need to be marked by applying this
-     function to them.  The mark method should also return a Lisp
-     object, which should be either nil or an object to mark. (This can
-     be used in lieu of calling `mark_object()' on the object, to
-     reduce the recursion depth, and consequently should be the most
-     heavily nested sub-object, such as a long list.)
-
-     *Please note:* When the mark method is called, garbage collection
-     is in progress, and special precautions need to be taken when
-     accessing objects; see section (B) above.
-
-     If your mark method does not need to do anything, it can be `NULL'.
-
-  2. A "print" method.  This is called to create a printed
-     representation of the object, whenever `princ', `prin1', or the
-     like is called.  It is passed the object, a stream to which the
-     output is to be directed, and an `escapeflag' which indicates
-     whether the object's printed representation should be "escaped" so
-     that it is readable. (This corresponds to the difference between
-     `princ' and `prin1'.) Basically, "escaped" means that strings will
-     have quotes around them and confusing characters in the strings
-     such as quotes, backslashes, and newlines will be backslashed; and
-     that special care will be taken to make symbols print in a
-     readable fashion (e.g. symbols that look like numbers will be
-     backslashed).  Other readable objects should perhaps pass
-     `escapeflag' on when sub-objects are printed, so that readability
-     is preserved when necessary (or if not, always pass in a 1 for
-     `escapeflag').  Non-readable objects should in general ignore
-     `escapeflag', except that some use it as an indication that more
-     verbose output should be given.
-
-     Sub-objects are printed using `print_internal()', which takes
-     exactly the same arguments as are passed to the print method.
-
-     Literal C strings should be printed using `write_c_string()', or
-     `write_string_1()' for non-null-terminated strings.
-
-     Functions that do not have a readable representation should check
-     the `print_readably' flag and signal an error if it is set.
-
-     If you specify NULL for the print method, the
-     `default_object_printer()' will be used.
-
-  3. A "finalize" method.  This is called at the beginning of the sweep
-     stage on lcrecords that are about to be freed, and should be used
-     to perform any extra object cleanup.  This typically involves
-     freeing any extra `malloc()'ed memory associated with the object,
-     releasing any operating-system and window-system resources
-     associated with the object (e.g. pixmaps, fonts), etc.
-
-     The finalize method can be NULL if nothing needs to be done.
-
-     WARNING #1: The finalize method is also called at the end of the
-     dump phase; this time with the for_disksave parameter set to
-     non-zero.  The object is *not* about to disappear, so you have to
-     make sure to *not* free any extra `malloc()'ed memory if you're
-     going to need it later.  (Also, signal an error if there are any
-     operating-system and window-system resources here, because they
-     can't be dumped.)
-
-     Finalize methods should, as a rule, set to zero any pointers after
-     they've been freed, and check to make sure pointers are not zero
-     before freeing.  Although I'm pretty sure that finalize methods
-     are not called twice on the same object (except for the
-     `for_disksave' proviso), we've gotten nastily burned in some cases
-     by not doing this.
-
-     WARNING #2: The finalize method is *only* called for lcrecords,
-     *not* for simply lrecords.  If you need a finalize method for
-     simple lrecords, you have to stick it in the
-     `ADDITIONAL_FREE_foo()' macro in `alloc.c'.
-
-     WARNING #3: Things are in an *extremely* bizarre state when
-     `ADDITIONAL_FREE_foo()' is called, so you have to be incredibly
-     careful when writing one of these functions.  See the comment in
-     `gc_sweep()'.  If you ever have to add one of these, consider
-     using an lcrecord or dealing with the problem in a different
-     fashion.
-
-  4. An "equal" method.  This compares the two objects for similarity,
-     when `equal' is called.  It should compare the contents of the
-     objects in some reasonable fashion.  It is passed the two objects
-     and a "depth" value, which is used to catch circular objects.  To
-     compare sub-Lisp-objects, call `internal_equal()' and bump the
-     depth value by one.  If this value gets too high, a
-     `circular-object' error will be signaled.
-
-     If this is NULL, objects are `equal' only when they are `eq', i.e.
-     identical.
-
-  5. A "hash" method.  This is used to hash objects when they are to be
-     compared with `equal'.  The rule here is that if two objects are
-     `equal', they *must* hash to the same value; i.e. your hash
-     function should use some subset of the sub-fields of the object
-     that are compared in the "equal" method.  If you specify this
-     method as `NULL', the object's pointer will be used as the hash,
-     which will *fail* if the object has an `equal' method, so don't do
-     this.
-
-     To hash a sub-Lisp-object, call `internal_hash()'.  Bump the depth
-     by one, just like in the "equal" method.
-
-     To convert a Lisp object directly into a hash value (using its
-     pointer), use `LISP_HASH()'.  This is what happens when the hash
-     method is NULL.
-
-     To hash two or more values together into a single value, use
-     `HASH2()', `HASH3()', `HASH4()', etc.
-
-  6. "getprop", "putprop", "remprop", and "plist" methods.  These are
-     used for object types that have properties.  I don't feel like
-     documenting them here.  If you create one of these objects, you
-     have to use different macros to define them, i.e.
-     `DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS()' or
-     `DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS()'.
-
-  7. A "size_in_bytes" method, when the object is of variable-size.
-     (i.e. declared with a `_SEQUENCE_IMPLEMENTATION' macro.)  This
-     should simply return the object's size in bytes, exactly as you
-     might expect.  For an example, see the methods for window
-     configurations and opaques.
-
-\1f
-File: internals.info,  Node: Low-level allocation,  Next: Pure Space,  Prev: lrecords,  Up: Allocation of Objects in XEmacs Lisp
-
-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 XEmacs 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 XEmacs 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 XEmacs.
-
-   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.
-XEmacs 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 calls `xmalloc()' but
-also verifies that the pointer to the memory can fit into a Lisp word
-(remember that some bits are taken away for a type tag and a mark bit).
-If not, an error is issued through `memory_full()'.
-`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.
-
-\1f
-File: internals.info,  Node: Pure Space,  Next: Cons,  Prev: Low-level allocation,  Up: Allocation of Objects in XEmacs Lisp
-
-Pure Space
-==========
-
-   Not yet documented.
-
-\1f
-File: internals.info,  Node: Cons,  Next: Vector,  Prev: Pure Space,  Up: Allocation of Objects in XEmacs Lisp
-
-Cons
-====
-
-   Conses are allocated in standard frob blocks.  The only thing to
-note is that conses can be explicitly freed using `free_cons()' and
-associated functions `free_list()' and `free_alist()'.  This
-immediately puts the conses onto the cons free list, and decrements the
-statistics on memory allocation appropriately.  This is used to good
-effect by some extremely commonly-used code, to avoid generating extra
-objects and thereby triggering GC sooner.  However, you have to be
-*extremely* careful when doing this.  If you mess this up, you will get
-BADLY BURNED, and it has happened before.
-
-\1f
-File: internals.info,  Node: Vector,  Next: Bit Vector,  Prev: Cons,  Up: Allocation of Objects in XEmacs Lisp
-
-Vector
-======
-
-   As mentioned above, each vector is `malloc()'ed individually, and
-all are threaded through the variable `all_vectors'.  Vectors are
-marked strangely during garbage collection, by kludging the size field.
-Note that the `struct Lisp_Vector' is declared with its `contents'
-field being a *stretchy* array of one element.  It is actually
-`malloc()'ed with the right size, however, and access to any element
-through the `contents' array works fine.
-
-\1f
-File: internals.info,  Node: Bit Vector,  Next: Symbol,  Prev: Vector,  Up: Allocation of Objects in XEmacs Lisp
-
-Bit Vector
-==========
-
-   Bit vectors work exactly like vectors, except for more complicated
-code to access an individual bit, and except for the fact that bit
-vectors are lrecords while vectors are not. (The only difference here is
-that there's an lrecord implementation pointer at the beginning and the
-tag field in bit vector Lisp words is "lrecord" rather than "vector".)
-
-\1f
-File: internals.info,  Node: Symbol,  Next: Marker,  Prev: Bit Vector,  Up: Allocation of Objects in XEmacs Lisp
-
-Symbol
-======
-
-   Symbols are also allocated in frob blocks.  Note that the code
-exists for symbols to be either lrecords (category (c) above) or simple
-types (category (b) above), and are lrecords by default (I think),
-although there is no good reason for this.
-
-   Note that symbols in the awful horrible obarray structure are
-chained through their `next' field.
-
-   Remember that `intern' looks up a symbol in an obarray, creating one
-if necessary.
-
-\1f
-File: internals.info,  Node: Marker,  Next: String,  Prev: Symbol,  Up: Allocation of Objects in XEmacs Lisp
-
-Marker
-======
-
-   Markers are allocated in frob blocks, as usual.  They are kept in a
-buffer unordered, but in a doubly-linked list so that they can easily
-be removed. (Formerly this was a singly-linked list, but in some cases
-garbage collection took an extraordinarily long time due to the O(N^2)
-time required to remove lots of markers from a buffer.) Markers are
-removed from a buffer in the finalize stage, in
-`ADDITIONAL_FREE_marker()'.
-
-\1f
-File: internals.info,  Node: String,  Next: Compiled Function,  Prev: Marker,  Up: Allocation of Objects in XEmacs Lisp
-
-String
-======
-
-   As mentioned above, strings are a special case.  A string is
-logically two parts, a fixed-size object (containing the length,
-property list, and a pointer to the actual data), and the actual data
-in the string.  The fixed-size object is a `struct Lisp_String' and is
-allocated in frob blocks, as usual.  The actual data is stored in
-special "string-chars blocks", which are 8K blocks of memory.
-Currently-allocated strings are simply laid end to end in these
-string-chars blocks, with a pointer back to the `struct Lisp_String'
-stored before each string in the string-chars block.  When a new string
-needs to be allocated, the remaining space at the end of the last
-string-chars block is used if there's enough, and a new string-chars
-block is created otherwise.
-
-   There are never any holes in the string-chars blocks due to the
-string compaction and relocation that happens at the end of garbage
-collection.  During the sweep stage of garbage collection, when objects
-are reclaimed, the garbage collector goes through all string-chars
-blocks, looking for unused strings.  Each chunk of string data is
-preceded by a pointer to the corresponding `struct Lisp_String', which
-indicates both whether the string is used and how big the string is,
-i.e. how to get to the next chunk of string data.  Holes are compressed
-by block-copying the next string into the empty space and relocating the
-pointer stored in the corresponding `struct Lisp_String'.  *This means
-you have to be careful with strings in your code.* See the section
-above on `GCPRO'ing.
-
-   Note that there is one situation not handled: a string that is too
-big to fit into a string-chars block.  Such strings, called "big
-strings", are all `malloc()'ed as their own block. (#### Although it
-would make more sense for the threshold for big strings to be somewhat
-lower, e.g. 1/2 or 1/4 the size of a string-chars block.  It seems that
-this was indeed the case formerly - indeed, the threshold was set at
-1/8 - but Mly forgot about this when rewriting things for 19.8.)
-
-   Note also that the string data in string-chars blocks is padded as
-necessary so that proper alignment constraints on the `struct
-Lisp_String' back pointers are maintained.
-
-   Finally, strings can be resized.  This happens in Mule when a
-character is substituted with a different-length character, or during
-modeline frobbing. (You could also export this to Lisp, but it's not
-done so currently.) Resizing a string is a potentially tricky process.
-If the change is small enough that the padding can absorb it, nothing
-other than a simple memory move needs to be done.  Keep in mind,
-however, that the string can't shrink too much because the offset to the
-next string in the string-chars block is computed by looking at the
-length and rounding to the nearest multiple of four or eight.  If the
-string would shrink or expand beyond the correct padding, new string
-data needs to be allocated at the end of the last string-chars block and
-the data moved appropriately.  This leaves some dead string data, which
-is marked by putting a special marker of 0xFFFFFFFF in the `struct
-Lisp_String' pointer before the data (there's no real `struct
-Lisp_String' to point to and relocate), and storing the size of the dead
-string data (which would normally be obtained from the now-non-existent
-`struct Lisp_String') at the beginning of the dead string data gap.
-The string compactor recognizes this special 0xFFFFFFFF marker and
-handles it correctly.
-
-\1f
-File: internals.info,  Node: Compiled Function,  Prev: String,  Up: Allocation of Objects in XEmacs Lisp
-
-Compiled Function
-=================
-
-   Not yet documented.
-
-\1f
-File: internals.info,  Node: Events and the Event Loop,  Next: Evaluation; Stack Frames; Bindings,  Prev: Allocation of Objects in XEmacs Lisp,  Up: Top
-
-Events and the Event Loop
-*************************
-
-* Menu:
-
-* Introduction to Events::
-* Main Loop::
-* Specifics of the Event Gathering Mechanism::
-* Specifics About the Emacs Event::
-* The Event Stream Callback Routines::
-* Other Event Loop Functions::
-* Converting Events::
-* Dispatching Events; The Command Builder::
-
-\1f
-File: internals.info,  Node: Introduction to Events,  Next: Main Loop,  Up: Events and the Event Loop
-
-Introduction to Events
-======================
-
-   An event is an object that encapsulates information about an
-interesting occurrence in the operating system.  Events are generated
-either by user action, direct (e.g. typing on the keyboard or moving
-the mouse) or indirect (moving another window, thereby generating an
-expose event on an Emacs frame), or as a result of some other typically
-asynchronous action happening, such as output from a subprocess being
-ready or a timer expiring.  Events come into the system in an
-asynchronous fashion (typically through a callback being called) and
-are converted into a synchronous event queue (first-in, first-out) in a
-process that we will call "collection".
-
-   Note that each application has its own event queue. (It is
-immaterial whether the collection process directly puts the events in
-the proper application's queue, or puts them into a single system
-queue, which is later split up.)
-
-   The most basic level of event collection is done by the operating
-system or window system.  Typically, XEmacs does its own event
-collection as well.  Often there are multiple layers of collection in
-XEmacs, with events from various sources being collected into a queue,
-which is then combined with other sources to go into another queue
-(i.e. a second level of collection), with perhaps another level on top
-of this, etc.
-
-   XEmacs has its own types of events (called "Emacs events"), which
-provides an abstract layer on top of the system-dependent nature of the
-most basic events that are received.  Part of the complex nature of the
-XEmacs event collection process involves converting from the
-operating-system events into the proper Emacs events - there may not be
-a one-to-one correspondence.
-
-   Emacs events are documented in `events.h'; I'll discuss them later.
-