XEmacs 21.2.30 "Hygeia".
[chise/xemacs-chise.git.1] / src / alloc.c
1 /* Storage allocation and gc for XEmacs Lisp interpreter.
2    Copyright (C) 1985-1998 Free Software Foundation, Inc.
3    Copyright (C) 1995 Sun Microsystems, Inc.
4    Copyright (C) 1995, 1996 Ben Wing.
5
6 This file is part of XEmacs.
7
8 XEmacs is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
11 later version.
12
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with XEmacs; see the file COPYING.  If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.  */
22
23 /* Synched up with: FSF 19.28, Mule 2.0.  Substantially different from
24    FSF. */
25
26 /* Authorship:
27
28    FSF: Original version; a long time ago.
29    Mly: Significantly rewritten to use new 3-bit tags and
30         nicely abstracted object definitions, for 19.8.
31    JWZ: Improved code to keep track of purespace usage and
32         issue nice purespace and GC stats.
33    Ben Wing: Cleaned up frob-block lrecord code, added error-checking
34         and various changes for Mule, for 19.12.
35         Added bit vectors for 19.13.
36         Added lcrecord lists for 19.14.
37    slb: Lots of work on the purification and dump time code.
38         Synched Doug Lea malloc support from Emacs 20.2.
39    og:  Killed the purespace.  Portable dumper.
40 */
41
42 #include <config.h>
43 #include "lisp.h"
44
45 #include "backtrace.h"
46 #include "buffer.h"
47 #include "bytecode.h"
48 #include "chartab.h"
49 #include "device.h"
50 #include "elhash.h"
51 #include "events.h"
52 #include "extents.h"
53 #include "frame.h"
54 #include "glyphs.h"
55 #include "opaque.h"
56 #include "redisplay.h"
57 #include "specifier.h"
58 #include "sysfile.h"
59 #include "window.h"
60 #include "console-stream.h"
61
62 #ifdef DOUG_LEA_MALLOC
63 #include <malloc.h>
64 #endif
65
66 #ifdef HAVE_MMAP
67 #include <unistd.h>
68 #include <sys/mman.h>
69 #endif
70
71 #ifdef PDUMP
72 typedef struct
73 {
74   const struct lrecord_description *desc;
75   int count;
76 } pdump_reloc_table;
77
78 static char *pdump_rt_list = 0;
79 #endif
80
81 EXFUN (Fgarbage_collect, 0);
82
83 #if 0 /* this is _way_ too slow to be part of the standard debug options */
84 #if defined(DEBUG_XEMACS) && defined(MULE)
85 #define VERIFY_STRING_CHARS_INTEGRITY
86 #endif
87 #endif
88
89 /* Define this to use malloc/free with no freelist for all datatypes,
90    the hope being that some debugging tools may help detect
91    freed memory references */
92 #ifdef USE_DEBUG_MALLOC /* Taking the above comment at face value -slb */
93 #include <dmalloc.h>
94 #define ALLOC_NO_POOLS
95 #endif
96
97 #ifdef DEBUG_XEMACS
98 static int debug_allocation;
99 static int debug_allocation_backtrace_length;
100 #endif
101
102 /* Number of bytes of consing done since the last gc */
103 EMACS_INT consing_since_gc;
104 #define INCREMENT_CONS_COUNTER_1(size) (consing_since_gc += (size))
105
106 #define debug_allocation_backtrace()                            \
107 do {                                                            \
108   if (debug_allocation_backtrace_length > 0)                    \
109     debug_short_backtrace (debug_allocation_backtrace_length);  \
110 } while (0)
111
112 #ifdef DEBUG_XEMACS
113 #define INCREMENT_CONS_COUNTER(foosize, type)                   \
114   do {                                                          \
115     if (debug_allocation)                                       \
116       {                                                         \
117         stderr_out ("allocating %s (size %ld)\n", type, (long)foosize); \
118         debug_allocation_backtrace ();                          \
119       }                                                         \
120     INCREMENT_CONS_COUNTER_1 (foosize);                         \
121   } while (0)
122 #define NOSEEUM_INCREMENT_CONS_COUNTER(foosize, type)           \
123   do {                                                          \
124     if (debug_allocation > 1)                                   \
125       {                                                         \
126         stderr_out ("allocating noseeum %s (size %ld)\n", type, (long)foosize); \
127         debug_allocation_backtrace ();                          \
128       }                                                         \
129     INCREMENT_CONS_COUNTER_1 (foosize);                         \
130   } while (0)
131 #else
132 #define INCREMENT_CONS_COUNTER(size, type) INCREMENT_CONS_COUNTER_1 (size)
133 #define NOSEEUM_INCREMENT_CONS_COUNTER(size, type) \
134   INCREMENT_CONS_COUNTER_1 (size)
135 #endif
136
137 #define DECREMENT_CONS_COUNTER(size) do {       \
138   consing_since_gc -= (size);                   \
139   if (consing_since_gc < 0)                     \
140     consing_since_gc = 0;                       \
141 } while (0)
142
143 /* Number of bytes of consing since gc before another gc should be done. */
144 EMACS_INT gc_cons_threshold;
145
146 /* Nonzero during gc */
147 int gc_in_progress;
148
149 /* Number of times GC has happened at this level or below.
150  * Level 0 is most volatile, contrary to usual convention.
151  *  (Of course, there's only one level at present) */
152 EMACS_INT gc_generation_number[1];
153
154 /* This is just for use by the printer, to allow things to print uniquely */
155 static int lrecord_uid_counter;
156
157 /* Nonzero when calling certain hooks or doing other things where
158    a GC would be bad */
159 int gc_currently_forbidden;
160
161 /* Hooks. */
162 Lisp_Object Vpre_gc_hook, Qpre_gc_hook;
163 Lisp_Object Vpost_gc_hook, Qpost_gc_hook;
164
165 /* "Garbage collecting" */
166 Lisp_Object Vgc_message;
167 Lisp_Object Vgc_pointer_glyph;
168 static const char gc_default_message[] = "Garbage collecting";
169 Lisp_Object Qgarbage_collecting;
170
171 #ifndef VIRT_ADDR_VARIES
172 extern
173 #endif /* VIRT_ADDR_VARIES */
174  EMACS_INT malloc_sbrk_used;
175
176 #ifndef VIRT_ADDR_VARIES
177 extern
178 #endif /* VIRT_ADDR_VARIES */
179  EMACS_INT malloc_sbrk_unused;
180
181 /* Non-zero means we're in the process of doing the dump */
182 int purify_flag;
183
184 #ifdef ERROR_CHECK_TYPECHECK
185
186 Error_behavior ERROR_ME, ERROR_ME_NOT, ERROR_ME_WARN;
187
188 #endif
189
190 int
191 c_readonly (Lisp_Object obj)
192 {
193   return POINTER_TYPE_P (XTYPE (obj)) && C_READONLY (obj);
194 }
195
196 int
197 lisp_readonly (Lisp_Object obj)
198 {
199   return POINTER_TYPE_P (XTYPE (obj)) && LISP_READONLY (obj);
200 }
201
202 \f
203 /* Maximum amount of C stack to save when a GC happens.  */
204
205 #ifndef MAX_SAVE_STACK
206 #define MAX_SAVE_STACK 0 /* 16000 */
207 #endif
208
209 /* Non-zero means ignore malloc warnings.  Set during initialization.  */
210 int ignore_malloc_warnings;
211
212 \f
213 static void *breathing_space;
214
215 void
216 release_breathing_space (void)
217 {
218   if (breathing_space)
219     {
220       void *tmp = breathing_space;
221       breathing_space = 0;
222       xfree (tmp);
223     }
224 }
225
226 /* malloc calls this if it finds we are near exhausting storage */
227 void
228 malloc_warning (const char *str)
229 {
230   if (ignore_malloc_warnings)
231     return;
232
233   warn_when_safe
234     (Qmemory, Qcritical,
235      "%s\n"
236      "Killing some buffers may delay running out of memory.\n"
237      "However, certainly by the time you receive the 95%% warning,\n"
238      "you should clean up, kill this Emacs, and start a new one.",
239      str);
240 }
241
242 /* Called if malloc returns zero */
243 DOESNT_RETURN
244 memory_full (void)
245 {
246   /* Force a GC next time eval is called.
247      It's better to loop garbage-collecting (we might reclaim enough
248      to win) than to loop beeping and barfing "Memory exhausted"
249    */
250   consing_since_gc = gc_cons_threshold + 1;
251   release_breathing_space ();
252
253   /* Flush some histories which might conceivably contain garbalogical
254      inhibitors.  */
255   if (!NILP (Fboundp (Qvalues)))
256     Fset (Qvalues, Qnil);
257   Vcommand_history = Qnil;
258
259   error ("Memory exhausted");
260 }
261
262 /* like malloc and realloc but check for no memory left, and block input. */
263
264 #undef xmalloc
265 void *
266 xmalloc (size_t size)
267 {
268   void *val = malloc (size);
269
270   if (!val && (size != 0)) memory_full ();
271   return val;
272 }
273
274 #undef xcalloc
275 static void *
276 xcalloc (size_t nelem, size_t elsize)
277 {
278   void *val = calloc (nelem, elsize);
279
280   if (!val && (nelem != 0)) memory_full ();
281   return val;
282 }
283
284 void *
285 xmalloc_and_zero (size_t size)
286 {
287   return xcalloc (size, sizeof (char));
288 }
289
290 #undef xrealloc
291 void *
292 xrealloc (void *block, size_t size)
293 {
294   /* We must call malloc explicitly when BLOCK is 0, since some
295      reallocs don't do this.  */
296   void *val = block ? realloc (block, size) : malloc (size);
297
298   if (!val && (size != 0)) memory_full ();
299   return val;
300 }
301
302 void
303 #ifdef ERROR_CHECK_MALLOC
304 xfree_1 (void *block)
305 #else
306 xfree (void *block)
307 #endif
308 {
309 #ifdef ERROR_CHECK_MALLOC
310   /* Unbelievably, calling free() on 0xDEADBEEF doesn't cause an
311      error until much later on for many system mallocs, such as
312      the one that comes with Solaris 2.3.  FMH!! */
313   assert (block != (void *) 0xDEADBEEF);
314   assert (block);
315 #endif /* ERROR_CHECK_MALLOC */
316   free (block);
317 }
318
319 #ifdef ERROR_CHECK_GC
320
321 #if SIZEOF_INT == 4
322 typedef unsigned int four_byte_t;
323 #elif SIZEOF_LONG == 4
324 typedef unsigned long four_byte_t;
325 #elif SIZEOF_SHORT == 4
326 typedef unsigned short four_byte_t;
327 #else
328 What kind of strange-ass system are we running on?
329 #endif
330
331 static void
332 deadbeef_memory (void *ptr, size_t size)
333 {
334   four_byte_t *ptr4 = (four_byte_t *) ptr;
335   size_t beefs = size >> 2;
336
337   /* In practice, size will always be a multiple of four.  */
338   while (beefs--)
339     (*ptr4++) = 0xDEADBEEF;
340 }
341
342 #else /* !ERROR_CHECK_GC */
343
344
345 #define deadbeef_memory(ptr, size)
346
347 #endif /* !ERROR_CHECK_GC */
348
349 #undef xstrdup
350 char *
351 xstrdup (const char *str)
352 {
353   int len = strlen (str) + 1;   /* for stupid terminating 0 */
354
355   void *val = xmalloc (len);
356   if (val == 0) return 0;
357   return (char *) memcpy (val, str, len);
358 }
359
360 #ifdef NEED_STRDUP
361 char *
362 strdup (const char *s)
363 {
364   return xstrdup (s);
365 }
366 #endif /* NEED_STRDUP */
367
368 \f
369 static void *
370 allocate_lisp_storage (size_t size)
371 {
372   return xmalloc (size);
373 }
374
375
376 /* lcrecords are chained together through their "next" field.
377    After doing the mark phase, GC will walk this linked list
378    and free any lcrecord which hasn't been marked. */
379 static struct lcrecord_header *all_lcrecords;
380
381 void *
382 alloc_lcrecord (size_t size, const struct lrecord_implementation *implementation)
383 {
384   struct lcrecord_header *lcheader;
385
386   type_checking_assert
387     ((implementation->static_size == 0 ?
388       implementation->size_in_bytes_method != NULL :
389       implementation->static_size == size)
390      &&
391      (! implementation->basic_p)
392      &&
393      (! (implementation->hash == NULL && implementation->equal != NULL)));
394
395   lcheader = (struct lcrecord_header *) allocate_lisp_storage (size);
396   set_lheader_implementation (&(lcheader->lheader), implementation);
397   lcheader->next = all_lcrecords;
398 #if 1                           /* mly prefers to see small ID numbers */
399   lcheader->uid = lrecord_uid_counter++;
400 #else                           /* jwz prefers to see real addrs */
401   lcheader->uid = (int) &lcheader;
402 #endif
403   lcheader->free = 0;
404   all_lcrecords = lcheader;
405   INCREMENT_CONS_COUNTER (size, implementation->name);
406   return lcheader;
407 }
408
409 #if 0 /* Presently unused */
410 /* Very, very poor man's EGC?
411  * This may be slow and thrash pages all over the place.
412  *  Only call it if you really feel you must (and if the
413  *  lrecord was fairly recently allocated).
414  * Otherwise, just let the GC do its job -- that's what it's there for
415  */
416 void
417 free_lcrecord (struct lcrecord_header *lcrecord)
418 {
419   if (all_lcrecords == lcrecord)
420     {
421       all_lcrecords = lcrecord->next;
422     }
423   else
424     {
425       struct lrecord_header *header = all_lcrecords;
426       for (;;)
427         {
428           struct lrecord_header *next = header->next;
429           if (next == lcrecord)
430             {
431               header->next = lrecord->next;
432               break;
433             }
434           else if (next == 0)
435             abort ();
436           else
437             header = next;
438         }
439     }
440   if (lrecord->implementation->finalizer)
441     lrecord->implementation->finalizer (lrecord, 0);
442   xfree (lrecord);
443   return;
444 }
445 #endif /* Unused */
446
447
448 static void
449 disksave_object_finalization_1 (void)
450 {
451   struct lcrecord_header *header;
452
453   for (header = all_lcrecords; header; header = header->next)
454     {
455       if (LHEADER_IMPLEMENTATION (&header->lheader)->finalizer &&
456           !header->free)
457         LHEADER_IMPLEMENTATION (&header->lheader)->finalizer (header, 1);
458     }
459 }
460
461 \f
462 /************************************************************************/
463 /*                        Debugger support                              */
464 /************************************************************************/
465 /* Give gdb/dbx enough information to decode Lisp Objects.  We make
466    sure certain symbols are always defined, so gdb doesn't complain
467    about expressions in src/.gdbinit.  See src/.gdbinit or src/.dbxrc
468    to see how this is used.  */
469
470 EMACS_UINT dbg_valmask = ((1UL << VALBITS) - 1) << GCBITS;
471 EMACS_UINT dbg_typemask = (1UL << GCTYPEBITS) - 1;
472
473 #ifdef USE_UNION_TYPE
474 unsigned char dbg_USE_UNION_TYPE = 1;
475 #else
476 unsigned char dbg_USE_UNION_TYPE = 0;
477 #endif
478
479 unsigned char dbg_valbits = VALBITS;
480 unsigned char dbg_gctypebits = GCTYPEBITS;
481
482 /* Macros turned into functions for ease of debugging.
483    Debuggers don't know about macros! */
484 int dbg_eq (Lisp_Object obj1, Lisp_Object obj2);
485 int
486 dbg_eq (Lisp_Object obj1, Lisp_Object obj2)
487 {
488   return EQ (obj1, obj2);
489 }
490
491 \f
492 /************************************************************************/
493 /*                        Fixed-size type macros                        */
494 /************************************************************************/
495
496 /* For fixed-size types that are commonly used, we malloc() large blocks
497    of memory at a time and subdivide them into chunks of the correct
498    size for an object of that type.  This is more efficient than
499    malloc()ing each object separately because we save on malloc() time
500    and overhead due to the fewer number of malloc()ed blocks, and
501    also because we don't need any extra pointers within each object
502    to keep them threaded together for GC purposes.  For less common
503    (and frequently large-size) types, we use lcrecords, which are
504    malloc()ed individually and chained together through a pointer
505    in the lcrecord header.  lcrecords do not need to be fixed-size
506    (i.e. two objects of the same type need not have the same size;
507    however, the size of a particular object cannot vary dynamically).
508    It is also much easier to create a new lcrecord type because no
509    additional code needs to be added to alloc.c.  Finally, lcrecords
510    may be more efficient when there are only a small number of them.
511
512    The types that are stored in these large blocks (or "frob blocks")
513    are cons, float, compiled-function, symbol, marker, extent, event,
514    and string.
515
516    Note that strings are special in that they are actually stored in
517    two parts: a structure containing information about the string, and
518    the actual data associated with the string.  The former structure
519    (a struct Lisp_String) is a fixed-size structure and is managed the
520    same way as all the other such types.  This structure contains a
521    pointer to the actual string data, which is stored in structures of
522    type struct string_chars_block.  Each string_chars_block consists
523    of a pointer to a struct Lisp_String, followed by the data for that
524    string, followed by another pointer to a Lisp_String, followed by
525    the data for that string, etc.  At GC time, the data in these
526    blocks is compacted by searching sequentially through all the
527    blocks and compressing out any holes created by unmarked strings.
528    Strings that are more than a certain size (bigger than the size of
529    a string_chars_block, although something like half as big might
530    make more sense) are malloc()ed separately and not stored in
531    string_chars_blocks.  Furthermore, no one string stretches across
532    two string_chars_blocks.
533
534    Vectors are each malloc()ed separately, similar to lcrecords.
535
536    In the following discussion, we use conses, but it applies equally
537    well to the other fixed-size types.
538
539    We store cons cells inside of cons_blocks, allocating a new
540    cons_block with malloc() whenever necessary.  Cons cells reclaimed
541    by GC are put on a free list to be reallocated before allocating
542    any new cons cells from the latest cons_block.  Each cons_block is
543    just under 2^n - MALLOC_OVERHEAD bytes long, since malloc (at least
544    the versions in malloc.c and gmalloc.c) really allocates in units
545    of powers of two and uses 4 bytes for its own overhead.
546
547    What GC actually does is to search through all the cons_blocks,
548    from the most recently allocated to the oldest, and put all
549    cons cells that are not marked (whether or not they're already
550    free) on a cons_free_list.  The cons_free_list is a stack, and
551    so the cons cells in the oldest-allocated cons_block end up
552    at the head of the stack and are the first to be reallocated.
553    If any cons_block is entirely free, it is freed with free()
554    and its cons cells removed from the cons_free_list.  Because
555    the cons_free_list ends up basically in memory order, we have
556    a high locality of reference (assuming a reasonable turnover
557    of allocating and freeing) and have a reasonable probability
558    of entirely freeing up cons_blocks that have been more recently
559    allocated.  This stage is called the "sweep stage" of GC, and
560    is executed after the "mark stage", which involves starting
561    from all places that are known to point to in-use Lisp objects
562    (e.g. the obarray, where are all symbols are stored; the
563    current catches and condition-cases; the backtrace list of
564    currently executing functions; the gcpro list; etc.) and
565    recursively marking all objects that are accessible.
566
567    At the beginning of the sweep stage, the conses in the cons
568    blocks are in one of three states: in use and marked, in use
569    but not marked, and not in use (already freed).  Any conses
570    that are marked have been marked in the mark stage just
571    executed, because as part of the sweep stage we unmark any
572    marked objects.  The way we tell whether or not a cons cell
573    is in use is through the FREE_STRUCT_P macro.  This basically
574    looks at the first 4 bytes (or however many bytes a pointer
575    fits in) to see if all the bits in those bytes are 1.  The
576    resulting value (0xFFFFFFFF) is not a valid pointer and is
577    not a valid Lisp_Object.  All current fixed-size types have
578    a pointer or Lisp_Object as their first element with the
579    exception of strings; they have a size value, which can
580    never be less than zero, and so 0xFFFFFFFF is invalid for
581    strings as well.  Now assuming that a cons cell is in use,
582    the way we tell whether or not it is marked is to look at
583    the mark bit of its car (each Lisp_Object has one bit
584    reserved as a mark bit, in case it's needed).  Note that
585    different types of objects use different fields to indicate
586    whether the object is marked, but the principle is the same.
587
588    Conses on the free_cons_list are threaded through a pointer
589    stored in the bytes directly after the bytes that are set
590    to 0xFFFFFFFF (we cannot overwrite these because the cons
591    is still in a cons_block and needs to remain marked as
592    not in use for the next time that GC happens).  This
593    implies that all fixed-size types must be at least big
594    enough to store two pointers, which is indeed the case
595    for all current fixed-size types.
596
597    Some types of objects need additional "finalization" done
598    when an object is converted from in use to not in use;
599    this is the purpose of the ADDITIONAL_FREE_type macro.
600    For example, markers need to be removed from the chain
601    of markers that is kept in each buffer.  This is because
602    markers in a buffer automatically disappear if the marker
603    is no longer referenced anywhere (the same does not
604    apply to extents, however).
605
606    WARNING: Things are in an extremely bizarre state when
607    the ADDITIONAL_FREE_type macros are called, so beware!
608
609    When ERROR_CHECK_GC is defined, we do things differently
610    so as to maximize our chances of catching places where
611    there is insufficient GCPROing.  The thing we want to
612    avoid is having an object that we're using but didn't
613    GCPRO get freed by GC and then reallocated while we're
614    in the process of using it -- this will result in something
615    seemingly unrelated getting trashed, and is extremely
616    difficult to track down.  If the object gets freed but
617    not reallocated, we can usually catch this because we
618    set all bytes of a freed object to 0xDEADBEEF. (The
619    first four bytes, however, are 0xFFFFFFFF, and the next
620    four are a pointer used to chain freed objects together;
621    we play some tricks with this pointer to make it more
622    bogus, so crashes are more likely to occur right away.)
623
624    We want freed objects to stay free as long as possible,
625    so instead of doing what we do above, we maintain the
626    free objects in a first-in first-out queue.  We also
627    don't recompute the free list each GC, unlike above;
628    this ensures that the queue ordering is preserved.
629    [This means that we are likely to have worse locality
630    of reference, and that we can never free a frob block
631    once it's allocated. (Even if we know that all cells
632    in it are free, there's no easy way to remove all those
633    cells from the free list because the objects on the
634    free list are unlikely to be in memory order.)]
635    Furthermore, we never take objects off the free list
636    unless there's a large number (usually 1000, but
637    varies depending on type) of them already on the list.
638    This way, we ensure that an object that gets freed will
639    remain free for the next 1000 (or whatever) times that
640    an object of that type is allocated.  */
641
642 #ifndef MALLOC_OVERHEAD
643 #ifdef GNU_MALLOC
644 #define MALLOC_OVERHEAD 0
645 #elif defined (rcheck)
646 #define MALLOC_OVERHEAD 20
647 #else
648 #define MALLOC_OVERHEAD 8
649 #endif
650 #endif /* MALLOC_OVERHEAD */
651
652 #if !defined(HAVE_MMAP) || defined(DOUG_LEA_MALLOC)
653 /* If we released our reserve (due to running out of memory),
654    and we have a fair amount free once again,
655    try to set aside another reserve in case we run out once more.
656
657    This is called when a relocatable block is freed in ralloc.c.  */
658 void refill_memory_reserve (void);
659 void
660 refill_memory_reserve ()
661 {
662   if (breathing_space == 0)
663     breathing_space = (char *) malloc (4096 - MALLOC_OVERHEAD);
664 }
665 #endif
666
667 #ifdef ALLOC_NO_POOLS
668 # define TYPE_ALLOC_SIZE(type, structtype) 1
669 #else
670 # define TYPE_ALLOC_SIZE(type, structtype)                      \
671     ((2048 - MALLOC_OVERHEAD - sizeof (struct type##_block *))  \
672      / sizeof (structtype))
673 #endif /* ALLOC_NO_POOLS */
674
675 #define DECLARE_FIXED_TYPE_ALLOC(type, structtype)      \
676                                                         \
677 struct type##_block                                     \
678 {                                                       \
679   struct type##_block *prev;                            \
680   structtype block[TYPE_ALLOC_SIZE (type, structtype)]; \
681 };                                                      \
682                                                         \
683 static struct type##_block *current_##type##_block;     \
684 static int current_##type##_block_index;                \
685                                                         \
686 static structtype *type##_free_list;                    \
687 static structtype *type##_free_list_tail;               \
688                                                         \
689 static void                                             \
690 init_##type##_alloc (void)                              \
691 {                                                       \
692   current_##type##_block = 0;                           \
693   current_##type##_block_index =                        \
694     countof (current_##type##_block->block);            \
695   type##_free_list = 0;                                 \
696   type##_free_list_tail = 0;                            \
697 }                                                       \
698                                                         \
699 static int gc_count_num_##type##_in_use;                \
700 static int gc_count_num_##type##_freelist
701
702 #define ALLOCATE_FIXED_TYPE_FROM_BLOCK(type, result) do {               \
703   if (current_##type##_block_index                                      \
704       == countof (current_##type##_block->block))                       \
705     {                                                                   \
706       struct type##_block *AFTFB_new = (struct type##_block *)          \
707         allocate_lisp_storage (sizeof (struct type##_block));           \
708       AFTFB_new->prev = current_##type##_block;                         \
709       current_##type##_block = AFTFB_new;                               \
710       current_##type##_block_index = 0;                                 \
711     }                                                                   \
712   (result) =                                                            \
713     &(current_##type##_block->block[current_##type##_block_index++]);   \
714 } while (0)
715
716 /* Allocate an instance of a type that is stored in blocks.
717    TYPE is the "name" of the type, STRUCTTYPE is the corresponding
718    structure type. */
719
720 #ifdef ERROR_CHECK_GC
721
722 /* Note: if you get crashes in this function, suspect incorrect calls
723    to free_cons() and friends.  This happened once because the cons
724    cell was not GC-protected and was getting collected before
725    free_cons() was called. */
726
727 #define ALLOCATE_FIXED_TYPE_1(type, structtype, result)                  \
728 do                                                                       \
729 {                                                                        \
730   if (gc_count_num_##type##_freelist >                                   \
731       MINIMUM_ALLOWED_FIXED_TYPE_CELLS_##type)                           \
732     {                                                                    \
733       result = type##_free_list;                                         \
734       /* Before actually using the chain pointer, we complement all its  \
735          bits; see FREE_FIXED_TYPE(). */                                 \
736       type##_free_list =                                                 \
737         (structtype *) ~(unsigned long)                                  \
738           (* (structtype **) ((char *) result + sizeof (void *)));       \
739       gc_count_num_##type##_freelist--;                                  \
740     }                                                                    \
741   else                                                                   \
742     ALLOCATE_FIXED_TYPE_FROM_BLOCK (type, result);                       \
743   MARK_STRUCT_AS_NOT_FREE (result);                                      \
744 } while (0)
745
746 #else /* !ERROR_CHECK_GC */
747
748 #define ALLOCATE_FIXED_TYPE_1(type, structtype, result)         \
749 do                                                              \
750 {                                                               \
751   if (type##_free_list)                                         \
752     {                                                           \
753       result = type##_free_list;                                \
754       type##_free_list =                                        \
755         * (structtype **) ((char *) result + sizeof (void *));  \
756     }                                                           \
757   else                                                          \
758     ALLOCATE_FIXED_TYPE_FROM_BLOCK (type, result);              \
759   MARK_STRUCT_AS_NOT_FREE (result);                             \
760 } while (0)
761
762 #endif /* !ERROR_CHECK_GC */
763
764 #define ALLOCATE_FIXED_TYPE(type, structtype, result)   \
765 do                                                      \
766 {                                                       \
767   ALLOCATE_FIXED_TYPE_1 (type, structtype, result);     \
768   INCREMENT_CONS_COUNTER (sizeof (structtype), #type);  \
769 } while (0)
770
771 #define NOSEEUM_ALLOCATE_FIXED_TYPE(type, structtype, result)   \
772 do                                                              \
773 {                                                               \
774   ALLOCATE_FIXED_TYPE_1 (type, structtype, result);             \
775   NOSEEUM_INCREMENT_CONS_COUNTER (sizeof (structtype), #type);  \
776 } while (0)
777
778 /* INVALID_POINTER_VALUE should be a value that is invalid as a pointer
779    to a Lisp object and invalid as an actual Lisp_Object value.  We have
780    to make sure that this value cannot be an integer in Lisp_Object form.
781    0xFFFFFFFF could be so on a 64-bit system, so we extend it to 64 bits.
782    On a 32-bit system, the type bits will be non-zero, making the value
783    be a pointer, and the pointer will be misaligned.
784
785    Even if Emacs is run on some weirdo system that allows and allocates
786    byte-aligned pointers, this pointer is at the very top of the address
787    space and so it's almost inconceivable that it could ever be valid. */
788
789 #if INTBITS == 32
790 # define INVALID_POINTER_VALUE 0xFFFFFFFF
791 #elif INTBITS == 48
792 # define INVALID_POINTER_VALUE 0xFFFFFFFFFFFF
793 #elif INTBITS == 64
794 # define INVALID_POINTER_VALUE 0xFFFFFFFFFFFFFFFF
795 #else
796 You have some weird system and need to supply a reasonable value here.
797 #endif
798
799 #define FREE_STRUCT_P(ptr) \
800   (* (void **) ptr == (void *) INVALID_POINTER_VALUE)
801 #define MARK_STRUCT_AS_FREE(ptr) \
802   (* (void **) ptr = (void *) INVALID_POINTER_VALUE)
803 #define MARK_STRUCT_AS_NOT_FREE(ptr) \
804   (* (void **) ptr = 0)
805
806 #ifdef ERROR_CHECK_GC
807
808 #define PUT_FIXED_TYPE_ON_FREE_LIST(type, structtype, ptr)              \
809 do { if (type##_free_list_tail)                                         \
810        {                                                                \
811          /* When we store the chain pointer, we complement all          \
812             its bits; this should significantly increase its            \
813             bogosity in case someone tries to use the value, and        \
814             should make us dump faster if someone stores something      \
815             over the pointer because when it gets un-complemented in    \
816             ALLOCATED_FIXED_TYPE(), the resulting pointer will be       \
817             extremely bogus. */                                         \
818          * (structtype **)                                              \
819            ((char *) type##_free_list_tail + sizeof (void *)) =         \
820              (structtype *) ~(unsigned long) ptr;                       \
821        }                                                                \
822      else                                                               \
823        type##_free_list = ptr;                                          \
824      type##_free_list_tail = ptr;                                       \
825    } while (0)
826
827 #else /* !ERROR_CHECK_GC */
828
829 #define PUT_FIXED_TYPE_ON_FREE_LIST(type, structtype, ptr)      \
830 do { * (structtype **) ((char *) (ptr) + sizeof (void *)) =     \
831        type##_free_list;                                        \
832      type##_free_list = (ptr);                                  \
833    } while (0)
834
835 #endif /* !ERROR_CHECK_GC */
836
837 /* TYPE and STRUCTTYPE are the same as in ALLOCATE_FIXED_TYPE(). */
838
839 #define FREE_FIXED_TYPE(type, structtype, ptr) do {             \
840   structtype *FFT_ptr = (ptr);                                  \
841   ADDITIONAL_FREE_##type (FFT_ptr);                             \
842   deadbeef_memory (FFT_ptr, sizeof (structtype));               \
843   PUT_FIXED_TYPE_ON_FREE_LIST (type, structtype, FFT_ptr);      \
844   MARK_STRUCT_AS_FREE (FFT_ptr);                                \
845 } while (0)
846
847 /* Like FREE_FIXED_TYPE() but used when we are explicitly
848    freeing a structure through free_cons(), free_marker(), etc.
849    rather than through the normal process of sweeping.
850    We attempt to undo the changes made to the allocation counters
851    as a result of this structure being allocated.  This is not
852    completely necessary but helps keep things saner: e.g. this way,
853    repeatedly allocating and freeing a cons will not result in
854    the consing-since-gc counter advancing, which would cause a GC
855    and somewhat defeat the purpose of explicitly freeing. */
856
857 #define FREE_FIXED_TYPE_WHEN_NOT_IN_GC(type, structtype, ptr)   \
858 do { FREE_FIXED_TYPE (type, structtype, ptr);                   \
859      DECREMENT_CONS_COUNTER (sizeof (structtype));              \
860      gc_count_num_##type##_freelist++;                          \
861    } while (0)
862
863
864 \f
865 /************************************************************************/
866 /*                         Cons allocation                              */
867 /************************************************************************/
868
869 DECLARE_FIXED_TYPE_ALLOC (cons, Lisp_Cons);
870 /* conses are used and freed so often that we set this really high */
871 /* #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_cons 20000 */
872 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_cons 2000
873
874 static Lisp_Object
875 mark_cons (Lisp_Object obj)
876 {
877   if (NILP (XCDR (obj)))
878     return XCAR (obj);
879
880   mark_object (XCAR (obj));
881   return XCDR (obj);
882 }
883
884 static int
885 cons_equal (Lisp_Object ob1, Lisp_Object ob2, int depth)
886 {
887   depth++;
888   while (internal_equal (XCAR (ob1), XCAR (ob2), depth))
889     {
890       ob1 = XCDR (ob1);
891       ob2 = XCDR (ob2);
892       if (! CONSP (ob1) || ! CONSP (ob2))
893         return internal_equal (ob1, ob2, depth);
894     }
895   return 0;
896 }
897
898 static const struct lrecord_description cons_description[] = {
899   { XD_LISP_OBJECT, offsetof (Lisp_Cons, car) },
900   { XD_LISP_OBJECT, offsetof (Lisp_Cons, cdr) },
901   { XD_END }
902 };
903
904 DEFINE_BASIC_LRECORD_IMPLEMENTATION ("cons", cons,
905                                      mark_cons, print_cons, 0,
906                                      cons_equal,
907                                      /*
908                                       * No `hash' method needed.
909                                       * internal_hash knows how to
910                                       * handle conses.
911                                       */
912                                      0,
913                                      cons_description,
914                                      Lisp_Cons);
915
916 DEFUN ("cons", Fcons, 2, 2, 0, /*
917 Create a new cons, give it CAR and CDR as components, and return it.
918 */
919        (car, cdr))
920 {
921   /* This cannot GC. */
922   Lisp_Object val;
923   Lisp_Cons *c;
924
925   ALLOCATE_FIXED_TYPE (cons, Lisp_Cons, c);
926   set_lheader_implementation (&(c->lheader), &lrecord_cons);
927   XSETCONS (val, c);
928   c->car = car;
929   c->cdr = cdr;
930   return val;
931 }
932
933 /* This is identical to Fcons() but it used for conses that we're
934    going to free later, and is useful when trying to track down
935    "real" consing. */
936 Lisp_Object
937 noseeum_cons (Lisp_Object car, Lisp_Object cdr)
938 {
939   Lisp_Object val;
940   Lisp_Cons *c;
941
942   NOSEEUM_ALLOCATE_FIXED_TYPE (cons, Lisp_Cons, c);
943   set_lheader_implementation (&(c->lheader), &lrecord_cons);
944   XSETCONS (val, c);
945   XCAR (val) = car;
946   XCDR (val) = cdr;
947   return val;
948 }
949
950 DEFUN ("list", Flist, 0, MANY, 0, /*
951 Return a newly created list with specified arguments as elements.
952 Any number of arguments, even zero arguments, are allowed.
953 */
954        (int nargs, Lisp_Object *args))
955 {
956   Lisp_Object val = Qnil;
957   Lisp_Object *argp = args + nargs;
958
959   while (argp > args)
960     val = Fcons (*--argp, val);
961   return val;
962 }
963
964 Lisp_Object
965 list1 (Lisp_Object obj0)
966 {
967   /* This cannot GC. */
968   return Fcons (obj0, Qnil);
969 }
970
971 Lisp_Object
972 list2 (Lisp_Object obj0, Lisp_Object obj1)
973 {
974   /* This cannot GC. */
975   return Fcons (obj0, Fcons (obj1, Qnil));
976 }
977
978 Lisp_Object
979 list3 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2)
980 {
981   /* This cannot GC. */
982   return Fcons (obj0, Fcons (obj1, Fcons (obj2, Qnil)));
983 }
984
985 Lisp_Object
986 cons3 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2)
987 {
988   /* This cannot GC. */
989   return Fcons (obj0, Fcons (obj1, obj2));
990 }
991
992 Lisp_Object
993 acons (Lisp_Object key, Lisp_Object value, Lisp_Object alist)
994 {
995   return Fcons (Fcons (key, value), alist);
996 }
997
998 Lisp_Object
999 list4 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2, Lisp_Object obj3)
1000 {
1001   /* This cannot GC. */
1002   return Fcons (obj0, Fcons (obj1, Fcons (obj2, Fcons (obj3, Qnil))));
1003 }
1004
1005 Lisp_Object
1006 list5 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2, Lisp_Object obj3,
1007        Lisp_Object obj4)
1008 {
1009   /* This cannot GC. */
1010   return Fcons (obj0, Fcons (obj1, Fcons (obj2, Fcons (obj3, Fcons (obj4, Qnil)))));
1011 }
1012
1013 Lisp_Object
1014 list6 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2, Lisp_Object obj3,
1015        Lisp_Object obj4, Lisp_Object obj5)
1016 {
1017   /* This cannot GC. */
1018   return Fcons (obj0, Fcons (obj1, Fcons (obj2, Fcons (obj3, Fcons (obj4, Fcons (obj5, Qnil))))));
1019 }
1020
1021 DEFUN ("make-list", Fmake_list, 2, 2, 0, /*
1022 Return a new list of length LENGTH, with each element being INIT.
1023 */
1024        (length, init))
1025 {
1026   CHECK_NATNUM (length);
1027
1028   {
1029     Lisp_Object val = Qnil;
1030     size_t size = XINT (length);
1031
1032     while (size--)
1033       val = Fcons (init, val);
1034     return val;
1035   }
1036 }
1037
1038 \f
1039 /************************************************************************/
1040 /*                        Float allocation                              */
1041 /************************************************************************/
1042
1043 #ifdef LISP_FLOAT_TYPE
1044
1045 DECLARE_FIXED_TYPE_ALLOC (float, Lisp_Float);
1046 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_float 1000
1047
1048 Lisp_Object
1049 make_float (double float_value)
1050 {
1051   Lisp_Object val;
1052   Lisp_Float *f;
1053
1054   ALLOCATE_FIXED_TYPE (float, Lisp_Float, f);
1055
1056   /* Avoid dump-time `uninitialized memory read' purify warnings. */
1057   if (sizeof (struct lrecord_header) + sizeof (double) != sizeof (*f))
1058     xzero (*f);
1059
1060   set_lheader_implementation (&(f->lheader), &lrecord_float);
1061   float_data (f) = float_value;
1062   XSETFLOAT (val, f);
1063   return val;
1064 }
1065
1066 #endif /* LISP_FLOAT_TYPE */
1067
1068 \f
1069 /************************************************************************/
1070 /*                         Vector allocation                            */
1071 /************************************************************************/
1072
1073 static Lisp_Object
1074 mark_vector (Lisp_Object obj)
1075 {
1076   Lisp_Vector *ptr = XVECTOR (obj);
1077   int len = vector_length (ptr);
1078   int i;
1079
1080   for (i = 0; i < len - 1; i++)
1081     mark_object (ptr->contents[i]);
1082   return (len > 0) ? ptr->contents[len - 1] : Qnil;
1083 }
1084
1085 static size_t
1086 size_vector (const void *lheader)
1087 {
1088   return offsetof (Lisp_Vector, contents[((Lisp_Vector *) lheader)->size]);
1089 }
1090
1091 static int
1092 vector_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
1093 {
1094   int len = XVECTOR_LENGTH (obj1);
1095   if (len != XVECTOR_LENGTH (obj2))
1096     return 0;
1097
1098   {
1099     Lisp_Object *ptr1 = XVECTOR_DATA (obj1);
1100     Lisp_Object *ptr2 = XVECTOR_DATA (obj2);
1101     while (len--)
1102       if (!internal_equal (*ptr1++, *ptr2++, depth + 1))
1103         return 0;
1104   }
1105   return 1;
1106 }
1107
1108 static hashcode_t
1109 vector_hash (Lisp_Object obj, int depth)
1110 {
1111   return HASH2 (XVECTOR_LENGTH (obj),
1112                 internal_array_hash (XVECTOR_DATA (obj),
1113                                      XVECTOR_LENGTH (obj),
1114                                      depth + 1));
1115 }
1116
1117 static const struct lrecord_description vector_description[] = {
1118   { XD_LONG,              offsetof (Lisp_Vector, size) },
1119   { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Vector, contents), XD_INDIRECT(0, 0) },
1120   { XD_END }
1121 };
1122
1123 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION("vector", vector,
1124                                        mark_vector, print_vector, 0,
1125                                        vector_equal,
1126                                        vector_hash,
1127                                        vector_description,
1128                                        size_vector, Lisp_Vector);
1129
1130 /* #### should allocate `small' vectors from a frob-block */
1131 static Lisp_Vector *
1132 make_vector_internal (size_t sizei)
1133 {
1134   /* no vector_next */
1135   size_t sizem = offsetof (Lisp_Vector, contents[sizei]);
1136   Lisp_Vector *p = (Lisp_Vector *) alloc_lcrecord (sizem, &lrecord_vector);
1137
1138   p->size = sizei;
1139   return p;
1140 }
1141
1142 Lisp_Object
1143 make_vector (size_t length, Lisp_Object init)
1144 {
1145   Lisp_Vector *vecp = make_vector_internal (length);
1146   Lisp_Object *p = vector_data (vecp);
1147
1148   while (length--)
1149     *p++ = init;
1150
1151   {
1152     Lisp_Object vector;
1153     XSETVECTOR (vector, vecp);
1154     return vector;
1155   }
1156 }
1157
1158 DEFUN ("make-vector", Fmake_vector, 2, 2, 0, /*
1159 Return a new vector of length LENGTH, with each element being INIT.
1160 See also the function `vector'.
1161 */
1162        (length, init))
1163 {
1164   CONCHECK_NATNUM (length);
1165   return make_vector (XINT (length), init);
1166 }
1167
1168 DEFUN ("vector", Fvector, 0, MANY, 0, /*
1169 Return a newly created vector with specified arguments as elements.
1170 Any number of arguments, even zero arguments, are allowed.
1171 */
1172        (int nargs, Lisp_Object *args))
1173 {
1174   Lisp_Vector *vecp = make_vector_internal (nargs);
1175   Lisp_Object *p = vector_data (vecp);
1176
1177   while (nargs--)
1178     *p++ = *args++;
1179
1180   {
1181     Lisp_Object vector;
1182     XSETVECTOR (vector, vecp);
1183     return vector;
1184   }
1185 }
1186
1187 Lisp_Object
1188 vector1 (Lisp_Object obj0)
1189 {
1190   return Fvector (1, &obj0);
1191 }
1192
1193 Lisp_Object
1194 vector2 (Lisp_Object obj0, Lisp_Object obj1)
1195 {
1196   Lisp_Object args[2];
1197   args[0] = obj0;
1198   args[1] = obj1;
1199   return Fvector (2, args);
1200 }
1201
1202 Lisp_Object
1203 vector3 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2)
1204 {
1205   Lisp_Object args[3];
1206   args[0] = obj0;
1207   args[1] = obj1;
1208   args[2] = obj2;
1209   return Fvector (3, args);
1210 }
1211
1212 #if 0 /* currently unused */
1213
1214 Lisp_Object
1215 vector4 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2,
1216          Lisp_Object obj3)
1217 {
1218   Lisp_Object args[4];
1219   args[0] = obj0;
1220   args[1] = obj1;
1221   args[2] = obj2;
1222   args[3] = obj3;
1223   return Fvector (4, args);
1224 }
1225
1226 Lisp_Object
1227 vector5 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2,
1228          Lisp_Object obj3, Lisp_Object obj4)
1229 {
1230   Lisp_Object args[5];
1231   args[0] = obj0;
1232   args[1] = obj1;
1233   args[2] = obj2;
1234   args[3] = obj3;
1235   args[4] = obj4;
1236   return Fvector (5, args);
1237 }
1238
1239 Lisp_Object
1240 vector6 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2,
1241          Lisp_Object obj3, Lisp_Object obj4, Lisp_Object obj5)
1242 {
1243   Lisp_Object args[6];
1244   args[0] = obj0;
1245   args[1] = obj1;
1246   args[2] = obj2;
1247   args[3] = obj3;
1248   args[4] = obj4;
1249   args[5] = obj5;
1250   return Fvector (6, args);
1251 }
1252
1253 Lisp_Object
1254 vector7 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2,
1255          Lisp_Object obj3, Lisp_Object obj4, Lisp_Object obj5,
1256          Lisp_Object obj6)
1257 {
1258   Lisp_Object args[7];
1259   args[0] = obj0;
1260   args[1] = obj1;
1261   args[2] = obj2;
1262   args[3] = obj3;
1263   args[4] = obj4;
1264   args[5] = obj5;
1265   args[6] = obj6;
1266   return Fvector (7, args);
1267 }
1268
1269 Lisp_Object
1270 vector8 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2,
1271          Lisp_Object obj3, Lisp_Object obj4, Lisp_Object obj5,
1272          Lisp_Object obj6, Lisp_Object obj7)
1273 {
1274   Lisp_Object args[8];
1275   args[0] = obj0;
1276   args[1] = obj1;
1277   args[2] = obj2;
1278   args[3] = obj3;
1279   args[4] = obj4;
1280   args[5] = obj5;
1281   args[6] = obj6;
1282   args[7] = obj7;
1283   return Fvector (8, args);
1284 }
1285 #endif /* unused */
1286
1287 /************************************************************************/
1288 /*                       Bit Vector allocation                          */
1289 /************************************************************************/
1290
1291 static Lisp_Object all_bit_vectors;
1292
1293 /* #### should allocate `small' bit vectors from a frob-block */
1294 static Lisp_Bit_Vector *
1295 make_bit_vector_internal (size_t sizei)
1296 {
1297   size_t num_longs = BIT_VECTOR_LONG_STORAGE (sizei);
1298   size_t sizem = offsetof (Lisp_Bit_Vector, bits[num_longs]);
1299   Lisp_Bit_Vector *p = (Lisp_Bit_Vector *) allocate_lisp_storage (sizem);
1300   set_lheader_implementation (&(p->lheader), &lrecord_bit_vector);
1301
1302   INCREMENT_CONS_COUNTER (sizem, "bit-vector");
1303
1304   bit_vector_length (p) = sizei;
1305   bit_vector_next   (p) = all_bit_vectors;
1306   /* make sure the extra bits in the last long are 0; the calling
1307      functions might not set them. */
1308   p->bits[num_longs - 1] = 0;
1309   XSETBIT_VECTOR (all_bit_vectors, p);
1310   return p;
1311 }
1312
1313 Lisp_Object
1314 make_bit_vector (size_t length, Lisp_Object init)
1315 {
1316   Lisp_Bit_Vector *p = make_bit_vector_internal (length);
1317   size_t num_longs = BIT_VECTOR_LONG_STORAGE (length);
1318
1319   CHECK_BIT (init);
1320
1321   if (ZEROP (init))
1322     memset (p->bits, 0, num_longs * sizeof (long));
1323   else
1324     {
1325       size_t bits_in_last = length & (LONGBITS_POWER_OF_2 - 1);
1326       memset (p->bits, ~0, num_longs * sizeof (long));
1327       /* But we have to make sure that the unused bits in the
1328          last long are 0, so that equal/hash is easy. */
1329       if (bits_in_last)
1330         p->bits[num_longs - 1] &= (1 << bits_in_last) - 1;
1331     }
1332
1333   {
1334     Lisp_Object bit_vector;
1335     XSETBIT_VECTOR (bit_vector, p);
1336     return bit_vector;
1337   }
1338 }
1339
1340 Lisp_Object
1341 make_bit_vector_from_byte_vector (unsigned char *bytevec, size_t length)
1342 {
1343   int i;
1344   Lisp_Bit_Vector *p = make_bit_vector_internal (length);
1345
1346   for (i = 0; i < length; i++)
1347     set_bit_vector_bit (p, i, bytevec[i]);
1348
1349   {
1350     Lisp_Object bit_vector;
1351     XSETBIT_VECTOR (bit_vector, p);
1352     return bit_vector;
1353   }
1354 }
1355
1356 DEFUN ("make-bit-vector", Fmake_bit_vector, 2, 2, 0, /*
1357 Return a new bit vector of length LENGTH. with each bit being INIT.
1358 Each element is set to INIT.  See also the function `bit-vector'.
1359 */
1360        (length, init))
1361 {
1362   CONCHECK_NATNUM (length);
1363
1364   return make_bit_vector (XINT (length), init);
1365 }
1366
1367 DEFUN ("bit-vector", Fbit_vector, 0, MANY, 0, /*
1368 Return a newly created bit vector with specified arguments as elements.
1369 Any number of arguments, even zero arguments, are allowed.
1370 */
1371        (int nargs, Lisp_Object *args))
1372 {
1373   int i;
1374   Lisp_Bit_Vector *p = make_bit_vector_internal (nargs);
1375
1376   for (i = 0; i < nargs; i++)
1377     {
1378       CHECK_BIT (args[i]);
1379       set_bit_vector_bit (p, i, !ZEROP (args[i]));
1380     }
1381
1382   {
1383     Lisp_Object bit_vector;
1384     XSETBIT_VECTOR (bit_vector, p);
1385     return bit_vector;
1386   }
1387 }
1388
1389 \f
1390 /************************************************************************/
1391 /*                   Compiled-function allocation                       */
1392 /************************************************************************/
1393
1394 DECLARE_FIXED_TYPE_ALLOC (compiled_function, Lisp_Compiled_Function);
1395 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_compiled_function 1000
1396
1397 static Lisp_Object
1398 make_compiled_function (void)
1399 {
1400   Lisp_Compiled_Function *f;
1401   Lisp_Object fun;
1402
1403   ALLOCATE_FIXED_TYPE (compiled_function, Lisp_Compiled_Function, f);
1404   set_lheader_implementation (&(f->lheader), &lrecord_compiled_function);
1405
1406   f->stack_depth = 0;
1407   f->specpdl_depth = 0;
1408   f->flags.documentationp = 0;
1409   f->flags.interactivep = 0;
1410   f->flags.domainp = 0; /* I18N3 */
1411   f->instructions = Qzero;
1412   f->constants = Qzero;
1413   f->arglist = Qnil;
1414   f->doc_and_interactive = Qnil;
1415 #ifdef COMPILED_FUNCTION_ANNOTATION_HACK
1416   f->annotated = Qnil;
1417 #endif
1418   XSETCOMPILED_FUNCTION (fun, f);
1419   return fun;
1420 }
1421
1422 DEFUN ("make-byte-code", Fmake_byte_code, 4, MANY, 0, /*
1423 Return a new compiled-function object.
1424 Usage: (arglist instructions constants stack-depth
1425         &optional doc-string interactive)
1426 Note that, unlike all other emacs-lisp functions, calling this with five
1427 arguments is NOT the same as calling it with six arguments, the last of
1428 which is nil.  If the INTERACTIVE arg is specified as nil, then that means
1429 that this function was defined with `(interactive)'.  If the arg is not
1430 specified, then that means the function is not interactive.
1431 This is terrible behavior which is retained for compatibility with old
1432 `.elc' files which expect these semantics.
1433 */
1434        (int nargs, Lisp_Object *args))
1435 {
1436 /* In a non-insane world this function would have this arglist...
1437    (arglist instructions constants stack_depth &optional doc_string interactive)
1438  */
1439   Lisp_Object fun = make_compiled_function ();
1440   Lisp_Compiled_Function *f = XCOMPILED_FUNCTION (fun);
1441
1442   Lisp_Object arglist      = args[0];
1443   Lisp_Object instructions = args[1];
1444   Lisp_Object constants    = args[2];
1445   Lisp_Object stack_depth  = args[3];
1446   Lisp_Object doc_string   = (nargs > 4) ? args[4] : Qnil;
1447   Lisp_Object interactive  = (nargs > 5) ? args[5] : Qunbound;
1448
1449   if (nargs < 4 || nargs > 6)
1450     return Fsignal (Qwrong_number_of_arguments,
1451                     list2 (intern ("make-byte-code"), make_int (nargs)));
1452
1453   /* Check for valid formal parameter list now, to allow us to use
1454      SPECBIND_FAST_UNSAFE() later in funcall_compiled_function(). */
1455   {
1456     Lisp_Object symbol, tail;
1457     EXTERNAL_LIST_LOOP_3 (symbol, arglist, tail)
1458       {
1459         CHECK_SYMBOL (symbol);
1460         if (EQ (symbol, Qt)   ||
1461             EQ (symbol, Qnil) ||
1462             SYMBOL_IS_KEYWORD (symbol))
1463           signal_simple_error_2
1464             ("Invalid constant symbol in formal parameter list",
1465              symbol, arglist);
1466       }
1467   }
1468   f->arglist = arglist;
1469
1470   /* `instructions' is a string or a cons (string . int) for a
1471      lazy-loaded function. */
1472   if (CONSP (instructions))
1473     {
1474       CHECK_STRING (XCAR (instructions));
1475       CHECK_INT (XCDR (instructions));
1476     }
1477   else
1478     {
1479       CHECK_STRING (instructions);
1480     }
1481   f->instructions = instructions;
1482
1483   if (!NILP (constants))
1484     CHECK_VECTOR (constants);
1485   f->constants = constants;
1486
1487   CHECK_NATNUM (stack_depth);
1488   f->stack_depth = XINT (stack_depth);
1489
1490 #ifdef COMPILED_FUNCTION_ANNOTATION_HACK
1491   if (!NILP (Vcurrent_compiled_function_annotation))
1492     f->annotated = Fcopy (Vcurrent_compiled_function_annotation);
1493   else if (!NILP (Vload_file_name_internal_the_purecopy))
1494     f->annotated = Vload_file_name_internal_the_purecopy;
1495   else if (!NILP (Vload_file_name_internal))
1496     {
1497       struct gcpro gcpro1;
1498       GCPRO1 (fun);             /* don't let fun get reaped */
1499       Vload_file_name_internal_the_purecopy =
1500         Ffile_name_nondirectory (Vload_file_name_internal);
1501       f->annotated = Vload_file_name_internal_the_purecopy;
1502       UNGCPRO;
1503     }
1504 #endif /* COMPILED_FUNCTION_ANNOTATION_HACK */
1505
1506   /* doc_string may be nil, string, int, or a cons (string . int).
1507      interactive may be list or string (or unbound). */
1508   f->doc_and_interactive = Qunbound;
1509 #ifdef I18N3
1510   if ((f->flags.domainp = !NILP (Vfile_domain)) != 0)
1511     f->doc_and_interactive = Vfile_domain;
1512 #endif
1513   if ((f->flags.interactivep = !UNBOUNDP (interactive)) != 0)
1514     {
1515       f->doc_and_interactive
1516         = (UNBOUNDP (f->doc_and_interactive) ? interactive :
1517            Fcons (interactive, f->doc_and_interactive));
1518     }
1519   if ((f->flags.documentationp = !NILP (doc_string)) != 0)
1520     {
1521       f->doc_and_interactive
1522         = (UNBOUNDP (f->doc_and_interactive) ? doc_string :
1523            Fcons (doc_string, f->doc_and_interactive));
1524     }
1525   if (UNBOUNDP (f->doc_and_interactive))
1526     f->doc_and_interactive = Qnil;
1527
1528   return fun;
1529 }
1530
1531 \f
1532 /************************************************************************/
1533 /*                          Symbol allocation                           */
1534 /************************************************************************/
1535
1536 DECLARE_FIXED_TYPE_ALLOC (symbol, Lisp_Symbol);
1537 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_symbol 1000
1538
1539 DEFUN ("make-symbol", Fmake_symbol, 1, 1, 0, /*
1540 Return a newly allocated uninterned symbol whose name is NAME.
1541 Its value and function definition are void, and its property list is nil.
1542 */
1543        (name))
1544 {
1545   Lisp_Object val;
1546   Lisp_Symbol *p;
1547
1548   CHECK_STRING (name);
1549
1550   ALLOCATE_FIXED_TYPE (symbol, Lisp_Symbol, p);
1551   set_lheader_implementation (&(p->lheader), &lrecord_symbol);
1552   p->name     = XSTRING (name);
1553   p->plist    = Qnil;
1554   p->value    = Qunbound;
1555   p->function = Qunbound;
1556   symbol_next (p) = 0;
1557   XSETSYMBOL (val, p);
1558   return val;
1559 }
1560
1561 \f
1562 /************************************************************************/
1563 /*                         Extent allocation                            */
1564 /************************************************************************/
1565
1566 DECLARE_FIXED_TYPE_ALLOC (extent, struct extent);
1567 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_extent 1000
1568
1569 struct extent *
1570 allocate_extent (void)
1571 {
1572   struct extent *e;
1573
1574   ALLOCATE_FIXED_TYPE (extent, struct extent, e);
1575   set_lheader_implementation (&(e->lheader), &lrecord_extent);
1576   extent_object (e) = Qnil;
1577   set_extent_start (e, -1);
1578   set_extent_end (e, -1);
1579   e->plist = Qnil;
1580
1581   xzero (e->flags);
1582
1583   extent_face (e) = Qnil;
1584   e->flags.end_open = 1;  /* default is for endpoints to behave like markers */
1585   e->flags.detachable = 1;
1586
1587   return e;
1588 }
1589
1590 \f
1591 /************************************************************************/
1592 /*                         Event allocation                             */
1593 /************************************************************************/
1594
1595 DECLARE_FIXED_TYPE_ALLOC (event, Lisp_Event);
1596 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_event 1000
1597
1598 Lisp_Object
1599 allocate_event (void)
1600 {
1601   Lisp_Object val;
1602   Lisp_Event *e;
1603
1604   ALLOCATE_FIXED_TYPE (event, Lisp_Event, e);
1605   set_lheader_implementation (&(e->lheader), &lrecord_event);
1606
1607   XSETEVENT (val, e);
1608   return val;
1609 }
1610
1611 \f
1612 /************************************************************************/
1613 /*                       Marker allocation                              */
1614 /************************************************************************/
1615
1616 DECLARE_FIXED_TYPE_ALLOC (marker, Lisp_Marker);
1617 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_marker 1000
1618
1619 DEFUN ("make-marker", Fmake_marker, 0, 0, 0, /*
1620 Return a new marker which does not point at any place.
1621 */
1622        ())
1623 {
1624   Lisp_Object val;
1625   Lisp_Marker *p;
1626
1627   ALLOCATE_FIXED_TYPE (marker, Lisp_Marker, p);
1628   set_lheader_implementation (&(p->lheader), &lrecord_marker);
1629   p->buffer = 0;
1630   p->memind = 0;
1631   marker_next (p) = 0;
1632   marker_prev (p) = 0;
1633   p->insertion_type = 0;
1634   XSETMARKER (val, p);
1635   return val;
1636 }
1637
1638 Lisp_Object
1639 noseeum_make_marker (void)
1640 {
1641   Lisp_Object val;
1642   Lisp_Marker *p;
1643
1644   NOSEEUM_ALLOCATE_FIXED_TYPE (marker, Lisp_Marker, p);
1645   set_lheader_implementation (&(p->lheader), &lrecord_marker);
1646   p->buffer = 0;
1647   p->memind = 0;
1648   marker_next (p) = 0;
1649   marker_prev (p) = 0;
1650   p->insertion_type = 0;
1651   XSETMARKER (val, p);
1652   return val;
1653 }
1654
1655 \f
1656 /************************************************************************/
1657 /*                        String allocation                             */
1658 /************************************************************************/
1659
1660 /* The data for "short" strings generally resides inside of structs of type
1661    string_chars_block. The Lisp_String structure is allocated just like any
1662    other Lisp object (except for vectors), and these are freelisted when
1663    they get garbage collected. The data for short strings get compacted,
1664    but the data for large strings do not.
1665
1666    Previously Lisp_String structures were relocated, but this caused a lot
1667    of bus-errors because the C code didn't include enough GCPRO's for
1668    strings (since EVERY REFERENCE to a short string needed to be GCPRO'd so
1669    that the reference would get relocated).
1670
1671    This new method makes things somewhat bigger, but it is MUCH safer.  */
1672
1673 DECLARE_FIXED_TYPE_ALLOC (string, Lisp_String);
1674 /* strings are used and freed quite often */
1675 /* #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_string 10000 */
1676 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_string 1000
1677
1678 static Lisp_Object
1679 mark_string (Lisp_Object obj)
1680 {
1681   Lisp_String *ptr = XSTRING (obj);
1682
1683   if (CONSP (ptr->plist) && EXTENT_INFOP (XCAR (ptr->plist)))
1684     flush_cached_extent_info (XCAR (ptr->plist));
1685   return ptr->plist;
1686 }
1687
1688 static int
1689 string_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
1690 {
1691   Bytecount len;
1692   return (((len = XSTRING_LENGTH (obj1)) == XSTRING_LENGTH (obj2)) &&
1693           !memcmp (XSTRING_DATA (obj1), XSTRING_DATA (obj2), len));
1694 }
1695
1696 static const struct lrecord_description string_description[] = {
1697   { XD_BYTECOUNT,       offsetof (Lisp_String, size) },
1698   { XD_OPAQUE_DATA_PTR, offsetof (Lisp_String, data), XD_INDIRECT(0, 1) },
1699   { XD_LISP_OBJECT,     offsetof (Lisp_String, plist) },
1700   { XD_END }
1701 };
1702
1703 /* We store the string's extent info as the first element of the string's
1704    property list; and the string's MODIFF as the first or second element
1705    of the string's property list (depending on whether the extent info
1706    is present), but only if the string has been modified.  This is ugly
1707    but it reduces the memory allocated for the string in the vast
1708    majority of cases, where the string is never modified and has no
1709    extent info.
1710
1711    #### This means you can't use an int as a key in a string's plist. */
1712
1713 static Lisp_Object *
1714 string_plist_ptr (Lisp_Object string)
1715 {
1716   Lisp_Object *ptr = &XSTRING (string)->plist;
1717
1718   if (CONSP (*ptr) && EXTENT_INFOP (XCAR (*ptr)))
1719     ptr = &XCDR (*ptr);
1720   if (CONSP (*ptr) && INTP (XCAR (*ptr)))
1721     ptr = &XCDR (*ptr);
1722   return ptr;
1723 }
1724
1725 static Lisp_Object
1726 string_getprop (Lisp_Object string, Lisp_Object property)
1727 {
1728   return external_plist_get (string_plist_ptr (string), property, 0, ERROR_ME);
1729 }
1730
1731 static int
1732 string_putprop (Lisp_Object string, Lisp_Object property, Lisp_Object value)
1733 {
1734   external_plist_put (string_plist_ptr (string), property, value, 0, ERROR_ME);
1735   return 1;
1736 }
1737
1738 static int
1739 string_remprop (Lisp_Object string, Lisp_Object property)
1740 {
1741   return external_remprop (string_plist_ptr (string), property, 0, ERROR_ME);
1742 }
1743
1744 static Lisp_Object
1745 string_plist (Lisp_Object string)
1746 {
1747   return *string_plist_ptr (string);
1748 }
1749
1750 /* No `finalize', or `hash' methods.
1751    internal_hash() already knows how to hash strings and finalization
1752    is done with the ADDITIONAL_FREE_string macro, which is the
1753    standard way to do finalization when using
1754    SWEEP_FIXED_TYPE_BLOCK(). */
1755 DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS ("string", string,
1756                                                 mark_string, print_string,
1757                                                 0, string_equal, 0,
1758                                                 string_description,
1759                                                 string_getprop,
1760                                                 string_putprop,
1761                                                 string_remprop,
1762                                                 string_plist,
1763                                                 Lisp_String);
1764
1765 /* String blocks contain this many useful bytes. */
1766 #define STRING_CHARS_BLOCK_SIZE                                 \
1767 ((Bytecount) (8192 - MALLOC_OVERHEAD -                          \
1768               ((2 * sizeof (struct string_chars_block *))       \
1769                + sizeof (EMACS_INT))))
1770 /* Block header for small strings. */
1771 struct string_chars_block
1772 {
1773   EMACS_INT pos;
1774   struct string_chars_block *next;
1775   struct string_chars_block *prev;
1776   /* Contents of string_chars_block->string_chars are interleaved
1777      string_chars structures (see below) and the actual string data */
1778   unsigned char string_chars[STRING_CHARS_BLOCK_SIZE];
1779 };
1780
1781 static struct string_chars_block *first_string_chars_block;
1782 static struct string_chars_block *current_string_chars_block;
1783
1784 /* If SIZE is the length of a string, this returns how many bytes
1785  *  the string occupies in string_chars_block->string_chars
1786  *  (including alignment padding).
1787  */
1788 #define STRING_FULLSIZE(size) \
1789    ALIGN_SIZE (((size) + 1 + sizeof (Lisp_String *)),\
1790                ALIGNOF (Lisp_String *))
1791
1792 #define BIG_STRING_FULLSIZE_P(fullsize) ((fullsize) >= STRING_CHARS_BLOCK_SIZE)
1793 #define BIG_STRING_SIZE_P(size) (BIG_STRING_FULLSIZE_P (STRING_FULLSIZE(size)))
1794
1795 struct string_chars
1796 {
1797   Lisp_String *string;
1798   unsigned char chars[1];
1799 };
1800
1801 struct unused_string_chars
1802 {
1803   Lisp_String *string;
1804   EMACS_INT fullsize;
1805 };
1806
1807 static void
1808 init_string_chars_alloc (void)
1809 {
1810   first_string_chars_block = xnew (struct string_chars_block);
1811   first_string_chars_block->prev = 0;
1812   first_string_chars_block->next = 0;
1813   first_string_chars_block->pos = 0;
1814   current_string_chars_block = first_string_chars_block;
1815 }
1816
1817 static struct string_chars *
1818 allocate_string_chars_struct (Lisp_String *string_it_goes_with,
1819                               EMACS_INT fullsize)
1820 {
1821   struct string_chars *s_chars;
1822
1823   if (fullsize <=
1824       (countof (current_string_chars_block->string_chars)
1825        - current_string_chars_block->pos))
1826     {
1827       /* This string can fit in the current string chars block */
1828       s_chars = (struct string_chars *)
1829         (current_string_chars_block->string_chars
1830          + current_string_chars_block->pos);
1831       current_string_chars_block->pos += fullsize;
1832     }
1833   else
1834     {
1835       /* Make a new current string chars block */
1836       struct string_chars_block *new_scb = xnew (struct string_chars_block);
1837
1838       current_string_chars_block->next = new_scb;
1839       new_scb->prev = current_string_chars_block;
1840       new_scb->next = 0;
1841       current_string_chars_block = new_scb;
1842       new_scb->pos = fullsize;
1843       s_chars = (struct string_chars *)
1844         current_string_chars_block->string_chars;
1845     }
1846
1847   s_chars->string = string_it_goes_with;
1848
1849   INCREMENT_CONS_COUNTER (fullsize, "string chars");
1850
1851   return s_chars;
1852 }
1853
1854 Lisp_Object
1855 make_uninit_string (Bytecount length)
1856 {
1857   Lisp_String *s;
1858   EMACS_INT fullsize = STRING_FULLSIZE (length);
1859   Lisp_Object val;
1860
1861   assert (length >= 0 && fullsize > 0);
1862
1863   /* Allocate the string header */
1864   ALLOCATE_FIXED_TYPE (string, Lisp_String, s);
1865   set_lheader_implementation (&(s->lheader), &lrecord_string);
1866
1867   set_string_data (s, BIG_STRING_FULLSIZE_P (fullsize)
1868                    ? xnew_array (Bufbyte, length + 1)
1869                    : allocate_string_chars_struct (s, fullsize)->chars);
1870
1871   set_string_length (s, length);
1872   s->plist = Qnil;
1873
1874   set_string_byte (s, length, 0);
1875
1876   XSETSTRING (val, s);
1877   return val;
1878 }
1879
1880 #ifdef VERIFY_STRING_CHARS_INTEGRITY
1881 static void verify_string_chars_integrity (void);
1882 #endif
1883
1884 /* Resize the string S so that DELTA bytes can be inserted starting
1885    at POS.  If DELTA < 0, it means deletion starting at POS.  If
1886    POS < 0, resize the string but don't copy any characters.  Use
1887    this if you're planning on completely overwriting the string.
1888 */
1889
1890 void
1891 resize_string (Lisp_String *s, Bytecount pos, Bytecount delta)
1892 {
1893   Bytecount oldfullsize, newfullsize;
1894 #ifdef VERIFY_STRING_CHARS_INTEGRITY
1895   verify_string_chars_integrity ();
1896 #endif
1897
1898 #ifdef ERROR_CHECK_BUFPOS
1899   if (pos >= 0)
1900     {
1901       assert (pos <= string_length (s));
1902       if (delta < 0)
1903         assert (pos + (-delta) <= string_length (s));
1904     }
1905   else
1906     {
1907       if (delta < 0)
1908         assert ((-delta) <= string_length (s));
1909     }
1910 #endif /* ERROR_CHECK_BUFPOS */
1911
1912   if (delta == 0)
1913     /* simplest case: no size change. */
1914     return;
1915
1916   if (pos >= 0 && delta < 0)
1917     /* If DELTA < 0, the functions below will delete the characters
1918        before POS.  We want to delete characters *after* POS, however,
1919        so convert this to the appropriate form. */
1920     pos += -delta;
1921
1922   oldfullsize = STRING_FULLSIZE (string_length (s));
1923   newfullsize = STRING_FULLSIZE (string_length (s) + delta);
1924
1925   if (BIG_STRING_FULLSIZE_P (oldfullsize))
1926     {
1927       if (BIG_STRING_FULLSIZE_P (newfullsize))
1928         {
1929           /* Both strings are big.  We can just realloc().
1930              But careful!  If the string is shrinking, we have to
1931              memmove() _before_ realloc(), and if growing, we have to
1932              memmove() _after_ realloc() - otherwise the access is
1933              illegal, and we might crash. */
1934           Bytecount len = string_length (s) + 1 - pos;
1935
1936           if (delta < 0 && pos >= 0)
1937             memmove (string_data (s) + pos + delta, string_data (s) + pos, len);
1938           set_string_data (s, (Bufbyte *) xrealloc (string_data (s),
1939                                                     string_length (s) + delta + 1));
1940           if (delta > 0 && pos >= 0)
1941             memmove (string_data (s) + pos + delta, string_data (s) + pos, len);
1942         }
1943       else /* String has been demoted from BIG_STRING. */
1944         {
1945           Bufbyte *new_data =
1946             allocate_string_chars_struct (s, newfullsize)->chars;
1947           Bufbyte *old_data = string_data (s);
1948
1949           if (pos >= 0)
1950             {
1951               memcpy (new_data, old_data, pos);
1952               memcpy (new_data + pos + delta, old_data + pos,
1953                       string_length (s) + 1 - pos);
1954             }
1955           set_string_data (s, new_data);
1956           xfree (old_data);
1957         }
1958     }
1959   else /* old string is small */
1960     {
1961       if (oldfullsize == newfullsize)
1962         {
1963           /* special case; size change but the necessary
1964              allocation size won't change (up or down; code
1965              somewhere depends on there not being any unused
1966              allocation space, modulo any alignment
1967              constraints). */
1968           if (pos >= 0)
1969             {
1970               Bufbyte *addroff = pos + string_data (s);
1971
1972               memmove (addroff + delta, addroff,
1973                        /* +1 due to zero-termination. */
1974                        string_length (s) + 1 - pos);
1975             }
1976         }
1977       else
1978         {
1979           Bufbyte *old_data = string_data (s);
1980           Bufbyte *new_data =
1981             BIG_STRING_FULLSIZE_P (newfullsize)
1982             ? xnew_array (Bufbyte, string_length (s) + delta + 1)
1983             : allocate_string_chars_struct (s, newfullsize)->chars;
1984
1985           if (pos >= 0)
1986             {
1987               memcpy (new_data, old_data, pos);
1988               memcpy (new_data + pos + delta, old_data + pos,
1989                       string_length (s) + 1 - pos);
1990             }
1991           set_string_data (s, new_data);
1992
1993           {
1994             /* We need to mark this chunk of the string_chars_block
1995                as unused so that compact_string_chars() doesn't
1996                freak. */
1997             struct string_chars *old_s_chars = (struct string_chars *)
1998               ((char *) old_data - offsetof (struct string_chars, chars));
1999             /* Sanity check to make sure we aren't hosed by strange
2000                alignment/padding. */
2001             assert (old_s_chars->string == s);
2002             MARK_STRUCT_AS_FREE (old_s_chars);
2003             ((struct unused_string_chars *) old_s_chars)->fullsize =
2004               oldfullsize;
2005           }
2006         }
2007     }
2008
2009   set_string_length (s, string_length (s) + delta);
2010   /* If pos < 0, the string won't be zero-terminated.
2011      Terminate now just to make sure. */
2012   string_data (s)[string_length (s)] = '\0';
2013
2014   if (pos >= 0)
2015     {
2016       Lisp_Object string;
2017
2018       XSETSTRING (string, s);
2019       /* We also have to adjust all of the extent indices after the
2020          place we did the change.  We say "pos - 1" because
2021          adjust_extents() is exclusive of the starting position
2022          passed to it. */
2023       adjust_extents (string, pos - 1, string_length (s),
2024                       delta);
2025     }
2026
2027 #ifdef VERIFY_STRING_CHARS_INTEGRITY
2028   verify_string_chars_integrity ();
2029 #endif
2030 }
2031
2032 #ifdef MULE
2033
2034 void
2035 set_string_char (Lisp_String *s, Charcount i, Emchar c)
2036 {
2037   Bufbyte newstr[MAX_EMCHAR_LEN];
2038   Bytecount bytoff = charcount_to_bytecount (string_data (s), i);
2039   Bytecount oldlen = charcount_to_bytecount (string_data (s) + bytoff, 1);
2040   Bytecount newlen = set_charptr_emchar (newstr, c);
2041
2042   if (oldlen != newlen)
2043     resize_string (s, bytoff, newlen - oldlen);
2044   /* Remember, string_data (s) might have changed so we can't cache it. */
2045   memcpy (string_data (s) + bytoff, newstr, newlen);
2046 }
2047
2048 #endif /* MULE */
2049
2050 DEFUN ("make-string", Fmake_string, 2, 2, 0, /*
2051 Return a new string of length LENGTH, with each character being INIT.
2052 LENGTH must be an integer and INIT must be a character.
2053 */
2054        (length, init))
2055 {
2056   CHECK_NATNUM (length);
2057   CHECK_CHAR_COERCE_INT (init);
2058   {
2059     Bufbyte init_str[MAX_EMCHAR_LEN];
2060     int len = set_charptr_emchar (init_str, XCHAR (init));
2061     Lisp_Object val = make_uninit_string (len * XINT (length));
2062
2063     if (len == 1)
2064       /* Optimize the single-byte case */
2065       memset (XSTRING_DATA (val), XCHAR (init), XSTRING_LENGTH (val));
2066     else
2067       {
2068         size_t i;
2069         Bufbyte *ptr = XSTRING_DATA (val);
2070
2071         for (i = XINT (length); i; i--)
2072           {
2073             Bufbyte *init_ptr = init_str;
2074             switch (len)
2075               {
2076               case 4: *ptr++ = *init_ptr++;
2077               case 3: *ptr++ = *init_ptr++;
2078               case 2: *ptr++ = *init_ptr++;
2079               case 1: *ptr++ = *init_ptr++;
2080               }
2081           }
2082       }
2083     return val;
2084   }
2085 }
2086
2087 DEFUN ("string", Fstring, 0, MANY, 0, /*
2088 Concatenate all the argument characters and make the result a string.
2089 */
2090        (int nargs, Lisp_Object *args))
2091 {
2092   Bufbyte *storage = alloca_array (Bufbyte, nargs * MAX_EMCHAR_LEN);
2093   Bufbyte *p = storage;
2094
2095   for (; nargs; nargs--, args++)
2096     {
2097       Lisp_Object lisp_char = *args;
2098       CHECK_CHAR_COERCE_INT (lisp_char);
2099       p += set_charptr_emchar (p, XCHAR (lisp_char));
2100     }
2101   return make_string (storage, p - storage);
2102 }
2103
2104
2105 /* Take some raw memory, which MUST already be in internal format,
2106    and package it up into a Lisp string. */
2107 Lisp_Object
2108 make_string (const Bufbyte *contents, Bytecount length)
2109 {
2110   Lisp_Object val;
2111
2112   /* Make sure we find out about bad make_string's when they happen */
2113 #if defined (ERROR_CHECK_BUFPOS) && defined (MULE)
2114   bytecount_to_charcount (contents, length); /* Just for the assertions */
2115 #endif
2116
2117   val = make_uninit_string (length);
2118   memcpy (XSTRING_DATA (val), contents, length);
2119   return val;
2120 }
2121
2122 /* Take some raw memory, encoded in some external data format,
2123    and convert it into a Lisp string. */
2124 Lisp_Object
2125 make_ext_string (const Extbyte *contents, EMACS_INT length,
2126                  Lisp_Object coding_system)
2127 {
2128   Lisp_Object string;
2129   TO_INTERNAL_FORMAT (DATA, (contents, length),
2130                       LISP_STRING, string,
2131                       coding_system);
2132   return string;
2133 }
2134
2135 Lisp_Object
2136 build_string (const char *str)
2137 {
2138   /* Some strlen's crash and burn if passed null. */
2139   return make_string ((const Bufbyte *) str, (str ? strlen(str) : 0));
2140 }
2141
2142 Lisp_Object
2143 build_ext_string (const char *str, Lisp_Object coding_system)
2144 {
2145   /* Some strlen's crash and burn if passed null. */
2146   return make_ext_string ((const Extbyte *) str, (str ? strlen(str) : 0),
2147                           coding_system);
2148 }
2149
2150 Lisp_Object
2151 build_translated_string (const char *str)
2152 {
2153   return build_string (GETTEXT (str));
2154 }
2155
2156 Lisp_Object
2157 make_string_nocopy (const Bufbyte *contents, Bytecount length)
2158 {
2159   Lisp_String *s;
2160   Lisp_Object val;
2161
2162   /* Make sure we find out about bad make_string_nocopy's when they happen */
2163 #if defined (ERROR_CHECK_BUFPOS) && defined (MULE)
2164   bytecount_to_charcount (contents, length); /* Just for the assertions */
2165 #endif
2166
2167   /* Allocate the string header */
2168   ALLOCATE_FIXED_TYPE (string, Lisp_String, s);
2169   set_lheader_implementation (&(s->lheader), &lrecord_string);
2170   SET_C_READONLY_RECORD_HEADER (&s->lheader);
2171   s->plist = Qnil;
2172   set_string_data (s, (Bufbyte *)contents);
2173   set_string_length (s, length);
2174
2175   XSETSTRING (val, s);
2176   return val;
2177 }
2178
2179 \f
2180 /************************************************************************/
2181 /*                           lcrecord lists                             */
2182 /************************************************************************/
2183
2184 /* Lcrecord lists are used to manage the allocation of particular
2185    sorts of lcrecords, to avoid calling alloc_lcrecord() (and thus
2186    malloc() and garbage-collection junk) as much as possible.
2187    It is similar to the Blocktype class.
2188
2189    It works like this:
2190
2191    1) Create an lcrecord-list object using make_lcrecord_list().
2192       This is often done at initialization.  Remember to staticpro_nodump
2193       this object!  The arguments to make_lcrecord_list() are the
2194       same as would be passed to alloc_lcrecord().
2195    2) Instead of calling alloc_lcrecord(), call allocate_managed_lcrecord()
2196       and pass the lcrecord-list earlier created.
2197    3) When done with the lcrecord, call free_managed_lcrecord().
2198       The standard freeing caveats apply: ** make sure there are no
2199       pointers to the object anywhere! **
2200    4) Calling free_managed_lcrecord() is just like kissing the
2201       lcrecord goodbye as if it were garbage-collected.  This means:
2202       -- the contents of the freed lcrecord are undefined, and the
2203          contents of something produced by allocate_managed_lcrecord()
2204          are undefined, just like for alloc_lcrecord().
2205       -- the mark method for the lcrecord's type will *NEVER* be called
2206          on freed lcrecords.
2207       -- the finalize method for the lcrecord's type will be called
2208          at the time that free_managed_lcrecord() is called.
2209
2210    */
2211
2212 static Lisp_Object
2213 mark_lcrecord_list (Lisp_Object obj)
2214 {
2215   struct lcrecord_list *list = XLCRECORD_LIST (obj);
2216   Lisp_Object chain = list->free;
2217
2218   while (!NILP (chain))
2219     {
2220       struct lrecord_header *lheader = XRECORD_LHEADER (chain);
2221       struct free_lcrecord_header *free_header =
2222         (struct free_lcrecord_header *) lheader;
2223
2224       gc_checking_assert
2225         (/* There should be no other pointers to the free list. */
2226          ! MARKED_RECORD_HEADER_P (lheader)
2227          &&
2228          /* Only lcrecords should be here. */
2229          ! LHEADER_IMPLEMENTATION (lheader)->basic_p
2230          &&
2231          /* Only free lcrecords should be here. */
2232          free_header->lcheader.free
2233          &&
2234          /* The type of the lcrecord must be right. */
2235          LHEADER_IMPLEMENTATION (lheader) == list->implementation
2236          &&
2237          /* So must the size. */
2238          (LHEADER_IMPLEMENTATION (lheader)->static_size == 0 ||
2239           LHEADER_IMPLEMENTATION (lheader)->static_size == list->size)
2240          );
2241
2242       MARK_RECORD_HEADER (lheader);
2243       chain = free_header->chain;
2244     }
2245
2246   return Qnil;
2247 }
2248
2249 DEFINE_LRECORD_IMPLEMENTATION ("lcrecord-list", lcrecord_list,
2250                                mark_lcrecord_list, internal_object_printer,
2251                                0, 0, 0, 0, struct lcrecord_list);
2252 Lisp_Object
2253 make_lcrecord_list (size_t size,
2254                     const struct lrecord_implementation *implementation)
2255 {
2256   struct lcrecord_list *p = alloc_lcrecord_type (struct lcrecord_list,
2257                                                  &lrecord_lcrecord_list);
2258   Lisp_Object val;
2259
2260   p->implementation = implementation;
2261   p->size = size;
2262   p->free = Qnil;
2263   XSETLCRECORD_LIST (val, p);
2264   return val;
2265 }
2266
2267 Lisp_Object
2268 allocate_managed_lcrecord (Lisp_Object lcrecord_list)
2269 {
2270   struct lcrecord_list *list = XLCRECORD_LIST (lcrecord_list);
2271   if (!NILP (list->free))
2272     {
2273       Lisp_Object val = list->free;
2274       struct free_lcrecord_header *free_header =
2275         (struct free_lcrecord_header *) XPNTR (val);
2276
2277 #ifdef ERROR_CHECK_GC
2278       struct lrecord_header *lheader = &free_header->lcheader.lheader;
2279
2280       /* There should be no other pointers to the free list. */
2281       assert (! MARKED_RECORD_HEADER_P (lheader));
2282       /* Only lcrecords should be here. */
2283       assert (! LHEADER_IMPLEMENTATION (lheader)->basic_p);
2284       /* Only free lcrecords should be here. */
2285       assert (free_header->lcheader.free);
2286       /* The type of the lcrecord must be right. */
2287       assert (LHEADER_IMPLEMENTATION (lheader) == list->implementation);
2288       /* So must the size. */
2289       assert (LHEADER_IMPLEMENTATION (lheader)->static_size == 0 ||
2290               LHEADER_IMPLEMENTATION (lheader)->static_size == list->size);
2291 #endif /* ERROR_CHECK_GC */
2292
2293       list->free = free_header->chain;
2294       free_header->lcheader.free = 0;
2295       return val;
2296     }
2297   else
2298     {
2299       Lisp_Object val;
2300
2301       XSETOBJ (val, Lisp_Type_Record,
2302                alloc_lcrecord (list->size, list->implementation));
2303       return val;
2304     }
2305 }
2306
2307 void
2308 free_managed_lcrecord (Lisp_Object lcrecord_list, Lisp_Object lcrecord)
2309 {
2310   struct lcrecord_list *list = XLCRECORD_LIST (lcrecord_list);
2311   struct free_lcrecord_header *free_header =
2312     (struct free_lcrecord_header *) XPNTR (lcrecord);
2313   struct lrecord_header *lheader = &free_header->lcheader.lheader;
2314   const struct lrecord_implementation *implementation
2315     = LHEADER_IMPLEMENTATION (lheader);
2316
2317   /* Make sure the size is correct.  This will catch, for example,
2318      putting a window configuration on the wrong free list. */
2319   gc_checking_assert ((implementation->size_in_bytes_method ?
2320                        implementation->size_in_bytes_method (lheader) :
2321                        implementation->static_size)
2322                       == list->size);
2323
2324   if (implementation->finalizer)
2325     implementation->finalizer (lheader, 0);
2326   free_header->chain = list->free;
2327   free_header->lcheader.free = 1;
2328   list->free = lcrecord;
2329 }
2330
2331 \f
2332
2333 \f
2334 DEFUN ("purecopy", Fpurecopy, 1, 1, 0, /*
2335 Kept for compatibility, returns its argument.
2336 Old:
2337 Make a copy of OBJECT in pure storage.
2338 Recursively copies contents of vectors and cons cells.
2339 Does not copy symbols.
2340 */
2341        (obj))
2342 {
2343   return obj;
2344 }
2345
2346 \f
2347 /************************************************************************/
2348 /*                         Garbage Collection                           */
2349 /************************************************************************/
2350
2351 /* This will be used more extensively In The Future */
2352 static int last_lrecord_type_index_assigned;
2353
2354 /* All the built-in lisp object types are enumerated in `enum lrecord_type'.
2355    Additional ones may be defined by a module (none yet).  We leave some
2356    room in `lrecord_implementations_table' for such new lisp object types. */
2357 #define MODULE_DEFINABLE_TYPE_COUNT 32
2358 const struct lrecord_implementation *lrecord_implementations_table[lrecord_type_count + MODULE_DEFINABLE_TYPE_COUNT];
2359
2360 /* Object marker functions are in the lrecord_implementation structure.
2361    But copying them to a parallel array is much more cache-friendly.
2362    This hack speeds up (garbage-collect) by about 5%. */
2363 Lisp_Object (*lrecord_markers[countof (lrecord_implementations_table)]) (Lisp_Object);
2364
2365 struct gcpro *gcprolist;
2366
2367 /* 415 used Mly 29-Jun-93 */
2368 /* 1327 used slb 28-Feb-98 */
2369 /* 1328 used og  03-Oct-99 (moving slowly, heh?) */
2370 #ifdef HAVE_SHLIB
2371 #define NSTATICS 4000
2372 #else
2373 #define NSTATICS 2000
2374 #endif
2375 /* Not "static" because of linker lossage on some systems */
2376 Lisp_Object *staticvec[NSTATICS]
2377      /* Force it into data space! */
2378      = {0};
2379 static int staticidx;
2380
2381 /* Put an entry in staticvec, pointing at the variable whose address is given
2382  */
2383 void
2384 staticpro (Lisp_Object *varaddress)
2385 {
2386   if (staticidx >= countof (staticvec))
2387     /* #### This is now a dubious abort() since this routine may be called */
2388     /* by Lisp attempting to load a DLL. */
2389     abort ();
2390   staticvec[staticidx++] = varaddress;
2391 }
2392
2393 /* Not "static" because of linker lossage on some systems */
2394 Lisp_Object *staticvec_nodump[200]
2395      /* Force it into data space! */
2396      = {0};
2397 static int staticidx_nodump;
2398
2399 /* Put an entry in staticvec_nodump, pointing at the variable whose address is given
2400  */
2401 void
2402 staticpro_nodump (Lisp_Object *varaddress)
2403 {
2404   if (staticidx_nodump >= countof (staticvec_nodump))
2405     /* #### This is now a dubious abort() since this routine may be called */
2406     /* by Lisp attempting to load a DLL. */
2407     abort ();
2408   staticvec_nodump[staticidx_nodump++] = varaddress;
2409 }
2410
2411 /* Not "static" because of linker lossage on some systems */
2412 struct
2413 {
2414   void *data;
2415   const struct struct_description *desc;
2416 } dumpstructvec[200];
2417
2418 static int dumpstructidx;
2419
2420 /* Put an entry in dumpstructvec, pointing at the variable whose address is given
2421  */
2422 void
2423 dumpstruct (void *varaddress, const struct struct_description *desc)
2424 {
2425   if (dumpstructidx >= countof (dumpstructvec))
2426     abort ();
2427   dumpstructvec[dumpstructidx].data = varaddress;
2428   dumpstructvec[dumpstructidx].desc = desc;
2429   dumpstructidx++;
2430 }
2431
2432 /* Not "static" because of linker lossage on some systems */
2433 struct dumpopaque_info
2434 {
2435   void *data;
2436   size_t size;
2437 } dumpopaquevec[200];
2438
2439 static int dumpopaqueidx;
2440
2441 /* Put an entry in dumpopaquevec, pointing at the variable whose address is given
2442  */
2443 void
2444 dumpopaque (void *varaddress, size_t size)
2445 {
2446   if (dumpopaqueidx >= countof (dumpopaquevec))
2447     abort ();
2448   dumpopaquevec[dumpopaqueidx].data = varaddress;
2449   dumpopaquevec[dumpopaqueidx].size = size;
2450   dumpopaqueidx++;
2451 }
2452
2453 Lisp_Object *pdump_wirevec[50];
2454 static int pdump_wireidx;
2455
2456 /* Put an entry in pdump_wirevec, pointing at the variable whose address is given
2457  */
2458 void
2459 pdump_wire (Lisp_Object *varaddress)
2460 {
2461   if (pdump_wireidx >= countof (pdump_wirevec))
2462     abort ();
2463   pdump_wirevec[pdump_wireidx++] = varaddress;
2464 }
2465
2466
2467 Lisp_Object *pdump_wirevec_list[50];
2468 static int pdump_wireidx_list;
2469
2470 /* Put an entry in pdump_wirevec_list, pointing at the variable whose address is given
2471  */
2472 void
2473 pdump_wire_list (Lisp_Object *varaddress)
2474 {
2475   if (pdump_wireidx_list >= countof (pdump_wirevec_list))
2476     abort ();
2477   pdump_wirevec_list[pdump_wireidx_list++] = varaddress;
2478 }
2479
2480 #ifdef ERROR_CHECK_GC
2481 #define GC_CHECK_LHEADER_INVARIANTS(lheader) do {               \
2482   struct lrecord_header * GCLI_lh = (lheader);                  \
2483   assert (GCLI_lh != 0);                                        \
2484   assert (GCLI_lh->type <= last_lrecord_type_index_assigned);   \
2485   assert (! C_READONLY_RECORD_HEADER_P (GCLI_lh) ||             \
2486           (MARKED_RECORD_HEADER_P (GCLI_lh) &&                  \
2487            LISP_READONLY_RECORD_HEADER_P (GCLI_lh)));           \
2488 } while (0)
2489 #else
2490 #define GC_CHECK_LHEADER_INVARIANTS(lheader)
2491 #endif
2492
2493 \f
2494 /* Mark reference to a Lisp_Object.  If the object referred to has not been
2495    seen yet, recursively mark all the references contained in it. */
2496
2497 void
2498 mark_object (Lisp_Object obj)
2499 {
2500  tail_recurse:
2501
2502   /* Checks we used to perform */
2503   /* if (EQ (obj, Qnull_pointer)) return; */
2504   /* if (!POINTER_TYPE_P (XGCTYPE (obj))) return; */
2505   /* if (PURIFIED (XPNTR (obj))) return; */
2506
2507   if (XTYPE (obj) == Lisp_Type_Record)
2508     {
2509       struct lrecord_header *lheader = XRECORD_LHEADER (obj);
2510
2511       GC_CHECK_LHEADER_INVARIANTS (lheader);
2512
2513       gc_checking_assert (LHEADER_IMPLEMENTATION (lheader)->basic_p ||
2514                           ! ((struct lcrecord_header *) lheader)->free);
2515
2516       /* All c_readonly objects have their mark bit set,
2517          so that we only need to check the mark bit here. */
2518       if (! MARKED_RECORD_HEADER_P (lheader))
2519         {
2520           MARK_RECORD_HEADER (lheader);
2521
2522           if (RECORD_MARKER (lheader))
2523             {
2524               obj = RECORD_MARKER (lheader) (obj);
2525               if (!NILP (obj)) goto tail_recurse;
2526             }
2527         }
2528     }
2529 }
2530
2531 /* mark all of the conses in a list and mark the final cdr; but
2532    DO NOT mark the cars.
2533
2534    Use only for internal lists!  There should never be other pointers
2535    to the cons cells, because if so, the cars will remain unmarked
2536    even when they maybe should be marked. */
2537 void
2538 mark_conses_in_list (Lisp_Object obj)
2539 {
2540   Lisp_Object rest;
2541
2542   for (rest = obj; CONSP (rest); rest = XCDR (rest))
2543     {
2544       if (CONS_MARKED_P (XCONS (rest)))
2545         return;
2546       MARK_CONS (XCONS (rest));
2547     }
2548
2549   mark_object (rest);
2550 }
2551
2552 \f
2553 /* Find all structures not marked, and free them. */
2554
2555 static int gc_count_num_bit_vector_used, gc_count_bit_vector_total_size;
2556 static int gc_count_bit_vector_storage;
2557 static int gc_count_num_short_string_in_use;
2558 static int gc_count_string_total_size;
2559 static int gc_count_short_string_total_size;
2560
2561 /* static int gc_count_total_records_used, gc_count_records_total_size; */
2562
2563 \f
2564 /* stats on lcrecords in use - kinda kludgy */
2565
2566 static struct
2567 {
2568   int instances_in_use;
2569   int bytes_in_use;
2570   int instances_freed;
2571   int bytes_freed;
2572   int instances_on_free_list;
2573 } lcrecord_stats [countof (lrecord_implementations_table)];
2574
2575 static void
2576 tick_lcrecord_stats (const struct lrecord_header *h, int free_p)
2577 {
2578   unsigned int type_index = h->type;
2579
2580   if (((struct lcrecord_header *) h)->free)
2581     {
2582       gc_checking_assert (!free_p);
2583       lcrecord_stats[type_index].instances_on_free_list++;
2584     }
2585   else
2586     {
2587       const struct lrecord_implementation *implementation =
2588         LHEADER_IMPLEMENTATION (h);
2589
2590       size_t sz = (implementation->size_in_bytes_method ?
2591                    implementation->size_in_bytes_method (h) :
2592                    implementation->static_size);
2593       if (free_p)
2594         {
2595           lcrecord_stats[type_index].instances_freed++;
2596           lcrecord_stats[type_index].bytes_freed += sz;
2597         }
2598       else
2599         {
2600           lcrecord_stats[type_index].instances_in_use++;
2601           lcrecord_stats[type_index].bytes_in_use += sz;
2602         }
2603     }
2604 }
2605
2606 \f
2607 /* Free all unmarked records */
2608 static void
2609 sweep_lcrecords_1 (struct lcrecord_header **prev, int *used)
2610 {
2611   struct lcrecord_header *header;
2612   int num_used = 0;
2613   /* int total_size = 0; */
2614
2615   xzero (lcrecord_stats); /* Reset all statistics to 0. */
2616
2617   /* First go through and call all the finalize methods.
2618      Then go through and free the objects.  There used to
2619      be only one loop here, with the call to the finalizer
2620      occurring directly before the xfree() below.  That
2621      is marginally faster but much less safe -- if the
2622      finalize method for an object needs to reference any
2623      other objects contained within it (and many do),
2624      we could easily be screwed by having already freed that
2625      other object. */
2626
2627   for (header = *prev; header; header = header->next)
2628     {
2629       struct lrecord_header *h = &(header->lheader);
2630
2631       GC_CHECK_LHEADER_INVARIANTS (h);
2632
2633       if (! MARKED_RECORD_HEADER_P (h) && ! header->free)
2634         {
2635           if (LHEADER_IMPLEMENTATION (h)->finalizer)
2636             LHEADER_IMPLEMENTATION (h)->finalizer (h, 0);
2637         }
2638     }
2639
2640   for (header = *prev; header; )
2641     {
2642       struct lrecord_header *h = &(header->lheader);
2643       if (MARKED_RECORD_HEADER_P (h))
2644         {
2645           if (! C_READONLY_RECORD_HEADER_P (h))
2646             UNMARK_RECORD_HEADER (h);
2647           num_used++;
2648           /* total_size += n->implementation->size_in_bytes (h);*/
2649           /* #### May modify header->next on a C_READONLY lcrecord */
2650           prev = &(header->next);
2651           header = *prev;
2652           tick_lcrecord_stats (h, 0);
2653         }
2654       else
2655         {
2656           struct lcrecord_header *next = header->next;
2657           *prev = next;
2658           tick_lcrecord_stats (h, 1);
2659           /* used to call finalizer right here. */
2660           xfree (header);
2661           header = next;
2662         }
2663     }
2664   *used = num_used;
2665   /* *total = total_size; */
2666 }
2667
2668
2669 static void
2670 sweep_bit_vectors_1 (Lisp_Object *prev,
2671                      int *used, int *total, int *storage)
2672 {
2673   Lisp_Object bit_vector;
2674   int num_used = 0;
2675   int total_size = 0;
2676   int total_storage = 0;
2677
2678   /* BIT_VECTORP fails because the objects are marked, which changes
2679      their implementation */
2680   for (bit_vector = *prev; !EQ (bit_vector, Qzero); )
2681     {
2682       Lisp_Bit_Vector *v = XBIT_VECTOR (bit_vector);
2683       int len = v->size;
2684       if (MARKED_RECORD_P (bit_vector))
2685         {
2686           if (! C_READONLY_RECORD_HEADER_P(&(v->lheader)))
2687             UNMARK_RECORD_HEADER (&(v->lheader));
2688           total_size += len;
2689           total_storage +=
2690             MALLOC_OVERHEAD +
2691             offsetof (Lisp_Bit_Vector, bits[BIT_VECTOR_LONG_STORAGE (len)]);
2692           num_used++;
2693           /* #### May modify next on a C_READONLY bitvector */
2694           prev = &(bit_vector_next (v));
2695           bit_vector = *prev;
2696         }
2697       else
2698         {
2699           Lisp_Object next = bit_vector_next (v);
2700           *prev = next;
2701           xfree (v);
2702           bit_vector = next;
2703         }
2704     }
2705   *used = num_used;
2706   *total = total_size;
2707   *storage = total_storage;
2708 }
2709
2710 /* And the Lord said: Thou shalt use the `c-backslash-region' command
2711    to make macros prettier. */
2712
2713 #ifdef ERROR_CHECK_GC
2714
2715 #define SWEEP_FIXED_TYPE_BLOCK(typename, obj_type)                      \
2716 do {                                                                    \
2717   struct typename##_block *SFTB_current;                                \
2718   struct typename##_block **SFTB_prev;                                  \
2719   int SFTB_limit;                                                       \
2720   int num_free = 0, num_used = 0;                                       \
2721                                                                         \
2722   for (SFTB_prev = &current_##typename##_block,                         \
2723        SFTB_current = current_##typename##_block,                       \
2724        SFTB_limit = current_##typename##_block_index;                   \
2725        SFTB_current;                                                    \
2726        )                                                                \
2727     {                                                                   \
2728       int SFTB_iii;                                                     \
2729                                                                         \
2730       for (SFTB_iii = 0; SFTB_iii < SFTB_limit; SFTB_iii++)             \
2731         {                                                               \
2732           obj_type *SFTB_victim = &(SFTB_current->block[SFTB_iii]);     \
2733                                                                         \
2734           if (FREE_STRUCT_P (SFTB_victim))                              \
2735             {                                                           \
2736               num_free++;                                               \
2737             }                                                           \
2738           else if (C_READONLY_RECORD_HEADER_P (&SFTB_victim->lheader))  \
2739             {                                                           \
2740               num_used++;                                               \
2741             }                                                           \
2742           else if (! MARKED_RECORD_HEADER_P (&SFTB_victim->lheader))    \
2743             {                                                           \
2744               num_free++;                                               \
2745               FREE_FIXED_TYPE (typename, obj_type, SFTB_victim);        \
2746             }                                                           \
2747           else                                                          \
2748             {                                                           \
2749               num_used++;                                               \
2750               UNMARK_##typename (SFTB_victim);                          \
2751             }                                                           \
2752         }                                                               \
2753       SFTB_prev = &(SFTB_current->prev);                                \
2754       SFTB_current = SFTB_current->prev;                                \
2755       SFTB_limit = countof (current_##typename##_block->block);         \
2756     }                                                                   \
2757                                                                         \
2758   gc_count_num_##typename##_in_use = num_used;                          \
2759   gc_count_num_##typename##_freelist = num_free;                        \
2760 } while (0)
2761
2762 #else /* !ERROR_CHECK_GC */
2763
2764 #define SWEEP_FIXED_TYPE_BLOCK(typename, obj_type)                              \
2765 do {                                                                            \
2766   struct typename##_block *SFTB_current;                                        \
2767   struct typename##_block **SFTB_prev;                                          \
2768   int SFTB_limit;                                                               \
2769   int num_free = 0, num_used = 0;                                               \
2770                                                                                 \
2771   typename##_free_list = 0;                                                     \
2772                                                                                 \
2773   for (SFTB_prev = &current_##typename##_block,                                 \
2774        SFTB_current = current_##typename##_block,                               \
2775        SFTB_limit = current_##typename##_block_index;                           \
2776        SFTB_current;                                                            \
2777        )                                                                        \
2778     {                                                                           \
2779       int SFTB_iii;                                                             \
2780       int SFTB_empty = 1;                                                       \
2781       obj_type *SFTB_old_free_list = typename##_free_list;                      \
2782                                                                                 \
2783       for (SFTB_iii = 0; SFTB_iii < SFTB_limit; SFTB_iii++)                     \
2784         {                                                                       \
2785           obj_type *SFTB_victim = &(SFTB_current->block[SFTB_iii]);             \
2786                                                                                 \
2787           if (FREE_STRUCT_P (SFTB_victim))                                      \
2788             {                                                                   \
2789               num_free++;                                                       \
2790               PUT_FIXED_TYPE_ON_FREE_LIST (typename, obj_type, SFTB_victim);    \
2791             }                                                                   \
2792           else if (C_READONLY_RECORD_HEADER_P (&SFTB_victim->lheader))          \
2793             {                                                                   \
2794               SFTB_empty = 0;                                                   \
2795               num_used++;                                                       \
2796             }                                                                   \
2797           else if (! MARKED_RECORD_HEADER_P (&SFTB_victim->lheader))            \
2798             {                                                                   \
2799               num_free++;                                                       \
2800               FREE_FIXED_TYPE (typename, obj_type, SFTB_victim);                \
2801             }                                                                   \
2802           else                                                                  \
2803             {                                                                   \
2804               SFTB_empty = 0;                                                   \
2805               num_used++;                                                       \
2806               UNMARK_##typename (SFTB_victim);                                  \
2807             }                                                                   \
2808         }                                                                       \
2809       if (!SFTB_empty)                                                          \
2810         {                                                                       \
2811           SFTB_prev = &(SFTB_current->prev);                                    \
2812           SFTB_current = SFTB_current->prev;                                    \
2813         }                                                                       \
2814       else if (SFTB_current == current_##typename##_block                       \
2815                && !SFTB_current->prev)                                          \
2816         {                                                                       \
2817           /* No real point in freeing sole allocation block */                  \
2818           break;                                                                \
2819         }                                                                       \
2820       else                                                                      \
2821         {                                                                       \
2822           struct typename##_block *SFTB_victim_block = SFTB_current;            \
2823           if (SFTB_victim_block == current_##typename##_block)                  \
2824             current_##typename##_block_index                                    \
2825               = countof (current_##typename##_block->block);                    \
2826           SFTB_current = SFTB_current->prev;                                    \
2827           {                                                                     \
2828             *SFTB_prev = SFTB_current;                                          \
2829             xfree (SFTB_victim_block);                                          \
2830             /* Restore free list to what it was before victim was swept */      \
2831             typename##_free_list = SFTB_old_free_list;                          \
2832             num_free -= SFTB_limit;                                             \
2833           }                                                                     \
2834         }                                                                       \
2835       SFTB_limit = countof (current_##typename##_block->block);                 \
2836     }                                                                           \
2837                                                                                 \
2838   gc_count_num_##typename##_in_use = num_used;                                  \
2839   gc_count_num_##typename##_freelist = num_free;                                \
2840 } while (0)
2841
2842 #endif /* !ERROR_CHECK_GC */
2843
2844 \f
2845
2846
2847 static void
2848 sweep_conses (void)
2849 {
2850 #define UNMARK_cons(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
2851 #define ADDITIONAL_FREE_cons(ptr)
2852
2853   SWEEP_FIXED_TYPE_BLOCK (cons, Lisp_Cons);
2854 }
2855
2856 /* Explicitly free a cons cell.  */
2857 void
2858 free_cons (Lisp_Cons *ptr)
2859 {
2860 #ifdef ERROR_CHECK_GC
2861   /* If the CAR is not an int, then it will be a pointer, which will
2862      always be four-byte aligned.  If this cons cell has already been
2863      placed on the free list, however, its car will probably contain
2864      a chain pointer to the next cons on the list, which has cleverly
2865      had all its 0's and 1's inverted.  This allows for a quick
2866      check to make sure we're not freeing something already freed. */
2867   if (POINTER_TYPE_P (XTYPE (ptr->car)))
2868     ASSERT_VALID_POINTER (XPNTR (ptr->car));
2869 #endif /* ERROR_CHECK_GC */
2870
2871 #ifndef ALLOC_NO_POOLS
2872   FREE_FIXED_TYPE_WHEN_NOT_IN_GC (cons, Lisp_Cons, ptr);
2873 #endif /* ALLOC_NO_POOLS */
2874 }
2875
2876 /* explicitly free a list.  You **must make sure** that you have
2877    created all the cons cells that make up this list and that there
2878    are no pointers to any of these cons cells anywhere else.  If there
2879    are, you will lose. */
2880
2881 void
2882 free_list (Lisp_Object list)
2883 {
2884   Lisp_Object rest, next;
2885
2886   for (rest = list; !NILP (rest); rest = next)
2887     {
2888       next = XCDR (rest);
2889       free_cons (XCONS (rest));
2890     }
2891 }
2892
2893 /* explicitly free an alist.  You **must make sure** that you have
2894    created all the cons cells that make up this alist and that there
2895    are no pointers to any of these cons cells anywhere else.  If there
2896    are, you will lose. */
2897
2898 void
2899 free_alist (Lisp_Object alist)
2900 {
2901   Lisp_Object rest, next;
2902
2903   for (rest = alist; !NILP (rest); rest = next)
2904     {
2905       next = XCDR (rest);
2906       free_cons (XCONS (XCAR (rest)));
2907       free_cons (XCONS (rest));
2908     }
2909 }
2910
2911 static void
2912 sweep_compiled_functions (void)
2913 {
2914 #define UNMARK_compiled_function(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
2915 #define ADDITIONAL_FREE_compiled_function(ptr)
2916
2917   SWEEP_FIXED_TYPE_BLOCK (compiled_function, Lisp_Compiled_Function);
2918 }
2919
2920
2921 #ifdef LISP_FLOAT_TYPE
2922 static void
2923 sweep_floats (void)
2924 {
2925 #define UNMARK_float(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
2926 #define ADDITIONAL_FREE_float(ptr)
2927
2928   SWEEP_FIXED_TYPE_BLOCK (float, Lisp_Float);
2929 }
2930 #endif /* LISP_FLOAT_TYPE */
2931
2932 static void
2933 sweep_symbols (void)
2934 {
2935 #define UNMARK_symbol(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
2936 #define ADDITIONAL_FREE_symbol(ptr)
2937
2938   SWEEP_FIXED_TYPE_BLOCK (symbol, Lisp_Symbol);
2939 }
2940
2941 static void
2942 sweep_extents (void)
2943 {
2944 #define UNMARK_extent(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
2945 #define ADDITIONAL_FREE_extent(ptr)
2946
2947   SWEEP_FIXED_TYPE_BLOCK (extent, struct extent);
2948 }
2949
2950 static void
2951 sweep_events (void)
2952 {
2953 #define UNMARK_event(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
2954 #define ADDITIONAL_FREE_event(ptr)
2955
2956   SWEEP_FIXED_TYPE_BLOCK (event, Lisp_Event);
2957 }
2958
2959 static void
2960 sweep_markers (void)
2961 {
2962 #define UNMARK_marker(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
2963 #define ADDITIONAL_FREE_marker(ptr)                                     \
2964   do { Lisp_Object tem;                                                 \
2965        XSETMARKER (tem, ptr);                                           \
2966        unchain_marker (tem);                                            \
2967      } while (0)
2968
2969   SWEEP_FIXED_TYPE_BLOCK (marker, Lisp_Marker);
2970 }
2971
2972 /* Explicitly free a marker.  */
2973 void
2974 free_marker (Lisp_Marker *ptr)
2975 {
2976   /* Perhaps this will catch freeing an already-freed marker. */
2977   gc_checking_assert (ptr->lheader.type = lrecord_type_marker);
2978
2979 #ifndef ALLOC_NO_POOLS
2980   FREE_FIXED_TYPE_WHEN_NOT_IN_GC (marker, Lisp_Marker, ptr);
2981 #endif /* ALLOC_NO_POOLS */
2982 }
2983 \f
2984
2985 #if defined (MULE) && defined (VERIFY_STRING_CHARS_INTEGRITY)
2986
2987 static void
2988 verify_string_chars_integrity (void)
2989 {
2990   struct string_chars_block *sb;
2991
2992   /* Scan each existing string block sequentially, string by string.  */
2993   for (sb = first_string_chars_block; sb; sb = sb->next)
2994     {
2995       int pos = 0;
2996       /* POS is the index of the next string in the block.  */
2997       while (pos < sb->pos)
2998         {
2999           struct string_chars *s_chars =
3000             (struct string_chars *) &(sb->string_chars[pos]);
3001           Lisp_String *string;
3002           int size;
3003           int fullsize;
3004
3005           /* If the string_chars struct is marked as free (i.e. the STRING
3006              pointer is 0xFFFFFFFF) then this is an unused chunk of string
3007              storage. (See below.) */
3008
3009           if (FREE_STRUCT_P (s_chars))
3010             {
3011               fullsize = ((struct unused_string_chars *) s_chars)->fullsize;
3012               pos += fullsize;
3013               continue;
3014             }
3015
3016           string = s_chars->string;
3017           /* Must be 32-bit aligned. */
3018           assert ((((int) string) & 3) == 0);
3019
3020           size = string_length (string);
3021           fullsize = STRING_FULLSIZE (size);
3022
3023           assert (!BIG_STRING_FULLSIZE_P (fullsize));
3024           assert (string_data (string) == s_chars->chars);
3025           pos += fullsize;
3026         }
3027       assert (pos == sb->pos);
3028     }
3029 }
3030
3031 #endif /* MULE && ERROR_CHECK_GC */
3032
3033 /* Compactify string chars, relocating the reference to each --
3034    free any empty string_chars_block we see. */
3035 static void
3036 compact_string_chars (void)
3037 {
3038   struct string_chars_block *to_sb = first_string_chars_block;
3039   int to_pos = 0;
3040   struct string_chars_block *from_sb;
3041
3042   /* Scan each existing string block sequentially, string by string.  */
3043   for (from_sb = first_string_chars_block; from_sb; from_sb = from_sb->next)
3044     {
3045       int from_pos = 0;
3046       /* FROM_POS is the index of the next string in the block.  */
3047       while (from_pos < from_sb->pos)
3048         {
3049           struct string_chars *from_s_chars =
3050             (struct string_chars *) &(from_sb->string_chars[from_pos]);
3051           struct string_chars *to_s_chars;
3052           Lisp_String *string;
3053           int size;
3054           int fullsize;
3055
3056           /* If the string_chars struct is marked as free (i.e. the STRING
3057              pointer is 0xFFFFFFFF) then this is an unused chunk of string
3058              storage.  This happens under Mule when a string's size changes
3059              in such a way that its fullsize changes. (Strings can change
3060              size because a different-length character can be substituted
3061              for another character.) In this case, after the bogus string
3062              pointer is the "fullsize" of this entry, i.e. how many bytes
3063              to skip. */
3064
3065           if (FREE_STRUCT_P (from_s_chars))
3066             {
3067               fullsize = ((struct unused_string_chars *) from_s_chars)->fullsize;
3068               from_pos += fullsize;
3069               continue;
3070             }
3071
3072           string = from_s_chars->string;
3073           assert (!(FREE_STRUCT_P (string)));
3074
3075           size = string_length (string);
3076           fullsize = STRING_FULLSIZE (size);
3077
3078           if (BIG_STRING_FULLSIZE_P (fullsize))
3079             abort ();
3080
3081           /* Just skip it if it isn't marked.  */
3082           if (! MARKED_RECORD_HEADER_P (&(string->lheader)))
3083             {
3084               from_pos += fullsize;
3085               continue;
3086             }
3087
3088           /* If it won't fit in what's left of TO_SB, close TO_SB out
3089              and go on to the next string_chars_block.  We know that TO_SB
3090              cannot advance past FROM_SB here since FROM_SB is large enough
3091              to currently contain this string. */
3092           if ((to_pos + fullsize) > countof (to_sb->string_chars))
3093             {
3094               to_sb->pos = to_pos;
3095               to_sb = to_sb->next;
3096               to_pos = 0;
3097             }
3098
3099           /* Compute new address of this string
3100              and update TO_POS for the space being used.  */
3101           to_s_chars = (struct string_chars *) &(to_sb->string_chars[to_pos]);
3102
3103           /* Copy the string_chars to the new place.  */
3104           if (from_s_chars != to_s_chars)
3105             memmove (to_s_chars, from_s_chars, fullsize);
3106
3107           /* Relocate FROM_S_CHARS's reference */
3108           set_string_data (string, &(to_s_chars->chars[0]));
3109
3110           from_pos += fullsize;
3111           to_pos += fullsize;
3112         }
3113     }
3114
3115   /* Set current to the last string chars block still used and
3116      free any that follow. */
3117   {
3118     struct string_chars_block *victim;
3119
3120     for (victim = to_sb->next; victim; )
3121       {
3122         struct string_chars_block *next = victim->next;
3123         xfree (victim);
3124         victim = next;
3125       }
3126
3127     current_string_chars_block = to_sb;
3128     current_string_chars_block->pos = to_pos;
3129     current_string_chars_block->next = 0;
3130   }
3131 }
3132
3133 #if 1 /* Hack to debug missing purecopy's */
3134 static int debug_string_purity;
3135
3136 static void
3137 debug_string_purity_print (Lisp_String *p)
3138 {
3139   Charcount i;
3140   Charcount s = string_char_length (p);
3141   putc ('\"', stderr);
3142   for (i = 0; i < s; i++)
3143   {
3144     Emchar ch = string_char (p, i);
3145     if (ch < 32 || ch >= 126)
3146       stderr_out ("\\%03o", ch);
3147     else if (ch == '\\' || ch == '\"')
3148       stderr_out ("\\%c", ch);
3149     else
3150       stderr_out ("%c", ch);
3151   }
3152   stderr_out ("\"\n");
3153 }
3154 #endif /* 1 */
3155
3156
3157 static void
3158 sweep_strings (void)
3159 {
3160   int num_small_used = 0, num_small_bytes = 0, num_bytes = 0;
3161   int debug = debug_string_purity;
3162
3163 #define UNMARK_string(ptr) do {                 \
3164     Lisp_String *p = (ptr);                     \
3165     size_t size = string_length (p);            \
3166     UNMARK_RECORD_HEADER (&(p->lheader));       \
3167     num_bytes += size;                          \
3168     if (!BIG_STRING_SIZE_P (size))              \
3169       { num_small_bytes += size;                \
3170       num_small_used++;                         \
3171       }                                         \
3172     if (debug)                                  \
3173       debug_string_purity_print (p);            \
3174   } while (0)
3175 #define ADDITIONAL_FREE_string(ptr) do {        \
3176     size_t size = string_length (ptr);          \
3177     if (BIG_STRING_SIZE_P (size))               \
3178       xfree (ptr->data);                        \
3179   } while (0)
3180
3181   SWEEP_FIXED_TYPE_BLOCK (string, Lisp_String);
3182
3183   gc_count_num_short_string_in_use = num_small_used;
3184   gc_count_string_total_size = num_bytes;
3185   gc_count_short_string_total_size = num_small_bytes;
3186 }
3187
3188
3189 /* I hate duplicating all this crap! */
3190 int
3191 marked_p (Lisp_Object obj)
3192 {
3193   /* Checks we used to perform. */
3194   /* if (EQ (obj, Qnull_pointer)) return 1; */
3195   /* if (!POINTER_TYPE_P (XGCTYPE (obj))) return 1; */
3196   /* if (PURIFIED (XPNTR (obj))) return 1; */
3197
3198   if (XTYPE (obj) == Lisp_Type_Record)
3199     {
3200       struct lrecord_header *lheader = XRECORD_LHEADER (obj);
3201
3202       GC_CHECK_LHEADER_INVARIANTS (lheader);
3203
3204       return MARKED_RECORD_HEADER_P (lheader);
3205     }
3206   return 1;
3207 }
3208
3209 static void
3210 gc_sweep (void)
3211 {
3212   /* Free all unmarked records.  Do this at the very beginning,
3213      before anything else, so that the finalize methods can safely
3214      examine items in the objects.  sweep_lcrecords_1() makes
3215      sure to call all the finalize methods *before* freeing anything,
3216      to complete the safety. */
3217   {
3218     int ignored;
3219     sweep_lcrecords_1 (&all_lcrecords, &ignored);
3220   }
3221
3222   compact_string_chars ();
3223
3224   /* Finalize methods below (called through the ADDITIONAL_FREE_foo
3225      macros) must be *extremely* careful to make sure they're not
3226      referencing freed objects.  The only two existing finalize
3227      methods (for strings and markers) pass muster -- the string
3228      finalizer doesn't look at anything but its own specially-
3229      created block, and the marker finalizer only looks at live
3230      buffers (which will never be freed) and at the markers before
3231      and after it in the chain (which, by induction, will never be
3232      freed because if so, they would have already removed themselves
3233      from the chain). */
3234
3235   /* Put all unmarked strings on free list, free'ing the string chars
3236      of large unmarked strings */
3237   sweep_strings ();
3238
3239   /* Put all unmarked conses on free list */
3240   sweep_conses ();
3241
3242   /* Free all unmarked bit vectors */
3243   sweep_bit_vectors_1 (&all_bit_vectors,
3244                        &gc_count_num_bit_vector_used,
3245                        &gc_count_bit_vector_total_size,
3246                        &gc_count_bit_vector_storage);
3247
3248   /* Free all unmarked compiled-function objects */
3249   sweep_compiled_functions ();
3250
3251 #ifdef LISP_FLOAT_TYPE
3252   /* Put all unmarked floats on free list */
3253   sweep_floats ();
3254 #endif
3255
3256   /* Put all unmarked symbols on free list */
3257   sweep_symbols ();
3258
3259   /* Put all unmarked extents on free list */
3260   sweep_extents ();
3261
3262   /* Put all unmarked markers on free list.
3263      Dechain each one first from the buffer into which it points. */
3264   sweep_markers ();
3265
3266   sweep_events ();
3267
3268 #ifdef PDUMP
3269   /* Unmark all dumped objects */
3270   {
3271     int i;
3272     char *p = pdump_rt_list;
3273     if (p)
3274       for (;;)
3275         {
3276           pdump_reloc_table *rt = (pdump_reloc_table *)p;
3277           p += sizeof (pdump_reloc_table);
3278           if (rt->desc)
3279             {
3280               for (i=0; i<rt->count; i++)
3281                 {
3282                   struct lrecord_header *lh = * (struct lrecord_header **) p;
3283                   if (! C_READONLY_RECORD_HEADER_P (lh))
3284                     UNMARK_RECORD_HEADER (lh);
3285                   p += sizeof (EMACS_INT);
3286                 }
3287             } else
3288               break;
3289         }
3290   }
3291 #endif
3292 }
3293 \f
3294 /* Clearing for disksave. */
3295
3296 void
3297 disksave_object_finalization (void)
3298 {
3299   /* It's important that certain information from the environment not get
3300      dumped with the executable (pathnames, environment variables, etc.).
3301      To make it easier to tell when this has happened with strings(1) we
3302      clear some known-to-be-garbage blocks of memory, so that leftover
3303      results of old evaluation don't look like potential problems.
3304      But first we set some notable variables to nil and do one more GC,
3305      to turn those strings into garbage.
3306   */
3307
3308   /* Yeah, this list is pretty ad-hoc... */
3309   Vprocess_environment = Qnil;
3310   Vexec_directory = Qnil;
3311   Vdata_directory = Qnil;
3312   Vsite_directory = Qnil;
3313   Vdoc_directory = Qnil;
3314   Vconfigure_info_directory = Qnil;
3315   Vexec_path = Qnil;
3316   Vload_path = Qnil;
3317   /* Vdump_load_path = Qnil; */
3318   /* Release hash tables for locate_file */
3319   Flocate_file_clear_hashing (Qt);
3320   uncache_home_directory();
3321
3322 #if defined(LOADHIST) && !(defined(LOADHIST_DUMPED) || \
3323                            defined(LOADHIST_BUILTIN))
3324   Vload_history = Qnil;
3325 #endif
3326   Vshell_file_name = Qnil;
3327
3328   garbage_collect_1 ();
3329
3330   /* Run the disksave finalization methods of all live objects. */
3331   disksave_object_finalization_1 ();
3332
3333   /* Zero out the uninitialized (really, unused) part of the containers
3334      for the live strings. */
3335   {
3336     struct string_chars_block *scb;
3337     for (scb = first_string_chars_block; scb; scb = scb->next)
3338       {
3339         int count = sizeof (scb->string_chars) - scb->pos;
3340
3341         assert (count >= 0 && count < STRING_CHARS_BLOCK_SIZE);
3342         if (count != 0)
3343           {
3344             /* from the block's fill ptr to the end */
3345             memset ((scb->string_chars + scb->pos), 0, count);
3346           }
3347       }
3348   }
3349
3350   /* There, that ought to be enough... */
3351
3352 }
3353
3354 \f
3355 Lisp_Object
3356 restore_gc_inhibit (Lisp_Object val)
3357 {
3358   gc_currently_forbidden = XINT (val);
3359   return val;
3360 }
3361
3362 /* Maybe we want to use this when doing a "panic" gc after memory_full()? */
3363 static int gc_hooks_inhibited;
3364
3365 \f
3366 void
3367 garbage_collect_1 (void)
3368 {
3369 #if MAX_SAVE_STACK > 0
3370   char stack_top_variable;
3371   extern char *stack_bottom;
3372 #endif
3373   struct frame *f;
3374   int speccount;
3375   int cursor_changed;
3376   Lisp_Object pre_gc_cursor;
3377   struct gcpro gcpro1;
3378
3379   if (gc_in_progress
3380       || gc_currently_forbidden
3381       || in_display
3382       || preparing_for_armageddon)
3383     return;
3384
3385   /* We used to call selected_frame() here.
3386
3387      The following functions cannot be called inside GC
3388      so we move to after the above tests. */
3389   {
3390     Lisp_Object frame;
3391     Lisp_Object device = Fselected_device (Qnil);
3392     if (NILP (device)) /* Could happen during startup, eg. if always_gc */
3393       return;
3394     frame = DEVICE_SELECTED_FRAME (XDEVICE (device));
3395     if (NILP (frame))
3396       signal_simple_error ("No frames exist on device", device);
3397     f = XFRAME (frame);
3398   }
3399
3400   pre_gc_cursor = Qnil;
3401   cursor_changed = 0;
3402
3403   GCPRO1 (pre_gc_cursor);
3404
3405   /* Very important to prevent GC during any of the following
3406      stuff that might run Lisp code; otherwise, we'll likely
3407      have infinite GC recursion. */
3408   speccount = specpdl_depth ();
3409   record_unwind_protect (restore_gc_inhibit,
3410                          make_int (gc_currently_forbidden));
3411   gc_currently_forbidden = 1;
3412
3413   if (!gc_hooks_inhibited)
3414     run_hook_trapping_errors ("Error in pre-gc-hook", Qpre_gc_hook);
3415
3416   /* Now show the GC cursor/message. */
3417   if (!noninteractive)
3418     {
3419       if (FRAME_WIN_P (f))
3420         {
3421           Lisp_Object frame = make_frame (f);
3422           Lisp_Object cursor = glyph_image_instance (Vgc_pointer_glyph,
3423                                                      FRAME_SELECTED_WINDOW (f),
3424                                                      ERROR_ME_NOT, 1);
3425           pre_gc_cursor = f->pointer;
3426           if (POINTER_IMAGE_INSTANCEP (cursor)
3427               /* don't change if we don't know how to change back. */
3428               && POINTER_IMAGE_INSTANCEP (pre_gc_cursor))
3429             {
3430               cursor_changed = 1;
3431               Fset_frame_pointer (frame, cursor);
3432             }
3433         }
3434
3435       /* Don't print messages to the stream device. */
3436       if (!cursor_changed && !FRAME_STREAM_P (f))
3437         {
3438           char *msg = (STRINGP (Vgc_message)
3439                        ? GETTEXT ((char *) XSTRING_DATA (Vgc_message))
3440                        : 0);
3441           Lisp_Object args[2], whole_msg;
3442           args[0] = build_string (msg ? msg :
3443                                   GETTEXT ((const char *) gc_default_message));
3444           args[1] = build_string ("...");
3445           whole_msg = Fconcat (2, args);
3446           echo_area_message (f, (Bufbyte *) 0, whole_msg, 0, -1,
3447                              Qgarbage_collecting);
3448         }
3449     }
3450
3451   /***** Now we actually start the garbage collection. */
3452
3453   gc_in_progress = 1;
3454
3455   gc_generation_number[0]++;
3456
3457 #if MAX_SAVE_STACK > 0
3458
3459   /* Save a copy of the contents of the stack, for debugging.  */
3460   if (!purify_flag)
3461     {
3462       /* Static buffer in which we save a copy of the C stack at each GC.  */
3463       static char *stack_copy;
3464       static size_t stack_copy_size;
3465
3466       ptrdiff_t stack_diff = &stack_top_variable - stack_bottom;
3467       size_t stack_size = (stack_diff > 0 ? stack_diff : -stack_diff);
3468       if (stack_size < MAX_SAVE_STACK)
3469         {
3470           if (stack_copy_size < stack_size)
3471             {
3472               stack_copy = (char *) xrealloc (stack_copy, stack_size);
3473               stack_copy_size = stack_size;
3474             }
3475
3476           memcpy (stack_copy,
3477                   stack_diff > 0 ? stack_bottom : &stack_top_variable,
3478                   stack_size);
3479         }
3480     }
3481 #endif /* MAX_SAVE_STACK > 0 */
3482
3483   /* Do some totally ad-hoc resource clearing. */
3484   /* #### generalize this? */
3485   clear_event_resource ();
3486   cleanup_specifiers ();
3487
3488   /* Mark all the special slots that serve as the roots of accessibility. */
3489
3490   { /* staticpro() */
3491     int i;
3492     for (i = 0; i < staticidx; i++)
3493       mark_object (*(staticvec[i]));
3494     for (i = 0; i < staticidx_nodump; i++)
3495       mark_object (*(staticvec_nodump[i]));
3496   }
3497
3498   { /* GCPRO() */
3499     struct gcpro *tail;
3500     int i;
3501     for (tail = gcprolist; tail; tail = tail->next)
3502       for (i = 0; i < tail->nvars; i++)
3503         mark_object (tail->var[i]);
3504   }
3505
3506   { /* specbind() */
3507     struct specbinding *bind;
3508     for (bind = specpdl; bind != specpdl_ptr; bind++)
3509       {
3510         mark_object (bind->symbol);
3511         mark_object (bind->old_value);
3512       }
3513   }
3514
3515   {
3516     struct catchtag *catch;
3517     for (catch = catchlist; catch; catch = catch->next)
3518       {
3519         mark_object (catch->tag);
3520         mark_object (catch->val);
3521       }
3522   }
3523
3524   {
3525     struct backtrace *backlist;
3526     for (backlist = backtrace_list; backlist; backlist = backlist->next)
3527       {
3528         int nargs = backlist->nargs;
3529         int i;
3530
3531         mark_object (*backlist->function);
3532         if (nargs == UNEVALLED || nargs == MANY)
3533           mark_object (backlist->args[0]);
3534         else
3535           for (i = 0; i < nargs; i++)
3536             mark_object (backlist->args[i]);
3537       }
3538   }
3539
3540   mark_redisplay ();
3541   mark_profiling_info ();
3542
3543   /* OK, now do the after-mark stuff.  This is for things that
3544      are only marked when something else is marked (e.g. weak hash tables).
3545      There may be complex dependencies between such objects -- e.g.
3546      a weak hash table might be unmarked, but after processing a later
3547      weak hash table, the former one might get marked.  So we have to
3548      iterate until nothing more gets marked. */
3549
3550   while (finish_marking_weak_hash_tables () > 0 ||
3551          finish_marking_weak_lists       () > 0)
3552     ;
3553
3554   /* And prune (this needs to be called after everything else has been
3555      marked and before we do any sweeping). */
3556   /* #### this is somewhat ad-hoc and should probably be an object
3557      method */
3558   prune_weak_hash_tables ();
3559   prune_weak_lists ();
3560   prune_specifiers ();
3561   prune_syntax_tables ();
3562
3563   gc_sweep ();
3564
3565   consing_since_gc = 0;
3566 #ifndef DEBUG_XEMACS
3567   /* Allow you to set it really fucking low if you really want ... */
3568   if (gc_cons_threshold < 10000)
3569     gc_cons_threshold = 10000;
3570 #endif
3571
3572   gc_in_progress = 0;
3573
3574   /******* End of garbage collection ********/
3575
3576   run_hook_trapping_errors ("Error in post-gc-hook", Qpost_gc_hook);
3577
3578   /* Now remove the GC cursor/message */
3579   if (!noninteractive)
3580     {
3581       if (cursor_changed)
3582         Fset_frame_pointer (make_frame (f), pre_gc_cursor);
3583       else if (!FRAME_STREAM_P (f))
3584         {
3585           char *msg = (STRINGP (Vgc_message)
3586                        ? GETTEXT ((char *) XSTRING_DATA (Vgc_message))
3587                        : 0);
3588
3589           /* Show "...done" only if the echo area would otherwise be empty. */
3590           if (NILP (clear_echo_area (selected_frame (),
3591                                      Qgarbage_collecting, 0)))
3592             {
3593               Lisp_Object args[2], whole_msg;
3594               args[0] = build_string (msg ? msg :
3595                                       GETTEXT ((const char *)
3596                                                gc_default_message));
3597               args[1] = build_string ("... done");
3598               whole_msg = Fconcat (2, args);
3599               echo_area_message (selected_frame (), (Bufbyte *) 0,
3600                                  whole_msg, 0, -1,
3601                                  Qgarbage_collecting);
3602             }
3603         }
3604     }
3605
3606   /* now stop inhibiting GC */
3607   unbind_to (speccount, Qnil);
3608
3609   if (!breathing_space)
3610     {
3611       breathing_space = malloc (4096 - MALLOC_OVERHEAD);
3612     }
3613
3614   UNGCPRO;
3615   return;
3616 }
3617
3618 /* Debugging aids.  */
3619
3620 static Lisp_Object
3621 gc_plist_hack (const char *name, int value, Lisp_Object tail)
3622 {
3623   /* C doesn't have local functions (or closures, or GC, or readable syntax,
3624      or portable numeric datatypes, or bit-vectors, or characters, or
3625      arrays, or exceptions, or ...) */
3626   return cons3 (intern (name), make_int (value), tail);
3627 }
3628
3629 #define HACK_O_MATIC(type, name, pl) do {                               \
3630   int s = 0;                                                            \
3631   struct type##_block *x = current_##type##_block;                      \
3632   while (x) { s += sizeof (*x) + MALLOC_OVERHEAD; x = x->prev; }        \
3633   (pl) = gc_plist_hack ((name), s, (pl));                               \
3634 } while (0)
3635
3636 DEFUN ("garbage-collect", Fgarbage_collect, 0, 0, "", /*
3637 Reclaim storage for Lisp objects no longer needed.
3638 Return info on amount of space in use:
3639  ((USED-CONSES . FREE-CONSES) (USED-SYMS . FREE-SYMS)
3640   (USED-MARKERS . FREE-MARKERS) USED-STRING-CHARS USED-VECTOR-SLOTS
3641   PLIST)
3642   where `PLIST' is a list of alternating keyword/value pairs providing
3643   more detailed information.
3644 Garbage collection happens automatically if you cons more than
3645 `gc-cons-threshold' bytes of Lisp data since previous garbage collection.
3646 */
3647        ())
3648 {
3649   Lisp_Object pl = Qnil;
3650   int i;
3651   int gc_count_vector_total_size = 0;
3652
3653   garbage_collect_1 ();
3654
3655   for (i = 0; i <= last_lrecord_type_index_assigned; i++)
3656     {
3657       if (lcrecord_stats[i].bytes_in_use != 0
3658           || lcrecord_stats[i].bytes_freed != 0
3659           || lcrecord_stats[i].instances_on_free_list != 0)
3660         {
3661           char buf [255];
3662           const char *name = lrecord_implementations_table[i]->name;
3663           int len = strlen (name);
3664           /* save this for the FSFmacs-compatible part of the summary */
3665           if (i == lrecord_vector.lrecord_type_index)
3666             gc_count_vector_total_size =
3667               lcrecord_stats[i].bytes_in_use + lcrecord_stats[i].bytes_freed;
3668
3669           sprintf (buf, "%s-storage", name);
3670           pl = gc_plist_hack (buf, lcrecord_stats[i].bytes_in_use, pl);
3671           /* Okay, simple pluralization check for `symbol-value-varalias' */
3672           if (name[len-1] == 's')
3673             sprintf (buf, "%ses-freed", name);
3674           else
3675             sprintf (buf, "%ss-freed", name);
3676           if (lcrecord_stats[i].instances_freed != 0)
3677             pl = gc_plist_hack (buf, lcrecord_stats[i].instances_freed, pl);
3678           if (name[len-1] == 's')
3679             sprintf (buf, "%ses-on-free-list", name);
3680           else
3681             sprintf (buf, "%ss-on-free-list", name);
3682           if (lcrecord_stats[i].instances_on_free_list != 0)
3683             pl = gc_plist_hack (buf, lcrecord_stats[i].instances_on_free_list,
3684                                 pl);
3685           if (name[len-1] == 's')
3686             sprintf (buf, "%ses-used", name);
3687           else
3688             sprintf (buf, "%ss-used", name);
3689           pl = gc_plist_hack (buf, lcrecord_stats[i].instances_in_use, pl);
3690         }
3691     }
3692
3693   HACK_O_MATIC (extent, "extent-storage", pl);
3694   pl = gc_plist_hack ("extents-free", gc_count_num_extent_freelist, pl);
3695   pl = gc_plist_hack ("extents-used", gc_count_num_extent_in_use, pl);
3696   HACK_O_MATIC (event, "event-storage", pl);
3697   pl = gc_plist_hack ("events-free", gc_count_num_event_freelist, pl);
3698   pl = gc_plist_hack ("events-used", gc_count_num_event_in_use, pl);
3699   HACK_O_MATIC (marker, "marker-storage", pl);
3700   pl = gc_plist_hack ("markers-free", gc_count_num_marker_freelist, pl);
3701   pl = gc_plist_hack ("markers-used", gc_count_num_marker_in_use, pl);
3702 #ifdef LISP_FLOAT_TYPE
3703   HACK_O_MATIC (float, "float-storage", pl);
3704   pl = gc_plist_hack ("floats-free", gc_count_num_float_freelist, pl);
3705   pl = gc_plist_hack ("floats-used", gc_count_num_float_in_use, pl);
3706 #endif /* LISP_FLOAT_TYPE */
3707   HACK_O_MATIC (string, "string-header-storage", pl);
3708   pl = gc_plist_hack ("long-strings-total-length",
3709                       gc_count_string_total_size
3710                       - gc_count_short_string_total_size, pl);
3711   HACK_O_MATIC (string_chars, "short-string-storage", pl);
3712   pl = gc_plist_hack ("short-strings-total-length",
3713                       gc_count_short_string_total_size, pl);
3714   pl = gc_plist_hack ("strings-free", gc_count_num_string_freelist, pl);
3715   pl = gc_plist_hack ("long-strings-used",
3716                       gc_count_num_string_in_use
3717                       - gc_count_num_short_string_in_use, pl);
3718   pl = gc_plist_hack ("short-strings-used",
3719                       gc_count_num_short_string_in_use, pl);
3720
3721   HACK_O_MATIC (compiled_function, "compiled-function-storage", pl);
3722   pl = gc_plist_hack ("compiled-functions-free",
3723                       gc_count_num_compiled_function_freelist, pl);
3724   pl = gc_plist_hack ("compiled-functions-used",
3725                       gc_count_num_compiled_function_in_use, pl);
3726
3727   pl = gc_plist_hack ("bit-vector-storage", gc_count_bit_vector_storage, pl);
3728   pl = gc_plist_hack ("bit-vectors-total-length",
3729                       gc_count_bit_vector_total_size, pl);
3730   pl = gc_plist_hack ("bit-vectors-used", gc_count_num_bit_vector_used, pl);
3731
3732   HACK_O_MATIC (symbol, "symbol-storage", pl);
3733   pl = gc_plist_hack ("symbols-free", gc_count_num_symbol_freelist, pl);
3734   pl = gc_plist_hack ("symbols-used", gc_count_num_symbol_in_use, pl);
3735
3736   HACK_O_MATIC (cons, "cons-storage", pl);
3737   pl = gc_plist_hack ("conses-free", gc_count_num_cons_freelist, pl);
3738   pl = gc_plist_hack ("conses-used", gc_count_num_cons_in_use, pl);
3739
3740   /* The things we do for backwards-compatibility */
3741   return
3742     list6 (Fcons (make_int (gc_count_num_cons_in_use),
3743                   make_int (gc_count_num_cons_freelist)),
3744            Fcons (make_int (gc_count_num_symbol_in_use),
3745                   make_int (gc_count_num_symbol_freelist)),
3746            Fcons (make_int (gc_count_num_marker_in_use),
3747                   make_int (gc_count_num_marker_freelist)),
3748            make_int (gc_count_string_total_size),
3749            make_int (gc_count_vector_total_size),
3750            pl);
3751 }
3752 #undef HACK_O_MATIC
3753
3754 DEFUN ("consing-since-gc", Fconsing_since_gc, 0, 0, "", /*
3755 Return the number of bytes consed since the last garbage collection.
3756 \"Consed\" is a misnomer in that this actually counts allocation
3757 of all different kinds of objects, not just conses.
3758
3759 If this value exceeds `gc-cons-threshold', a garbage collection happens.
3760 */
3761        ())
3762 {
3763   return make_int (consing_since_gc);
3764 }
3765
3766 #if 0
3767 DEFUN ("memory-limit", Fmemory_limit, 0, 0, "", /*
3768 Return the address of the last byte Emacs has allocated, divided by 1024.
3769 This may be helpful in debugging Emacs's memory usage.
3770 The value is divided by 1024 to make sure it will fit in a lisp integer.
3771 */
3772        ())
3773 {
3774   return make_int ((EMACS_INT) sbrk (0) / 1024);
3775 }
3776 #endif
3777
3778 \f
3779 int
3780 object_dead_p (Lisp_Object obj)
3781 {
3782   return ((BUFFERP  (obj) && !BUFFER_LIVE_P  (XBUFFER  (obj))) ||
3783           (FRAMEP   (obj) && !FRAME_LIVE_P   (XFRAME   (obj))) ||
3784           (WINDOWP  (obj) && !WINDOW_LIVE_P  (XWINDOW  (obj))) ||
3785           (DEVICEP  (obj) && !DEVICE_LIVE_P  (XDEVICE  (obj))) ||
3786           (CONSOLEP (obj) && !CONSOLE_LIVE_P (XCONSOLE (obj))) ||
3787           (EVENTP   (obj) && !EVENT_LIVE_P   (XEVENT   (obj))) ||
3788           (EXTENTP  (obj) && !EXTENT_LIVE_P  (XEXTENT  (obj))));
3789 }
3790
3791 #ifdef MEMORY_USAGE_STATS
3792
3793 /* Attempt to determine the actual amount of space that is used for
3794    the block allocated starting at PTR, supposedly of size "CLAIMED_SIZE".
3795
3796    It seems that the following holds:
3797
3798    1. When using the old allocator (malloc.c):
3799
3800       -- blocks are always allocated in chunks of powers of two.  For
3801          each block, there is an overhead of 8 bytes if rcheck is not
3802          defined, 20 bytes if it is defined.  In other words, a
3803          one-byte allocation needs 8 bytes of overhead for a total of
3804          9 bytes, and needs to have 16 bytes of memory chunked out for
3805          it.
3806
3807    2. When using the new allocator (gmalloc.c):
3808
3809       -- blocks are always allocated in chunks of powers of two up
3810          to 4096 bytes.  Larger blocks are allocated in chunks of
3811          an integral multiple of 4096 bytes.  The minimum block
3812          size is 2*sizeof (void *), or 16 bytes if SUNOS_LOCALTIME_BUG
3813          is defined.  There is no per-block overhead, but there
3814          is an overhead of 3*sizeof (size_t) for each 4096 bytes
3815          allocated.
3816
3817     3. When using the system malloc, anything goes, but they are
3818        generally slower and more space-efficient than the GNU
3819        allocators.  One possibly reasonable assumption to make
3820        for want of better data is that sizeof (void *), or maybe
3821        2 * sizeof (void *), is required as overhead and that
3822        blocks are allocated in the minimum required size except
3823        that some minimum block size is imposed (e.g. 16 bytes). */
3824
3825 size_t
3826 malloced_storage_size (void *ptr, size_t claimed_size,
3827                        struct overhead_stats *stats)
3828 {
3829   size_t orig_claimed_size = claimed_size;
3830
3831 #ifdef GNU_MALLOC
3832
3833   if (claimed_size < 2 * sizeof (void *))
3834     claimed_size = 2 * sizeof (void *);
3835 # ifdef SUNOS_LOCALTIME_BUG
3836   if (claimed_size < 16)
3837     claimed_size = 16;
3838 # endif
3839   if (claimed_size < 4096)
3840     {
3841       int log = 1;
3842
3843       /* compute the log base two, more or less, then use it to compute
3844          the block size needed. */
3845       claimed_size--;
3846       /* It's big, it's heavy, it's wood! */
3847       while ((claimed_size /= 2) != 0)
3848         ++log;
3849       claimed_size = 1;
3850       /* It's better than bad, it's good! */
3851       while (log > 0)
3852         {
3853           claimed_size *= 2;
3854           log--;
3855         }
3856       /* We have to come up with some average about the amount of
3857          blocks used. */
3858       if ((size_t) (rand () & 4095) < claimed_size)
3859         claimed_size += 3 * sizeof (void *);
3860     }
3861   else
3862     {
3863       claimed_size += 4095;
3864       claimed_size &= ~4095;
3865       claimed_size += (claimed_size / 4096) * 3 * sizeof (size_t);
3866     }
3867
3868 #elif defined (SYSTEM_MALLOC)
3869
3870   if (claimed_size < 16)
3871     claimed_size = 16;
3872   claimed_size += 2 * sizeof (void *);
3873
3874 #else /* old GNU allocator */
3875
3876 # ifdef rcheck /* #### may not be defined here */
3877   claimed_size += 20;
3878 # else
3879   claimed_size += 8;
3880 # endif
3881   {
3882     int log = 1;
3883
3884     /* compute the log base two, more or less, then use it to compute
3885        the block size needed. */
3886     claimed_size--;
3887     /* It's big, it's heavy, it's wood! */
3888     while ((claimed_size /= 2) != 0)
3889       ++log;
3890     claimed_size = 1;
3891     /* It's better than bad, it's good! */
3892     while (log > 0)
3893       {
3894         claimed_size *= 2;
3895         log--;
3896       }
3897   }
3898
3899 #endif /* old GNU allocator */
3900
3901   if (stats)
3902     {
3903       stats->was_requested += orig_claimed_size;
3904       stats->malloc_overhead += claimed_size - orig_claimed_size;
3905     }
3906   return claimed_size;
3907 }
3908
3909 size_t
3910 fixed_type_block_overhead (size_t size)
3911 {
3912   size_t per_block = TYPE_ALLOC_SIZE (cons, unsigned char);
3913   size_t overhead = 0;
3914   size_t storage_size = malloced_storage_size (0, per_block, 0);
3915   while (size >= per_block)
3916     {
3917       size -= per_block;
3918       overhead += sizeof (void *) + per_block - storage_size;
3919     }
3920   if (rand () % per_block < size)
3921     overhead += sizeof (void *) + per_block - storage_size;
3922   return overhead;
3923 }
3924
3925 #endif /* MEMORY_USAGE_STATS */
3926
3927 \f
3928 /* Initialization */
3929 void
3930 reinit_alloc_once_early (void)
3931 {
3932   gc_generation_number[0] = 0;
3933   breathing_space = 0;
3934   XSETINT (all_bit_vectors, 0); /* Qzero may not be set yet. */
3935   XSETINT (Vgc_message, 0);
3936   all_lcrecords = 0;
3937   ignore_malloc_warnings = 1;
3938 #ifdef DOUG_LEA_MALLOC
3939   mallopt (M_TRIM_THRESHOLD, 128*1024); /* trim threshold */
3940   mallopt (M_MMAP_THRESHOLD, 64*1024); /* mmap threshold */
3941 #if 0 /* Moved to emacs.c */
3942   mallopt (M_MMAP_MAX, 64); /* max. number of mmap'ed areas */
3943 #endif
3944 #endif
3945   init_string_alloc ();
3946   init_string_chars_alloc ();
3947   init_cons_alloc ();
3948   init_symbol_alloc ();
3949   init_compiled_function_alloc ();
3950 #ifdef LISP_FLOAT_TYPE
3951   init_float_alloc ();
3952 #endif /* LISP_FLOAT_TYPE */
3953   init_marker_alloc ();
3954   init_extent_alloc ();
3955   init_event_alloc ();
3956
3957   ignore_malloc_warnings = 0;
3958
3959   staticidx_nodump = 0;
3960   dumpstructidx = 0;
3961   pdump_wireidx = 0;
3962
3963   consing_since_gc = 0;
3964 #if 1
3965   gc_cons_threshold = 500000; /* XEmacs change */
3966 #else
3967   gc_cons_threshold = 15000; /* debugging */
3968 #endif
3969 #ifdef VIRT_ADDR_VARIES
3970   malloc_sbrk_unused = 1<<22;   /* A large number */
3971   malloc_sbrk_used = 100000;    /* as reasonable as any number */
3972 #endif /* VIRT_ADDR_VARIES */
3973   lrecord_uid_counter = 259;
3974   debug_string_purity = 0;
3975   gcprolist = 0;
3976
3977   gc_currently_forbidden = 0;
3978   gc_hooks_inhibited = 0;
3979
3980 #ifdef ERROR_CHECK_TYPECHECK
3981   ERROR_ME.really_unlikely_name_to_have_accidentally_in_a_non_errb_structure =
3982     666;
3983   ERROR_ME_NOT.
3984     really_unlikely_name_to_have_accidentally_in_a_non_errb_structure = 42;
3985   ERROR_ME_WARN.
3986     really_unlikely_name_to_have_accidentally_in_a_non_errb_structure =
3987       3333632;
3988 #endif /* ERROR_CHECK_TYPECHECK */
3989 }
3990
3991 void
3992 init_alloc_once_early (void)
3993 {
3994   reinit_alloc_once_early ();
3995
3996   last_lrecord_type_index_assigned = lrecord_type_count - 1;
3997
3998   {
3999     int i;
4000     for (i = 0; i < countof (lrecord_implementations_table); i++)
4001       lrecord_implementations_table[i] = 0;
4002   }
4003
4004   INIT_LRECORD_IMPLEMENTATION (cons);
4005   INIT_LRECORD_IMPLEMENTATION (vector);
4006   INIT_LRECORD_IMPLEMENTATION (string);
4007   INIT_LRECORD_IMPLEMENTATION (lcrecord_list);
4008
4009   staticidx = 0;
4010 }
4011
4012 int pure_bytes_used = 0;
4013
4014 void
4015 reinit_alloc (void)
4016 {
4017   gcprolist = 0;
4018 }
4019
4020 void
4021 syms_of_alloc (void)
4022 {
4023   defsymbol (&Qpre_gc_hook, "pre-gc-hook");
4024   defsymbol (&Qpost_gc_hook, "post-gc-hook");
4025   defsymbol (&Qgarbage_collecting, "garbage-collecting");
4026
4027   DEFSUBR (Fcons);
4028   DEFSUBR (Flist);
4029   DEFSUBR (Fvector);
4030   DEFSUBR (Fbit_vector);
4031   DEFSUBR (Fmake_byte_code);
4032   DEFSUBR (Fmake_list);
4033   DEFSUBR (Fmake_vector);
4034   DEFSUBR (Fmake_bit_vector);
4035   DEFSUBR (Fmake_string);
4036   DEFSUBR (Fstring);
4037   DEFSUBR (Fmake_symbol);
4038   DEFSUBR (Fmake_marker);
4039   DEFSUBR (Fpurecopy);
4040   DEFSUBR (Fgarbage_collect);
4041 #if 0
4042   DEFSUBR (Fmemory_limit);
4043 #endif
4044   DEFSUBR (Fconsing_since_gc);
4045 }
4046
4047 void
4048 vars_of_alloc (void)
4049 {
4050   DEFVAR_INT ("gc-cons-threshold", &gc_cons_threshold /*
4051 *Number of bytes of consing between garbage collections.
4052 \"Consing\" is a misnomer in that this actually counts allocation
4053 of all different kinds of objects, not just conses.
4054 Garbage collection can happen automatically once this many bytes have been
4055 allocated since the last garbage collection.  All data types count.
4056
4057 Garbage collection happens automatically when `eval' or `funcall' are
4058 called.  (Note that `funcall' is called implicitly as part of evaluation.)
4059 By binding this temporarily to a large number, you can effectively
4060 prevent garbage collection during a part of the program.
4061
4062 See also `consing-since-gc'.
4063 */ );
4064
4065   DEFVAR_INT ("pure-bytes-used", &pure_bytes_used /*
4066 Number of bytes of sharable Lisp data allocated so far.
4067 */ );
4068
4069 #if 0
4070   DEFVAR_INT ("data-bytes-used", &malloc_sbrk_used /*
4071 Number of bytes of unshared memory allocated in this session.
4072 */ );
4073
4074   DEFVAR_INT ("data-bytes-free", &malloc_sbrk_unused /*
4075 Number of bytes of unshared memory remaining available in this session.
4076 */ );
4077 #endif
4078
4079 #ifdef DEBUG_XEMACS
4080   DEFVAR_INT ("debug-allocation", &debug_allocation /*
4081 If non-zero, print out information to stderr about all objects allocated.
4082 See also `debug-allocation-backtrace-length'.
4083 */ );
4084   debug_allocation = 0;
4085
4086   DEFVAR_INT ("debug-allocation-backtrace-length",
4087               &debug_allocation_backtrace_length /*
4088 Length (in stack frames) of short backtrace printed out by `debug-allocation'.
4089 */ );
4090   debug_allocation_backtrace_length = 2;
4091 #endif
4092
4093   DEFVAR_BOOL ("purify-flag", &purify_flag /*
4094 Non-nil means loading Lisp code in order to dump an executable.
4095 This means that certain objects should be allocated in readonly space.
4096 */ );
4097
4098   DEFVAR_LISP ("pre-gc-hook", &Vpre_gc_hook /*
4099 Function or functions to be run just before each garbage collection.
4100 Interrupts, garbage collection, and errors are inhibited while this hook
4101 runs, so be extremely careful in what you add here.  In particular, avoid
4102 consing, and do not interact with the user.
4103 */ );
4104   Vpre_gc_hook = Qnil;
4105
4106   DEFVAR_LISP ("post-gc-hook", &Vpost_gc_hook /*
4107 Function or functions to be run just after each garbage collection.
4108 Interrupts, garbage collection, and errors are inhibited while this hook
4109 runs, so be extremely careful in what you add here.  In particular, avoid
4110 consing, and do not interact with the user.
4111 */ );
4112   Vpost_gc_hook = Qnil;
4113
4114   DEFVAR_LISP ("gc-message", &Vgc_message /*
4115 String to print to indicate that a garbage collection is in progress.
4116 This is printed in the echo area.  If the selected frame is on a
4117 window system and `gc-pointer-glyph' specifies a value (i.e. a pointer
4118 image instance) in the domain of the selected frame, the mouse pointer
4119 will change instead of this message being printed.
4120 */ );
4121   Vgc_message = build_string (gc_default_message);
4122
4123   DEFVAR_LISP ("gc-pointer-glyph", &Vgc_pointer_glyph /*
4124 Pointer glyph used to indicate that a garbage collection is in progress.
4125 If the selected window is on a window system and this glyph specifies a
4126 value (i.e. a pointer image instance) in the domain of the selected
4127 window, the pointer will be changed as specified during garbage collection.
4128 Otherwise, a message will be printed in the echo area, as controlled
4129 by `gc-message'.
4130 */ );
4131 }
4132
4133 void
4134 complex_vars_of_alloc (void)
4135 {
4136   Vgc_pointer_glyph = Fmake_glyph_internal (Qpointer);
4137 }
4138
4139
4140 #ifdef PDUMP
4141
4142 /* The structure of the file
4143  *
4144  * 0                    - header
4145  * 256                  - dumped objects
4146  * stab_offset          - nb_staticpro*(Lisp_Object *) from staticvec
4147  *                      - nb_staticpro*(relocated Lisp_Object) pointed to by staticpro
4148  *                      - nb_structdmp*pair(void *, adr) for pointers to structures
4149  *                      - lrecord_implementations_table[]
4150  *                      - relocation table
4151  *                      - wired variable address/value couples with the count preceding the list
4152  */
4153 typedef struct
4154 {
4155   char signature[8];
4156   EMACS_UINT stab_offset;
4157   EMACS_UINT reloc_address;
4158   int nb_staticpro;
4159   int nb_structdmp;
4160   int nb_opaquedmp;
4161   int last_type;
4162 } dump_header;
4163
4164 char *pdump_start, *pdump_end;
4165
4166 static const unsigned char align_table[256] =
4167 {
4168   8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4169   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4170   5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4171   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4172   6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4173   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4174   5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4175   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4176   7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4177   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4178   5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4179   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4180   6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4181   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4182   5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4183   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
4184 };
4185
4186 typedef struct pdump_entry_list_elmt
4187 {
4188   struct pdump_entry_list_elmt *next;
4189   const void *obj;
4190   size_t size;
4191   int count;
4192   int is_lrecord;
4193   EMACS_INT save_offset;
4194 } pdump_entry_list_elmt;
4195
4196 typedef struct
4197 {
4198   pdump_entry_list_elmt *first;
4199   int align;
4200   int count;
4201 } pdump_entry_list;
4202
4203 typedef struct pdump_struct_list_elmt
4204 {
4205   pdump_entry_list list;
4206   const struct struct_description *sdesc;
4207 } pdump_struct_list_elmt;
4208
4209 typedef struct
4210 {
4211   pdump_struct_list_elmt *list;
4212   int count;
4213   int size;
4214 } pdump_struct_list;
4215
4216 static pdump_entry_list pdump_object_table[256];
4217 static pdump_entry_list pdump_opaque_data_list;
4218 static pdump_struct_list pdump_struct_table;
4219 static pdump_entry_list_elmt *pdump_qnil;
4220
4221 static int pdump_alert_undump_object[256];
4222
4223 static unsigned long cur_offset;
4224 static size_t max_size;
4225 static int pdump_fd;
4226 static void *pdump_buf;
4227
4228 #define PDUMP_HASHSIZE 200001
4229
4230 static pdump_entry_list_elmt **pdump_hash;
4231
4232 /* Since most pointers are eight bytes aligned, the >>3 allows for a better hash */
4233 static int
4234 pdump_make_hash (const void *obj)
4235 {
4236   return ((unsigned long)(obj)>>3) % PDUMP_HASHSIZE;
4237 }
4238
4239 static pdump_entry_list_elmt *
4240 pdump_get_entry (const void *obj)
4241 {
4242   int pos = pdump_make_hash (obj);
4243   pdump_entry_list_elmt *e;
4244
4245   assert (obj != 0);
4246
4247   while ((e = pdump_hash[pos]) != 0)
4248     {
4249       if (e->obj == obj)
4250         return e;
4251
4252       pos++;
4253       if (pos == PDUMP_HASHSIZE)
4254         pos = 0;
4255     }
4256   return 0;
4257 }
4258
4259 static void
4260 pdump_add_entry (pdump_entry_list *list, const void *obj, size_t size, int count, int is_lrecord)
4261 {
4262   pdump_entry_list_elmt *e;
4263   int align;
4264   int pos = pdump_make_hash (obj);
4265
4266   while ((e = pdump_hash[pos]) != 0)
4267     {
4268       if (e->obj == obj)
4269         return;
4270
4271       pos++;
4272       if (pos == PDUMP_HASHSIZE)
4273         pos = 0;
4274     }
4275
4276   e = xnew (pdump_entry_list_elmt);
4277
4278   e->next = list->first;
4279   e->obj = obj;
4280   e->size = size;
4281   e->count = count;
4282   e->is_lrecord = is_lrecord;
4283   list->first = e;
4284
4285   list->count += count;
4286   pdump_hash[pos] = e;
4287
4288   align = align_table[size & 255];
4289   if (align < 2 && is_lrecord)
4290     align = 2;
4291
4292   if (align < list->align)
4293     list->align = align;
4294 }
4295
4296 static pdump_entry_list *
4297 pdump_get_entry_list (const struct struct_description *sdesc)
4298 {
4299   int i;
4300   for (i=0; i<pdump_struct_table.count; i++)
4301     if (pdump_struct_table.list[i].sdesc == sdesc)
4302       return &pdump_struct_table.list[i].list;
4303
4304   if (pdump_struct_table.size <= pdump_struct_table.count)
4305     {
4306       if (pdump_struct_table.size == -1)
4307         pdump_struct_table.size = 10;
4308       else
4309         pdump_struct_table.size = pdump_struct_table.size * 2;
4310       pdump_struct_table.list = (pdump_struct_list_elmt *)
4311         xrealloc (pdump_struct_table.list,
4312                   pdump_struct_table.size * sizeof (pdump_struct_list_elmt));
4313     }
4314   pdump_struct_table.list[pdump_struct_table.count].list.first = 0;
4315   pdump_struct_table.list[pdump_struct_table.count].list.align = 8;
4316   pdump_struct_table.list[pdump_struct_table.count].list.count = 0;
4317   pdump_struct_table.list[pdump_struct_table.count].sdesc = sdesc;
4318
4319   return &pdump_struct_table.list[pdump_struct_table.count++].list;
4320 }
4321
4322 static struct
4323 {
4324   struct lrecord_header *obj;
4325   int position;
4326   int offset;
4327 } backtrace[65536];
4328
4329 static int depth;
4330
4331 static void pdump_backtrace (void)
4332 {
4333   int i;
4334   fprintf (stderr, "pdump backtrace :\n");
4335   for (i=0;i<depth;i++)
4336     {
4337       if (!backtrace[i].obj)
4338         fprintf (stderr, "  - ind. (%d, %d)\n", backtrace[i].position, backtrace[i].offset);
4339       else
4340         {
4341           fprintf (stderr, "  - %s (%d, %d)\n",
4342                    LHEADER_IMPLEMENTATION (backtrace[i].obj)->name,
4343                    backtrace[i].position,
4344                    backtrace[i].offset);
4345         }
4346     }
4347 }
4348
4349 static void pdump_register_object (Lisp_Object obj);
4350 static void pdump_register_struct (const void *data, const struct struct_description *sdesc, int count);
4351
4352 static EMACS_INT
4353 pdump_get_indirect_count (EMACS_INT code, const struct lrecord_description *idesc, const void *idata)
4354 {
4355   EMACS_INT count;
4356   const void *irdata;
4357
4358   int line = XD_INDIRECT_VAL (code);
4359   int delta = XD_INDIRECT_DELTA (code);
4360
4361   irdata = ((char *)idata) + idesc[line].offset;
4362   switch (idesc[line].type)
4363     {
4364     case XD_SIZE_T:
4365       count = *(size_t *)irdata;
4366       break;
4367     case XD_INT:
4368       count = *(int *)irdata;
4369       break;
4370     case XD_LONG:
4371       count = *(long *)irdata;
4372       break;
4373     case XD_BYTECOUNT:
4374       count = *(Bytecount *)irdata;
4375       break;
4376     default:
4377       fprintf (stderr, "Unsupported count type : %d (line = %d, code=%ld)\n", idesc[line].type, line, (long)code);
4378       pdump_backtrace ();
4379       abort ();
4380     }
4381   count += delta;
4382   return count;
4383 }
4384
4385 static void
4386 pdump_register_sub (const void *data, const struct lrecord_description *desc, int me)
4387 {
4388   int pos;
4389
4390  restart:
4391   for (pos = 0; desc[pos].type != XD_END; pos++)
4392     {
4393       const void *rdata = (const char *)data + desc[pos].offset;
4394
4395       backtrace[me].position = pos;
4396       backtrace[me].offset = desc[pos].offset;
4397
4398       switch (desc[pos].type)
4399         {
4400         case XD_SPECIFIER_END:
4401           pos = 0;
4402           desc = ((const Lisp_Specifier *)data)->methods->extra_description;
4403           goto restart;
4404         case XD_SIZE_T:
4405         case XD_INT:
4406         case XD_LONG:
4407         case XD_BYTECOUNT:
4408         case XD_LO_RESET_NIL:
4409         case XD_INT_RESET:
4410         case XD_LO_LINK:
4411           break;
4412         case XD_OPAQUE_DATA_PTR:
4413           {
4414             EMACS_INT count = desc[pos].data1;
4415             if (XD_IS_INDIRECT (count))
4416               count = pdump_get_indirect_count (count, desc, data);
4417
4418             pdump_add_entry (&pdump_opaque_data_list,
4419                              *(void **)rdata,
4420                              count,
4421                              1,
4422                              0);
4423             break;
4424           }
4425         case XD_C_STRING:
4426           {
4427             const char *str = *(const char **)rdata;
4428             if (str)
4429               pdump_add_entry (&pdump_opaque_data_list, str, strlen (str)+1, 1, 0);
4430             break;
4431           }
4432         case XD_DOC_STRING:
4433           {
4434             const char *str = *(const char **)rdata;
4435             if ((EMACS_INT)str > 0)
4436               pdump_add_entry (&pdump_opaque_data_list, str, strlen (str)+1, 1, 0);
4437             break;
4438           }
4439         case XD_LISP_OBJECT:
4440           {
4441             const Lisp_Object *pobj = (const Lisp_Object *)rdata;
4442
4443             assert (desc[pos].data1 == 0);
4444
4445             backtrace[me].offset = (const char *)pobj - (const char *)data;
4446             pdump_register_object (*pobj);
4447             break;
4448           }
4449         case XD_LISP_OBJECT_ARRAY:
4450           {
4451             int i;
4452             EMACS_INT count = desc[pos].data1;
4453             if (XD_IS_INDIRECT (count))
4454               count = pdump_get_indirect_count (count, desc, data);
4455
4456             for (i = 0; i < count; i++)
4457               {
4458                 const Lisp_Object *pobj = ((const Lisp_Object *)rdata) + i;
4459                 Lisp_Object dobj = *pobj;
4460
4461                 backtrace[me].offset = (const char *)pobj - (const char *)data;
4462                 pdump_register_object (dobj);
4463               }
4464             break;
4465           }
4466         case XD_STRUCT_PTR:
4467           {
4468             EMACS_INT count = desc[pos].data1;
4469             const struct struct_description *sdesc = desc[pos].data2;
4470             const char *dobj = *(const char **)rdata;
4471             if (dobj)
4472               {
4473                 if (XD_IS_INDIRECT (count))
4474                   count = pdump_get_indirect_count (count, desc, data);
4475
4476                 pdump_register_struct (dobj, sdesc, count);
4477               }
4478             break;
4479           }
4480         default:
4481           fprintf (stderr, "Unsupported dump type : %d\n", desc[pos].type);
4482           pdump_backtrace ();
4483           abort ();
4484         };
4485     }
4486 }
4487
4488 static void
4489 pdump_register_object (Lisp_Object obj)
4490 {
4491   struct lrecord_header *objh;
4492
4493   if (!POINTER_TYPE_P (XTYPE (obj)))
4494     return;
4495
4496   objh = XRECORD_LHEADER (obj);
4497   if (!objh)
4498     return;
4499
4500   if (pdump_get_entry (objh))
4501     return;
4502
4503   if (LHEADER_IMPLEMENTATION (objh)->description)
4504     {
4505       int me = depth++;
4506       if (me>65536)
4507         {
4508           fprintf (stderr, "Backtrace overflow, loop ?\n");
4509           abort ();
4510         }
4511       backtrace[me].obj = objh;
4512       backtrace[me].position = 0;
4513       backtrace[me].offset = 0;
4514
4515       pdump_add_entry (pdump_object_table + objh->type,
4516                        objh,
4517                        LHEADER_IMPLEMENTATION (objh)->static_size ?
4518                        LHEADER_IMPLEMENTATION (objh)->static_size :
4519                        LHEADER_IMPLEMENTATION (objh)->size_in_bytes_method (objh),
4520                        1,
4521                        1);
4522       pdump_register_sub (objh,
4523                           LHEADER_IMPLEMENTATION (objh)->description,
4524                           me);
4525       --depth;
4526     }
4527   else
4528     {
4529       pdump_alert_undump_object[objh->type]++;
4530       fprintf (stderr, "Undumpable object type : %s\n", LHEADER_IMPLEMENTATION (objh)->name);
4531       pdump_backtrace ();
4532     }
4533 }
4534
4535 static void
4536 pdump_register_struct (const void *data, const struct struct_description *sdesc, int count)
4537 {
4538   if (data && !pdump_get_entry (data))
4539     {
4540       int me = depth++;
4541       int i;
4542       if (me>65536)
4543         {
4544           fprintf (stderr, "Backtrace overflow, loop ?\n");
4545           abort ();
4546         }
4547       backtrace[me].obj = 0;
4548       backtrace[me].position = 0;
4549       backtrace[me].offset = 0;
4550
4551       pdump_add_entry (pdump_get_entry_list (sdesc),
4552                        data,
4553                        sdesc->size,
4554                        count,
4555                        0);
4556       for (i=0; i<count; i++)
4557         {
4558           pdump_register_sub (((char *)data) + sdesc->size*i,
4559                               sdesc->description,
4560                               me);
4561         }
4562       --depth;
4563     }
4564 }
4565
4566 static void
4567 pdump_dump_data (pdump_entry_list_elmt *elmt, const struct lrecord_description *desc)
4568 {
4569   size_t size = elmt->size;
4570   int count = elmt->count;
4571   if (desc)
4572     {
4573       int pos, i;
4574       memcpy (pdump_buf, elmt->obj, size*count);
4575
4576       for (i=0; i<count; i++)
4577         {
4578           char *cur = ((char *)pdump_buf) + i*size;
4579         restart:
4580           for (pos = 0; desc[pos].type != XD_END; pos++)
4581             {
4582               void *rdata = cur + desc[pos].offset;
4583               switch (desc[pos].type)
4584                 {
4585                 case XD_SPECIFIER_END:
4586                   desc = ((const Lisp_Specifier *)(elmt->obj))->methods->extra_description;
4587                   goto restart;
4588                 case XD_SIZE_T:
4589                 case XD_INT:
4590                 case XD_LONG:
4591                 case XD_BYTECOUNT:
4592                   break;
4593                 case XD_LO_RESET_NIL:
4594                   {
4595                     EMACS_INT count = desc[pos].data1;
4596                     int i;
4597                     if (XD_IS_INDIRECT (count))
4598                       count = pdump_get_indirect_count (count, desc, elmt->obj);
4599                     for (i=0; i<count; i++)
4600                       ((EMACS_INT *)rdata)[i] = pdump_qnil->save_offset;
4601                     break;
4602                   }
4603                 case XD_INT_RESET:
4604                   {
4605                     EMACS_INT val = desc[pos].data1;
4606                     if (XD_IS_INDIRECT (val))
4607                       val = pdump_get_indirect_count (val, desc, elmt->obj);
4608                     *(int *)rdata = val;
4609                     break;
4610                   }
4611                 case XD_OPAQUE_DATA_PTR:
4612                 case XD_C_STRING:
4613                 case XD_STRUCT_PTR:
4614                   {
4615                     void *ptr = *(void **)rdata;
4616                     if (ptr)
4617                       *(EMACS_INT *)rdata = pdump_get_entry (ptr)->save_offset;
4618                     break;
4619                   }
4620                 case XD_LO_LINK:
4621                   {
4622                     Lisp_Object obj = *(Lisp_Object *)rdata;
4623                     pdump_entry_list_elmt *elmt1;
4624                     for (;;)
4625                       {
4626                         elmt1 = pdump_get_entry (XRECORD_LHEADER (obj));
4627                         if (elmt1)
4628                           break;
4629                         obj = *(Lisp_Object *)(desc[pos].offset + (char *)(XRECORD_LHEADER (obj)));
4630                       }
4631                     *(EMACS_INT *)rdata = elmt1->save_offset;
4632                     break;
4633                   }
4634                 case XD_LISP_OBJECT:
4635                   {
4636                     Lisp_Object *pobj = (Lisp_Object *) rdata;
4637
4638                     assert (desc[pos].data1 == 0);
4639
4640                     if (POINTER_TYPE_P (XTYPE (*pobj)) && XRECORD_LHEADER (*pobj))
4641                       *(EMACS_INT *)pobj =
4642                         pdump_get_entry (XRECORD_LHEADER (*pobj))->save_offset;
4643                     break;
4644                   }
4645                 case XD_LISP_OBJECT_ARRAY:
4646                   {
4647                     EMACS_INT count = desc[pos].data1;
4648                     int i;
4649                     if (XD_IS_INDIRECT (count))
4650                       count = pdump_get_indirect_count (count, desc, elmt->obj);
4651
4652                     for (i=0; i<count; i++)
4653                       {
4654                         Lisp_Object *pobj = ((Lisp_Object *)rdata) + i;
4655                         if (POINTER_TYPE_P (XTYPE (*pobj)) && XRECORD_LHEADER (*pobj))
4656                           *(EMACS_INT *)pobj =
4657                             pdump_get_entry (XRECORD_LHEADER (*pobj))->save_offset;
4658                       }
4659                     break;
4660                   }
4661                 case XD_DOC_STRING:
4662                   {
4663                     EMACS_INT str = *(EMACS_INT *)rdata;
4664                     if (str > 0)
4665                       *(EMACS_INT *)rdata = pdump_get_entry ((void *)str)->save_offset;
4666                     break;
4667                   }
4668                 default:
4669                   fprintf (stderr, "Unsupported dump type : %d\n", desc[pos].type);
4670                   abort ();
4671                 };
4672             }
4673         }
4674     }
4675   write (pdump_fd, desc ? pdump_buf : elmt->obj, size*count);
4676   if (elmt->is_lrecord && ((size*count) & 3))
4677     write (pdump_fd, "\0\0\0", 4-((size*count) & 3));
4678 }
4679
4680 static void
4681 pdump_reloc_one (void *data, EMACS_INT delta, const struct lrecord_description *desc)
4682 {
4683   int pos;
4684
4685  restart:
4686   for (pos = 0; desc[pos].type != XD_END; pos++)
4687     {
4688       void *rdata = (char *)data + desc[pos].offset;
4689       switch (desc[pos].type)
4690         {
4691         case XD_SPECIFIER_END:
4692           pos = 0;
4693           desc = ((const Lisp_Specifier *)data)->methods->extra_description;
4694           goto restart;
4695         case XD_SIZE_T:
4696         case XD_INT:
4697         case XD_LONG:
4698         case XD_BYTECOUNT:
4699         case XD_INT_RESET:
4700           break;
4701         case XD_OPAQUE_DATA_PTR:
4702         case XD_C_STRING:
4703         case XD_STRUCT_PTR:
4704         case XD_LO_LINK:
4705           {
4706             EMACS_INT ptr = *(EMACS_INT *)rdata;
4707             if (ptr)
4708               *(EMACS_INT *)rdata = ptr+delta;
4709             break;
4710           }
4711         case XD_LISP_OBJECT:
4712           {
4713             Lisp_Object *pobj = (Lisp_Object *) rdata;
4714
4715             assert (desc[pos].data1 == 0);
4716
4717             if (POINTER_TYPE_P (XTYPE (*pobj))
4718                 && ! EQ (*pobj, Qnull_pointer))
4719               XSETOBJ (*pobj, XTYPE (*pobj), (char *) XPNTR (*pobj) + delta);
4720
4721             break;
4722           }
4723         case XD_LISP_OBJECT_ARRAY:
4724         case XD_LO_RESET_NIL:
4725           {
4726             EMACS_INT count = desc[pos].data1;
4727             int i;
4728             if (XD_IS_INDIRECT (count))
4729               count = pdump_get_indirect_count (count, desc, data);
4730
4731             for (i=0; i<count; i++)
4732               {
4733                 Lisp_Object *pobj = (Lisp_Object *) rdata + i;
4734
4735                 if (POINTER_TYPE_P (XTYPE (*pobj))
4736                     && ! EQ (*pobj, Qnull_pointer))
4737                   XSETOBJ (*pobj, XTYPE (*pobj), (char *) XPNTR (*pobj) + delta);
4738               }
4739             break;
4740           }
4741         case XD_DOC_STRING:
4742           {
4743             EMACS_INT str = *(EMACS_INT *)rdata;
4744             if (str > 0)
4745               *(EMACS_INT *)rdata = str + delta;
4746             break;
4747           }
4748         default:
4749           fprintf (stderr, "Unsupported dump type : %d\n", desc[pos].type);
4750           abort ();
4751         };
4752     }
4753 }
4754
4755 static void
4756 pdump_allocate_offset (pdump_entry_list_elmt *elmt, const struct lrecord_description *desc)
4757 {
4758   size_t size = (elmt->is_lrecord ? (elmt->size + 3) & ~3 : elmt->size)*elmt->count;
4759   elmt->save_offset = cur_offset;
4760   if (size>max_size)
4761     max_size = size;
4762   cur_offset += size;
4763 }
4764
4765 static void
4766 pdump_scan_by_alignment (void (*f)(pdump_entry_list_elmt *, const struct lrecord_description *))
4767 {
4768   int align, i;
4769   const struct lrecord_description *idesc;
4770   pdump_entry_list_elmt *elmt;
4771   for (align=8; align>=0; align--)
4772     {
4773       for (i=0; i<=last_lrecord_type_index_assigned; i++)
4774         if (pdump_object_table[i].align == align)
4775           {
4776             elmt = pdump_object_table[i].first;
4777             if (!elmt)
4778               continue;
4779             idesc = lrecord_implementations_table[i]->description;
4780             while (elmt)
4781               {
4782                 f (elmt, idesc);
4783                 elmt = elmt->next;
4784               }
4785           }
4786
4787       for (i=0; i<pdump_struct_table.count; i++)
4788         if (pdump_struct_table.list[i].list.align == align)
4789           {
4790             elmt = pdump_struct_table.list[i].list.first;
4791             idesc = pdump_struct_table.list[i].sdesc->description;
4792             while (elmt)
4793               {
4794                 f (elmt, idesc);
4795                 elmt = elmt->next;
4796               }
4797           }
4798
4799       elmt = pdump_opaque_data_list.first;
4800       while (elmt)
4801         {
4802           if (align_table[elmt->size & 255] == align)
4803             f (elmt, 0);
4804           elmt = elmt->next;
4805         }
4806     }
4807 }
4808
4809 static void
4810 pdump_dump_staticvec (void)
4811 {
4812   EMACS_INT *reloc = xnew_array (EMACS_INT, staticidx);
4813   int i;
4814   write (pdump_fd, staticvec, staticidx*sizeof (Lisp_Object *));
4815
4816   for (i=0; i<staticidx; i++)
4817     {
4818       Lisp_Object obj = *staticvec[i];
4819       if (POINTER_TYPE_P (XTYPE (obj)))
4820         reloc[i] = pdump_get_entry (XRECORD_LHEADER (obj))->save_offset;
4821       else
4822         reloc[i] = *(EMACS_INT *)(staticvec[i]);
4823     }
4824   write (pdump_fd, reloc, staticidx*sizeof (Lisp_Object));
4825   free (reloc);
4826 }
4827
4828 static void
4829 pdump_dump_structvec (void)
4830 {
4831   int i;
4832   for (i=0; i<dumpstructidx; i++)
4833     {
4834       EMACS_INT adr;
4835       write (pdump_fd, &(dumpstructvec[i].data), sizeof (void *));
4836       adr = pdump_get_entry (*(void **)(dumpstructvec[i].data))->save_offset;
4837       write (pdump_fd, &adr, sizeof (adr));
4838     }
4839 }
4840
4841 static void
4842 pdump_dump_opaquevec (void)
4843 {
4844   int i;
4845   for (i=0; i<dumpopaqueidx; i++)
4846     {
4847       write (pdump_fd, &(dumpopaquevec[i]), sizeof (dumpopaquevec[i]));
4848       write (pdump_fd, dumpopaquevec[i].data, dumpopaquevec[i].size);
4849     }
4850 }
4851
4852 static void
4853 pdump_dump_itable (void)
4854 {
4855   write (pdump_fd, lrecord_implementations_table, sizeof (lrecord_implementations_table));
4856 }
4857
4858 static void
4859 pdump_dump_rtables (void)
4860 {
4861   int i, j;
4862   pdump_entry_list_elmt *elmt;
4863   pdump_reloc_table rt;
4864
4865   for (i=0; i<=last_lrecord_type_index_assigned; i++)
4866     {
4867       elmt = pdump_object_table[i].first;
4868       if (!elmt)
4869         continue;
4870       rt.desc = lrecord_implementations_table[i]->description;
4871       rt.count = pdump_object_table[i].count;
4872       write (pdump_fd, &rt, sizeof (rt));
4873       while (elmt)
4874         {
4875           EMACS_INT rdata = pdump_get_entry (elmt->obj)->save_offset;
4876           write (pdump_fd, &rdata, sizeof (rdata));
4877           elmt = elmt->next;
4878         }
4879     }
4880
4881   rt.desc = 0;
4882   rt.count = 0;
4883   write (pdump_fd, &rt, sizeof (rt));
4884
4885   for (i=0; i<pdump_struct_table.count; i++)
4886     {
4887       elmt = pdump_struct_table.list[i].list.first;
4888       rt.desc = pdump_struct_table.list[i].sdesc->description;
4889       rt.count = pdump_struct_table.list[i].list.count;
4890       write (pdump_fd, &rt, sizeof (rt));
4891       while (elmt)
4892         {
4893           EMACS_INT rdata = pdump_get_entry (elmt->obj)->save_offset;
4894           for (j=0; j<elmt->count; j++)
4895             {
4896               write (pdump_fd, &rdata, sizeof (rdata));
4897               rdata += elmt->size;
4898             }
4899           elmt = elmt->next;
4900         }
4901     }
4902   rt.desc = 0;
4903   rt.count = 0;
4904   write (pdump_fd, &rt, sizeof (rt));
4905 }
4906
4907 static void
4908 pdump_dump_wired (void)
4909 {
4910   EMACS_INT count = pdump_wireidx + pdump_wireidx_list;
4911   int i;
4912
4913   write (pdump_fd, &count, sizeof (count));
4914
4915   for (i=0; i<pdump_wireidx; i++)
4916     {
4917       EMACS_INT obj = pdump_get_entry (XRECORD_LHEADER (*(pdump_wirevec[i])))->save_offset;
4918       write (pdump_fd, &pdump_wirevec[i], sizeof (pdump_wirevec[i]));
4919       write (pdump_fd, &obj, sizeof (obj));
4920     }
4921
4922   for (i=0; i<pdump_wireidx_list; i++)
4923     {
4924       Lisp_Object obj = *(pdump_wirevec_list[i]);
4925       pdump_entry_list_elmt *elmt;
4926       EMACS_INT res;
4927
4928       for (;;)
4929         {
4930           const struct lrecord_description *desc;
4931           int pos;
4932           elmt = pdump_get_entry (XRECORD_LHEADER (obj));
4933           if (elmt)
4934             break;
4935           desc = XRECORD_LHEADER_IMPLEMENTATION (obj)->description;
4936           for (pos = 0; desc[pos].type != XD_LO_LINK; pos++)
4937             if (desc[pos].type == XD_END)
4938               abort ();
4939
4940           obj = *(Lisp_Object *)(desc[pos].offset + (char *)(XRECORD_LHEADER (obj)));
4941         }
4942       res = elmt->save_offset;
4943
4944       write (pdump_fd, &pdump_wirevec_list[i], sizeof (pdump_wirevec_list[i]));
4945       write (pdump_fd, &res, sizeof (res));
4946     }
4947 }
4948
4949 void
4950 pdump (void)
4951 {
4952   int i;
4953   Lisp_Object t_console, t_device, t_frame;
4954   int none;
4955   dump_header hd;
4956
4957   /* These appear in a DEFVAR_LISP, which does a staticpro() */
4958   t_console = Vterminal_console;
4959   t_frame   = Vterminal_frame;
4960   t_device  = Vterminal_device;
4961
4962   Vterminal_console = Qnil;
4963   Vterminal_frame   = Qnil;
4964   Vterminal_device  = Qnil;
4965
4966   pdump_hash = xnew_array_and_zero (pdump_entry_list_elmt *, PDUMP_HASHSIZE);
4967
4968   for (i=0; i<=last_lrecord_type_index_assigned; i++)
4969     {
4970       pdump_object_table[i].first = 0;
4971       pdump_object_table[i].align = 8;
4972       pdump_object_table[i].count = 0;
4973       pdump_alert_undump_object[i] = 0;
4974     }
4975   pdump_struct_table.count = 0;
4976   pdump_struct_table.size = -1;
4977
4978   pdump_opaque_data_list.first = 0;
4979   pdump_opaque_data_list.align = 8;
4980   pdump_opaque_data_list.count = 0;
4981   depth = 0;
4982
4983   for (i=0; i<staticidx; i++)
4984     pdump_register_object (*staticvec[i]);
4985   for (i=0; i<pdump_wireidx; i++)
4986     pdump_register_object (*pdump_wirevec[i]);
4987
4988   none = 1;
4989   for (i=0; i<=last_lrecord_type_index_assigned; i++)
4990     if (pdump_alert_undump_object[i])
4991       {
4992         if (none)
4993           printf ("Undumpable types list :\n");
4994         none = 0;
4995         printf ("  - %s (%d)\n", lrecord_implementations_table[i]->name, pdump_alert_undump_object[i]);
4996       }
4997   if (!none)
4998     return;
4999
5000   for (i=0; i<dumpstructidx; i++)
5001     pdump_register_struct (*(void **)(dumpstructvec[i].data), dumpstructvec[i].desc, 1);
5002
5003   memcpy (hd.signature, "XEmacsDP", 8);
5004   hd.reloc_address = 0;
5005   hd.nb_staticpro = staticidx;
5006   hd.nb_structdmp = dumpstructidx;
5007   hd.nb_opaquedmp = dumpopaqueidx;
5008   hd.last_type    = last_lrecord_type_index_assigned;
5009
5010   cur_offset = 256;
5011   max_size = 0;
5012
5013   pdump_scan_by_alignment (pdump_allocate_offset);
5014   pdump_qnil = pdump_get_entry (XRECORD_LHEADER (Qnil));
5015
5016   pdump_buf = xmalloc (max_size);
5017   /* Avoid use of the `open' macro.  We want the real function. */
5018 #undef open
5019   pdump_fd = open ("xemacs.dmp",
5020                    O_WRONLY | O_CREAT | O_TRUNC | OPEN_BINARY, 0666);
5021   hd.stab_offset = (cur_offset + 3) & ~3;
5022
5023   write (pdump_fd, &hd, sizeof (hd));
5024   lseek (pdump_fd, 256, SEEK_SET);
5025
5026   pdump_scan_by_alignment (pdump_dump_data);
5027
5028   lseek (pdump_fd, hd.stab_offset, SEEK_SET);
5029
5030   pdump_dump_staticvec ();
5031   pdump_dump_structvec ();
5032   pdump_dump_opaquevec ();
5033   pdump_dump_itable ();
5034   pdump_dump_rtables ();
5035   pdump_dump_wired ();
5036
5037   close (pdump_fd);
5038   free (pdump_buf);
5039
5040   free (pdump_hash);
5041
5042   Vterminal_console = t_console;
5043   Vterminal_frame   = t_frame;
5044   Vterminal_device  = t_device;
5045 }
5046
5047 int
5048 pdump_load (void)
5049 {
5050   size_t length;
5051   int i;
5052   char *p;
5053   EMACS_INT delta;
5054   EMACS_INT count;
5055
5056 #define PDUMP_READ(p, type) (p = (char*) (((type *) p) + 1), *((type *) p - 1))
5057
5058   pdump_start = pdump_end = 0;
5059
5060   pdump_fd = open ("xemacs.dmp", O_RDONLY | OPEN_BINARY);
5061   if (pdump_fd<0)
5062     return 0;
5063
5064   length = lseek (pdump_fd, 0, SEEK_END);
5065   lseek (pdump_fd, 0, SEEK_SET);
5066
5067 #ifdef HAVE_MMAP
5068   pdump_start = (char *) mmap (0, length, PROT_READ|PROT_WRITE, MAP_PRIVATE, pdump_fd, 0);
5069   if (pdump_start == MAP_FAILED)
5070     pdump_start = 0;
5071 #endif
5072
5073   if (!pdump_start)
5074     {
5075       pdump_start = (char *)((((unsigned long)(xmalloc(length+255))) + 255) & ~255);
5076       read (pdump_fd, pdump_start, length);
5077     }
5078
5079   close (pdump_fd);
5080
5081   pdump_end = pdump_start + length;
5082
5083   staticidx = ((dump_header *)(pdump_start))->nb_staticpro;
5084   last_lrecord_type_index_assigned = ((dump_header *)pdump_start)->last_type;
5085   delta = ((EMACS_INT)pdump_start) - ((dump_header *)pdump_start)->reloc_address;
5086   p = pdump_start + ((dump_header *)pdump_start)->stab_offset;
5087
5088   /* Put back the staticvec in place */
5089   memcpy (staticvec, p, staticidx*sizeof (Lisp_Object *));
5090   p += staticidx*sizeof (Lisp_Object *);
5091   for (i=0; i<staticidx; i++)
5092     {
5093       Lisp_Object obj = PDUMP_READ (p, Lisp_Object);
5094       if (POINTER_TYPE_P (XTYPE (obj)))
5095         XSETOBJ (obj, XTYPE (obj), (char *) XPNTR (obj) + delta);
5096       *staticvec[i] = obj;
5097     }
5098
5099   /* Put back the dumpstructs */
5100   for (i=0; i<((dump_header *)pdump_start)->nb_structdmp; i++)
5101     {
5102       void **adr = PDUMP_READ (p, void **);
5103       *adr = (void *) (PDUMP_READ (p, char *) + delta);
5104     }
5105
5106   /* Put back the opaques */
5107   for (i=0; i<((dump_header *)pdump_start)->nb_opaquedmp; i++)
5108     {
5109       struct dumpopaque_info di = PDUMP_READ (p, struct dumpopaque_info);
5110       memcpy (di.data, p, di.size);
5111       p += di.size;
5112     }
5113
5114   /* Put back the lrecord_implementations_table */
5115   memcpy (lrecord_implementations_table, p, sizeof (lrecord_implementations_table));
5116   p += sizeof (lrecord_implementations_table);
5117
5118   /* Reinitialize lrecord_markers from lrecord_implementations_table */
5119   for (i=0; i < countof (lrecord_implementations_table); i++)
5120     if (lrecord_implementations_table[i])
5121       lrecord_markers[i] = lrecord_implementations_table[i]->marker;
5122
5123   /* Do the relocations */
5124   pdump_rt_list = p;
5125   count = 2;
5126   for (;;)
5127     {
5128       pdump_reloc_table rt = PDUMP_READ (p, pdump_reloc_table);
5129       if (rt.desc)
5130         {
5131           for (i=0; i < rt.count; i++)
5132             {
5133               char *adr = delta + *(char **)p;
5134               *(char **)p = adr;
5135               pdump_reloc_one (adr, delta, rt.desc);
5136               p += sizeof (char *);
5137             }
5138         } else
5139           if (!(--count))
5140             break;
5141     }
5142
5143   /* Put the pdump_wire variables in place */
5144   count = PDUMP_READ (p, EMACS_INT);
5145
5146   for (i=0; i<count; i++)
5147     {
5148       Lisp_Object *var = PDUMP_READ (p, Lisp_Object *);
5149       Lisp_Object  obj = PDUMP_READ (p, Lisp_Object);
5150
5151       if (POINTER_TYPE_P (XTYPE (obj)))
5152         XSETOBJ (obj, XTYPE (obj), (char *) XPNTR (obj) + delta);
5153
5154       *var = obj;
5155     }
5156
5157   /* Final cleanups */
5158   /*   reorganize hash tables */
5159   p = pdump_rt_list;
5160   for (;;)
5161     {
5162       pdump_reloc_table rt = PDUMP_READ (p, pdump_reloc_table);
5163       if (!rt.desc)
5164         break;
5165       if (rt.desc == hash_table_description)
5166         {
5167           for (i=0; i < rt.count; i++)
5168             pdump_reorganize_hash_table (PDUMP_READ (p, Lisp_Object));
5169           break;
5170         } else
5171           p += sizeof (Lisp_Object) * rt.count;
5172     }
5173
5174   /* Put back noninteractive1 to its real value */
5175   noninteractive1 = noninteractive;
5176
5177   return 1;
5178 }
5179
5180 #endif /* PDUMP */
5181