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