Merge remote-tracking branch 'origin/master' into for-steve
[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
1231 #ifdef HAVE_FPFLOAT
1232 #include <math.h>
1233
1234 DECLARE_FIXED_TYPE_ALLOC(float, Lisp_Float);
1235 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_float 1000
1236
1237 Lisp_Object make_float(fpfloat float_value)
1238 {
1239         Lisp_Object val;
1240         Lisp_Float *f;
1241
1242         if (ENT_FLOAT_PINF_P(float_value))
1243                 return make_indef(POS_INFINITY);
1244         else if (ENT_FLOAT_NINF_P(float_value))
1245                 return make_indef(NEG_INFINITY);
1246         else if (ENT_FLOAT_NAN_P(float_value))
1247                 return make_indef(NOT_A_NUMBER);
1248
1249         ALLOCATE_FIXED_TYPE(float, Lisp_Float, f);
1250
1251         /* Avoid dump-time `uninitialized memory read' purify warnings. */
1252         if (sizeof(struct lrecord_header) +
1253             sizeof(fpfloat) != sizeof(*f))
1254                 xzero(*f);
1255
1256         set_lheader_implementation(&f->lheader, &lrecord_float);
1257         float_data(f) = float_value;
1258         XSETFLOAT(val, f);
1259         return val;
1260 }
1261
1262 #endif  /* HAVE_FPFLOAT */
1263 \f
1264 /************************************************************************/
1265 /*                      Enhanced number allocation                      */
1266 /************************************************************************/
1267
1268 /*** Bignum ***/
1269 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
1270 DECLARE_FIXED_TYPE_ALLOC(bigz, Lisp_Bigz);
1271 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_bigz 250
1272
1273 #if defined HAVE_BDWGC && defined EF_USE_BDWGC && 0
1274 static void
1275 bigz_register_finaliser(Lisp_Bigz *b)
1276 {
1277         GC_finalization_proc *foo = NULL;
1278         void **bar = NULL;
1279         auto void bigz_finaliser();
1280
1281         auto void bigz_finaliser(void *obj, void *SXE_UNUSED(data))
1282         {
1283                 bigz_fini(bigz_data((Lisp_Bigz*)obj));
1284                 /* cleanse */
1285                 memset(obj, 0, sizeof(Lisp_Bigz));
1286                 return;
1287         }
1288
1289         GC_REGISTER_FINALIZER(b, bigz_finaliser, NULL, foo, bar);
1290         return;
1291 }
1292 #else  /* !BDWGC */
1293 static inline void
1294 bigz_register_finaliser(Lisp_Bigz *SXE_UNUSED(b))
1295 {
1296         return;
1297 }
1298 #endif  /* HAVE_BDWGC */
1299
1300 /* WARNING: This function returns a bignum even if its argument fits into a
1301    fixnum.  See Fcanonicalize_number(). */
1302 Lisp_Object
1303 make_bigz (long bigz_value)
1304 {
1305         Lisp_Bigz *b;
1306
1307         ALLOCATE_FIXED_TYPE(bigz, Lisp_Bigz, b);
1308         bigz_register_finaliser(b);
1309
1310         set_lheader_implementation(&b->lheader, &lrecord_bigz);
1311         bigz_init(bigz_data(b));
1312         bigz_set_long(bigz_data(b), bigz_value);
1313         return wrap_bigz(b);
1314 }
1315
1316 /* WARNING: This function returns a bigz even if its argument fits into a
1317    fixnum.  See Fcanonicalize_number(). */
1318 Lisp_Object
1319 make_bigz_bz (bigz bz)
1320 {
1321         Lisp_Bigz *b;
1322
1323         ALLOCATE_FIXED_TYPE(bigz, Lisp_Bigz, b);
1324         bigz_register_finaliser(b);
1325
1326         set_lheader_implementation(&b->lheader, &lrecord_bigz);
1327         bigz_init(bigz_data(b));
1328         bigz_set(bigz_data(b), bz);
1329         return wrap_bigz(b);
1330 }
1331 #endif /* HAVE_MPZ */
1332
1333 /*** Ratio ***/
1334 #if defined HAVE_MPQ && defined WITH_GMP
1335 DECLARE_FIXED_TYPE_ALLOC(bigq, Lisp_Bigq);
1336 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_bigq 250
1337
1338 #if defined HAVE_BDWGC && defined EF_USE_BDWGC && 0
1339 static void
1340 bigq_register_finaliser(Lisp_Bigq *b)
1341 {
1342         GC_finalization_proc *foo = NULL;
1343         void **bar = NULL;
1344         auto void bigq_finaliser();
1345
1346         auto void bigq_finaliser(void *obj, void *SXE_UNUSED(data))
1347         {
1348                 bigq_fini(bigq_data((Lisp_Bigq*)obj));
1349                 /* cleanse */
1350                 memset(obj, 0, sizeof(Lisp_Bigq));
1351                 return;
1352         }
1353
1354         GC_REGISTER_FINALIZER(b, bigq_finaliser, NULL, foo, bar);
1355         return;
1356 }
1357 #else  /* !BDWGC */
1358 static inline void
1359 bigq_register_finaliser(Lisp_Bigq *SXE_UNUSED(b))
1360 {
1361         return;
1362 }
1363 #endif  /* HAVE_BDWGC */
1364
1365 Lisp_Object
1366 make_bigq(long numerator, unsigned long denominator)
1367 {
1368         Lisp_Bigq *r;
1369
1370         ALLOCATE_FIXED_TYPE(bigq, Lisp_Bigq, r);
1371         bigq_register_finaliser(r);
1372
1373         set_lheader_implementation(&r->lheader, &lrecord_bigq);
1374         bigq_init(bigq_data(r));
1375         bigq_set_long_ulong(bigq_data(r), numerator, denominator);
1376         bigq_canonicalize(bigq_data(r));
1377         return wrap_bigq(r);
1378 }
1379
1380 Lisp_Object
1381 make_bigq_bz(bigz numerator, bigz denominator)
1382 {
1383         Lisp_Bigq *r;
1384
1385         ALLOCATE_FIXED_TYPE(bigq, Lisp_Bigq, r);
1386         bigq_register_finaliser(r);
1387
1388         set_lheader_implementation(&r->lheader, &lrecord_bigq);
1389         bigq_init(bigq_data(r));
1390         bigq_set_bigz_bigz(bigq_data(r), numerator, denominator);
1391         bigq_canonicalize(bigq_data(r));
1392         return wrap_bigq(r);
1393 }
1394
1395 Lisp_Object
1396 make_bigq_bq(bigq rat)
1397 {
1398         Lisp_Bigq *r;
1399
1400         ALLOCATE_FIXED_TYPE(bigq, Lisp_Bigq, r);
1401         bigq_register_finaliser(r);
1402
1403         set_lheader_implementation(&r->lheader, &lrecord_bigq);
1404         bigq_init(bigq_data(r));
1405         bigq_set(bigq_data(r), rat);
1406         return wrap_bigq(r);
1407 }
1408 #endif  /* HAVE_MPQ */
1409
1410 /*** Bigfloat ***/
1411 #if defined HAVE_MPF && defined WITH_GMP
1412 DECLARE_FIXED_TYPE_ALLOC(bigf, Lisp_Bigf);
1413 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_bigf 250
1414
1415 #if defined HAVE_BDWGC && defined EF_USE_BDWGC && 0
1416 static void
1417 bigf_register_finaliser(Lisp_Bigf *b)
1418 {
1419         GC_finalization_proc *foo = NULL;
1420         void **bar = NULL;
1421         auto void bigf_finaliser();
1422
1423         auto void bigf_finaliser(void *obj, void *SXE_UNUSED(data))
1424         {
1425                 bigf_fini(bigf_data((Lisp_Bigf*)obj));
1426                 /* cleanse */
1427                 memset(obj, 0, sizeof(Lisp_Bigf));
1428                 return;
1429         }
1430
1431         GC_REGISTER_FINALIZER(b, bigf_finaliser, NULL, foo, bar);
1432         return;
1433 }
1434 #else  /* !BDWGC */
1435 static inline void
1436 bigf_register_finaliser(Lisp_Bigf *SXE_UNUSED(b))
1437 {
1438         return;
1439 }
1440 #endif  /* HAVE_BDWGC */
1441
1442 /* This function creates a bigfloat with the default precision if the
1443    PRECISION argument is zero. */
1444 Lisp_Object
1445 make_bigf(fpfloat float_value, unsigned long precision)
1446 {
1447         Lisp_Bigf *f;
1448
1449         ALLOCATE_FIXED_TYPE(bigf, Lisp_Bigf, f);
1450         bigf_register_finaliser(f);
1451
1452         set_lheader_implementation(&f->lheader, &lrecord_bigf);
1453         if (precision == 0UL)
1454                 bigf_init(bigf_data(f));
1455         else
1456                 bigf_init_prec(bigf_data(f), precision);
1457         bigf_set_fpfloat(bigf_data(f), float_value);
1458         return wrap_bigf(f);
1459 }
1460
1461 /* This function creates a bigfloat with the precision of its argument */
1462 Lisp_Object
1463 make_bigf_bf(bigf float_value)
1464 {
1465         Lisp_Bigf *f;
1466
1467         ALLOCATE_FIXED_TYPE(bigf, Lisp_Bigf, f);
1468         bigf_register_finaliser(f);
1469
1470         set_lheader_implementation(&f->lheader, &lrecord_bigf);
1471         bigf_init_prec(bigf_data(f), bigf_get_prec(float_value));
1472         bigf_set(bigf_data(f), float_value);
1473         return wrap_bigf(f);
1474 }
1475 #endif /* HAVE_MPF */
1476
1477 /*** Bigfloat with correct rounding ***/
1478 #if defined HAVE_MPFR && defined WITH_MPFR
1479 DECLARE_FIXED_TYPE_ALLOC(bigfr, Lisp_Bigfr);
1480 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_bigfr 250
1481
1482 #if defined HAVE_BDWGC && defined EF_USE_BDWGC && 0
1483 static void
1484 bigfr_register_finaliser(Lisp_Bigfr *b)
1485 {
1486         GC_finalization_proc *foo = NULL;
1487         void **bar = NULL;
1488         auto void bigfr_finaliser();
1489
1490         auto void bigfr_finaliser(void *obj, void *SXE_UNUSED(data))
1491         {
1492                 bigfr_fini(bigfr_data((Lisp_Bigfr*)obj));
1493                 /* cleanse */
1494                 memset(obj, 0, sizeof(Lisp_Bigfr));
1495                 return;
1496         }
1497
1498         GC_REGISTER_FINALIZER(b, bigfr_finaliser, NULL, foo, bar);
1499         return;
1500 }
1501 #else  /* !BDWGC */
1502 static inline void
1503 bigfr_register_finaliser(Lisp_Bigfr *SXE_UNUSED(b))
1504 {
1505         return;
1506 }
1507 #endif  /* HAVE_BDWGC */
1508
1509 /* This function creates a bigfloat with the default precision if the
1510    PRECISION argument is zero. */
1511 Lisp_Object
1512 make_bigfr(fpfloat float_value, unsigned long precision)
1513 {
1514         Lisp_Bigfr *f;
1515
1516         ALLOCATE_FIXED_TYPE(bigfr, Lisp_Bigfr, f);
1517         set_lheader_implementation(&f->lheader, &lrecord_bigfr);
1518         bigfr_register_finaliser(f);
1519
1520         if (precision == 0UL) {
1521                 bigfr_init(bigfr_data(f));
1522         } else {
1523                 bigfr_init_prec(bigfr_data(f), precision);
1524         }
1525         bigfr_set_fpfloat(bigfr_data(f), float_value);
1526         return wrap_bigfr(f);
1527 }
1528
1529 /* This function creates a bigfloat with the precision of its argument */
1530 Lisp_Object
1531 make_bigfr_bf(bigf float_value)
1532 {
1533         Lisp_Bigfr *f;
1534
1535         ALLOCATE_FIXED_TYPE(bigfr, Lisp_Bigfr, f);
1536         set_lheader_implementation(&f->lheader, &lrecord_bigfr);
1537         bigfr_register_finaliser(f);
1538
1539         bigfr_init_prec(bigfr_data(f), bigf_get_prec(float_value));
1540         bigfr_set_bigf(bigfr_data(f), float_value);
1541         return wrap_bigfr(f);
1542 }
1543
1544 /* This function creates a bigfloat with the precision of its argument */
1545 Lisp_Object
1546 make_bigfr_bfr(bigfr bfr_value)
1547 {
1548         Lisp_Bigfr *f;
1549
1550         if (bigfr_nan_p(bfr_value) || bigfr_inf_p(bfr_value)) {
1551                 return make_indef_bfr(bfr_value);
1552         }
1553
1554         ALLOCATE_FIXED_TYPE(bigfr, Lisp_Bigfr, f);
1555         set_lheader_implementation(&f->lheader, &lrecord_bigfr);
1556         bigfr_register_finaliser(f);
1557
1558         bigfr_init_prec(bigfr_data(f), bigfr_get_prec(bfr_value));
1559         bigfr_set(bigfr_data(f), bfr_value);
1560         return wrap_bigfr(f);
1561 }
1562 #endif /* HAVE_MPFR */
1563
1564 /*** Big gaussian numbers ***/
1565 #if defined HAVE_PSEUG && defined HAVE_MPZ && defined WITH_PSEUG
1566 DECLARE_FIXED_TYPE_ALLOC(bigg, Lisp_Bigg);
1567 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_bigg 250
1568
1569 #if defined HAVE_BDWGC && defined EF_USE_BDWGC && 0
1570 static void
1571 bigg_register_finaliser(Lisp_Bigg *b)
1572 {
1573         GC_finalization_proc *foo = NULL;
1574         void **bar = NULL;
1575         auto void bigg_finaliser();
1576
1577         auto void bigg_finaliser(void *obj, void *SXE_UNUSED(data))
1578         {
1579                 bigg_fini(bigg_data((Lisp_Bigg*)obj));
1580                 /* cleanse */
1581                 memset(obj, 0, sizeof(Lisp_Bigg));
1582                 return;
1583         }
1584
1585         GC_REGISTER_FINALIZER(b, bigg_finaliser, NULL, foo, bar);
1586         return;
1587 }
1588 #else  /* !BDWGC */
1589 static inline void
1590 bigg_register_finaliser(Lisp_Bigg *SXE_UNUSED(b))
1591 {
1592         return;
1593 }
1594 #endif  /* HAVE_BDWGC */
1595
1596 /* This function creates a gaussian number. */
1597 Lisp_Object
1598 make_bigg(long intg, long imag)
1599 {
1600         Lisp_Bigg *g;
1601
1602         ALLOCATE_FIXED_TYPE(bigg, Lisp_Bigg, g);
1603         set_lheader_implementation(&g->lheader, &lrecord_bigg);
1604         bigg_register_finaliser(g);
1605
1606         bigg_init(bigg_data(g));
1607         bigg_set_long_long(bigg_data(g), intg, imag);
1608         return wrap_bigg(g);
1609 }
1610
1611 /* This function creates a complex with the precision of its argument */
1612 Lisp_Object
1613 make_bigg_bz(bigz intg, bigz imag)
1614 {
1615         Lisp_Bigg *g;
1616
1617         ALLOCATE_FIXED_TYPE(bigg, Lisp_Bigg, g);
1618         set_lheader_implementation(&g->lheader, &lrecord_bigg);
1619         bigg_register_finaliser(g);
1620
1621         bigg_init(bigg_data(g));
1622         bigg_set_bigz_bigz(bigg_data(g), intg, imag);
1623         return wrap_bigg(g);
1624 }
1625
1626 /* This function creates a complex with the precision of its argument */
1627 Lisp_Object
1628 make_bigg_bg(bigg gaussian_value)
1629 {
1630         Lisp_Bigg *g;
1631
1632         ALLOCATE_FIXED_TYPE(bigg, Lisp_Bigg, g);
1633         set_lheader_implementation(&g->lheader, &lrecord_bigg);
1634         bigg_register_finaliser(g);
1635
1636         bigg_init(bigg_data(g));
1637         bigg_set(bigg_data(g), gaussian_value);
1638         return wrap_bigg(g);
1639 }
1640 #endif /* HAVE_PSEUG */
1641
1642 /*** Big complex numbers with correct rounding ***/
1643 #if defined HAVE_MPC && defined WITH_MPC || \
1644         defined HAVE_PSEUC && defined WITH_PSEUC
1645 DECLARE_FIXED_TYPE_ALLOC(bigc, Lisp_Bigc);
1646 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_bigc 250
1647
1648 #if defined HAVE_BDWGC && defined EF_USE_BDWGC && 0
1649 static void
1650 bigc_register_finaliser(Lisp_Bigc *b)
1651 {
1652         GC_finalization_proc *foo = NULL;
1653         void **bar = NULL;
1654         auto void bigc_finaliser();
1655
1656         auto void bigc_finaliser(void *obj, void *SXE_UNUSED(data))
1657         {
1658                 bigc_fini(bigc_data((Lisp_Bigc*)obj));
1659                 /* cleanse */
1660                 memset(obj, 0, sizeof(Lisp_Bigc));
1661                 return;
1662         }
1663
1664         GC_REGISTER_FINALIZER(b, bigc_finaliser, NULL, foo, bar);
1665         return;
1666 }
1667 #else  /* !BDWGC */
1668 static inline void
1669 bigc_register_finaliser(Lisp_Bigc *SXE_UNUSED(b))
1670 {
1671         return;
1672 }
1673 #endif  /* HAVE_BDWGC */
1674
1675 /* This function creates a bigfloat with the default precision if the
1676    PRECISION argument is zero. */
1677 Lisp_Object
1678 make_bigc(fpfloat re_value, fpfloat im_value, unsigned long precision)
1679 {
1680         Lisp_Bigc *c;
1681
1682         ALLOCATE_FIXED_TYPE(bigc, Lisp_Bigc, c);
1683         set_lheader_implementation(&c->lheader, &lrecord_bigc);
1684         bigc_register_finaliser(c);
1685
1686         if (precision == 0UL) {
1687                 bigc_init(bigc_data(c));
1688         } else {
1689                 bigc_init_prec(bigc_data(c), precision);
1690         }
1691         bigc_set_fpfloat_fpfloat(bigc_data(c), re_value, im_value);
1692         return wrap_bigc(c);
1693 }
1694
1695 /* This function creates a complex with the precision of its argument */
1696 Lisp_Object
1697 make_bigc_bfr(bigfr re_value, bigfr im_value, unsigned long precision)
1698 {
1699         Lisp_Bigc *c;
1700
1701         ALLOCATE_FIXED_TYPE(bigc, Lisp_Bigc, c);
1702         set_lheader_implementation(&c->lheader, &lrecord_bigc);
1703         bigc_register_finaliser(c);
1704
1705         if (precision == 0UL) {
1706                 bigc_init(bigc_data(c));
1707         } else {
1708                 bigc_init_prec(bigc_data(c), precision);
1709         }
1710         bigc_set_bigfr_bigfr(bigc_data(c), re_value, im_value);
1711         return wrap_bigc(c);
1712 }
1713
1714 /* This function creates a complex with the precision of its argument */
1715 Lisp_Object
1716 make_bigc_bc(bigc complex_value)
1717 {
1718         Lisp_Bigc *c;
1719
1720         ALLOCATE_FIXED_TYPE(bigc, Lisp_Bigc, c);
1721         set_lheader_implementation(&c->lheader, &lrecord_bigc);
1722         bigc_register_finaliser(c);
1723
1724         bigc_init_prec(bigc_data(c), bigc_get_prec(complex_value));
1725         bigc_set(bigc_data(c), complex_value);
1726         return wrap_bigc(c);
1727 }
1728 #endif /* HAVE_MPC */
1729
1730 /*** Quaternions ***/
1731 #if defined HAVE_QUATERN && defined HAVE_MPZ && defined WITH_QUATERN
1732 DECLARE_FIXED_TYPE_ALLOC(quatern, Lisp_Quatern);
1733 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_quatern 250
1734
1735 #if defined HAVE_BDWGC && defined EF_USE_BDWGC && 0
1736 static void
1737 quatern_register_finaliser(Lisp_Quatern *b)
1738 {
1739         GC_finalization_proc *foo = NULL;
1740         void **bar = NULL;
1741         auto void quatern_finaliser();
1742
1743         auto void quatern_finaliser(void *obj, void *SXE_UNUSED(data))
1744         {
1745                 quatern_fini(quatern_data((Lisp_Quatern*)obj));
1746                 /* cleanse */
1747                 memset(obj, 0, sizeof(Lisp_Quatern));
1748                 return;
1749         }
1750
1751         GC_REGISTER_FINALIZER(b, quatern_finaliser, NULL, foo, bar);
1752         return;
1753 }
1754 #else  /* !BDWGC */
1755 static inline void
1756 quatern_register_finaliser(Lisp_Quatern *SXE_UNUSED(b))
1757 {
1758         return;
1759 }
1760 #endif  /* HAVE_BDWGC */
1761
1762 /* This function creates a quaternion. */
1763 Lisp_Object
1764 make_quatern(EMACS_INT z, EMACS_INT i, EMACS_INT j, EMACS_INT k)
1765 {
1766         Lisp_Quatern *g;
1767
1768         ALLOCATE_FIXED_TYPE(quatern, Lisp_Quatern, g);
1769         set_lheader_implementation(&g->lheader, &lrecord_quatern);
1770         quatern_register_finaliser(g);
1771
1772         quatern_init(quatern_data(g));
1773         quatern_set_long_long_long_long(quatern_data(g), z, i, j, k);
1774         return wrap_quatern(g);
1775 }
1776
1777 Lisp_Object
1778 make_quatern_bz(bigz z, bigz i, bigz j, bigz k)
1779 {
1780         Lisp_Quatern *g;
1781
1782         ALLOCATE_FIXED_TYPE(quatern, Lisp_Quatern, g);
1783         set_lheader_implementation(&g->lheader, &lrecord_quatern);
1784         quatern_register_finaliser(g);
1785
1786         quatern_init(quatern_data(g));
1787         quatern_set_bigz_bigz_bigz_bigz(quatern_data(g), z, i, j, k);
1788         return wrap_quatern(g);
1789 }
1790
1791 Lisp_Object
1792 make_quatern_qu(quatern quaternion)
1793 {
1794         Lisp_Quatern *g;
1795
1796         ALLOCATE_FIXED_TYPE(quatern, Lisp_Quatern, g);
1797         set_lheader_implementation(&g->lheader, &lrecord_quatern);
1798         quatern_register_finaliser(g);
1799
1800         quatern_init(quatern_data(g));
1801         quatern_set(quatern_data(g), quaternion);
1802         return wrap_quatern(g);
1803 }
1804 #endif /* HAVE_QUATERN */
1805
1806 Lisp_Object
1807 make_indef_internal(indef sym)
1808 {
1809         Lisp_Indef *i;
1810
1811         i = allocate_lisp_storage(sizeof(Lisp_Indef));
1812         set_lheader_implementation(&i->lheader, &lrecord_indef);
1813         indef_data(i) = sym;
1814         return wrap_indef(i);
1815 }
1816
1817 Lisp_Object
1818 make_indef(indef sym)
1819 {
1820         switch (sym) {
1821         case NEG_INFINITY:
1822                 return Vninfinity;
1823         case POS_INFINITY:
1824                 return Vpinfinity;
1825         case COMPLEX_INFINITY:
1826                 return Vcomplex_infinity;
1827         case NOT_A_NUMBER:
1828         default:
1829                 /* list some more here */
1830         case END_OF_COMPARABLE_INFINITIES:
1831         case END_OF_INFINITIES:
1832         case NUMBER_INDEFS:
1833                 return Vnot_a_number;
1834         }
1835 }
1836
1837 #if defined HAVE_MPFR && defined WITH_MPFR
1838 Lisp_Object
1839 make_indef_bfr(bigfr bfr_value)
1840 {
1841         if (bigfr_nan_p(bfr_value)) {
1842                 return make_indef(NOT_A_NUMBER);
1843         } else if (bigfr_inf_p(bfr_value)) {
1844                 if (bigfr_sign(bfr_value) > 0)
1845                         return make_indef(POS_INFINITY);
1846                 else
1847                         return make_indef(NEG_INFINITY);
1848         } else {
1849                 return make_indef(NOT_A_NUMBER);
1850         }
1851 }
1852 #endif
1853
1854 DECLARE_FIXED_TYPE_ALLOC(dynacat, struct dynacat_s);
1855 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_dynacat 1000
1856
1857 #if defined HAVE_BDWGC && defined EF_USE_BDWGC
1858 static void
1859 dynacat_register_finaliser(dynacat_t b)
1860 {
1861         GC_finalization_proc *foo = NULL;
1862         void **bar = NULL;
1863         auto void dynacat_finaliser();
1864
1865         auto void dynacat_finaliser(void *obj, void *SXE_UNUSED(data))
1866         {
1867                 SXE_DEBUG_GC("calling dynacat finaliser on %p\n", obj);
1868                 dynacat_fini(obj);
1869                 /* cleanse */
1870                 memset(obj, 0, sizeof(struct dynacat_s));
1871                 return;
1872         }
1873
1874         SXE_DEBUG_GC("dynacat-fina %p\n", b);
1875         GC_REGISTER_FINALIZER(b, dynacat_finaliser, NULL, foo, bar);
1876         return;
1877 }
1878 #else  /* !BDWGC */
1879 static inline void
1880 dynacat_register_finaliser(dynacat_t SXE_UNUSED(b))
1881 {
1882         return;
1883 }
1884 #endif  /* HAVE_BDWGC */
1885
1886 Lisp_Object
1887 make_dynacat(void *ptr)
1888 {
1889         dynacat_t emp;
1890
1891         ALLOCATE_FIXED_TYPE(dynacat, struct dynacat_s, emp);
1892         dynacat_register_finaliser(emp);
1893         set_lheader_implementation(&emp->lheader, &lrecord_dynacat);
1894
1895         emp->prfun = NULL;
1896         emp->intprfun = NULL;
1897         emp->finfun = NULL;
1898         emp->mrkfun = NULL;
1899         emp->ptr = ptr;
1900         emp->type = Qnil;
1901         emp->plist = Qnil;
1902
1903         return wrap_object(emp);
1904 }
1905
1906 \f
1907 /************************************************************************/
1908 /*                         Vector allocation                            */
1909 /************************************************************************/
1910
1911 static Lisp_Object mark_vector(Lisp_Object obj)
1912 {
1913         Lisp_Vector *ptr = XVECTOR(obj);
1914         int len = vector_length(ptr);
1915         int i;
1916
1917         for (i = 0; i < len - 1; i++)
1918                 mark_object(ptr->contents[i]);
1919         return (len > 0) ? ptr->contents[len - 1] : Qnil;
1920 }
1921
1922 static size_t size_vector(const void *lheader)
1923 {
1924         return FLEXIBLE_ARRAY_STRUCT_SIZEOF(
1925                 Lisp_Vector, Lisp_Object, contents,
1926                 ((const Lisp_Vector*)lheader)->size);
1927 }
1928
1929 static int vector_equal(Lisp_Object obj1, Lisp_Object obj2, int depth)
1930 {
1931         int len = XVECTOR_LENGTH(obj1);
1932         if (len != XVECTOR_LENGTH(obj2))
1933                 return 0;
1934
1935         {
1936                 Lisp_Object *ptr1 = XVECTOR_DATA(obj1);
1937                 Lisp_Object *ptr2 = XVECTOR_DATA(obj2);
1938                 while (len--)
1939                         if (!internal_equal(*ptr1++, *ptr2++, depth + 1))
1940                                 return 0;
1941         }
1942         return 1;
1943 }
1944
1945 static hcode_t vector_hash(Lisp_Object obj, int depth)
1946 {
1947         return HASH2(XVECTOR_LENGTH(obj),
1948                      internal_array_hash(XVECTOR_DATA(obj),
1949                                          XVECTOR_LENGTH(obj), depth + 1));
1950 }
1951
1952 /* the seq approach for conses */
1953 static size_t
1954 vec_length(const seq_t v)
1955 {
1956         return XVECTOR_LENGTH((Lisp_Object)(long int)v);
1957 }
1958
1959 static void
1960 vec_iter_init(seq_t v, seq_iter_t si)
1961 {
1962         si->seq = v;
1963         si->data = (void*)0;
1964         return;
1965 }
1966
1967 static void
1968 vec_iter_next(seq_iter_t si, void **elt)
1969 {
1970         if (si->seq != NULL &&
1971             (long int)si->data < ((Lisp_Vector*)si->seq)->size) {
1972                 *elt = (void*)vector_data((Lisp_Vector*)si->seq)
1973                         [(long int)si->data];
1974                 si->data = (void*)((long int)si->data + 1L);
1975         } else {
1976                 *elt = NULL;
1977         }
1978         return;
1979 }
1980
1981 static void
1982 vec_iter_fini(seq_iter_t si)
1983 {
1984         si->data = si->seq = NULL;
1985         return;
1986 }
1987
1988 static void
1989 vec_iter_reset(seq_iter_t si)
1990 {
1991         si->data = (void*)0;
1992         return;
1993 }
1994
1995 static size_t
1996 vec_explode(void *restrict tgt[], size_t ntgt, const seq_t s)
1997 {
1998         size_t len = vector_length((const Lisp_Vector*)s);
1999         volatile size_t i = 0;
2000
2001         while (i < len && i < ntgt) {
2002                 tgt[i] = (void*)vector_data((const Lisp_Vector*)s)[i];
2003                 i++;
2004         }
2005         return i;
2006 }
2007
2008 static struct seq_impl_s __svec = {
2009         .length_f = vec_length,
2010         .iter_init_f = vec_iter_init,
2011         .iter_next_f = vec_iter_next,
2012         .iter_fini_f = vec_iter_fini,
2013         .iter_reset_f = vec_iter_reset,
2014         .explode_f = vec_explode,
2015 };
2016
2017 static const struct lrecord_description vector_description[] = {
2018         {XD_LONG, offsetof(Lisp_Vector, size)},
2019         {XD_LISP_OBJECT_ARRAY, offsetof(Lisp_Vector, contents),
2020          XD_INDIRECT(0, 0)},
2021         {XD_END}
2022 };
2023
2024 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION("vector", vector,
2025                                        mark_vector, print_vector, 0,
2026                                        vector_equal,
2027                                        vector_hash,
2028                                        vector_description,
2029                                        size_vector, Lisp_Vector);
2030
2031 /* #### should allocate `small' vectors from a frob-block */
2032 static Lisp_Vector *make_vector_internal(size_t sizei)
2033 {
2034         /* no vector_next */
2035         size_t sizem = FLEXIBLE_ARRAY_STRUCT_SIZEOF(Lisp_Vector, Lisp_Object,
2036                                                     contents, sizei);
2037         Lisp_Vector *p = (Lisp_Vector *) alloc_lcrecord(sizem, &lrecord_vector);
2038
2039         p->size = sizei;
2040         p->header.lheader.morphisms = (1<<cat_mk_lc);
2041         return p;
2042 }
2043
2044 Lisp_Object make_vector(size_t length, Lisp_Object object)
2045 {
2046         Lisp_Vector *vecp = make_vector_internal(length);
2047         Lisp_Object *p = vector_data(vecp);
2048
2049         while (length--)
2050                 *p++ = object;
2051
2052         {
2053                 Lisp_Object vector;
2054                 XSETVECTOR(vector, vecp);
2055                 return vector;
2056         }
2057 }
2058
2059 DEFUN("make-vector", Fmake_vector, 2, 2, 0,     /*
2060 Return a new vector of length LENGTH, with each element being OBJECT.
2061 See also the function `vector'.
2062 */
2063       (length, object))
2064 {
2065         CONCHECK_NATNUM(length);
2066         return make_vector(XINT(length), object);
2067 }
2068
2069 DEFUN("vector", Fvector, 0, MANY, 0,    /*
2070 Return a newly created vector with specified arguments as elements.
2071 Any number of arguments, even zero arguments, are allowed.
2072 */
2073       (int nargs, Lisp_Object * args))
2074 {
2075         Lisp_Vector *vecp = make_vector_internal(nargs);
2076         Lisp_Object *p = vector_data(vecp);
2077
2078         while (nargs--)
2079                 *p++ = *args++;
2080
2081         {
2082                 Lisp_Object vector;
2083                 XSETVECTOR(vector, vecp);
2084                 return vector;
2085         }
2086 }
2087
2088 Lisp_Object vector1(Lisp_Object obj0)
2089 {
2090         return Fvector(1, &obj0);
2091 }
2092
2093 Lisp_Object vector2(Lisp_Object obj0, Lisp_Object obj1)
2094 {
2095         Lisp_Object args[2];
2096         args[0] = obj0;
2097         args[1] = obj1;
2098         return Fvector(2, args);
2099 }
2100
2101 Lisp_Object vector3(Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2)
2102 {
2103         Lisp_Object args[3];
2104         args[0] = obj0;
2105         args[1] = obj1;
2106         args[2] = obj2;
2107         return Fvector(3, args);
2108 }
2109
2110 #if 0                           /* currently unused */
2111
2112 Lisp_Object
2113 vector4(Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2, Lisp_Object obj3)
2114 {
2115         Lisp_Object args[4];
2116         args[0] = obj0;
2117         args[1] = obj1;
2118         args[2] = obj2;
2119         args[3] = obj3;
2120         return Fvector(4, args);
2121 }
2122
2123 Lisp_Object
2124 vector5(Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2,
2125         Lisp_Object obj3, Lisp_Object obj4)
2126 {
2127         Lisp_Object args[5];
2128         args[0] = obj0;
2129         args[1] = obj1;
2130         args[2] = obj2;
2131         args[3] = obj3;
2132         args[4] = obj4;
2133         return Fvector(5, args);
2134 }
2135
2136 Lisp_Object
2137 vector6(Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2,
2138         Lisp_Object obj3, Lisp_Object obj4, Lisp_Object obj5)
2139 {
2140         Lisp_Object args[6];
2141         args[0] = obj0;
2142         args[1] = obj1;
2143         args[2] = obj2;
2144         args[3] = obj3;
2145         args[4] = obj4;
2146         args[5] = obj5;
2147         return Fvector(6, args);
2148 }
2149
2150 Lisp_Object
2151 vector7(Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2,
2152         Lisp_Object obj3, Lisp_Object obj4, Lisp_Object obj5, Lisp_Object obj6)
2153 {
2154         Lisp_Object args[7];
2155         args[0] = obj0;
2156         args[1] = obj1;
2157         args[2] = obj2;
2158         args[3] = obj3;
2159         args[4] = obj4;
2160         args[5] = obj5;
2161         args[6] = obj6;
2162         return Fvector(7, args);
2163 }
2164
2165 Lisp_Object
2166 vector8(Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2,
2167         Lisp_Object obj3, Lisp_Object obj4, Lisp_Object obj5,
2168         Lisp_Object obj6, Lisp_Object obj7)
2169 {
2170         Lisp_Object args[8];
2171         args[0] = obj0;
2172         args[1] = obj1;
2173         args[2] = obj2;
2174         args[3] = obj3;
2175         args[4] = obj4;
2176         args[5] = obj5;
2177         args[6] = obj6;
2178         args[7] = obj7;
2179         return Fvector(8, args);
2180 }
2181 #endif                          /* unused */
2182
2183 /************************************************************************/
2184 /*                       Bit Vector allocation                          */
2185 /************************************************************************/
2186
2187 static Lisp_Object all_bit_vectors;
2188
2189 /* #### should allocate `small' bit vectors from a frob-block */
2190 static Lisp_Bit_Vector *make_bit_vector_internal(size_t sizei)
2191 {
2192         size_t num_longs = BIT_VECTOR_LONG_STORAGE(sizei);
2193         size_t sizem =
2194             FLEXIBLE_ARRAY_STRUCT_SIZEOF(Lisp_Bit_Vector, unsigned long,
2195                                          bits, num_longs);
2196         Lisp_Bit_Vector *p = (Lisp_Bit_Vector *) allocate_lisp_storage(sizem);
2197         set_lheader_implementation(&p->lheader, &lrecord_bit_vector);
2198
2199         INCREMENT_CONS_COUNTER(sizem, "bit-vector");
2200
2201         bit_vector_length(p) = sizei;
2202         bit_vector_next(p) = all_bit_vectors;
2203         /* make sure the extra bits in the last long are 0; the calling
2204            functions might not set them. */
2205         p->bits[num_longs - 1] = 0;
2206         XSETBIT_VECTOR(all_bit_vectors, p);
2207
2208         /* propagate seq implementation */
2209         p->lheader.morphisms = 0;
2210         return p;
2211 }
2212
2213 Lisp_Object make_bit_vector(size_t length, Lisp_Object bit)
2214 {
2215         Lisp_Bit_Vector *p = make_bit_vector_internal(length);
2216         size_t num_longs = BIT_VECTOR_LONG_STORAGE(length);
2217
2218         CHECK_BIT(bit);
2219
2220         if (ZEROP(bit))
2221                 memset(p->bits, 0, num_longs * sizeof(long));
2222         else {
2223                 size_t bits_in_last = length & (LONGBITS_POWER_OF_2 - 1);
2224                 memset(p->bits, ~0, num_longs * sizeof(long));
2225                 /* But we have to make sure that the unused bits in the
2226                    last long are 0, so that equal/hash is easy. */
2227                 if (bits_in_last)
2228                         p->bits[num_longs - 1] &= (1 << bits_in_last) - 1;
2229         }
2230
2231         {
2232                 Lisp_Object bit_vector;
2233                 XSETBIT_VECTOR(bit_vector, p);
2234                 return bit_vector;
2235         }
2236 }
2237
2238 Lisp_Object
2239 make_bit_vector_from_byte_vector(unsigned char *bytevec, size_t length)
2240 {
2241         size_t i;
2242         Lisp_Bit_Vector *p = make_bit_vector_internal(length);
2243
2244         for (i = 0; i < length; i++)
2245                 set_bit_vector_bit(p, i, bytevec[i]);
2246
2247         {
2248                 Lisp_Object bit_vector;
2249                 XSETBIT_VECTOR(bit_vector, p);
2250                 return bit_vector;
2251         }
2252 }
2253
2254 DEFUN("make-bit-vector", Fmake_bit_vector, 2, 2, 0,     /*
2255 Return a new bit vector of length LENGTH. with each bit set to BIT.
2256 BIT must be one of the integers 0 or 1.  See also the function `bit-vector'.
2257 */
2258       (length, bit))
2259 {
2260         CONCHECK_NATNUM(length);
2261
2262         return make_bit_vector(XINT(length), bit);
2263 }
2264
2265 DEFUN("bit-vector", Fbit_vector, 0, MANY, 0,    /*
2266 Return a newly created bit vector with specified arguments as elements.
2267 Any number of arguments, even zero arguments, are allowed.
2268 Each argument must be one of the integers 0 or 1.
2269 */
2270       (int nargs, Lisp_Object * args))
2271 {
2272         int i;
2273         Lisp_Bit_Vector *p = make_bit_vector_internal(nargs);
2274
2275         for (i = 0; i < nargs; i++) {
2276                 CHECK_BIT(args[i]);
2277                 set_bit_vector_bit(p, i, !ZEROP(args[i]));
2278         }
2279
2280         {
2281                 Lisp_Object bit_vector;
2282                 XSETBIT_VECTOR(bit_vector, p);
2283                 return bit_vector;
2284         }
2285 }
2286
2287 /* the seq approach for conses */
2288 static size_t
2289 bvc_length(const seq_t bv)
2290 {
2291         return bit_vector_length(XBIT_VECTOR((Lisp_Object)(long int)bv));
2292 }
2293
2294 static void
2295 bvc_iter_init(seq_t bv, seq_iter_t si)
2296 {
2297         si->seq = bv;
2298         si->data = (void*)0;
2299         return;
2300 }
2301
2302 static void
2303 bvc_iter_next(seq_iter_t si, void **elt)
2304 {
2305         if (si->seq != NULL &&
2306             (long int)si->data < bit_vector_length((Lisp_Bit_Vector*)si->seq)) {
2307                 *elt = (void*)make_int(
2308                         bit_vector_bit(
2309                                 (Lisp_Bit_Vector*)si->seq, (size_t)si->data));
2310                 si->data = (void*)((long int)si->data + 1L);
2311         } else {
2312                 *elt = NULL;
2313         }
2314         return;
2315 }
2316
2317 static void
2318 bvc_iter_fini(seq_iter_t si)
2319 {
2320         si->data = si->seq = NULL;
2321         return;
2322 }
2323
2324 static void
2325 bvc_iter_reset(seq_iter_t si)
2326 {
2327         si->data = (void*)0;
2328         return;
2329 }
2330
2331 static size_t
2332 bvc_explode(void *restrict tgt[], size_t ntgt, const seq_t s)
2333 {
2334         size_t len = bit_vector_length((const Lisp_Bit_Vector*)s);
2335         volatile size_t i = 0;
2336
2337         while (i < len && i < ntgt) {
2338                 tgt[i] = (void*)make_int(
2339                         bit_vector_bit((const Lisp_Bit_Vector*)s, i));
2340                 i++;
2341         }
2342         return i;
2343 }
2344
2345 static struct seq_impl_s __sbvc = {
2346         .length_f = bvc_length,
2347         .iter_init_f = bvc_iter_init,
2348         .iter_next_f = bvc_iter_next,
2349         .iter_fini_f = bvc_iter_fini,
2350         .iter_reset_f = bvc_iter_reset,
2351         .explode_f = bvc_explode,
2352 };
2353 \f
2354 /************************************************************************/
2355 /*                   Compiled-function allocation                       */
2356 /************************************************************************/
2357
2358 DECLARE_FIXED_TYPE_ALLOC(compiled_function, Lisp_Compiled_Function);
2359 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_compiled_function 1000
2360
2361 static Lisp_Object make_compiled_function(void)
2362 {
2363         Lisp_Compiled_Function *f;
2364         Lisp_Object fun;
2365
2366         ALLOCATE_FIXED_TYPE(compiled_function, Lisp_Compiled_Function, f);
2367         set_lheader_implementation(&f->lheader, &lrecord_compiled_function);
2368
2369         f->stack_depth = 0;
2370         f->specpdl_depth = 0;
2371         f->flags.documentationp = 0;
2372         f->flags.interactivep = 0;
2373         f->flags.domainp = 0;   /* I18N3 */
2374         f->instructions = Qzero;
2375         f->constants = Qzero;
2376         f->arglist = Qnil;
2377         f->doc_and_interactive = Qnil;
2378 #ifdef COMPILED_FUNCTION_ANNOTATION_HACK
2379         f->annotated = Qnil;
2380 #endif
2381         XSETCOMPILED_FUNCTION(fun, f);
2382         return fun;
2383 }
2384
2385 DEFUN("make-byte-code", Fmake_byte_code, 4, MANY, 0,    /*
2386 Return a new compiled-function object.
2387 Usage: (arglist instructions constants stack-depth
2388 &optional doc-string interactive)
2389 Note that, unlike all other emacs-lisp functions, calling this with five
2390 arguments is NOT the same as calling it with six arguments, the last of
2391 which is nil.  If the INTERACTIVE arg is specified as nil, then that means
2392 that this function was defined with `(interactive)'.  If the arg is not
2393 specified, then that means the function is not interactive.
2394 This is terrible behavior which is retained for compatibility with old
2395 `.elc' files which expect these semantics.
2396 */
2397       (int nargs, Lisp_Object * args))
2398 {
2399 /* In a non-insane world this function would have this arglist...
2400    (arglist instructions constants stack_depth &optional doc_string interactive)
2401  */
2402         Lisp_Object fun = make_compiled_function();
2403         Lisp_Compiled_Function *f = XCOMPILED_FUNCTION(fun);
2404
2405         Lisp_Object arglist = args[0];
2406         Lisp_Object instructions = args[1];
2407         Lisp_Object constants = args[2];
2408         Lisp_Object stack_depth = args[3];
2409         Lisp_Object doc_string = (nargs > 4) ? args[4] : Qnil;
2410         Lisp_Object interactive = (nargs > 5) ? args[5] : Qunbound;
2411
2412         if (nargs < 4 || nargs > 6)
2413                 return Fsignal(Qwrong_number_of_arguments,
2414                                list2(intern("make-byte-code"),
2415                                      make_int(nargs)));
2416
2417         /* Check for valid formal parameter list now, to allow us to use
2418            SPECBIND_FAST_UNSAFE() later in funcall_compiled_function(). */
2419         {
2420                 EXTERNAL_LIST_LOOP_3(symbol, arglist, tail) {
2421                         CHECK_SYMBOL(symbol);
2422                         if (EQ(symbol, Qt) ||
2423                             EQ(symbol, Qnil) || SYMBOL_IS_KEYWORD(symbol))
2424                                 signal_simple_error_2
2425                                     ("Invalid constant symbol in formal parameter list",
2426                                      symbol, arglist);
2427                 }
2428         }
2429         f->arglist = arglist;
2430
2431         /* `instructions' is a string or a cons (string . int) for a
2432            lazy-loaded function. */
2433         if (CONSP(instructions)) {
2434                 CHECK_STRING(XCAR(instructions));
2435                 CHECK_INT(XCDR(instructions));
2436         } else {
2437                 CHECK_STRING(instructions);
2438         }
2439         f->instructions = instructions;
2440
2441         if (!NILP(constants))
2442                 CHECK_VECTOR(constants);
2443         f->constants = constants;
2444
2445         CHECK_NATNUM(stack_depth);
2446         f->stack_depth = (unsigned short)XINT(stack_depth);
2447
2448 #ifdef COMPILED_FUNCTION_ANNOTATION_HACK
2449         if (!NILP(Vcurrent_compiled_function_annotation))
2450                 f->annotated = Fcopy(Vcurrent_compiled_function_annotation);
2451         else if (!NILP(Vload_file_name_internal_the_purecopy))
2452                 f->annotated = Vload_file_name_internal_the_purecopy;
2453         else if (!NILP(Vload_file_name_internal)) {
2454                 struct gcpro gcpro1;
2455                 GCPRO1(fun);    /* don't let fun get reaped */
2456                 Vload_file_name_internal_the_purecopy =
2457                     Ffile_name_nondirectory(Vload_file_name_internal);
2458                 f->annotated = Vload_file_name_internal_the_purecopy;
2459                 UNGCPRO;
2460         }
2461 #endif                          /* COMPILED_FUNCTION_ANNOTATION_HACK */
2462
2463         /* doc_string may be nil, string, int, or a cons (string . int).
2464            interactive may be list or string (or unbound). */
2465         f->doc_and_interactive = Qunbound;
2466 #ifdef I18N3
2467         if ((f->flags.domainp = !NILP(Vfile_domain)) != 0)
2468                 f->doc_and_interactive = Vfile_domain;
2469 #endif
2470         if ((f->flags.interactivep = !UNBOUNDP(interactive)) != 0) {
2471                 f->doc_and_interactive
2472                     = (UNBOUNDP(f->doc_and_interactive) ? interactive :
2473                        Fcons(interactive, f->doc_and_interactive));
2474         }
2475         if ((f->flags.documentationp = !NILP(doc_string)) != 0) {
2476                 f->doc_and_interactive
2477                     = (UNBOUNDP(f->doc_and_interactive) ? doc_string :
2478                        Fcons(doc_string, f->doc_and_interactive));
2479         }
2480         if (UNBOUNDP(f->doc_and_interactive))
2481                 f->doc_and_interactive = Qnil;
2482
2483         return fun;
2484 }
2485 \f
2486 /************************************************************************/
2487 /*                          Symbol allocation                           */
2488 /************************************************************************/
2489
2490 DECLARE_FIXED_TYPE_ALLOC(symbol, Lisp_Symbol);
2491 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_symbol 1000
2492
2493 DEFUN("make-symbol", Fmake_symbol, 1, 1, 0,     /*
2494 Return a newly allocated uninterned symbol whose name is NAME.
2495 Its value and function definition are void, and its property list is nil.
2496 */
2497       (name))
2498 {
2499         Lisp_Object val;
2500         Lisp_Symbol *p;
2501
2502         CHECK_STRING(name);
2503
2504         ALLOCATE_FIXED_TYPE(symbol, Lisp_Symbol, p);
2505         set_lheader_implementation(&p->lheader, &lrecord_symbol);
2506         p->name = XSTRING(name);
2507         p->plist = Qnil;
2508         p->value = Qunbound;
2509         p->function = Qunbound;
2510         symbol_next(p) = 0;
2511         XSETSYMBOL(val, p);
2512         return val;
2513 }
2514 \f
2515 /************************************************************************/
2516 /*                         Extent allocation                            */
2517 /************************************************************************/
2518
2519 DECLARE_FIXED_TYPE_ALLOC(extent, struct extent);
2520 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_extent 1000
2521
2522 struct extent *allocate_extent(void)
2523 {
2524         struct extent *e;
2525
2526         ALLOCATE_FIXED_TYPE(extent, struct extent, e);
2527         set_lheader_implementation(&e->lheader, &lrecord_extent);
2528         extent_object(e) = Qnil;
2529         set_extent_start(e, -1);
2530         set_extent_end(e, -1);
2531         e->plist = Qnil;
2532
2533         xzero(e->flags);
2534
2535         extent_face(e) = Qnil;
2536         e->flags.end_open = 1;  /* default is for endpoints to behave like markers */
2537         e->flags.detachable = 1;
2538
2539         return e;
2540 }
2541 \f
2542 /************************************************************************/
2543 /*                         Event allocation                             */
2544 /************************************************************************/
2545
2546 DECLARE_FIXED_TYPE_ALLOC(event, Lisp_Event);
2547 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_event 1000
2548
2549 Lisp_Object allocate_event(void)
2550 {
2551         Lisp_Object val;
2552         Lisp_Event *e;
2553
2554         ALLOCATE_FIXED_TYPE(event, Lisp_Event, e);
2555         set_lheader_implementation(&e->lheader, &lrecord_event);
2556
2557         XSETEVENT(val, e);
2558         return val;
2559 }
2560 \f
2561 /************************************************************************/
2562 /*                       Marker allocation                              */
2563 /************************************************************************/
2564
2565 DECLARE_FIXED_TYPE_ALLOC(marker, Lisp_Marker);
2566 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_marker 1000
2567
2568 DEFUN("make-marker", Fmake_marker, 0, 0, 0,     /*
2569 Return a new marker which does not point at any place.
2570 */
2571       ())
2572 {
2573         Lisp_Object val;
2574         Lisp_Marker *p;
2575
2576         ALLOCATE_FIXED_TYPE(marker, Lisp_Marker, p);
2577         set_lheader_implementation(&p->lheader, &lrecord_marker);
2578         p->buffer = 0;
2579         p->memind = 0;
2580         marker_next(p) = 0;
2581         marker_prev(p) = 0;
2582         p->insertion_type = 0;
2583         XSETMARKER(val, p);
2584         return val;
2585 }
2586
2587 Lisp_Object noseeum_make_marker(void)
2588 {
2589         Lisp_Object val;
2590         Lisp_Marker *p;
2591
2592         NOSEEUM_ALLOCATE_FIXED_TYPE(marker, Lisp_Marker, p);
2593         set_lheader_implementation(&p->lheader, &lrecord_marker);
2594         p->buffer = 0;
2595         p->memind = 0;
2596         marker_next(p) = 0;
2597         marker_prev(p) = 0;
2598         p->insertion_type = 0;
2599         XSETMARKER(val, p);
2600         return val;
2601 }
2602 \f
2603 /************************************************************************/
2604 /*                        String allocation                             */
2605 /************************************************************************/
2606
2607 /* The data for "short" strings generally resides inside of structs of type
2608    string_chars_block. The Lisp_String structure is allocated just like any
2609    other Lisp object (except for vectors), and these are freelisted when
2610    they get garbage collected. The data for short strings get compacted,
2611    but the data for large strings do not.
2612
2613    Previously Lisp_String structures were relocated, but this caused a lot
2614    of bus-errors because the C code didn't include enough GCPRO's for
2615    strings (since EVERY REFERENCE to a short string needed to be GCPRO'd so
2616    that the reference would get relocated).
2617
2618    This new method makes things somewhat bigger, but it is MUCH safer.  */
2619
2620 DECLARE_FIXED_TYPE_ALLOC(string, Lisp_String);
2621 /* strings are used and freed quite often */
2622 /* #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_string 10000 */
2623 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_string 1000
2624
2625 #if defined HAVE_BDWGC && defined EF_USE_BDWGC && 0
2626 static void
2627 string_register_finaliser(Lisp_String *s)
2628 {
2629         GC_finalization_proc *foo = NULL;
2630         void **bar = NULL;
2631         auto void string_finaliser();
2632
2633         auto void string_finaliser(void *obj, void *SXE_UNUSED(data))
2634         {
2635                 if (!(((Lisp_String*)obj)->lheader.c_readonly)) {
2636                         yfree(((Lisp_String*)obj)->data);
2637                 }
2638                 /* cleanse */
2639                 memset(obj, 0, sizeof(Lisp_String));
2640                 return;
2641         }
2642
2643         SXE_DEBUG_GC("string-fina %p\n", s);
2644         GC_REGISTER_FINALIZER(s, string_finaliser, NULL, foo, bar);
2645         return;
2646 }
2647 #else  /* !BDWGC */
2648 static inline void
2649 string_register_finaliser(Lisp_String *SXE_UNUSED(b))
2650 {
2651         return;
2652 }
2653 #endif  /* HAVE_BDWGC */
2654
2655 static Lisp_Object mark_string(Lisp_Object obj)
2656 {
2657         Lisp_String *ptr = XSTRING(obj);
2658
2659         if (CONSP(ptr->plist) && EXTENT_INFOP(XCAR(ptr->plist)))
2660                 flush_cached_extent_info(XCAR(ptr->plist));
2661 #ifdef EF_USE_COMPRE
2662         mark_object(ptr->compre);
2663 #endif
2664         return ptr->plist;
2665 }
2666
2667 static int string_equal(Lisp_Object obj1, Lisp_Object obj2, int depth)
2668 {
2669         Bytecount len;
2670         return (((len = XSTRING_LENGTH(obj1)) == XSTRING_LENGTH(obj2)) &&
2671                 !memcmp(XSTRING_DATA(obj1), XSTRING_DATA(obj2), len));
2672 }
2673
2674 static const struct lrecord_description string_description[] = {
2675         {XD_BYTECOUNT, offsetof(Lisp_String, size)},
2676         {XD_OPAQUE_DATA_PTR, offsetof(Lisp_String, data), XD_INDIRECT(0, 1)},
2677 #ifdef EF_USE_COMPRE
2678         {XD_LISP_OBJECT, offsetof(Lisp_String, compre)},
2679 #endif
2680         {XD_LISP_OBJECT, offsetof(Lisp_String, plist)},
2681         {XD_END}
2682 };
2683
2684 /* the seq implementation */
2685 static size_t
2686 str_length(const seq_t str)
2687 {
2688         return string_char_length((const Lisp_String*)str);
2689 }
2690
2691 static void
2692 str_iter_init(seq_t str, seq_iter_t si)
2693 {
2694         si->seq = str;
2695         si->data = (void*)0;
2696         return;
2697 }
2698
2699 static void
2700 str_iter_next(seq_iter_t si, void **elt)
2701 {
2702         if (si->seq != NULL &&
2703             (long int)si->data < string_char_length((Lisp_String*)si->seq)) {
2704                 *elt = (void*)make_char(
2705                         string_char((Lisp_String*)si->seq, (long int)si->data));
2706                 si->data = (void*)((long int)si->data + 1);
2707         } else {
2708                 *elt = NULL;
2709         }
2710         return;
2711 }
2712
2713 static void
2714 str_iter_fini(seq_iter_t si)
2715 {
2716         si->data = si->seq = NULL;
2717         return;
2718 }
2719
2720 static void
2721 str_iter_reset(seq_iter_t si)
2722 {
2723         si->data = (void*)0;
2724         return;
2725 }
2726
2727 static size_t
2728 str_explode(void *restrict tgt[], size_t ntgt, const seq_t s)
2729 {
2730         size_t len = string_char_length((const Lisp_String*)s);
2731         volatile size_t i = 0;
2732
2733         while (i < len && i < ntgt) {
2734                 tgt[i] = (void*)make_char(string_char((Lisp_String*)s, i));
2735                 i++;
2736         }
2737         return i;
2738 }
2739
2740 static struct seq_impl_s __sstr = {
2741         .length_f = str_length,
2742         .iter_init_f = str_iter_init,
2743         .iter_next_f = str_iter_next,
2744         .iter_fini_f = str_iter_fini,
2745         .iter_reset_f = str_iter_reset,
2746         .explode_f = str_explode,
2747 };
2748
2749
2750 /* We store the string's extent info as the first element of the string's
2751    property list; and the string's MODIFF as the first or second element
2752    of the string's property list (depending on whether the extent info
2753    is present), but only if the string has been modified.  This is ugly
2754    but it reduces the memory allocated for the string in the vast
2755    majority of cases, where the string is never modified and has no
2756    extent info.
2757
2758    #### This means you can't use an int as a key in a string's plist. */
2759
2760 static Lisp_Object *string_plist_ptr(Lisp_Object string)
2761 {
2762         Lisp_Object *ptr = &XSTRING(string)->plist;
2763
2764         if (CONSP(*ptr) && EXTENT_INFOP(XCAR(*ptr)))
2765                 ptr = &XCDR(*ptr);
2766         if (CONSP(*ptr) && INTP(XCAR(*ptr)))
2767                 ptr = &XCDR(*ptr);
2768         return ptr;
2769 }
2770
2771 static Lisp_Object string_getprop(Lisp_Object string, Lisp_Object property)
2772 {
2773         return external_plist_get(string_plist_ptr(string), property, 0,
2774                                   ERROR_ME);
2775 }
2776
2777 static int
2778 string_putprop(Lisp_Object string, Lisp_Object property, Lisp_Object value)
2779 {
2780         external_plist_put(string_plist_ptr(string), property, value, 0,
2781                            ERROR_ME);
2782         return 1;
2783 }
2784
2785 static int string_remprop(Lisp_Object string, Lisp_Object property)
2786 {
2787         return external_remprop(string_plist_ptr(string), property, 0,
2788                                 ERROR_ME);
2789 }
2790
2791 static Lisp_Object string_plist(Lisp_Object string)
2792 {
2793         return *string_plist_ptr(string);
2794 }
2795
2796 /* No `finalize', or `hash' methods.
2797    internal_hash() already knows how to hash strings and finalization
2798    is done with the ADDITIONAL_FREE_string macro, which is the
2799    standard way to do finalization when using
2800    SWEEP_FIXED_TYPE_BLOCK(). */
2801 DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS("string", string,
2802                                                mark_string, print_string,
2803                                                0, string_equal, 0,
2804                                                string_description,
2805                                                string_getprop,
2806                                                string_putprop,
2807                                                string_remprop,
2808                                                string_plist, Lisp_String);
2809
2810 #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
2811 /* String blocks contain this many useful bytes. */
2812 #define STRING_CHARS_BLOCK_SIZE                                         \
2813         ((Bytecount) (8192 - MALLOC_OVERHEAD -                          \
2814                       ((2 * sizeof (struct string_chars_block *))       \
2815                        + sizeof (EMACS_INT))))
2816 /* Block header for small strings. */
2817 struct string_chars_block {
2818         EMACS_INT pos;
2819         struct string_chars_block *next;
2820         struct string_chars_block *prev;
2821         /* Contents of string_chars_block->string_chars are interleaved
2822            string_chars structures (see below) and the actual string data */
2823         unsigned char string_chars[STRING_CHARS_BLOCK_SIZE];
2824 };
2825
2826 static struct string_chars_block *first_string_chars_block;
2827 static struct string_chars_block *current_string_chars_block;
2828
2829 /* If SIZE is the length of a string, this returns how many bytes
2830  *  the string occupies in string_chars_block->string_chars
2831  *  (including alignment padding).
2832  */
2833 #define STRING_FULLSIZE(size) \
2834         ALIGN_SIZE(((size) + 1 + sizeof(Lisp_String*)), ALIGNOF(Lisp_String*))
2835
2836 #define BIG_STRING_FULLSIZE_P(fullsize) ((fullsize) >= STRING_CHARS_BLOCK_SIZE)
2837 #define BIG_STRING_SIZE_P(size) (BIG_STRING_FULLSIZE_P (STRING_FULLSIZE(size)))
2838
2839 #define STRING_CHARS_FREE_P(ptr) ((ptr)->string == NULL)
2840 #define MARK_STRING_CHARS_AS_FREE(ptr) ((void) ((ptr)->string = NULL))
2841
2842 struct string_chars {
2843         Lisp_String *string;
2844         unsigned char chars[1];
2845 };
2846
2847 struct unused_string_chars {
2848         Lisp_String *string;
2849         EMACS_INT fullsize;
2850 };
2851
2852 static void init_string_chars_alloc(void)
2853 {
2854         first_string_chars_block = ynew(struct string_chars_block);
2855         first_string_chars_block->prev = 0;
2856         first_string_chars_block->next = 0;
2857         first_string_chars_block->pos = 0;
2858         current_string_chars_block = first_string_chars_block;
2859 }
2860
2861 static struct string_chars*
2862 allocate_string_chars_struct(Lisp_String *string_it_goes_with,
2863                              EMACS_INT fullsize)
2864 {
2865         struct string_chars *s_chars;
2866
2867         if (fullsize <= (countof(current_string_chars_block->string_chars)
2868                          - current_string_chars_block->pos)) {
2869                 /* This string can fit in the current string chars block */
2870                 s_chars = (struct string_chars *)
2871                         (current_string_chars_block->string_chars
2872                          + current_string_chars_block->pos);
2873                 current_string_chars_block->pos += fullsize;
2874         } else {
2875                 /* Make a new current string chars block */
2876                 struct string_chars_block *new_scb =
2877                         ynew(struct string_chars_block);
2878
2879                 current_string_chars_block->next = new_scb;
2880                 new_scb->prev = current_string_chars_block;
2881                 new_scb->next = 0;
2882                 current_string_chars_block = new_scb;
2883                 new_scb->pos = fullsize;
2884                 s_chars = (struct string_chars *)
2885                         current_string_chars_block->string_chars;
2886         }
2887
2888         s_chars->string = string_it_goes_with;
2889
2890         INCREMENT_CONS_COUNTER(fullsize, "string chars");
2891
2892         return s_chars;
2893 }
2894 #endif  /* !BDWGC */
2895
2896 Lisp_Object make_uninit_string(Bytecount length)
2897 {
2898         Lisp_String *s = NULL;
2899 #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
2900         EMACS_INT fullsize = STRING_FULLSIZE(length);
2901 #endif  /* !BDWGC */
2902         Lisp_Object val;
2903
2904 #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
2905         assert(length >= 0 && fullsize > 0);
2906 #endif  /* !BDWGC */
2907
2908         /* Allocate the string header */
2909         ALLOCATE_FIXED_TYPE(string, Lisp_String, s);
2910         set_lheader_implementation(&s->lheader, &lrecord_string);
2911         string_register_finaliser(s);
2912
2913         {
2914                 Bufbyte *foo = NULL;
2915 #if defined HAVE_BDWGC && defined EF_USE_BDWGC
2916                 foo = xnew_atomic_array(Bufbyte, length+1);
2917                 assert(foo != NULL);
2918 #else
2919                 if (BIG_STRING_FULLSIZE_P(fullsize)) {
2920                         foo = xnew_atomic_array(Bufbyte, length + 1);
2921                         assert(foo != NULL);
2922                 } else {
2923                         foo = allocate_string_chars_struct(s, fullsize)->chars;
2924                         assert(foo != NULL);
2925                 }
2926 #endif
2927                 set_string_data(s, foo);
2928         }
2929         set_string_length(s, length);
2930         s->plist = Qnil;
2931 #ifdef EF_USE_COMPRE
2932         s->compre = Qnil;
2933 #endif
2934         /* propagate the cat system, go with the standard impl of a seq first */
2935         s->lheader.morphisms = 0;
2936
2937         set_string_byte(s, length, 0);
2938
2939         XSETSTRING(val, s);
2940         return val;
2941 }
2942
2943 #ifdef VERIFY_STRING_CHARS_INTEGRITY
2944 static void verify_string_chars_integrity(void);
2945 #endif
2946
2947 /* Resize the string S so that DELTA bytes can be inserted starting
2948    at POS.  If DELTA < 0, it means deletion starting at POS.  If
2949    POS < 0, resize the string but don't copy any characters.  Use
2950    this if you're planning on completely overwriting the string.
2951 */
2952
2953 #if defined HAVE_BDWGC && defined EF_USE_BDWGC
2954 void resize_string(Lisp_String * s, Bytecount pos, Bytecount delta)
2955 {
2956         Bytecount len;
2957         Bufbyte *foo;
2958
2959         /* trivial cases first */
2960         if (delta == 0) {
2961                 /* simplest case: no size change. */
2962                 return;
2963         }
2964
2965         if (pos >= 0 && delta < 0) {
2966                 /* If DELTA < 0, the functions below will delete the characters
2967                    before POS.  We want to delete characters *after* POS,
2968                    however, so convert this to the appropriate form. */
2969                 pos += -delta;
2970         }
2971
2972         /* Both strings are big.  We can just realloc().
2973            But careful!  If the string is shrinking, we have to
2974            memmove() _before_ realloc(), and if growing, we have to
2975            memmove() _after_ realloc() - otherwise the access is
2976            illegal, and we might crash. */
2977         len = string_length(s) + 1 - pos;
2978
2979         if (delta < 0 && pos >= 0) {
2980                 memmove(string_data(s) + pos + delta,
2981                         string_data(s) + pos, len);
2982         }
2983
2984         /* do the reallocation */
2985         foo = xrealloc(string_data(s), string_length(s) + delta + 1);
2986         set_string_data(s, foo);
2987
2988         if (delta > 0 && pos >= 0) {
2989                 memmove(string_data(s) + pos + delta,
2990                         string_data(s) + pos, len);
2991         }
2992
2993         set_string_length(s, string_length(s) + delta);
2994         /* If pos < 0, the string won't be zero-terminated.
2995            Terminate now just to make sure. */
2996         string_data(s)[string_length(s)] = '\0';
2997
2998         if (pos >= 0) {
2999                 Lisp_Object string;
3000
3001                 XSETSTRING(string, s);
3002                 /* We also have to adjust all of the extent indices after the
3003                    place we did the change.  We say "pos - 1" because
3004                    adjust_extents() is exclusive of the starting position
3005                    passed to it. */
3006                 adjust_extents(string, pos - 1, string_length(s), delta);
3007         }
3008         return;
3009 }
3010 #else  /* !HAVE_BDWGC */
3011 void resize_string(Lisp_String * s, Bytecount pos, Bytecount delta)
3012 {
3013         Bytecount oldfullsize, newfullsize;
3014 #ifdef VERIFY_STRING_CHARS_INTEGRITY
3015         verify_string_chars_integrity();
3016 #endif
3017
3018 #ifdef ERROR_CHECK_BUFPOS
3019         if (pos >= 0) {
3020                 assert(pos <= string_length(s));
3021                 if (delta < 0)
3022                         assert(pos + (-delta) <= string_length(s));
3023         } else {
3024                 if (delta < 0)
3025                         assert((-delta) <= string_length(s));
3026         }
3027 #endif                          /* ERROR_CHECK_BUFPOS */
3028
3029         if (delta == 0)
3030                 /* simplest case: no size change. */
3031                 return;
3032
3033         if (pos >= 0 && delta < 0)
3034                 /* If DELTA < 0, the functions below will delete the characters
3035                    before POS.  We want to delete characters *after* POS, however,
3036                    so convert this to the appropriate form. */
3037                 pos += -delta;
3038
3039         oldfullsize = STRING_FULLSIZE(string_length(s));
3040         newfullsize = STRING_FULLSIZE(string_length(s) + delta);
3041
3042         if (BIG_STRING_FULLSIZE_P(oldfullsize)) {
3043                 if (BIG_STRING_FULLSIZE_P(newfullsize)) {
3044                         /* Both strings are big.  We can just realloc().
3045                            But careful!  If the string is shrinking, we have to
3046                            memmove() _before_ realloc(), and if growing, we have to
3047                            memmove() _after_ realloc() - otherwise the access is
3048                            illegal, and we might crash. */
3049                         Bytecount len = string_length(s) + 1 - pos;
3050                         Bufbyte *foo;
3051
3052                         if (delta < 0 && pos >= 0)
3053                                 memmove(string_data(s) + pos + delta,
3054                                         string_data(s) + pos, len);
3055
3056                         foo = xrealloc(string_data(s),
3057                                        string_length(s) + delta + 1);
3058                         set_string_data(s, foo);
3059                         if (delta > 0 && pos >= 0) {
3060                                 memmove(string_data(s) + pos + delta,
3061                                         string_data(s) + pos, len);
3062                         }
3063                 } else {
3064                         /* String has been demoted from BIG_STRING. */
3065
3066                         Bufbyte *new_data =
3067                                 allocate_string_chars_struct(s, newfullsize)
3068                                 ->chars;
3069                         Bufbyte *old_data = string_data(s);
3070
3071                         if (pos >= 0) {
3072                                 memcpy(new_data, old_data, pos);
3073                                 memcpy(new_data + pos + delta, old_data + pos,
3074                                        string_length(s) + 1 - pos);
3075                         }
3076                         set_string_data(s, new_data);
3077                         xfree(old_data);
3078                 }
3079         } else {                /* old string is small */
3080
3081                 if (oldfullsize == newfullsize) {
3082                         /* special case; size change but the necessary
3083                            allocation size won't change (up or down; code
3084                            somewhere depends on there not being any unused
3085                            allocation space, modulo any alignment
3086                            constraints). */
3087                         if (pos >= 0) {
3088                                 Bufbyte *addroff = pos + string_data(s);
3089
3090                                 memmove(addroff + delta, addroff,
3091                                         /* +1 due to zero-termination. */
3092                                         string_length(s) + 1 - pos);
3093                         }
3094                 } else {
3095                         Bufbyte *old_data = string_data(s);
3096                         Bufbyte *new_data = BIG_STRING_FULLSIZE_P(newfullsize)
3097                                 ? xnew_atomic_array(
3098                                         Bufbyte, string_length(s) + delta + 1)
3099                                 : allocate_string_chars_struct(
3100                                         s, newfullsize)->chars;
3101
3102                         if (pos >= 0) {
3103                                 memcpy(new_data, old_data, pos);
3104                                 memcpy(new_data + pos + delta, old_data + pos,
3105                                        string_length(s) + 1 - pos);
3106                         }
3107                         set_string_data(s, new_data);
3108
3109                         {
3110                                 /* We need to mark this chunk of the
3111                                    string_chars_block as unused so that
3112                                    compact_string_chars() doesn't freak. */
3113                                 struct string_chars *old_s_chars =
3114                                         (struct string_chars *)
3115                                         ((char *)old_data -
3116                                          offsetof(struct string_chars, chars));
3117                                 /* Sanity check to make sure we aren't hosed by
3118                                    strange alignment/padding. */
3119                                 assert(old_s_chars->string == s);
3120                                 MARK_STRING_CHARS_AS_FREE(old_s_chars);
3121                                 ((struct unused_string_chars *)old_s_chars)->
3122                                         fullsize = oldfullsize;
3123                         }
3124                 }
3125         }
3126
3127         set_string_length(s, string_length(s) + delta);
3128         /* If pos < 0, the string won't be zero-terminated.
3129            Terminate now just to make sure. */
3130         string_data(s)[string_length(s)] = '\0';
3131
3132         if (pos >= 0) {
3133                 Lisp_Object string;
3134
3135                 XSETSTRING(string, s);
3136                 /* We also have to adjust all of the extent indices after the
3137                    place we did the change.  We say "pos - 1" because
3138                    adjust_extents() is exclusive of the starting position
3139                    passed to it. */
3140                 adjust_extents(string, pos - 1, string_length(s), delta);
3141         }
3142 #ifdef VERIFY_STRING_CHARS_INTEGRITY
3143         verify_string_chars_integrity();
3144 #endif
3145 }
3146 #endif  /* BDWGC */
3147 #ifdef MULE
3148
3149 void set_string_char(Lisp_String * s, Charcount i, Emchar c)
3150 {
3151         Bufbyte newstr[MAX_EMCHAR_LEN];
3152         Bytecount bytoff = charcount_to_bytecount(string_data(s), i);
3153         Bytecount oldlen = charcount_to_bytecount(string_data(s) + bytoff, 1);
3154         Bytecount newlen = set_charptr_emchar(newstr, c);
3155
3156         if (oldlen != newlen) {
3157                 resize_string(s, bytoff, newlen - oldlen);
3158         }
3159         /* Remember, string_data (s) might have changed so we can't cache it. */
3160         memcpy(string_data(s) + bytoff, newstr, newlen);
3161 }
3162
3163 #endif                          /* MULE */
3164
3165 DEFUN("make-string", Fmake_string, 2, 2, 0,     /*
3166 Return a new string consisting of LENGTH copies of CHARACTER.
3167 LENGTH must be a non-negative integer.
3168 */
3169       (length, character))
3170 {
3171         CHECK_NATNUM(length);
3172         CHECK_CHAR_COERCE_INT(character);
3173         {
3174                 Bufbyte init_str[MAX_EMCHAR_LEN];
3175                 int len = set_charptr_emchar(init_str, XCHAR(character));
3176                 Lisp_Object val = make_uninit_string(len * XINT(length));
3177
3178                 if (len == 1)
3179                         /* Optimize the single-byte case */
3180                         memset(XSTRING_DATA(val), XCHAR(character),
3181                                XSTRING_LENGTH(val));
3182                 else {
3183                         size_t i;
3184                         Bufbyte *ptr = XSTRING_DATA(val);
3185
3186                         for (i = XINT(length); i; i--) {
3187                                 Bufbyte *init_ptr = init_str;
3188                                 switch (len) {
3189                                 case 4:
3190                                         *ptr++ = *init_ptr++;
3191                                 case 3:
3192                                         *ptr++ = *init_ptr++;
3193                                 case 2:
3194                                         *ptr++ = *init_ptr++;
3195                                 case 1:
3196                                         *ptr++ = *init_ptr++;
3197                                 default:
3198                                         break;
3199                                 }
3200                         }
3201                 }
3202                 return val;
3203         }
3204 }
3205
3206 DEFUN("string", Fstring, 0, MANY, 0,    /*
3207 Concatenate all the argument characters and make the result a string.
3208 */
3209       (int nargs, Lisp_Object * args))
3210 {
3211         Bufbyte *storage, *p;
3212         Lisp_Object result;
3213         int speccount = specpdl_depth();
3214         int len = nargs * MAX_EMCHAR_LEN;
3215
3216         XMALLOC_OR_ALLOCA(storage, len, Bufbyte);
3217         p = storage;
3218         for (; nargs; nargs--, args++) {
3219                 Lisp_Object lisp_char = *args;
3220                 CHECK_CHAR_COERCE_INT(lisp_char);
3221                 p += set_charptr_emchar(p, XCHAR(lisp_char));
3222         }
3223         result = make_string(storage, p - storage);
3224         XMALLOC_UNBIND(storage, len, speccount );
3225
3226         return result;
3227 }
3228
3229 /* Take some raw memory, which MUST already be in internal format,
3230    and package it up into a Lisp string. */
3231 Lisp_Object
3232 make_string(const Bufbyte *contents, Bytecount length)
3233 {
3234         Lisp_Object val;
3235
3236         /* Make sure we find out about bad make_string's when they happen */
3237 #if defined (ERROR_CHECK_BUFPOS) && defined (MULE)
3238         /* Just for the assertions */
3239         bytecount_to_charcount(contents, length);
3240 #endif
3241
3242         val = make_uninit_string(length);
3243         memcpy(XSTRING_DATA(val), contents, length);
3244         return val;
3245 }
3246
3247 /* Take some raw memory, encoded in some external data format,
3248    and convert it into a Lisp string. */
3249 Lisp_Object
3250 make_ext_string(const Extbyte *contents, EMACS_INT length,
3251                 Lisp_Object coding_system)
3252 {
3253         Lisp_Object string;
3254         TO_INTERNAL_FORMAT(DATA, (contents, length),
3255                            LISP_STRING, string, coding_system);
3256         return string;
3257 }
3258
3259 /* why arent the next 3 inlines? */
3260 Lisp_Object build_string(const char *str)
3261 {
3262         /* Some strlen's crash and burn if passed null. */
3263         if( str )
3264                 return make_string((const Bufbyte*)str, strlen(str));
3265         else
3266                 abort();
3267         return Qnil;
3268 }
3269
3270 Lisp_Object build_ext_string(const char *str, Lisp_Object coding_system)
3271 {
3272         /* Some strlen's crash and burn if passed null. */
3273         return make_ext_string((const Extbyte*)str, (str ? strlen(str) : 0), coding_system);
3274 }
3275
3276 Lisp_Object build_translated_string(const char *str)
3277 {
3278         return build_string(GETTEXT(str));
3279 }
3280
3281 Lisp_Object make_string_nocopy(Bufbyte *contents, Bytecount length)
3282 {
3283         Lisp_String *s;
3284         Lisp_Object val;
3285
3286         /* Make sure we find out about bad make_string_nocopy's when they
3287            happen */
3288 #if defined (ERROR_CHECK_BUFPOS) && defined (MULE)
3289         /* Just for the assertions */
3290         bytecount_to_charcount(contents, length);
3291 #endif
3292
3293         /* Allocate the string header */
3294         ALLOCATE_FIXED_TYPE(string, Lisp_String, s);
3295         set_lheader_implementation(&s->lheader, &lrecord_string);
3296         SET_C_READONLY_RECORD_HEADER(&s->lheader);
3297         string_register_finaliser(s);
3298
3299         s->plist = Qnil;
3300 #ifdef EF_USE_COMPRE
3301         s->compre = Qnil;
3302 #endif
3303         set_string_data(s, (Bufbyte*)contents);
3304         set_string_length(s, length);
3305
3306         XSETSTRING(val, s);
3307         return val;
3308 }
3309 \f
3310 /************************************************************************/
3311 /*                           lcrecord lists                             */
3312 /************************************************************************/
3313
3314 /* Lcrecord lists are used to manage the allocation of particular
3315    sorts of lcrecords, to avoid calling alloc_lcrecord() (and thus
3316    malloc() and garbage-collection junk) as much as possible.
3317    It is similar to the Blocktype class.
3318
3319    It works like this:
3320
3321    1) Create an lcrecord-list object using make_lcrecord_list().
3322       This is often done at initialization.  Remember to staticpro_nodump
3323       this object!  The arguments to make_lcrecord_list() are the
3324       same as would be passed to alloc_lcrecord().
3325    2) Instead of calling alloc_lcrecord(), call allocate_managed_lcrecord()
3326       and pass the lcrecord-list earlier created.
3327    3) When done with the lcrecord, call free_managed_lcrecord().
3328       The standard freeing caveats apply: ** make sure there are no
3329       pointers to the object anywhere! **
3330    4) Calling free_managed_lcrecord() is just like kissing the
3331       lcrecord goodbye as if it were garbage-collected.  This means:
3332       -- the contents of the freed lcrecord are undefined, and the
3333          contents of something produced by allocate_managed_lcrecord()
3334          are undefined, just like for alloc_lcrecord().
3335       -- the mark method for the lcrecord's type will *NEVER* be called
3336          on freed lcrecords.
3337       -- the finalize method for the lcrecord's type will be called
3338          at the time that free_managed_lcrecord() is called.
3339
3340    lcrecord lists do not work in bdwgc mode. -hrop
3341
3342    */
3343
3344 #if defined HAVE_BDWGC && defined EF_USE_BDWGC
3345 static Lisp_Object
3346 mark_lcrecord_list(Lisp_Object obj)
3347 {
3348         return Qnil;
3349 }
3350
3351 /* just imitate the lcrecord spectactular */
3352 Lisp_Object
3353 make_lcrecord_list(size_t size,
3354                    const struct lrecord_implementation *implementation)
3355 {
3356         struct lcrecord_list *p =
3357                 alloc_lcrecord_type(struct lcrecord_list,
3358                                     &lrecord_lcrecord_list);
3359         Lisp_Object val;
3360
3361         p->implementation = implementation;
3362         p->size = size;
3363         p->free = Qnil;
3364         XSETLCRECORD_LIST(val, p);
3365         return val;
3366 }
3367
3368 Lisp_Object
3369 allocate_managed_lcrecord(Lisp_Object lcrecord_list)
3370 {
3371         struct lcrecord_list *list = XLCRECORD_LIST(lcrecord_list);
3372         void *tmp = alloc_lcrecord(list->size, list->implementation);
3373         Lisp_Object val;
3374
3375         XSETOBJ(val, tmp);
3376         return val;
3377 }
3378
3379 void
3380 free_managed_lcrecord(Lisp_Object SXE_UNUSED(lcrecord_list), Lisp_Object lcrecord)
3381 {
3382         struct free_lcrecord_header *free_header =
3383                 (struct free_lcrecord_header*)XPNTR(lcrecord);
3384         struct lrecord_header *lheader = &free_header->lcheader.lheader;
3385         const struct lrecord_implementation *imp =
3386                 LHEADER_IMPLEMENTATION(lheader);
3387
3388         if (imp->finalizer) {
3389                 imp->finalizer(lheader, 0);
3390         }
3391         return;
3392 }
3393
3394 #else  /* !BDWGC */
3395
3396 static Lisp_Object
3397 mark_lcrecord_list(Lisp_Object obj)
3398 {
3399         struct lcrecord_list *list = XLCRECORD_LIST(obj);
3400         Lisp_Object chain = list->free;
3401
3402         while (!NILP(chain)) {
3403                 struct lrecord_header *lheader = XRECORD_LHEADER(chain);
3404                 struct free_lcrecord_header *free_header =
3405                     (struct free_lcrecord_header *)lheader;
3406
3407                 gc_checking_assert(
3408                         /* There should be no other pointers to the free list. */
3409                         !MARKED_RECORD_HEADER_P(lheader)
3410                         &&
3411                         /* Only lcrecords should be here. */
3412                         !LHEADER_IMPLEMENTATION(lheader)->
3413                         basic_p &&
3414                         /* Only free lcrecords should be here. */
3415                         free_header->lcheader.free &&
3416                         /* The type of the lcrecord must be right. */
3417                         LHEADER_IMPLEMENTATION(lheader) ==
3418                         list->implementation &&
3419                         /* So must the size. */
3420                         (LHEADER_IMPLEMENTATION(lheader)->
3421                          static_size == 0
3422                          || LHEADER_IMPLEMENTATION(lheader)->
3423                          static_size == list->size)
3424                         );
3425
3426                 MARK_RECORD_HEADER(lheader);
3427                 chain = free_header->chain;
3428         }
3429
3430         return Qnil;
3431 }
3432
3433 Lisp_Object
3434 make_lcrecord_list(size_t size,
3435                    const struct lrecord_implementation *implementation)
3436 {
3437         struct lcrecord_list *p =
3438                 alloc_lcrecord_type(struct lcrecord_list,
3439                                     &lrecord_lcrecord_list);
3440         Lisp_Object val;
3441
3442         p->implementation = implementation;
3443         p->size = size;
3444         p->free = Qnil;
3445         XSETLCRECORD_LIST(val, p);
3446         return val;
3447 }
3448
3449 Lisp_Object
3450 allocate_managed_lcrecord(Lisp_Object lcrecord_list)
3451 {
3452         struct lcrecord_list *list = XLCRECORD_LIST(lcrecord_list);
3453         if (!NILP(list->free)) {
3454                 Lisp_Object val = list->free;
3455                 struct free_lcrecord_header *free_header =
3456                     (struct free_lcrecord_header *)XPNTR(val);
3457
3458 #ifdef ERROR_CHECK_GC
3459                 struct lrecord_header *lheader = &free_header->lcheader.lheader;
3460
3461                 /* There should be no other pointers to the free list. */
3462                 assert(!MARKED_RECORD_HEADER_P(lheader));
3463                 /* Only lcrecords should be here. */
3464                 assert(!LHEADER_IMPLEMENTATION(lheader)->basic_p);
3465                 /* Only free lcrecords should be here. */
3466                 assert(free_header->lcheader.free);
3467                 /* The type of the lcrecord must be right. */
3468                 assert(LHEADER_IMPLEMENTATION(lheader) == list->implementation);
3469                 /* So must the size. */
3470                 assert(LHEADER_IMPLEMENTATION(lheader)->static_size == 0 ||
3471                        LHEADER_IMPLEMENTATION(lheader)->static_size ==
3472                        list->size);
3473 #endif                          /* ERROR_CHECK_GC */
3474
3475                 list->free = free_header->chain;
3476                 free_header->lcheader.free = 0;
3477                 return val;
3478         } else {
3479                 void *tmp = alloc_lcrecord(list->size, list->implementation);
3480                 Lisp_Object val;
3481
3482                 XSETOBJ(val, tmp);
3483                 return val;
3484         }
3485 }
3486
3487 void
3488 free_managed_lcrecord(Lisp_Object lcrecord_list, Lisp_Object lcrecord)
3489 {
3490         struct lcrecord_list *list = XLCRECORD_LIST(lcrecord_list);
3491         struct free_lcrecord_header *free_header =
3492                 (struct free_lcrecord_header*)XPNTR(lcrecord);
3493         struct lrecord_header *lheader = &free_header->lcheader.lheader;
3494         const struct lrecord_implementation *implementation
3495             = LHEADER_IMPLEMENTATION(lheader);
3496
3497         /* Make sure the size is correct.  This will catch, for example,
3498            putting a window configuration on the wrong free list. */
3499         gc_checking_assert((implementation->size_in_bytes_method ?
3500                             implementation->size_in_bytes_method(lheader) :
3501                             implementation->static_size)
3502                            == list->size);
3503
3504         if (implementation->finalizer) {
3505                 implementation->finalizer(lheader, 0);
3506         }
3507         free_header->chain = list->free;
3508         free_header->lcheader.free = 1;
3509         list->free = lcrecord;
3510 }
3511 #endif  /* BDWGC */
3512
3513 DEFINE_LRECORD_IMPLEMENTATION("lcrecord-list", lcrecord_list,
3514                               mark_lcrecord_list, internal_object_printer,
3515                               0, 0, 0, 0, struct lcrecord_list);
3516
3517 \f
3518 DEFUN("purecopy", Fpurecopy, 1, 1, 0,   /*
3519 Kept for compatibility, returns its argument.
3520 Old:
3521 Make a copy of OBJECT in pure storage.
3522 Recursively copies contents of vectors and cons cells.
3523 Does not copy symbols.
3524 */
3525       (object))
3526 {
3527         return object;
3528 }
3529 \f
3530 /************************************************************************/
3531 /*                         Garbage Collection                           */
3532 /************************************************************************/
3533
3534 /* All the built-in lisp object types are enumerated in `enum lrecord_type'.
3535    Additional ones may be defined by a module (none yet).  We leave some
3536    room in `lrecord_implementations_table' for such new lisp object types. */
3537 const struct lrecord_implementation
3538     *lrecord_implementations_table[(unsigned int)lrecord_type_last_built_in_type
3539                                    + MODULE_DEFINABLE_TYPE_COUNT];
3540 unsigned int lrecord_type_count = (unsigned int)lrecord_type_last_built_in_type;
3541 /* Object marker functions are in the lrecord_implementation structure.
3542    But copying them to a parallel array is much more cache-friendly.
3543    This hack speeds up (garbage-collect) by about 5%. */
3544 Lisp_Object(*lrecord_markers[countof(lrecord_implementations_table)])
3545     (Lisp_Object);
3546
3547 #ifndef EF_USE_ASYNEQ
3548 struct gcpro *gcprolist;
3549 #endif
3550
3551 /* We want the staticpros relocated, but not the pointers found therein.
3552    Hence we use a trivial description, as for pointerless objects. */
3553 static const struct lrecord_description staticpro_description_1[] = {
3554         {XD_END}
3555 };
3556
3557 static const struct struct_description staticpro_description = {
3558         sizeof(Lisp_Object *),
3559         staticpro_description_1
3560 };
3561
3562 static const struct lrecord_description staticpros_description_1[] = {
3563         XD_DYNARR_DESC(Lisp_Object_ptr_dynarr, &staticpro_description),
3564         {XD_END}
3565 };
3566
3567 static const struct struct_description staticpros_description = {
3568         sizeof(Lisp_Object_ptr_dynarr),
3569         staticpros_description_1
3570 };
3571
3572 Lisp_Object_ptr_dynarr *staticpros;
3573
3574 /* Mark the Lisp_Object at non-heap VARADDRESS as a root object for
3575    garbage collection, and for dumping. */
3576 void staticpro(Lisp_Object * varaddress)
3577 {
3578         lock_allocator();
3579         Dynarr_add(staticpros, varaddress);
3580         dump_add_root_object(varaddress);
3581         unlock_allocator();
3582 }
3583
3584 #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
3585 Lisp_Object_ptr_dynarr *staticpros_nodump;
3586
3587 /* Mark the Lisp_Object at non-heap VARADDRESS as a root object for
3588    garbage collection, but not for dumping. */
3589 void staticpro_nodump(Lisp_Object * varaddress)
3590 {
3591         lock_allocator();
3592         Dynarr_add(staticpros_nodump, varaddress);
3593         unlock_allocator();
3594 }
3595 #endif  /* !BDWGC */
3596
3597
3598 #ifdef ERROR_CHECK_GC
3599 #define GC_CHECK_LHEADER_INVARIANTS(lheader)                            \
3600         do {                                                            \
3601                 struct lrecord_header * GCLI_lh = (lheader);            \
3602                 assert (GCLI_lh != 0);                                  \
3603                 assert (GCLI_lh->type < lrecord_type_count);            \
3604                 assert (! C_READONLY_RECORD_HEADER_P (GCLI_lh) ||       \
3605                         (MARKED_RECORD_HEADER_P (GCLI_lh) &&            \
3606                          LISP_READONLY_RECORD_HEADER_P (GCLI_lh)));     \
3607         } while (0)
3608 #else
3609 #define GC_CHECK_LHEADER_INVARIANTS(lheader)
3610 #endif
3611 \f
3612 /* Mark reference to a Lisp_Object.  If the object referred to has not been
3613    seen yet, recursively mark all the references contained in it. */
3614
3615 #if defined HAVE_BDWGC && defined EF_USE_BDWGC
3616 void mark_object(Lisp_Object SXE_UNUSED(obj))
3617 {
3618         return;
3619 }
3620
3621 #else  /* !BDWGC */
3622 void mark_object(Lisp_Object obj)
3623 {
3624         if (obj == Qnull_pointer) {
3625                 return;
3626         }
3627
3628 tail_recurse:
3629         /* Checks we used to perform */
3630         /* if (EQ (obj, Qnull_pointer)) return; */
3631         /* if (!POINTER_TYPE_P (XGCTYPE (obj))) return; */
3632         /* if (PURIFIED (XPNTR (obj))) return; */
3633
3634         if (XTYPE(obj) == Lisp_Type_Record) {
3635                 struct lrecord_header *lheader = XRECORD_LHEADER(obj);
3636
3637                 GC_CHECK_LHEADER_INVARIANTS(lheader);
3638
3639                 gc_checking_assert(LHEADER_IMPLEMENTATION(lheader)->basic_p ||
3640                                    !((struct lcrecord_header *)lheader)->free);
3641
3642                 /* All c_readonly objects have their mark bit set,
3643                    so that we only need to check the mark bit here. */
3644                 if (!MARKED_RECORD_HEADER_P(lheader)) {
3645                         MARK_RECORD_HEADER(lheader);
3646
3647                         if (RECORD_MARKER(lheader)) {
3648                                 obj = RECORD_MARKER(lheader) (obj);
3649                                 if (!NILP(obj))
3650                                         goto tail_recurse;
3651                         }
3652                 }
3653         }
3654 }
3655 #endif  /* BDWGC */
3656
3657 /* mark all of the conses in a list and mark the final cdr; but
3658    DO NOT mark the cars.
3659
3660    Use only for internal lists!  There should never be other pointers
3661    to the cons cells, because if so, the cars will remain unmarked
3662    even when they maybe should be marked. */
3663 void mark_conses_in_list(Lisp_Object obj)
3664 {
3665         Lisp_Object rest;
3666
3667         for (rest = obj; CONSP(rest); rest = XCDR(rest)) {
3668                 if (CONS_MARKED_P(XCONS(rest)))
3669                         return;
3670                 MARK_CONS(XCONS(rest));
3671         }
3672
3673         mark_object(rest);
3674 }
3675 \f
3676 /* Find all structures not marked, and free them. */
3677
3678 #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
3679 static int gc_count_num_bit_vector_used, gc_count_bit_vector_total_size;
3680 static int gc_count_bit_vector_storage;
3681 static int gc_count_num_short_string_in_use;
3682 static int gc_count_string_total_size;
3683 static int gc_count_short_string_total_size;
3684 #endif  /* !BDWGC */
3685
3686 /* static int gc_count_total_records_used, gc_count_records_total_size; */
3687 \f
3688 /* stats on lcrecords in use - kinda kludgy */
3689
3690 #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
3691 static struct {
3692         int instances_in_use;
3693         int bytes_in_use;
3694         int instances_freed;
3695         int bytes_freed;
3696         int instances_on_free_list;
3697 } lcrecord_stats[countof(lrecord_implementations_table)
3698                  + MODULE_DEFINABLE_TYPE_COUNT];
3699 #endif  /* !BDWGC */
3700
3701 #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
3702 static void tick_lcrecord_stats(const struct lrecord_header *h, int free_p)
3703 {
3704         unsigned int type_index = h->type;
3705
3706         if (((const struct lcrecord_header *)h)->free) {
3707                 gc_checking_assert(!free_p);
3708                 lcrecord_stats[type_index].instances_on_free_list++;
3709         } else {
3710                 const struct lrecord_implementation *implementation =
3711                     LHEADER_IMPLEMENTATION(h);
3712
3713                 size_t sz = (implementation->size_in_bytes_method ?
3714                              implementation->size_in_bytes_method(h) :
3715                              implementation->static_size);
3716                 if (free_p) {
3717                         lcrecord_stats[type_index].instances_freed++;
3718                         lcrecord_stats[type_index].bytes_freed += sz;
3719                 } else {
3720                         lcrecord_stats[type_index].instances_in_use++;
3721                         lcrecord_stats[type_index].bytes_in_use += sz;
3722                 }
3723         }
3724 }
3725 #endif  /* !BDWGC */
3726 \f
3727 /* Free all unmarked records */
3728 #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
3729 static void
3730 sweep_lcrecords_1(struct lcrecord_header *volatile*prev, int *used)
3731 {
3732         int num_used = 0;
3733         /* int total_size = 0; */
3734
3735         xzero(lcrecord_stats);  /* Reset all statistics to 0. */
3736
3737         /* First go through and call all the finalize methods.
3738            Then go through and free the objects.  There used to
3739            be only one loop here, with the call to the finalizer
3740            occurring directly before the xfree() below.  That
3741            is marginally faster but much less safe -- if the
3742            finalize method for an object needs to reference any
3743            other objects contained within it (and many do),
3744            we could easily be screwed by having already freed that
3745            other object. */
3746
3747         for (struct lcrecord_header *volatile header = *prev;
3748              header; header = header->next) {
3749                 struct lrecord_header *h = &(header->lheader);
3750
3751                 GC_CHECK_LHEADER_INVARIANTS(h);
3752
3753                 if (!MARKED_RECORD_HEADER_P(h) && !header->free) {
3754                         if (LHEADER_IMPLEMENTATION(h)->finalizer)
3755                                 LHEADER_IMPLEMENTATION(h)->finalizer(h, 0);
3756                 }
3757         }
3758
3759         for (struct lcrecord_header *volatile header = *prev; header;) {
3760                 struct lrecord_header *volatile h = &(header->lheader);
3761                 if (MARKED_RECORD_HEADER_P(h)) {
3762                         if (!C_READONLY_RECORD_HEADER_P(h))
3763                                 UNMARK_RECORD_HEADER(h);
3764                         num_used++;
3765                         /* total_size += n->implementation->size_in_bytes (h); */
3766                         /* #### May modify header->next on a C_READONLY lcrecord */
3767                         prev = &(header->next);
3768                         header = *prev;
3769                         tick_lcrecord_stats(h, 0);
3770                 } else {
3771                         struct lcrecord_header *next = header->next;
3772                         *prev = next;
3773                         tick_lcrecord_stats(h, 1);
3774                         /* used to call finalizer right here. */
3775                         xfree(header);
3776                         header = next;
3777                 }
3778         }
3779         *used = num_used;
3780         /* *total = total_size; */
3781         return;
3782 }
3783
3784 static void
3785 sweep_bit_vectors_1(Lisp_Object * prev, int *used, int *total, int *storage)
3786 {
3787         Lisp_Object bit_vector;
3788         int num_used = 0;
3789         int total_size = 0;
3790         int total_storage = 0;
3791
3792         /* BIT_VECTORP fails because the objects are marked, which changes
3793            their implementation */
3794         for (bit_vector = *prev; !EQ(bit_vector, Qzero);) {
3795                 Lisp_Bit_Vector *v = XBIT_VECTOR(bit_vector);
3796                 int len = v->size;
3797                 if (MARKED_RECORD_P(bit_vector)) {
3798                         if (!C_READONLY_RECORD_HEADER_P(&(v->lheader)))
3799                                 UNMARK_RECORD_HEADER(&(v->lheader));
3800                         total_size += len;
3801                         total_storage +=
3802                             MALLOC_OVERHEAD +
3803                             FLEXIBLE_ARRAY_STRUCT_SIZEOF(Lisp_Bit_Vector,
3804                                                          unsigned long, bits,
3805                                                          BIT_VECTOR_LONG_STORAGE
3806                                                          (len));
3807                         num_used++;
3808                         /* #### May modify next on a C_READONLY bitvector */
3809                         prev = &(bit_vector_next(v));
3810                         bit_vector = *prev;
3811                 } else {
3812                         Lisp_Object next = bit_vector_next(v);
3813                         *prev = next;
3814                         xfree(v);
3815                         bit_vector = next;
3816                 }
3817         }
3818         *used = num_used;
3819         *total = total_size;
3820         *storage = total_storage;
3821 }
3822 #endif  /* !BDWGC */
3823
3824 /* And the Lord said: Thou shalt use the `c-backslash-region' command
3825    to make macros prettier. */
3826
3827 #if defined HAVE_BDWGC && defined EF_USE_BDWGC
3828 #define SWEEP_FIXED_TYPE_BLOCK(typename, obj_type)
3829
3830 #elif defined ERROR_CHECK_GC
3831
3832 #define SWEEP_FIXED_TYPE_BLOCK(typename, obj_type)                      \
3833         do {                                                            \
3834                 struct typename##_block *SFTB_current;                  \
3835                 int SFTB_limit;                                         \
3836                 int num_free = 0, num_used = 0;                         \
3837                                                                         \
3838                 for (SFTB_current = current_##typename##_block,         \
3839                              SFTB_limit = current_##typename##_block_index; \
3840                      SFTB_current;                                      \
3841                         ) {                                             \
3842                         int SFTB_iii;                                   \
3843                                                                         \
3844                         for (SFTB_iii = 0;                              \
3845                              SFTB_iii < SFTB_limit;                     \
3846                              SFTB_iii++) {                              \
3847                                 obj_type *SFTB_victim =                 \
3848                                         &(SFTB_current->block[SFTB_iii]); \
3849                                                                         \
3850                                 if (LRECORD_FREE_P (SFTB_victim)) {     \
3851                                         num_free++;                     \
3852                                 } else if (C_READONLY_RECORD_HEADER_P   \
3853                                            (&SFTB_victim->lheader)) {   \
3854                                         num_used++;                     \
3855                                 } else if (!MARKED_RECORD_HEADER_P      \
3856                                            (&SFTB_victim->lheader)) {   \
3857                                         num_free++;                     \
3858                                         FREE_FIXED_TYPE(typename, obj_type, \
3859                                                         SFTB_victim);   \
3860                                 } else {                                \
3861                                         num_used++;                     \
3862                                         UNMARK_##typename(SFTB_victim); \
3863                                 }                                       \
3864                         }                                               \
3865                         SFTB_current = SFTB_current->prev;              \
3866                         SFTB_limit = countof(current_##typename##_block \
3867                                              ->block);                  \
3868                 }                                                       \
3869                                                                         \
3870                 gc_count_num_##typename##_in_use = num_used;            \
3871                 gc_count_num_##typename##_freelist = num_free;          \
3872         } while (0)
3873
3874 #else  /* !ERROR_CHECK_GC, !BDWGC*/
3875
3876 #define SWEEP_FIXED_TYPE_BLOCK(typename, obj_type)                      \
3877         do {                                                            \
3878                 struct typename##_block *SFTB_current;                  \
3879                 struct typename##_block **SFTB_prev;                    \
3880                 int SFTB_limit;                                         \
3881                 int num_free = 0, num_used = 0;                         \
3882                                                                         \
3883                 typename##_free_list = 0;                               \
3884                                                                         \
3885                 for (SFTB_prev = &current_##typename##_block,           \
3886                              SFTB_current = current_##typename##_block, \
3887                              SFTB_limit = current_##typename##_block_index; \
3888                      SFTB_current;                                      \
3889                         ) {                                                     \
3890                         int SFTB_iii;                                   \
3891                         int SFTB_empty = 1;                             \
3892                         Lisp_Free *SFTB_old_free_list =                 \
3893                                 typename##_free_list;                   \
3894                                                                         \
3895                         for (SFTB_iii = 0; SFTB_iii < SFTB_limit;       \
3896                              SFTB_iii++) {                              \
3897                                 obj_type *SFTB_victim =                 \
3898                                         &(SFTB_current->block[SFTB_iii]); \
3899                                                                         \
3900                                 if (LRECORD_FREE_P (SFTB_victim)) {     \
3901                                         num_free++;                     \
3902                                         PUT_FIXED_TYPE_ON_FREE_LIST     \
3903                                                 (typename, obj_type,    \
3904                                                  SFTB_victim);          \
3905                                 } else if (C_READONLY_RECORD_HEADER_P   \
3906                                            (&SFTB_victim->lheader)) {   \
3907                                         SFTB_empty = 0;                 \
3908                                         num_used++;                     \
3909                                 } else if (! MARKED_RECORD_HEADER_P     \
3910                                            (&SFTB_victim->lheader)) {   \
3911                                         num_free++;                     \
3912                                         FREE_FIXED_TYPE(typename, obj_type, \
3913                                                         SFTB_victim);   \
3914                                 } else {                                \
3915                                         SFTB_empty = 0;                 \
3916                                         num_used++;                     \
3917                                         UNMARK_##typename (SFTB_victim); \
3918                                 }                                       \
3919                         }                                               \
3920                         if (!SFTB_empty) {                              \
3921                                 SFTB_prev = &(SFTB_current->prev);      \
3922                                 SFTB_current = SFTB_current->prev;      \
3923                         } else if (SFTB_current == current_##typename##_block \
3924                                    && !SFTB_current->prev) {            \
3925                                 /* No real point in freeing sole        \
3926                                  * allocation block */                  \
3927                                 break;                                  \
3928                         } else {                                        \
3929                                 struct typename##_block *SFTB_victim_block = \
3930                                         SFTB_current;                   \
3931                                 if (SFTB_victim_block ==                \
3932                                     current_##typename##_block) {       \
3933                                         current_##typename##_block_index \
3934                                                 = countof               \
3935                                                 (current_##typename##_block \
3936                                                  ->block);              \
3937                                 }                                       \
3938                                 SFTB_current = SFTB_current->prev;      \
3939                                 {                                       \
3940                                         *SFTB_prev = SFTB_current;      \
3941                                         xfree(SFTB_victim_block);       \
3942                                         /* Restore free list to what it was \
3943                                            before victim was swept */   \
3944                                         typename##_free_list =          \
3945                                                 SFTB_old_free_list;     \
3946                                         num_free -= SFTB_limit;         \
3947                                 }                                       \
3948                         }                                               \
3949                         SFTB_limit = countof (current_##typename##_block \
3950                                               ->block);                 \
3951                 }                                                       \
3952                                                                         \
3953                 gc_count_num_##typename##_in_use = num_used;            \
3954                 gc_count_num_##typename##_freelist = num_free;          \
3955         } while (0)
3956
3957 #endif  /* !ERROR_CHECK_GC */
3958 \f
3959 #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
3960 static void sweep_conses(void)
3961 {
3962 #define UNMARK_cons(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
3963 #define ADDITIONAL_FREE_cons(ptr)
3964
3965         SWEEP_FIXED_TYPE_BLOCK(cons, Lisp_Cons);
3966 }
3967 #endif  /* !BDWGC */
3968
3969 /* Explicitly free a cons cell.  */
3970 void free_cons(Lisp_Cons * ptr)
3971 {
3972 #ifdef ERROR_CHECK_GC
3973         /* If the CAR is not an int, then it will be a pointer, which will
3974            always be four-byte aligned.  If this cons cell has already been
3975            placed on the free list, however, its car will probably contain
3976            a chain pointer to the next cons on the list, which has cleverly
3977            had all its 0's and 1's inverted.  This allows for a quick
3978            check to make sure we're not freeing something already freed. */
3979         if (POINTER_TYPE_P(XTYPE(ptr->car)))
3980                 ASSERT_VALID_POINTER(XPNTR(ptr->car));
3981 #endif                          /* ERROR_CHECK_GC */
3982
3983 #ifndef ALLOC_NO_POOLS
3984         FREE_FIXED_TYPE_WHEN_NOT_IN_GC(cons, Lisp_Cons, ptr);
3985 #endif                          /* ALLOC_NO_POOLS */
3986 }
3987
3988 /* explicitly free a list.  You **must make sure** that you have
3989    created all the cons cells that make up this list and that there
3990    are no pointers to any of these cons cells anywhere else.  If there
3991    are, you will lose. */
3992
3993 void free_list(Lisp_Object list)
3994 {
3995         Lisp_Object rest, next;
3996
3997         for (rest = list; !NILP(rest); rest = next) {
3998                 next = XCDR(rest);
3999                 free_cons(XCONS(rest));
4000         }
4001 }
4002
4003 /* explicitly free an alist.  You **must make sure** that you have
4004    created all the cons cells that make up this alist and that there
4005    are no pointers to any of these cons cells anywhere else.  If there
4006    are, you will lose. */
4007
4008 void free_alist(Lisp_Object alist)
4009 {
4010         Lisp_Object rest, next;
4011
4012         for (rest = alist; !NILP(rest); rest = next) {
4013                 next = XCDR(rest);
4014                 free_cons(XCONS(XCAR(rest)));
4015                 free_cons(XCONS(rest));
4016         }
4017 }
4018
4019 #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
4020 static void sweep_compiled_functions(void)
4021 {
4022 #define UNMARK_compiled_function(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
4023 #define ADDITIONAL_FREE_compiled_function(ptr)
4024
4025         SWEEP_FIXED_TYPE_BLOCK(compiled_function, Lisp_Compiled_Function);
4026 }
4027
4028 #ifdef HAVE_FPFLOAT
4029 static void sweep_floats(void)
4030 {
4031 #define UNMARK_float(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
4032 #define ADDITIONAL_FREE_float(ptr)
4033
4034         SWEEP_FIXED_TYPE_BLOCK(float, Lisp_Float);
4035 }
4036 #endif  /* HAVE_FPFLOAT */
4037
4038 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
4039 static void
4040 sweep_bigzs (void)
4041 {
4042 #define UNMARK_bigz(ptr) UNMARK_RECORD_HEADER(&((ptr)->lheader))
4043 #define ADDITIONAL_FREE_bigz(ptr) bigz_fini(ptr->data)
4044
4045         SWEEP_FIXED_TYPE_BLOCK(bigz, Lisp_Bigz);
4046 }
4047 #endif /* HAVE_MPZ */
4048
4049 #if defined HAVE_MPQ && defined WITH_GMP
4050 static void
4051 sweep_bigqs (void)
4052 {
4053 #define UNMARK_bigq(ptr) UNMARK_RECORD_HEADER(&((ptr)->lheader))
4054 #define ADDITIONAL_FREE_bigq(ptr) bigq_fini(ptr->data)
4055
4056         SWEEP_FIXED_TYPE_BLOCK(bigq, Lisp_Bigq);
4057 }
4058 #endif /* HAVE_MPQ */
4059
4060 #if defined HAVE_MPF && defined WITH_GMP
4061 static void
4062 sweep_bigfs (void)
4063 {
4064 #define UNMARK_bigf(ptr) UNMARK_RECORD_HEADER(&((ptr)->lheader))
4065 #define ADDITIONAL_FREE_bigf(ptr) bigf_fini(ptr->data)
4066
4067         SWEEP_FIXED_TYPE_BLOCK(bigf, Lisp_Bigf);
4068 }
4069 #endif  /* HAVE_MPF */
4070
4071 #if defined HAVE_MPFR && defined WITH_MPFR
4072 static void
4073 sweep_bigfrs (void)
4074 {
4075 #define UNMARK_bigfr(ptr) UNMARK_RECORD_HEADER(&((ptr)->lheader))
4076 #define ADDITIONAL_FREE_bigfr(ptr) bigfr_fini(ptr->data)
4077
4078         SWEEP_FIXED_TYPE_BLOCK(bigfr, Lisp_Bigfr);
4079 }
4080 #endif  /* HAVE_MPFR */
4081
4082 #if defined HAVE_PSEUG && defined WITH_PSEUG
4083 static void
4084 sweep_biggs (void)
4085 {
4086 #define UNMARK_bigg(ptr) UNMARK_RECORD_HEADER(&((ptr)->lheader))
4087 #define ADDITIONAL_FREE_bigg(ptr) bigg_fini(ptr->data)
4088
4089         SWEEP_FIXED_TYPE_BLOCK(bigg, Lisp_Bigg);
4090 }
4091 #endif  /* HAVE_PSEUG */
4092
4093 #if defined HAVE_MPC && defined WITH_MPC ||     \
4094         defined HAVE_PSEUC && defined WITH_PSEUC
4095 static void
4096 sweep_bigcs (void)
4097 {
4098 #define UNMARK_bigc(ptr) UNMARK_RECORD_HEADER(&((ptr)->lheader))
4099 #define ADDITIONAL_FREE_bigc(ptr) bigc_fini(ptr->data)
4100
4101         SWEEP_FIXED_TYPE_BLOCK(bigc, Lisp_Bigc);
4102 }
4103 #endif  /* HAVE_MPC */
4104
4105 #if defined HAVE_QUATERN && defined HAVE_MPZ && defined WITH_QUATERN
4106 static void
4107 sweep_quaterns (void)
4108 {
4109 #define UNMARK_quatern(ptr) UNMARK_RECORD_HEADER(&((ptr)->lheader))
4110 #define ADDITIONAL_FREE_quatern(ptr) quatern_fini(ptr->data)
4111
4112         SWEEP_FIXED_TYPE_BLOCK(quatern, Lisp_Quatern);
4113 }
4114 #endif  /* HAVE_QUATERN */
4115
4116 static void
4117 sweep_dynacats(void)
4118 {
4119 #define UNMARK_dynacat(ptr) UNMARK_RECORD_HEADER(&((ptr)->lheader))
4120 #define ADDITIONAL_FREE_dynacat(ptr) dynacat_fini(ptr);
4121
4122         SWEEP_FIXED_TYPE_BLOCK(dynacat, struct dynacat_s);
4123 }
4124
4125 static void sweep_symbols(void)
4126 {
4127 #define UNMARK_symbol(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
4128 #define ADDITIONAL_FREE_symbol(ptr)
4129
4130         SWEEP_FIXED_TYPE_BLOCK(symbol, Lisp_Symbol);
4131 }
4132
4133 static void sweep_extents(void)
4134 {
4135 #define UNMARK_extent(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
4136 #define ADDITIONAL_FREE_extent(ptr)
4137
4138         SWEEP_FIXED_TYPE_BLOCK(extent, struct extent);
4139 }
4140
4141 static void sweep_events(void)
4142 {
4143 #define UNMARK_event(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
4144 #define ADDITIONAL_FREE_event(ptr)
4145
4146         SWEEP_FIXED_TYPE_BLOCK(event, Lisp_Event);
4147 }
4148
4149 static void sweep_markers(void)
4150 {
4151 #define UNMARK_marker(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
4152 #define ADDITIONAL_FREE_marker(ptr)                                     \
4153   do { Lisp_Object tem;                                                 \
4154        XSETMARKER (tem, ptr);                                           \
4155        unchain_marker (tem);                                            \
4156      } while (0)
4157
4158         SWEEP_FIXED_TYPE_BLOCK(marker, Lisp_Marker);
4159 }
4160 #endif  /* !BDWGC */
4161
4162 /* Explicitly free a marker.  */
4163 void free_marker(Lisp_Marker * ptr)
4164 {
4165         /* Perhaps this will catch freeing an already-freed marker. */
4166         gc_checking_assert(ptr->lheader.type == lrecord_type_marker);
4167
4168 #ifndef ALLOC_NO_POOLS
4169         FREE_FIXED_TYPE_WHEN_NOT_IN_GC(marker, Lisp_Marker, ptr);
4170 #endif                          /* ALLOC_NO_POOLS */
4171 }
4172 \f
4173 #if defined (MULE) && defined (VERIFY_STRING_CHARS_INTEGRITY)
4174
4175 static void verify_string_chars_integrity(void)
4176 {
4177         struct string_chars_block *sb;
4178
4179         /* Scan each existing string block sequentially, string by string.  */
4180         for (sb = first_string_chars_block; sb; sb = sb->next) {
4181                 int pos = 0;
4182                 /* POS is the index of the next string in the block.  */
4183                 while (pos < sb->pos) {
4184                         struct string_chars *s_chars =
4185                             (struct string_chars *)&(sb->string_chars[pos]);
4186                         Lisp_String *string;
4187                         int size;
4188                         int fullsize;
4189
4190                         /* If the string_chars struct is marked as free (i.e. the
4191                            STRING pointer is NULL) then this is an unused chunk of
4192                            string storage. (See below.) */
4193
4194                         if (STRING_CHARS_FREE_P(s_chars)) {
4195                                 fullsize =
4196                                     ((struct unused_string_chars *)s_chars)->
4197                                     fullsize;
4198                                 pos += fullsize;
4199                                 continue;
4200                         }
4201
4202                         string = s_chars->string;
4203                         /* Must be 32-bit aligned. */
4204                         assert((((int)string) & 3) == 0);
4205
4206                         size = string_length(string);
4207                         fullsize = STRING_FULLSIZE(size);
4208
4209                         assert(!BIG_STRING_FULLSIZE_P(fullsize));
4210                         assert(string_data(string) == s_chars->chars);
4211                         pos += fullsize;
4212                 }
4213                 assert(pos == sb->pos);
4214         }
4215 }
4216
4217 #endif                          /* MULE && ERROR_CHECK_GC */
4218
4219 #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
4220 /* Compactify string chars, relocating the reference to each --
4221    free any empty string_chars_block we see. */
4222 static void compact_string_chars(void)
4223 {
4224         struct string_chars_block *to_sb = first_string_chars_block;
4225         int to_pos = 0;
4226         struct string_chars_block *from_sb;
4227
4228         /* Scan each existing string block sequentially, string by string.  */
4229         for (from_sb = first_string_chars_block; from_sb;
4230              from_sb = from_sb->next) {
4231                 int from_pos = 0;
4232                 /* FROM_POS is the index of the next string in the block.  */
4233                 while (from_pos < from_sb->pos) {
4234                         struct string_chars *from_s_chars =
4235                             (struct string_chars *)&(from_sb->
4236                                                      string_chars[from_pos]);
4237                         struct string_chars *to_s_chars;
4238                         Lisp_String *string;
4239                         int size;
4240                         int fullsize;
4241
4242                         /* If the string_chars struct is marked as free (i.e. the
4243                            STRING pointer is NULL) then this is an unused chunk of
4244                            string storage.  This happens under Mule when a string's
4245                            size changes in such a way that its fullsize changes.
4246                            (Strings can change size because a different-length
4247                            character can be substituted for another character.)
4248                            In this case, after the bogus string pointer is the
4249                            "fullsize" of this entry, i.e. how many bytes to skip. */
4250
4251                         if (STRING_CHARS_FREE_P(from_s_chars)) {
4252                                 fullsize =
4253                                     ((struct unused_string_chars *)
4254                                      from_s_chars)->fullsize;
4255                                 from_pos += fullsize;
4256                                 continue;
4257                         }
4258
4259                         string = from_s_chars->string;
4260                         assert(!(LRECORD_FREE_P(string)));
4261
4262                         size = string_length(string);
4263                         fullsize = STRING_FULLSIZE(size);
4264
4265                         gc_checking_assert(!BIG_STRING_FULLSIZE_P(fullsize));
4266
4267                         /* Just skip it if it isn't marked.  */
4268                         if (!MARKED_RECORD_HEADER_P(&(string->lheader))) {
4269                                 from_pos += fullsize;
4270                                 continue;
4271                         }
4272
4273                         /* If it won't fit in what's left of TO_SB, close TO_SB
4274                            out and go on to the next string_chars_block.  We
4275                            know that TO_SB cannot advance past FROM_SB here
4276                            since FROM_SB is large enough to currently contain
4277                            this string. */
4278                         if ((to_pos + fullsize) >
4279                             countof(to_sb->string_chars)) {
4280                                 to_sb->pos = to_pos;
4281                                 to_sb = to_sb->next;
4282                                 to_pos = 0;
4283                         }
4284
4285                         /* Compute new address of this string
4286                            and update TO_POS for the space being used.  */
4287                         to_s_chars =
4288                             (struct string_chars *)&(to_sb->
4289                                                      string_chars[to_pos]);
4290
4291                         /* Copy the string_chars to the new place.  */
4292                         if (from_s_chars != to_s_chars)
4293                                 memmove(to_s_chars, from_s_chars, fullsize);
4294
4295                         /* Relocate FROM_S_CHARS's reference */
4296                         set_string_data(string, &(to_s_chars->chars[0]));
4297
4298                         from_pos += fullsize;
4299                         to_pos += fullsize;
4300                 }
4301         }
4302
4303         /* Set current to the last string chars block still used and
4304            free any that follow. */
4305         for (volatile struct string_chars_block *victim = to_sb->next;
4306              victim;) {
4307                 volatile struct string_chars_block *tofree = victim;
4308                 victim = victim->next;
4309                 xfree(tofree);
4310         }
4311
4312         current_string_chars_block = to_sb;
4313         current_string_chars_block->pos = to_pos;
4314         current_string_chars_block->next = 0;
4315 }
4316
4317 static int debug_string_purity;
4318
4319 static void debug_string_purity_print(Lisp_String * p)
4320 {
4321         Charcount i;
4322         Charcount s = string_char_length(p);
4323         stderr_out("\"");
4324         for (i = 0; i < s; i++) {
4325                 Emchar ch = string_char(p, i);
4326                 if (ch < 32 || ch >= 126)
4327                         stderr_out("\\%03o", ch);
4328                 else if (ch == '\\' || ch == '\"')
4329                         stderr_out("\\%c", ch);
4330                 else
4331                         stderr_out("%c", ch);
4332         }
4333         stderr_out("\"\n");
4334 }
4335 #endif  /* !BDWGC */
4336
4337 #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
4338 static void sweep_strings(void)
4339 {
4340         int num_small_used = 0, num_small_bytes = 0, num_bytes = 0;
4341         int debug = debug_string_purity;
4342
4343 #define UNMARK_string(ptr)                              \
4344         do {                                            \
4345                 Lisp_String *p = (ptr);                 \
4346                 size_t size = string_length (p);        \
4347                 UNMARK_RECORD_HEADER (&(p->lheader));   \
4348                 num_bytes += size;                      \
4349                 if (!BIG_STRING_SIZE_P (size)) {        \
4350                         num_small_bytes += size;        \
4351                         num_small_used++;               \
4352                 }                                       \
4353                 if (debug)                              \
4354                         debug_string_purity_print (p);  \
4355         } while (0)
4356 #define ADDITIONAL_FREE_string(ptr)                     \
4357         do {                                            \
4358                 size_t size = string_length (ptr);      \
4359                 if (BIG_STRING_SIZE_P(size)) {          \
4360                         yfree(ptr->data);               \
4361                 }                                       \
4362         } while (0)
4363
4364         SWEEP_FIXED_TYPE_BLOCK(string, Lisp_String);
4365
4366         gc_count_num_short_string_in_use = num_small_used;
4367         gc_count_string_total_size = num_bytes;
4368         gc_count_short_string_total_size = num_small_bytes;
4369 }
4370 #endif  /* !BDWGC */
4371
4372 /* I hate duplicating all this crap! */
4373 int marked_p(Lisp_Object obj)
4374 {
4375         /* Checks we used to perform. */
4376         /* if (EQ (obj, Qnull_pointer)) return 1; */
4377         /* if (!POINTER_TYPE_P (XGCTYPE (obj))) return 1; */
4378         /* if (PURIFIED (XPNTR (obj))) return 1; */
4379
4380         if (XTYPE(obj) == Lisp_Type_Record) {
4381                 struct lrecord_header *lheader = XRECORD_LHEADER(obj);
4382
4383                 GC_CHECK_LHEADER_INVARIANTS(lheader);
4384
4385                 return MARKED_RECORD_HEADER_P(lheader);
4386         }
4387         return 1;
4388 }
4389
4390 #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
4391 static void gc_sweep(void)
4392 {
4393         /* Free all unmarked records.  Do this at the very beginning,
4394            before anything else, so that the finalize methods can safely
4395            examine items in the objects.  sweep_lcrecords_1() makes
4396            sure to call all the finalize methods *before* freeing anything,
4397            to complete the safety. */
4398         {
4399                 int ignored;
4400                 sweep_lcrecords_1(&all_lcrecords, &ignored);
4401         }
4402
4403         compact_string_chars();
4404
4405         /* Finalize methods below (called through the ADDITIONAL_FREE_foo
4406            macros) must be *extremely* careful to make sure they're not
4407            referencing freed objects.  The only two existing finalize
4408            methods (for strings and markers) pass muster -- the string
4409            finalizer doesn't look at anything but its own specially-
4410            created block, and the marker finalizer only looks at live
4411            buffers (which will never be freed) and at the markers before
4412            and after it in the chain (which, by induction, will never be
4413            freed because if so, they would have already removed themselves
4414            from the chain). */
4415
4416         /* Put all unmarked strings on free list, free'ing the string chars
4417            of large unmarked strings */
4418         sweep_strings();
4419
4420         /* Put all unmarked conses on free list */
4421         sweep_conses();
4422
4423         /* Free all unmarked bit vectors */
4424         sweep_bit_vectors_1(&all_bit_vectors,
4425                             &gc_count_num_bit_vector_used,
4426                             &gc_count_bit_vector_total_size,
4427                             &gc_count_bit_vector_storage);
4428
4429         /* Free all unmarked compiled-function objects */
4430         sweep_compiled_functions();
4431
4432 #ifdef HAVE_FPFLOAT
4433         /* Put all unmarked floats on free list */
4434         sweep_floats();
4435 #endif  /* HAVE_FPFLOAT */
4436
4437 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
4438         /* Put all unmarked bignums on free list */
4439         sweep_bigzs();
4440 #endif  /* HAVE_MPZ */
4441
4442 #if defined HAVE_MPQ && defined WITH_GMP
4443         /* Put all unmarked ratios on free list */
4444         sweep_bigqs();
4445 #endif  /* HAVE_MPQ */
4446
4447 #if defined HAVE_MPF && defined WITH_GMP
4448         /* Put all unmarked bigfloats on free list */
4449         sweep_bigfs();
4450 #endif  /* HAVE_MPF */
4451
4452 #if defined HAVE_MPFR && defined WITH_MPFR
4453         /* Put all unmarked bigfloats on free list */
4454         sweep_bigfrs();
4455 #endif  /* HAVE_MPFR */
4456
4457 #if defined HAVE_PSEUG && defined WITH_PSEUG
4458         /* Put all unmarked gaussian numbers on free list */
4459         sweep_biggs();
4460 #endif  /* HAVE_PSEUG */
4461
4462 #if defined HAVE_MPC && defined WITH_MPC ||     \
4463         defined HAVE_PSEUC && defined WITH_PSEUC
4464         /* Put all unmarked complex numbers on free list */
4465         sweep_bigcs();
4466 #endif  /* HAVE_MPC */
4467
4468 #if defined HAVE_QUATERN && defined WITH_QUATERN
4469         /* Put all unmarked quaternions on free list */
4470         sweep_quaterns();
4471 #endif  /* HAVE_QUATERN */
4472
4473         /* Put all unmarked dynacats on free list */
4474         sweep_dynacats();
4475
4476         /* Put all unmarked symbols on free list */
4477         sweep_symbols();
4478
4479         /* Put all unmarked extents on free list */
4480         sweep_extents();
4481
4482         /* Put all unmarked markers on free list.
4483            Dechain each one first from the buffer into which it points. */
4484         sweep_markers();
4485
4486         sweep_events();
4487
4488 #ifdef PDUMP
4489         pdump_objects_unmark();
4490 #endif
4491 }
4492 #endif  /* !BDWGC */
4493 \f
4494 /* Clearing for disksave. */
4495
4496 void disksave_object_finalization(void)
4497 {
4498         /* It's important that certain information from the environment not get
4499            dumped with the executable (pathnames, environment variables, etc.).
4500            To make it easier to tell when this has happened with strings(1) we
4501            clear some known-to-be-garbage blocks of memory, so that leftover
4502            results of old evaluation don't look like potential problems.
4503            But first we set some notable variables to nil and do one more GC,
4504            to turn those strings into garbage.
4505          */
4506
4507         /* Yeah, this list is pretty ad-hoc... */
4508         Vprocess_environment = Qnil;
4509         /* Vexec_directory = Qnil; */
4510         Vdata_directory = Qnil;
4511         Vdoc_directory = Qnil;
4512         Vconfigure_info_directory = Qnil;
4513         Vexec_path = Qnil;
4514         Vload_path = Qnil;
4515         /* Vdump_load_path = Qnil; */
4516         /* Release hash tables for locate_file */
4517         Flocate_file_clear_hashing(Qt);
4518         uncache_home_directory();
4519
4520 #if defined(LOADHIST) && !(defined(LOADHIST_DUMPED) || \
4521                            defined(LOADHIST_BUILTIN))
4522         Vload_history = Qnil;
4523 #endif
4524         Vshell_file_name = Qnil;
4525
4526         garbage_collect_1();
4527
4528         /* Run the disksave finalization methods of all live objects. */
4529         disksave_object_finalization_1();
4530
4531         /* Zero out the uninitialized (really, unused) part of the containers
4532            for the live strings. */
4533         /* dont know what its counterpart in bdwgc mode is, so leave it out */
4534 #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
4535         {
4536                 struct string_chars_block *scb;
4537                 for (scb = first_string_chars_block; scb; scb = scb->next) {
4538                         int count = sizeof(scb->string_chars) - scb->pos;
4539
4540                         assert(count >= 0 && count < STRING_CHARS_BLOCK_SIZE);
4541                         if (count != 0) {
4542                                 /* from the block's fill ptr to the end */
4543                                 memset((scb->string_chars + scb->pos), 0,
4544                                        count);
4545                         }
4546                 }
4547         }
4548 #endif
4549
4550         /* There, that ought to be enough... */
4551         return;
4552 }
4553 \f
4554 Lisp_Object restore_gc_inhibit(Lisp_Object val)
4555 {
4556         gc_currently_forbidden = XINT(val);
4557         return val;
4558 }
4559
4560 /* Maybe we want to use this when doing a "panic" gc after memory_full()? */
4561 static int gc_hooks_inhibited;
4562
4563 struct post_gc_action {
4564         void (*fun) (void *);
4565         void *arg;
4566 };
4567
4568 typedef struct post_gc_action post_gc_action;
4569
4570 typedef struct {
4571         Dynarr_declare(post_gc_action);
4572 } post_gc_action_dynarr;
4573
4574 static post_gc_action_dynarr *post_gc_actions;
4575
4576 /* Register an action to be called at the end of GC.
4577    gc_in_progress is 0 when this is called.
4578    This is used when it is discovered that an action needs to be taken,
4579    but it's during GC, so it's not safe. (e.g. in a finalize method.)
4580
4581    As a general rule, do not use Lisp objects here.
4582    And NEVER signal an error.
4583 */
4584
4585 void register_post_gc_action(void (*fun) (void *), void *arg)
4586 {
4587         post_gc_action action;
4588
4589         if (!post_gc_actions)
4590                 post_gc_actions = Dynarr_new(post_gc_action);
4591
4592         action.fun = fun;
4593         action.arg = arg;
4594
4595         Dynarr_add(post_gc_actions, action);
4596 }
4597
4598 #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
4599 static void run_post_gc_actions(void)
4600 {
4601         int i;
4602
4603         if (post_gc_actions) {
4604                 for (i = 0; i < Dynarr_length(post_gc_actions); i++) {
4605                         post_gc_action action = Dynarr_at(post_gc_actions, i);
4606                         (action.fun) (action.arg);
4607                 }
4608
4609                 Dynarr_reset(post_gc_actions);
4610         }
4611 }
4612 #endif  /* !BDWGC */
4613 \f
4614 static inline void
4615 mark_gcprolist(struct gcpro *gcpl)
4616 {
4617         struct gcpro *tail;
4618         int i;
4619         for (tail = gcpl; tail; tail = tail->next) {
4620                 for (i = 0; i < tail->nvars; i++) {
4621                         mark_object(tail->var[i]);
4622                 }
4623         }
4624         return;
4625 }
4626
4627 #if defined HAVE_BDWGC && defined EF_USE_BDWGC
4628 #if 0
4629 static int
4630 stop_gc_p(void)
4631 {
4632         return 0;
4633 }
4634 #endif
4635
4636 void garbage_collect_1(void)
4637 {
4638         SXE_DEBUG_GC("GC\n");
4639 #if defined GC_DEBUG_FLAG
4640         GC_dump();
4641 #endif  /* GC_DEBUG_FLAG */
4642 #if 0
4643         GC_collect_a_little();
4644 #elif 0
4645         GC_gcollect();
4646 #elif 0
4647         GC_try_to_collect(stop_gc_p);
4648 #endif
4649         return;
4650 }
4651 #else  /* !BDWGC */
4652
4653 void garbage_collect_1(void)
4654 {
4655 #if MAX_SAVE_STACK > 0
4656         char stack_top_variable;
4657         extern char *stack_bottom;
4658 #endif
4659         struct frame *f;
4660         int speccount;
4661         int cursor_changed;
4662         Lisp_Object pre_gc_cursor;
4663         struct gcpro gcpro1;
4664
4665         if (gc_in_progress
4666             || gc_currently_forbidden || in_display || preparing_for_armageddon)
4667                 return;
4668
4669         /* We used to call selected_frame() here.
4670
4671            The following functions cannot be called inside GC
4672            so we move to after the above tests. */
4673         {
4674                 Lisp_Object frame;
4675                 Lisp_Object device = Fselected_device(Qnil);
4676                 /* Could happen during startup, eg. if always_gc */
4677                 if (NILP(device)) {
4678                         return;
4679                 }
4680                 frame = DEVICE_SELECTED_FRAME(XDEVICE(device));
4681                 if (NILP(frame)) {
4682                         signal_simple_error("No frames exist on device",
4683                                             device);
4684                 }
4685                 f = XFRAME(frame);
4686         }
4687
4688         pre_gc_cursor = Qnil;
4689         cursor_changed = 0;
4690
4691         GCPRO1(pre_gc_cursor);
4692
4693         /* Very important to prevent GC during any of the following
4694            stuff that might run Lisp code; otherwise, we'll likely
4695            have infinite GC recursion. */
4696         speccount = specpdl_depth();
4697         record_unwind_protect(restore_gc_inhibit,
4698                               make_int(gc_currently_forbidden));
4699         gc_currently_forbidden = 1;
4700
4701         if (!gc_hooks_inhibited)
4702                 run_hook_trapping_errors("Error in pre-gc-hook", Qpre_gc_hook);
4703
4704         /* Now show the GC cursor/message. */
4705         if (!noninteractive) {
4706                 if (FRAME_WIN_P(f)) {
4707                         Lisp_Object frame = make_frame(f);
4708                         Lisp_Object cursor =
4709                             glyph_image_instance(Vgc_pointer_glyph,
4710                                                  FRAME_SELECTED_WINDOW(f),
4711                                                  ERROR_ME_NOT, 1);
4712                         pre_gc_cursor = f->pointer;
4713                         if (POINTER_IMAGE_INSTANCEP(cursor)
4714                             /* don't change if we don't know how to change
4715                                back. */
4716                             && POINTER_IMAGE_INSTANCEP(pre_gc_cursor)) {
4717                                 cursor_changed = 1;
4718                                 Fset_frame_pointer(frame, cursor);
4719                         }
4720                 }
4721
4722                 /* Don't print messages to the stream device. */
4723                 if (STRINGP(Vgc_message) &&
4724                     !cursor_changed &&
4725                     !FRAME_STREAM_P(f)) {
4726                         char *msg = GETTEXT((char *) XSTRING_DATA(Vgc_message));
4727                         Lisp_Object args[2], whole_msg;
4728
4729                         args[0] = build_string(
4730                                 msg ? msg : GETTEXT((char*)gc_default_message));
4731                         args[1] = build_string("...");
4732                         whole_msg = Fconcat(2, args);
4733                         echo_area_message(f, (Bufbyte *) 0, whole_msg, 0, -1,
4734                                           Qgarbage_collecting);
4735                 }
4736         }
4737
4738         /***** Now we actually start the garbage collection. */
4739
4740         lock_allocator();
4741         gc_in_progress = 1;
4742         inhibit_non_essential_printing_operations = 1;
4743
4744         gc_generation_number[0]++;
4745
4746 #if MAX_SAVE_STACK > 0
4747
4748         /* Save a copy of the contents of the stack, for debugging.  */
4749         if (!purify_flag) {
4750                 /* Static buffer in which we save a copy of the C stack at each
4751                    GC.  */
4752                 static char *stack_copy;
4753                 static size_t stack_copy_size;
4754
4755                 ptrdiff_t stack_diff = &stack_top_variable - stack_bottom;
4756                 size_t stack_size = (stack_diff > 0 ? stack_diff : -stack_diff);
4757                 if (stack_size < MAX_SAVE_STACK) {
4758                         if (stack_copy_size < stack_size) {
4759                                 stack_copy =
4760                                     (char *)xrealloc(stack_copy, stack_size);
4761                                 stack_copy_size = stack_size;
4762                         }
4763
4764                         memcpy(stack_copy,
4765                                stack_diff >
4766                                0 ? stack_bottom : &stack_top_variable,
4767                                stack_size);
4768                 }
4769         }
4770 #endif                          /* MAX_SAVE_STACK > 0 */
4771
4772         /* Do some totally ad-hoc resource clearing. */
4773         /* #### generalize this? */
4774         clear_event_resource();
4775         cleanup_specifiers();
4776
4777         /* Mark all the special slots that serve as the roots of
4778            accessibility. */
4779
4780         {                       /* staticpro() */
4781                 Lisp_Object **p = Dynarr_begin(staticpros);
4782                 size_t count;
4783                 for (count = Dynarr_length(staticpros); count; count--) {
4784                         mark_object(**p++);
4785                 }
4786         }
4787
4788         {                       /* staticpro_nodump() */
4789                 Lisp_Object **p = Dynarr_begin(staticpros_nodump);
4790                 size_t count;
4791                 for (count = Dynarr_length(staticpros_nodump); count; count--) {
4792                         mark_object(**p++);
4793                 }
4794         }
4795
4796 #if defined(EF_USE_ASYNEQ)
4797         WITH_DLLIST_TRAVERSE(
4798                 workers,
4799                 eq_worker_t eqw = dllist_item;
4800                 struct gcpro *gcpl = eqw->gcprolist;
4801                 mark_gcprolist(gcpl));
4802 #else
4803         /* GCPRO() */
4804         mark_gcprolist(gcprolist);
4805 #endif
4806         {                       /* specbind() */
4807                 struct specbinding *bind;
4808                 for (bind = specpdl; bind != specpdl_ptr; bind++) {
4809                         mark_object(bind->symbol);
4810                         mark_object(bind->old_value);
4811                 }
4812         }
4813
4814         {
4815                 struct catchtag *catch;
4816                 for (catch = catchlist; catch; catch = catch->next) {
4817                         mark_object(catch->tag);
4818                         mark_object(catch->val);
4819                 }
4820         }
4821
4822         {
4823                 struct backtrace *backlist;
4824                 for (backlist = backtrace_list; backlist;
4825                      backlist = backlist->next) {
4826                         int nargs = backlist->nargs;
4827                         int i;
4828
4829                         mark_object(*backlist->function);
4830                         if (nargs <
4831                             0 /* nargs == UNEVALLED || nargs == MANY */ )
4832                                 mark_object(backlist->args[0]);
4833                         else
4834                                 for (i = 0; i < nargs; i++)
4835                                         mark_object(backlist->args[i]);
4836                 }
4837         }
4838
4839         mark_redisplay();
4840         mark_profiling_info();
4841
4842         /* OK, now do the after-mark stuff.  This is for things that are only
4843            marked when something else is marked (e.g. weak hash tables).  There
4844            may be complex dependencies between such objects -- e.g.  a weak hash
4845            table might be unmarked, but after processing a later weak hash
4846            table, the former one might get marked.  So we have to iterate until
4847            nothing more gets marked. */
4848         while (finish_marking_weak_hash_tables() > 0 ||
4849                finish_marking_weak_lists() > 0) ;
4850
4851         /* And prune (this needs to be called after everything else has been
4852            marked and before we do any sweeping). */
4853         /* #### this is somewhat ad-hoc and should probably be an object
4854            method */
4855         prune_weak_hash_tables();
4856         prune_weak_lists();
4857         prune_specifiers();
4858         prune_syntax_tables();
4859
4860         gc_sweep();
4861
4862         consing_since_gc = 0;
4863 #ifndef DEBUG_SXEMACS
4864         /* Allow you to set it really fucking low if you really want ... */
4865         if (gc_cons_threshold < 10000)
4866                 gc_cons_threshold = 10000;
4867 #endif
4868
4869         unlock_allocator();
4870         inhibit_non_essential_printing_operations = 0;
4871         gc_in_progress = 0;
4872
4873         run_post_gc_actions();
4874
4875         /******* End of garbage collection ********/
4876
4877         run_hook_trapping_errors("Error in post-gc-hook", Qpost_gc_hook);
4878
4879         /* Now remove the GC cursor/message */
4880         if (!noninteractive) {
4881                 if (cursor_changed)
4882                         Fset_frame_pointer(make_frame(f), pre_gc_cursor);
4883                 else if (STRINGP(Vgc_message) && !FRAME_STREAM_P(f)) {
4884                         char *msg = GETTEXT((char *)XSTRING_DATA(Vgc_message));
4885
4886                         /* Show "...done" only if the echo area would otherwise
4887                            be empty. */
4888                         if (NILP(clear_echo_area(selected_frame(),
4889                                                  Qgarbage_collecting, 0))) {
4890                                 Lisp_Object args[2], whole_msg;
4891                                 args[0] = build_string(
4892                                         msg ? msg
4893                                         : GETTEXT((char*)gc_default_message));
4894                                 args[1] = build_string("... done");
4895                                 whole_msg = Fconcat(2, args);
4896                                 echo_area_message(selected_frame(),
4897                                                   (Bufbyte *) 0, whole_msg, 0,
4898                                                   -1, Qgarbage_collecting);
4899                         }
4900                 }
4901         }
4902
4903         /* now stop inhibiting GC */
4904         unbind_to(speccount, Qnil);
4905
4906         if (!breathing_space) {
4907                 breathing_space = malloc(0xFFFF - MALLOC_OVERHEAD);
4908         }
4909
4910         UNGCPRO;
4911         return;
4912 }
4913 #endif  /* BDWGC */
4914
4915
4916 /* Debugging aids.  */
4917 #if defined HAVE_BDWGC && defined EF_USE_BDWGC
4918 #define HACK_O_MATIC(args...)
4919 #define gc_plist_hack(name, val, tail)          \
4920         cons3(intern(name), Qzero, tail)
4921
4922 #else  /* !BDWGC */
4923
4924 static Lisp_Object gc_plist_hack(const char *name, int value, Lisp_Object tail)
4925 {
4926         /* C doesn't have local functions (or closures, or GC, or readable
4927            syntax, or portable numeric datatypes, or bit-vectors, or characters,
4928            or arrays, or exceptions, or ...) */
4929         return cons3(intern(name), make_int(value), tail);
4930 }
4931
4932 #define HACK_O_MATIC(type, name, pl)                                    \
4933         do {                                                            \
4934                 int s = 0;                                              \
4935                 struct type##_block *x = current_##type##_block;        \
4936                 while (x) {                                             \
4937                         s += sizeof (*x) + MALLOC_OVERHEAD;             \
4938                         x = x->prev;                                    \
4939                 }                                                       \
4940                 (pl) = gc_plist_hack ((name), s, (pl));                 \
4941         } while (0)
4942 #endif  /* BDWGC */
4943
4944 DEFUN("garbage-collect", Fgarbage_collect, 0, 0, "",    /*
4945 Reclaim storage for Lisp objects no longer needed.
4946 Return info on amount of space in use:
4947 ((USED-CONSES . FREE-CONSES) (USED-SYMS . FREE-SYMS)
4948 (USED-MARKERS . FREE-MARKERS) USED-STRING-CHARS USED-VECTOR-SLOTS
4949 PLIST)
4950 where `PLIST' is a list of alternating keyword/value pairs providing
4951 more detailed information.
4952 Garbage collection happens automatically if you cons more than
4953 `gc-cons-threshold' bytes of Lisp data since previous garbage collection.
4954 */
4955       ())
4956 {
4957 #if defined HAVE_BDWGC && defined EF_USE_BDWGC
4958         GC_gcollect();
4959         return Qnil;
4960 #else  /* !BDWGC */
4961         Lisp_Object pl = Qnil;
4962         unsigned int i;
4963         int gc_count_vector_total_size = 0;
4964
4965         garbage_collect_1();
4966
4967         for (i = 0; i < lrecord_type_count; i++) {
4968                 if (lcrecord_stats[i].bytes_in_use != 0
4969                     || lcrecord_stats[i].bytes_freed != 0
4970                     || lcrecord_stats[i].instances_on_free_list != 0) {
4971                         char buf[255];
4972                         const char *name =
4973                             lrecord_implementations_table[i]->name;
4974                         int len = strlen(name);
4975                         int sz;
4976
4977                         /* save this for the FSFmacs-compatible part of the
4978                            summary */
4979                         if (i == lrecord_type_vector)
4980                                 gc_count_vector_total_size =
4981                                     lcrecord_stats[i].bytes_in_use +
4982                                     lcrecord_stats[i].bytes_freed;
4983
4984                         sz = snprintf(buf, sizeof(buf), "%s-storage", name);
4985                         assert(sz >=0  && (size_t)sz < sizeof(buf));
4986                         pl = gc_plist_hack(buf, lcrecord_stats[i].bytes_in_use,
4987                                            pl);
4988                         /* Okay, simple pluralization check for
4989                            `symbol-value-varalias' */
4990                         if (name[len - 1] == 's')
4991                                 sz = snprintf(buf, sizeof(buf), "%ses-freed", name);
4992                         else
4993                                 sz = snprintf(buf, sizeof(buf), "%ss-freed", name);
4994                         assert(sz >=0  && (size_t)sz < sizeof(buf));
4995                         if (lcrecord_stats[i].instances_freed != 0)
4996                                 pl = gc_plist_hack(buf,
4997                                                    lcrecord_stats[i].
4998                                                    instances_freed, pl);
4999                         if (name[len - 1] == 's')
5000                                 sz = snprintf(buf, sizeof(buf), "%ses-on-free-list", name);
5001                         else
5002                                 sz = snprintf(buf, sizeof(buf), "%ss-on-free-list", name);
5003                         assert(sz >=0  && (size_t)sz < sizeof(buf));
5004                         if (lcrecord_stats[i].instances_on_free_list != 0)
5005                                 pl = gc_plist_hack(buf,
5006                                                    lcrecord_stats[i].
5007                                                    instances_on_free_list, pl);
5008                         if (name[len - 1] == 's')
5009                                 sz = snprintf(buf, sizeof(buf), "%ses-used", name);
5010                         else
5011                                 sz = snprintf(buf, sizeof(buf), "%ss-used", name);
5012                         assert(sz >=0  && (size_t)sz < sizeof(buf));
5013                         pl = gc_plist_hack(buf,
5014                                            lcrecord_stats[i].instances_in_use,
5015                                            pl);
5016                 }
5017         }
5018
5019         HACK_O_MATIC(extent, "extent-storage", pl);
5020         pl = gc_plist_hack("extents-free", gc_count_num_extent_freelist, pl);
5021         pl = gc_plist_hack("extents-used", gc_count_num_extent_in_use, pl);
5022         HACK_O_MATIC(event, "event-storage", pl);
5023         pl = gc_plist_hack("events-free", gc_count_num_event_freelist, pl);
5024         pl = gc_plist_hack("events-used", gc_count_num_event_in_use, pl);
5025         HACK_O_MATIC(marker, "marker-storage", pl);
5026         pl = gc_plist_hack("markers-free", gc_count_num_marker_freelist, pl);
5027         pl = gc_plist_hack("markers-used", gc_count_num_marker_in_use, pl);
5028 #ifdef HAVE_FPFLOAT
5029         HACK_O_MATIC(float, "float-storage", pl);
5030         pl = gc_plist_hack("floats-free", gc_count_num_float_freelist, pl);
5031         pl = gc_plist_hack("floats-used", gc_count_num_float_in_use, pl);
5032 #endif  /* HAVE_FPFLOAT */
5033 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
5034         HACK_O_MATIC(bigz, "bigz-storage", pl);
5035         pl = gc_plist_hack("bigzs-free", gc_count_num_bigz_freelist, pl);
5036         pl = gc_plist_hack("bigzs-used", gc_count_num_bigz_in_use, pl);
5037 #endif /* HAVE_MPZ */
5038 #if defined HAVE_MPQ && defined WITH_GMP
5039         HACK_O_MATIC(bigq, "bigq-storage", pl);
5040         pl = gc_plist_hack("bigqs-free", gc_count_num_bigq_freelist, pl);
5041         pl = gc_plist_hack("bigqs-used", gc_count_num_bigq_in_use, pl);
5042 #endif /* HAVE_MPQ */
5043 #if defined HAVE_MPF && defined WITH_GMP
5044         HACK_O_MATIC(bigf, "bigf-storage", pl);
5045         pl = gc_plist_hack("bigfs-free", gc_count_num_bigf_freelist, pl);
5046         pl = gc_plist_hack("bigfs-used", gc_count_num_bigf_in_use, pl);
5047 #endif /* HAVE_MPF */
5048 #if defined HAVE_MPFR && defined WITH_MPFR
5049         HACK_O_MATIC(bigfr, "bigfr-storage", pl);
5050         pl = gc_plist_hack("bigfrs-free", gc_count_num_bigfr_freelist, pl);
5051         pl = gc_plist_hack("bigfrs-used", gc_count_num_bigfr_in_use, pl);
5052 #endif /* HAVE_MPFR */
5053 #if defined HAVE_PSEUG && defined WITH_PSEUG
5054         HACK_O_MATIC(bigg, "bigg-storage", pl);
5055         pl = gc_plist_hack("biggs-free", gc_count_num_bigg_freelist, pl);
5056         pl = gc_plist_hack("biggs-used", gc_count_num_bigg_in_use, pl);
5057 #endif /* HAVE_PSEUG */
5058 #if defined HAVE_MPC && defined WITH_MPC ||     \
5059         defined HAVE_PSEUC && defined WITH_PSEUC
5060         HACK_O_MATIC(bigc, "bigc-storage", pl);
5061         pl = gc_plist_hack("bigcs-free", gc_count_num_bigc_freelist, pl);
5062         pl = gc_plist_hack("bigcs-used", gc_count_num_bigc_in_use, pl);
5063 #endif /* HAVE_MPC */
5064 #if defined HAVE_QUATERN && defined WITH_QUATERN
5065         HACK_O_MATIC(quatern, "quatern-storage", pl);
5066         pl = gc_plist_hack("quaterns-free", gc_count_num_quatern_freelist, pl);
5067         pl = gc_plist_hack("quaterns-used", gc_count_num_quatern_in_use, pl);
5068 #endif /* HAVE_QUATERN */
5069
5070         HACK_O_MATIC(dynacat, "dynacat-storage", pl);
5071         pl = gc_plist_hack("dynacats-free", gc_count_num_dynacat_freelist, pl);
5072         pl = gc_plist_hack("dynacats-used", gc_count_num_dynacat_in_use, pl);
5073
5074         HACK_O_MATIC(string, "string-header-storage", pl);
5075         pl = gc_plist_hack("long-strings-total-length",
5076                            gc_count_string_total_size
5077                            - gc_count_short_string_total_size, pl);
5078         HACK_O_MATIC(string_chars, "short-string-storage", pl);
5079         pl = gc_plist_hack("short-strings-total-length",
5080                            gc_count_short_string_total_size, pl);
5081         pl = gc_plist_hack("strings-free", gc_count_num_string_freelist, pl);
5082         pl = gc_plist_hack("long-strings-used",
5083                            gc_count_num_string_in_use
5084                            - gc_count_num_short_string_in_use, pl);
5085         pl = gc_plist_hack("short-strings-used",
5086                            gc_count_num_short_string_in_use, pl);
5087
5088         HACK_O_MATIC(compiled_function, "compiled-function-storage", pl);
5089         pl = gc_plist_hack("compiled-functions-free",
5090                            gc_count_num_compiled_function_freelist, pl);
5091         pl = gc_plist_hack("compiled-functions-used",
5092                            gc_count_num_compiled_function_in_use, pl);
5093
5094         pl = gc_plist_hack("bit-vector-storage", gc_count_bit_vector_storage,
5095                            pl);
5096         pl = gc_plist_hack("bit-vectors-total-length",
5097                            gc_count_bit_vector_total_size, pl);
5098         pl = gc_plist_hack("bit-vectors-used", gc_count_num_bit_vector_used,
5099                            pl);
5100
5101         HACK_O_MATIC(symbol, "symbol-storage", pl);
5102         pl = gc_plist_hack("symbols-free", gc_count_num_symbol_freelist, pl);
5103         pl = gc_plist_hack("symbols-used", gc_count_num_symbol_in_use, pl);
5104
5105         HACK_O_MATIC(cons, "cons-storage", pl);
5106         pl = gc_plist_hack("conses-free", gc_count_num_cons_freelist, pl);
5107         pl = gc_plist_hack("conses-used", gc_count_num_cons_in_use, pl);
5108
5109         /* The things we do for backwards-compatibility */
5110         /* fuck, what are we doing about those in the bdwgc era? -hrop */
5111         return
5112                 list6(Fcons(make_int(gc_count_num_cons_in_use),
5113                             make_int(gc_count_num_cons_freelist)),
5114                       Fcons(make_int(gc_count_num_symbol_in_use),
5115                             make_int(gc_count_num_symbol_freelist)),
5116                       Fcons(make_int(gc_count_num_marker_in_use),
5117                             make_int(gc_count_num_marker_freelist)),
5118                       make_int(gc_count_string_total_size),
5119                       make_int(gc_count_vector_total_size), pl);
5120 #endif  /* BDWGC */
5121 }
5122
5123 #undef HACK_O_MATIC
5124
5125 /* grrrr ... lisp/itimer-autosave.el is using this, WTF? */
5126 DEFUN("consing-since-gc", Fconsing_since_gc, 0, 0, "",  /*
5127 Return the number of bytes consed since the last garbage collection.
5128 \"Consed\" is a misnomer in that this actually counts allocation
5129 of all different kinds of objects, not just conses.
5130
5131 If this value exceeds `gc-cons-threshold', a garbage collection happens.
5132 */
5133       ())
5134 {
5135 #if defined HAVE_BDWGC && defined EF_USE_BDWGC
5136         return Qzero;
5137 #else
5138         return make_int(consing_since_gc);
5139 #endif  /* BDWGC */
5140 }
5141
5142 \f
5143 int object_dead_p(Lisp_Object obj)
5144 {
5145         return ((BUFFERP(obj) && !BUFFER_LIVE_P(XBUFFER(obj))) ||
5146                 (FRAMEP(obj) && !FRAME_LIVE_P(XFRAME(obj))) ||
5147                 (WINDOWP(obj) && !WINDOW_LIVE_P(XWINDOW(obj))) ||
5148                 (DEVICEP(obj) && !DEVICE_LIVE_P(XDEVICE(obj))) ||
5149                 (CONSOLEP(obj) && !CONSOLE_LIVE_P(XCONSOLE(obj))) ||
5150                 (EVENTP(obj) && !EVENT_LIVE_P(XEVENT(obj))) ||
5151                 (EXTENTP(obj) && !EXTENT_LIVE_P(XEXTENT(obj))));
5152 }
5153
5154 #if defined MEMORY_USAGE_STATS && !(defined HAVE_BDWGC && defined EF_USE_BDWGC)
5155
5156 /* Attempt to determine the actual amount of space that is used for
5157    the block allocated starting at PTR, supposedly of size "CLAIMED_SIZE".
5158
5159    It seems that the following holds:
5160
5161    1. When using the old allocator (malloc.c):
5162
5163       -- blocks are always allocated in chunks of powers of two.  For
5164          each block, there is an overhead of 8 bytes if rcheck is not
5165          defined, 20 bytes if it is defined.  In other words, a
5166          one-byte allocation needs 8 bytes of overhead for a total of
5167          9 bytes, and needs to have 16 bytes of memory chunked out for
5168          it.
5169
5170    2. When using the new allocator (gmalloc.c):
5171
5172       -- blocks are always allocated in chunks of powers of two up
5173          to 4096 bytes.  Larger blocks are allocated in chunks of
5174          an integral multiple of 4096 bytes.  The minimum block
5175          size is 2*sizeof (void *), or 16 bytes if SUNOS_LOCALTIME_BUG
5176          is defined.  There is no per-block overhead, but there
5177          is an overhead of 3*sizeof (size_t) for each 4096 bytes
5178          allocated.
5179
5180     3. When using the system malloc, anything goes, but they are
5181        generally slower and more space-efficient than the GNU
5182        allocators.  One possibly reasonable assumption to make
5183        for want of better data is that sizeof (void *), or maybe
5184        2 * sizeof (void *), is required as overhead and that
5185        blocks are allocated in the minimum required size except
5186        that some minimum block size is imposed (e.g. 16 bytes). */
5187
5188 size_t
5189 malloced_storage_size(void *ptr, size_t claimed_size,
5190                       struct overhead_stats * stats)
5191 {
5192         size_t orig_claimed_size = claimed_size;
5193
5194 #ifdef GNU_MALLOC
5195
5196         if (claimed_size < 2 * sizeof(void *))
5197                 claimed_size = 2 * sizeof(void *);
5198 # ifdef SUNOS_LOCALTIME_BUG
5199         if (claimed_size < 16)
5200                 claimed_size = 16;
5201 # endif
5202         if (claimed_size < 4096) {
5203                 int _log_ = 1;
5204
5205                 /* compute the log base two, more or less, then use it to compute
5206                    the block size needed. */
5207                 claimed_size--;
5208                 /* It's big, it's heavy, it's wood! */
5209                 while ((claimed_size /= 2) != 0)
5210                         ++_log_;
5211                 claimed_size = 1;
5212                 /* It's better than bad, it's good! */
5213                 while (_log_ > 0) {
5214                         claimed_size *= 2;
5215                         _log_--;
5216                 }
5217                 /* We have to come up with some average about the amount of
5218                    blocks used. */
5219                 if ((size_t) (rand() & 4095) < claimed_size)
5220                         claimed_size += 3 * sizeof(void *);
5221         } else {
5222                 claimed_size += 4095;
5223                 claimed_size &= ~4095;
5224                 claimed_size += (claimed_size / 4096) * 3 * sizeof(size_t);
5225         }
5226
5227 #elif defined (SYSTEM_MALLOC)
5228
5229         if (claimed_size < 16)
5230                 claimed_size = 16;
5231         claimed_size += 2 * sizeof(void *);
5232
5233 #else                           /* old GNU allocator */
5234
5235 # ifdef rcheck                  /* #### may not be defined here */
5236         claimed_size += 20;
5237 # else
5238         claimed_size += 8;
5239 # endif
5240         {
5241                 int _log_ = 1;
5242
5243                 /* compute the log base two, more or less, then use it to compute
5244                    the block size needed. */
5245                 claimed_size--;
5246                 /* It's big, it's heavy, it's wood! */
5247                 while ((claimed_size /= 2) != 0)
5248                         ++_log_;
5249                 claimed_size = 1;
5250                 /* It's better than bad, it's good! */
5251                 while (_log_ > 0) {
5252                         claimed_size *= 2;
5253                         _log_--;
5254                 }
5255         }
5256
5257 #endif                          /* old GNU allocator */
5258
5259         if (stats) {
5260                 stats->was_requested += orig_claimed_size;
5261                 stats->malloc_overhead += claimed_size - orig_claimed_size;
5262         }
5263         return claimed_size;
5264 }
5265
5266 size_t fixed_type_block_overhead(size_t size)
5267 {
5268         size_t per_block = TYPE_ALLOC_SIZE(cons, unsigned char);
5269         size_t overhead = 0;
5270         size_t storage_size = malloced_storage_size(0, per_block, 0);
5271         while (size >= per_block) {
5272                 size -= per_block;
5273                 overhead += sizeof(void *) + per_block - storage_size;
5274         }
5275         if (rand() % per_block < size)
5276                 overhead += sizeof(void *) + per_block - storage_size;
5277         return overhead;
5278 }
5279
5280 #endif                          /* MEMORY_USAGE_STATS */
5281
5282 #ifdef EF_USE_ASYNEQ
5283 static eq_worker_t
5284 init_main_worker(void)
5285 {
5286         eq_worker_t res = eq_make_worker();
5287         eq_worker_thread(res) = pthread_self();
5288         return res;
5289 }
5290 #endif
5291
5292 #if defined HAVE_MPZ && defined WITH_GMP ||             \
5293         defined HAVE_MPFR && defined WITH_MPFR
5294 static void*
5295 my_malloc(size_t bar)
5296 {
5297         /* we use atomic here since GMP/MPFR do supervise their objects */
5298         void *foo = xmalloc(bar);
5299         SXE_DEBUG_GC_GMP("alloc :is %p :size %lu\n",
5300                          foo, (long unsigned int)bar);
5301         return foo;
5302 }
5303
5304 /* We need the next two functions since GNU MP insists on giving us an extra
5305    parameter. */
5306 static void*
5307 my_realloc (void *ptr, size_t SXE_UNUSED(old_size), size_t new_size)
5308 {
5309         void *foo = xrealloc(ptr, new_size);
5310         SXE_DEBUG_GC_GMP("gmp realloc :was %p  :is %p\n", ptr, foo);
5311         return foo;
5312 }
5313
5314 static void
5315 my_free (void *ptr, size_t size)
5316 {
5317         SXE_DEBUG_GC_GMP("free :was %p :size %lu\n",
5318                          ptr, (long unsigned int)size);
5319         memset(ptr, 0, size);
5320         xfree(ptr);
5321         return;
5322 }
5323 #endif  /* GMP || MPFR */
5324
5325 #if defined HAVE_BDWGC && defined EF_USE_BDWGC && !defined GC_DEBUG_FLAG
5326 static void
5327 my_shy_warn_proc(char *msg, GC_word arg)
5328 {
5329         /* just don't do anything */
5330         return;
5331 }
5332 #endif  /* BDWGC */
5333
5334 \f
5335 /* Initialization */
5336 void init_bdwgc(void);
5337
5338 void
5339 init_bdwgc(void)
5340 {
5341 #if defined HAVE_BDWGC && defined EF_USE_BDWGC
5342 # if defined GC_DEBUG_FLAG
5343         extern long GC_large_alloc_warn_interval;
5344 # endif
5345         GC_time_limit = GC_TIME_UNLIMITED;
5346         GC_use_entire_heap = 0;
5347         GC_find_leak = 0;
5348         GC_dont_gc = 0;
5349         GC_all_interior_pointers = 1;
5350 #if 0
5351         GC_parallel = 1;
5352         GC_dont_expand = 1;
5353         GC_free_space_divisor = 8;
5354 #endif
5355 #if !defined GC_DEBUG_FLAG
5356         GC_set_warn_proc(my_shy_warn_proc);
5357 #else  /* GC_DEBUG_FLAG */
5358         GC_large_alloc_warn_interval = 1L;
5359 #endif  /* GC_DEBUG_FLAG */
5360         GC_INIT();
5361 #endif  /* BDWGC */
5362         return;
5363 }
5364
5365 static inline void
5366 __init_gmp_mem_funs(void)
5367 {
5368 #if defined HAVE_MPZ && defined WITH_GMP ||             \
5369         defined HAVE_MPFR && defined WITH_MPFR
5370         mp_set_memory_functions(my_malloc, my_realloc, my_free);
5371 #endif  /* GMP || MPFR */
5372 }
5373
5374 void reinit_alloc_once_early(void)
5375 {
5376         gc_generation_number[0] = 0;
5377         breathing_space = NULL;
5378         XSETINT(all_bit_vectors, 0);    /* Qzero may not be set yet. */
5379         XSETINT(Vgc_message, 0);
5380 #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
5381         all_lcrecords = 0;
5382 #endif  /* !BDWGC */
5383         ignore_malloc_warnings = 1;
5384 #ifdef DOUG_LEA_MALLOC
5385         mallopt(M_TRIM_THRESHOLD, 128 * 1024);  /* trim threshold */
5386         mallopt(M_MMAP_THRESHOLD, 64 * 1024);   /* mmap threshold */
5387 #if 1                           /* Moved to emacs.c */
5388         mallopt(M_MMAP_MAX, 0); /* max. number of mmap'ed areas */
5389 #endif
5390 #endif
5391         /* the category subsystem */
5392         morphisms[lrecord_type_cons].seq_impl = &__scons;
5393         morphisms[lrecord_type_vector].seq_impl = &__svec;
5394         morphisms[lrecord_type_string].seq_impl = &__sstr;
5395         morphisms[lrecord_type_bit_vector].seq_impl = &__sbvc;
5396
5397         init_string_alloc();
5398 #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
5399         init_string_chars_alloc();
5400 #endif  /* !BDWGC */
5401         init_cons_alloc();
5402         init_symbol_alloc();
5403         init_compiled_function_alloc();
5404
5405         init_float_alloc();
5406
5407         __init_gmp_mem_funs();
5408 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP) &&        \
5409         !(defined HAVE_BDWGC && defined EF_USE_BDWGC)
5410         init_bigz_alloc();
5411 #endif
5412 #if defined HAVE_MPQ && defined WITH_GMP &&     \
5413         !(defined HAVE_BDWGC && defined EF_USE_BDWGC)
5414         init_bigq_alloc();
5415 #endif
5416 #if defined HAVE_MPF && defined WITH_GMP &&     \
5417         !(defined HAVE_BDWGC && defined EF_USE_BDWGC)
5418         init_bigf_alloc();
5419 #endif
5420 #if defined HAVE_MPFR && defined WITH_MPFR
5421         init_bigfr_alloc();
5422 #endif
5423 #if defined HAVE_PSEUG && defined HAVE_MPZ && defined WITH_PSEUG
5424         init_bigg_alloc();
5425 #endif
5426 #if defined HAVE_MPC && defined WITH_MPC ||     \
5427         defined HAVE_PSEUC && defined WITH_PSEUC
5428         init_bigc_alloc();
5429 #endif
5430 #if defined HAVE_QUATERN && defined HAVE_MPZ && defined WITH_QUATERN
5431         init_quatern_alloc();
5432 #endif
5433         init_dynacat_alloc();
5434
5435         init_marker_alloc();
5436         init_extent_alloc();
5437         init_event_alloc();
5438
5439         ignore_malloc_warnings = 0;
5440
5441         /* we only use the 500k value for now */
5442         gc_cons_threshold = 500000;
5443         lrecord_uid_counter = 259;
5444
5445 #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
5446         if (staticpros_nodump) {
5447                 Dynarr_free(staticpros_nodump);
5448         }
5449         staticpros_nodump = Dynarr_new2(Lisp_Object_ptr_dynarr, Lisp_Object *);
5450         /* merely a small optimization */
5451         Dynarr_resize(staticpros_nodump, 100);
5452
5453         /* tuning the GCor */
5454         consing_since_gc = 0;
5455         debug_string_purity = 0;
5456 #endif  /* !BDWGC */
5457 #ifdef EF_USE_ASYNEQ
5458         workers = make_noseeum_dllist();
5459         dllist_prepend(workers, init_main_worker());
5460 #else
5461         gcprolist = 0;
5462 #endif
5463
5464 #if defined EF_USE_ASYNEQ && !(defined HAVE_BDWGC && defined EF_USE_BDWGC)
5465         SXE_MUTEX_INIT(&cons_mutex);
5466 #endif
5467
5468         gc_currently_forbidden = 0;
5469         gc_hooks_inhibited = 0;
5470
5471 #ifdef ERROR_CHECK_TYPECHECK
5472         ERROR_ME.
5473             really_unlikely_name_to_have_accidentally_in_a_non_errb_structure =
5474             666;
5475         ERROR_ME_NOT.
5476             really_unlikely_name_to_have_accidentally_in_a_non_errb_structure =
5477             42;
5478         ERROR_ME_WARN.
5479             really_unlikely_name_to_have_accidentally_in_a_non_errb_structure =
5480             3333632;
5481 #endif                          /* ERROR_CHECK_TYPECHECK */
5482 }
5483
5484 void init_alloc_once_early(void)
5485 {
5486         reinit_alloc_once_early();
5487
5488         for (int i = 0; i < countof(lrecord_implementations_table); i++) {
5489                 lrecord_implementations_table[i] = 0;
5490         }
5491
5492         INIT_LRECORD_IMPLEMENTATION(cons);
5493         INIT_LRECORD_IMPLEMENTATION(vector);
5494         INIT_LRECORD_IMPLEMENTATION(string);
5495         INIT_LRECORD_IMPLEMENTATION(lcrecord_list);
5496
5497         staticpros = Dynarr_new2(Lisp_Object_ptr_dynarr, Lisp_Object *);
5498         Dynarr_resize(staticpros, 1410);        /* merely a small optimization */
5499         dump_add_root_struct_ptr(&staticpros, &staticpros_description);
5500
5501         /* GMP/MPFR mem funs */
5502         __init_gmp_mem_funs();
5503
5504         return;
5505 }
5506
5507 void reinit_alloc(void)
5508 {
5509 #ifdef EF_USE_ASYNEQ
5510         eq_worker_t main_th;
5511         assert(dllist_size(workers) == 1);
5512         main_th = dllist_car(workers);
5513         eq_worker_gcprolist(main_th) = NULL;
5514 #else
5515         gcprolist = 0;
5516 #endif
5517 }
5518
5519 void syms_of_alloc(void)
5520 {
5521         DEFSYMBOL(Qpre_gc_hook);
5522         DEFSYMBOL(Qpost_gc_hook);
5523         DEFSYMBOL(Qgarbage_collecting);
5524
5525         DEFSUBR(Fcons);
5526         DEFSUBR(Flist);
5527         DEFSUBR(Fvector);
5528         DEFSUBR(Fbit_vector);
5529         DEFSUBR(Fmake_byte_code);
5530         DEFSUBR(Fmake_list);
5531         DEFSUBR(Fmake_vector);
5532         DEFSUBR(Fmake_bit_vector);
5533         DEFSUBR(Fmake_string);
5534         DEFSUBR(Fstring);
5535         DEFSUBR(Fmake_symbol);
5536         DEFSUBR(Fmake_marker);
5537         DEFSUBR(Fpurecopy);
5538         DEFSUBR(Fgarbage_collect);
5539         DEFSUBR(Fconsing_since_gc);
5540 }
5541
5542 void vars_of_alloc(void)
5543 {
5544         DEFVAR_INT("gc-cons-threshold", &gc_cons_threshold      /*
5545 *Number of bytes of consing between garbage collections.
5546 \"Consing\" is a misnomer in that this actually counts allocation
5547 of all different kinds of objects, not just conses.
5548 Garbage collection can happen automatically once this many bytes have been
5549 allocated since the last garbage collection.  All data types count.
5550
5551 Garbage collection happens automatically when `eval' or `funcall' are
5552 called.  (Note that `funcall' is called implicitly as part of evaluation.)
5553 By binding this temporarily to a large number, you can effectively
5554 prevent garbage collection during a part of the program.
5555
5556 See also `consing-since-gc'.
5557                                                                  */ );
5558
5559 #ifdef DEBUG_SXEMACS
5560         DEFVAR_INT("debug-allocation", &debug_allocation        /*
5561 If non-zero, print out information to stderr about all objects allocated.
5562 See also `debug-allocation-backtrace-length'.
5563                                                                  */ );
5564         debug_allocation = 0;
5565
5566         DEFVAR_INT("debug-allocation-backtrace-length", &debug_allocation_backtrace_length      /*
5567 Length (in stack frames) of short backtrace printed out by `debug-allocation'.
5568                                                                                                  */ );
5569         debug_allocation_backtrace_length = 2;
5570 #endif
5571
5572         DEFVAR_BOOL("purify-flag", &purify_flag /*
5573 Non-nil means loading Lisp code in order to dump an executable.
5574 This means that certain objects should be allocated in readonly space.
5575                                                  */ );
5576
5577         DEFVAR_LISP("pre-gc-hook", &Vpre_gc_hook        /*
5578 Function or functions to be run just before each garbage collection.
5579 Interrupts, garbage collection, and errors are inhibited while this hook
5580 runs, so be extremely careful in what you add here.  In particular, avoid
5581 consing, and do not interact with the user.
5582                                                          */ );
5583         Vpre_gc_hook = Qnil;
5584
5585         DEFVAR_LISP("post-gc-hook", &Vpost_gc_hook      /*
5586 Function or functions to be run just after each garbage collection.
5587 Interrupts, garbage collection, and errors are inhibited while this hook
5588 runs, so be extremely careful in what you add here.  In particular, avoid
5589 consing, and do not interact with the user.
5590                                                          */ );
5591         Vpost_gc_hook = Qnil;
5592
5593         DEFVAR_LISP("gc-message", &Vgc_message  /*
5594 String to print to indicate that a garbage collection is in progress.
5595 This is printed in the echo area.  If the selected frame is on a
5596 window system and `gc-pointer-glyph' specifies a value (i.e. a pointer
5597 image instance) in the domain of the selected frame, the mouse pointer
5598 will change instead of this message being printed.
5599 If it has non-string value - nothing is printed.
5600                                                  */ );
5601         Vgc_message = build_string(gc_default_message);
5602
5603         DEFVAR_LISP("gc-pointer-glyph", &Vgc_pointer_glyph      /*
5604 Pointer glyph used to indicate that a garbage collection is in progress.
5605 If the selected window is on a window system and this glyph specifies a
5606 value (i.e. a pointer image instance) in the domain of the selected
5607 window, the pointer will be changed as specified during garbage collection.
5608 Otherwise, a message will be printed in the echo area, as controlled
5609 by `gc-message'.
5610                                                                  */ );
5611 }
5612
5613 void complex_vars_of_alloc(void)
5614 {
5615         Vgc_pointer_glyph = Fmake_glyph_internal(Qpointer);
5616 }