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