Mercurial > hg > xemacs-beta
comparison src/alloc.c @ 272:c5d627a313b1 r21-0b34
Import from CVS: tag r21-0b34
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:28:48 +0200 |
parents | 8efd647ea9ca |
children | ca9a9ec9c1c1 |
comparison
equal
deleted
inserted
replaced
271:c7b7086b0a39 | 272:c5d627a313b1 |
---|---|
1 /* Storage allocation and gc for XEmacs Lisp interpreter. | 1 /* Storage allocation and gc for XEmacs Lisp interpreter. |
2 Copyright (C) 1985, 1986, 1988, 1992, 1993, 1994 | 2 Copyright (C) 1985-1998 Free Software Foundation, Inc. |
3 Free Software Foundation, Inc. | |
4 Copyright (C) 1995 Sun Microsystems, Inc. | 3 Copyright (C) 1995 Sun Microsystems, Inc. |
5 Copyright (C) 1995, 1996 Ben Wing. | 4 Copyright (C) 1995, 1996 Ben Wing. |
6 | 5 |
7 This file is part of XEmacs. | 6 This file is part of XEmacs. |
8 | 7 |
39 Synched Doug Lea malloc support from Emacs 20.2. | 38 Synched Doug Lea malloc support from Emacs 20.2. |
40 */ | 39 */ |
41 | 40 |
42 #include <config.h> | 41 #include <config.h> |
43 #include "lisp.h" | 42 #include "lisp.h" |
44 #include "sysdep.h" | |
45 | 43 |
46 #ifndef standalone | 44 #ifndef standalone |
47 #include "backtrace.h" | 45 #include "backtrace.h" |
48 #include "buffer.h" | 46 #include "buffer.h" |
49 #include "bytecode.h" | 47 #include "bytecode.h" |
54 #include "extents.h" | 52 #include "extents.h" |
55 #include "frame.h" | 53 #include "frame.h" |
56 #include "glyphs.h" | 54 #include "glyphs.h" |
57 #include "redisplay.h" | 55 #include "redisplay.h" |
58 #include "specifier.h" | 56 #include "specifier.h" |
57 #include "sysfile.h" | |
59 #include "window.h" | 58 #include "window.h" |
60 #endif | 59 #endif |
61 | 60 |
62 #ifdef DOUG_LEA_MALLOC | 61 #ifdef DOUG_LEA_MALLOC |
63 #include <malloc.h> | 62 #include <malloc.h> |
64 #endif | 63 #endif |
64 | |
65 EXFUN (Fgarbage_collect, 0); | |
65 | 66 |
66 /* #define GDB_SUCKS */ | 67 /* #define GDB_SUCKS */ |
67 | 68 |
68 #if 0 /* this is _way_ too slow to be part of the standard debug options */ | 69 #if 0 /* this is _way_ too slow to be part of the standard debug options */ |
69 #if defined(DEBUG_XEMACS) && defined(MULE) | 70 #if defined(DEBUG_XEMACS) && defined(MULE) |
192 | 193 |
193 #ifdef HEAP_IN_DATA | 194 #ifdef HEAP_IN_DATA |
194 extern void sheap_adjust_h(); | 195 extern void sheap_adjust_h(); |
195 #endif | 196 #endif |
196 | 197 |
197 extern Lisp_Object pure[];/* moved to pure.c to speed incremental linking */ | 198 #define PUREBEG ((char *) pure) |
198 | |
199 #define PUREBEG ((unsigned char *) pure) | |
200 | 199 |
201 #if 0 /* This is breathing_space in XEmacs */ | 200 #if 0 /* This is breathing_space in XEmacs */ |
202 /* Points to memory space allocated as "spare", | 201 /* Points to memory space allocated as "spare", |
203 to be freed if we run out of memory. */ | 202 to be freed if we run out of memory. */ |
204 static char *spare_memory; | 203 static char *spare_memory; |
205 | 204 |
206 /* Amount of spare memory to keep in reserve. */ | 205 /* Amount of spare memory to keep in reserve. */ |
207 #define SPARE_MEMORY (1 << 14) | 206 #define SPARE_MEMORY (1 << 14) |
208 #endif | 207 #endif |
209 | 208 |
210 /* Number of extra blocks malloc should get when it needs more core. */ | |
211 static int malloc_hysteresis; | |
212 | |
213 /* Index in pure at which next pure object will be allocated. */ | 209 /* Index in pure at which next pure object will be allocated. */ |
214 static long pureptr; | 210 static size_t pure_bytes_used; |
215 | 211 |
216 #define PURIFIED(ptr) \ | 212 #define PURIFIED(ptr) \ |
217 ((uintptr_t) (ptr) < \ | 213 ((char *) (ptr) >= PUREBEG && \ |
218 (uintptr_t) (PUREBEG + get_PURESIZE()) && \ | 214 (char *) (ptr) < PUREBEG + get_PURESIZE()) |
219 (uintptr_t) (ptr) >= \ | 215 |
220 (uintptr_t) PUREBEG) | 216 /* Non-zero if pure_bytes_used > get_PURESIZE(); accounts for excess purespace needs. */ |
221 | 217 static size_t pure_lossage; |
222 /* Non-zero if pureptr > get_PURESIZE(); accounts for excess purespace needs. */ | |
223 static long pure_lossage; | |
224 | 218 |
225 #ifdef ERROR_CHECK_TYPECHECK | 219 #ifdef ERROR_CHECK_TYPECHECK |
226 | 220 |
227 Error_behavior ERROR_ME, ERROR_ME_NOT, ERROR_ME_WARN; | 221 Error_behavior ERROR_ME, ERROR_ME_NOT, ERROR_ME_WARN; |
228 | 222 |
229 #endif | 223 #endif |
230 | 224 |
231 int | 225 int |
232 purified (Lisp_Object obj) | 226 purified (Lisp_Object obj) |
233 { | 227 { |
234 return !POINTER_TYPE_P (XGCTYPE (obj)) ? 0 : PURIFIED (XPNTR (obj)); | 228 return POINTER_TYPE_P (XGCTYPE (obj)) && PURIFIED (XPNTR (obj)); |
235 } | 229 } |
236 | 230 |
237 int | 231 size_t |
238 purespace_usage (void) | 232 purespace_usage (void) |
239 { | 233 { |
240 return (int) pureptr; | 234 return pure_bytes_used; |
241 } | 235 } |
242 | 236 |
243 static int | 237 static int |
244 check_purespace (EMACS_INT size) | 238 check_purespace (size_t size) |
245 { | 239 { |
246 if (pure_lossage) | 240 if (pure_lossage) |
247 { | 241 { |
248 pure_lossage += size; | 242 pure_lossage += size; |
249 return 0; | 243 return 0; |
250 } | 244 } |
251 else if (pureptr + size > get_PURESIZE()) | 245 else if (pure_bytes_used + size > get_PURESIZE()) |
252 { | 246 { |
253 /* This can cause recursive bad behavior, we'll yell at the end */ | 247 /* This can cause recursive bad behavior, we'll yell at the end */ |
254 /* when we're done. */ | 248 /* when we're done. */ |
255 /* message ("\nERROR: Pure Lisp storage exhausted!\n"); */ | 249 /* message ("\nERROR: Pure Lisp storage exhausted!\n"); */ |
256 pure_lossage = size; | 250 pure_lossage = size; |
262 | 256 |
263 | 257 |
264 | 258 |
265 #ifndef PURESTAT | 259 #ifndef PURESTAT |
266 | 260 |
267 #define bump_purestat(p,b) do {} while (0) /* Do nothing */ | 261 #define bump_purestat(p,b) DO_NOTHING |
268 | 262 |
269 #else /* PURESTAT */ | 263 #else /* PURESTAT */ |
270 | 264 |
271 static int purecopying_for_bytecode; | 265 static int purecopying_for_bytecode; |
272 | 266 |
273 static int pure_sizeof (Lisp_Object /*, int recurse */); | 267 static size_t pure_sizeof (Lisp_Object /*, int recurse */); |
274 | 268 |
275 /* Keep statistics on how much of what is in purespace */ | 269 /* Keep statistics on how much of what is in purespace */ |
276 static struct purestat | 270 static struct purestat |
277 { | 271 { |
278 int nobjects; | 272 int nobjects; |
316 &purestat_string_all, | 310 &purestat_string_all, |
317 &purestat_vector_all | 311 &purestat_vector_all |
318 }; | 312 }; |
319 | 313 |
320 static void | 314 static void |
321 bump_purestat (struct purestat *purestat, int nbytes) | 315 bump_purestat (struct purestat *purestat, size_t nbytes) |
322 { | 316 { |
323 if (pure_lossage) return; | 317 if (pure_lossage) return; |
324 purestat->nobjects += 1; | 318 purestat->nobjects += 1; |
325 purestat->nbytes += nbytes; | 319 purestat->nbytes += nbytes; |
326 } | 320 } |
330 /* Maximum amount of C stack to save when a GC happens. */ | 324 /* Maximum amount of C stack to save when a GC happens. */ |
331 | 325 |
332 #ifndef MAX_SAVE_STACK | 326 #ifndef MAX_SAVE_STACK |
333 #define MAX_SAVE_STACK 16000 | 327 #define MAX_SAVE_STACK 16000 |
334 #endif | 328 #endif |
335 | |
336 /* Buffer in which we save a copy of the C stack at each GC. */ | |
337 | |
338 static char *stack_copy; | |
339 static int stack_copy_size; | |
340 | 329 |
341 /* Non-zero means ignore malloc warnings. Set during initialization. */ | 330 /* Non-zero means ignore malloc warnings. Set during initialization. */ |
342 int ignore_malloc_warnings; | 331 int ignore_malloc_warnings; |
343 | 332 |
344 | 333 |
446 assert (block); | 435 assert (block); |
447 #endif /* ERROR_CHECK_MALLOC */ | 436 #endif /* ERROR_CHECK_MALLOC */ |
448 free (block); | 437 free (block); |
449 } | 438 } |
450 | 439 |
451 #if INTBITS == 32 | 440 #ifdef ERROR_CHECK_GC |
452 # define FOUR_BYTE_TYPE unsigned int | 441 |
453 #elif LONGBITS == 32 | 442 #if SIZEOF_INT == 4 |
454 # define FOUR_BYTE_TYPE unsigned long | 443 typedef unsigned int four_byte_t; |
455 #elif SHORTBITS == 32 | 444 #elif SIZEOF_LONG == 4 |
456 # define FOUR_BYTE_TYPE unsigned short | 445 typedef unsigned long four_byte_t; |
446 #elif SIZEOF_SHORT == 4 | |
447 typedef unsigned short four_byte_t; | |
457 #else | 448 #else |
458 What kind of strange-ass system are we running on? | 449 What kind of strange-ass system are we running on? |
459 #endif | 450 #endif |
460 | 451 |
461 #ifdef ERROR_CHECK_GC | |
462 | |
463 #ifdef WORDS_BIGENDIAN | |
464 static unsigned char deadbeef_as_char[] = {0xDE, 0xAD, 0xBE, 0xEF}; | |
465 #else | |
466 static unsigned char deadbeef_as_char[] = {0xEF, 0xBE, 0xAD, 0xDE}; | |
467 #endif | |
468 | |
469 static void | 452 static void |
470 deadbeef_memory (void *ptr, unsigned long size) | 453 deadbeef_memory (void *ptr, size_t size) |
471 { | 454 { |
472 unsigned long long_length = size / sizeof (FOUR_BYTE_TYPE); | 455 four_byte_t *ptr4 = (four_byte_t *) ptr; |
473 unsigned long i; | 456 size_t beefs = size >> 2; |
474 unsigned long bytes_left_over = size - sizeof (FOUR_BYTE_TYPE) * long_length; | 457 |
475 | 458 /* In practice, size will always be a multiple of four. */ |
476 for (i = 0; i < long_length; i++) | 459 while (beefs--) |
477 ((FOUR_BYTE_TYPE *) ptr)[i] = 0xdeadbeef; | 460 (*ptr4++) = 0xDEADBEEF; |
478 for (i = i; i < bytes_left_over; i++) | |
479 ((unsigned char *) ptr + long_length)[i] = deadbeef_as_char[i]; | |
480 } | 461 } |
481 | 462 |
482 #else /* !ERROR_CHECK_GC */ | 463 #else /* !ERROR_CHECK_GC */ |
483 | 464 |
484 | 465 |
509 } | 490 } |
510 #endif /* NEED_STRDUP */ | 491 #endif /* NEED_STRDUP */ |
511 | 492 |
512 | 493 |
513 static void * | 494 static void * |
514 allocate_lisp_storage (int size) | 495 allocate_lisp_storage (size_t size) |
515 { | 496 { |
516 void *p = xmalloc (size); | 497 void *p = xmalloc (size); |
498 #ifndef USE_MINIMAL_TAGBITS | |
517 char *lim = ((char *) p) + size; | 499 char *lim = ((char *) p) + size; |
518 Lisp_Object val = Qnil; | 500 Lisp_Object val; |
519 | 501 |
520 XSETOBJ (val, Lisp_Type_Record, lim); | 502 XSETOBJ (val, Lisp_Type_Record, lim); |
521 if ((char *) XPNTR (val) != lim) | 503 if ((char *) XPNTR (val) != lim) |
522 { | 504 { |
523 xfree (p); | 505 xfree (p); |
524 memory_full (); | 506 memory_full (); |
525 } | 507 } |
508 #endif /* ! USE_MINIMAL_TAGBITS */ | |
526 return p; | 509 return p; |
527 } | 510 } |
528 | 511 |
529 | 512 |
530 /* lrecords are chained together through their "next.v" field. | 513 /* lrecords are chained together through their "next.v" field. |
531 * After doing the mark phase, the GC will walk this linked | 514 * After doing the mark phase, the GC will walk this linked |
532 * list and free any record which hasn't been marked | 515 * list and free any record which hasn't been marked. |
533 */ | 516 */ |
534 static struct lcrecord_header *all_lcrecords; | 517 static struct lcrecord_header *all_lcrecords; |
535 | 518 |
536 void * | 519 void * |
537 alloc_lcrecord (int size, CONST struct lrecord_implementation *implementation) | 520 alloc_lcrecord (size_t size, CONST struct lrecord_implementation *implementation) |
538 { | 521 { |
539 struct lcrecord_header *lcheader; | 522 struct lcrecord_header *lcheader; |
540 | 523 |
541 if (size <= 0) abort (); | 524 if (size <= 0) abort (); |
542 if (implementation->static_size == 0) | 525 if (implementation->static_size == 0) |
639 | 622 |
640 /* XGCTYPE for records */ | 623 /* XGCTYPE for records */ |
641 int | 624 int |
642 gc_record_type_p (Lisp_Object frob, CONST struct lrecord_implementation *type) | 625 gc_record_type_p (Lisp_Object frob, CONST struct lrecord_implementation *type) |
643 { | 626 { |
627 CONST struct lrecord_implementation *imp; | |
628 | |
629 if (XGCTYPE (frob) != Lisp_Type_Record) | |
630 return 0; | |
631 | |
632 imp = XRECORD_LHEADER_IMPLEMENTATION (frob); | |
644 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION | 633 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION |
645 return (XGCTYPE (frob) == Lisp_Type_Record | 634 return imp == type; |
646 && XRECORD_LHEADER_IMPLEMENTATION (frob) == type); | |
647 #else | 635 #else |
648 return (XGCTYPE (frob) == Lisp_Type_Record | 636 return imp == type || imp == type + 1; |
649 && (XRECORD_LHEADER (frob)->implementation == type || | 637 #endif |
650 XRECORD_LHEADER (frob)->implementation == type + 1)); | 638 } |
651 #endif | 639 |
652 } | 640 |
641 /**********************************************************************/ | |
642 /* Debugger support */ | |
643 /**********************************************************************/ | |
644 /* Give gdb/dbx enough information to decode Lisp Objects. | |
645 We make sure certain symbols are defined, so gdb doesn't complain | |
646 about expressions in src/gdbinit. Values are randomly chosen. | |
647 See src/gdbinit or src/dbxrc to see how this is used. */ | |
648 | |
649 enum dbg_constants | |
650 { | |
651 #ifdef USE_MINIMAL_TAGBITS | |
652 dbg_valmask = (EMACS_INT) (((1UL << VALBITS) - 1) << GCBITS), | |
653 dbg_typemask = (EMACS_INT) ((1UL << GCTYPEBITS) - 1), | |
654 dbg_USE_MINIMAL_TAGBITS = 1, | |
655 dbg_Lisp_Type_Int = 100, | |
656 #else /* ! USE_MIMIMAL_TAGBITS */ | |
657 dbg_valmask = (EMACS_INT) ((1UL << VALBITS) - 1), | |
658 dbg_typemask = (EMACS_INT) (((1UL << GCTYPEBITS) - 1) << (VALBITS + GCMARKBITS)), | |
659 dbg_USE_MINIMAL_TAGBITS = 0, | |
660 dbg_Lisp_Type_Int = Lisp_Type_Int, | |
661 #endif /* ! USE_MIMIMAL_TAGBITS */ | |
662 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION | |
663 dbg_USE_INDEXED_LRECORD_IMPLEMENTATION = 1, | |
664 #else | |
665 dbg_USE_INDEXED_LRECORD_IMPLEMENTATION = 0, | |
666 #endif | |
667 dbg_Lisp_Type_Char = Lisp_Type_Char, | |
668 dbg_Lisp_Type_Record = Lisp_Type_Record, | |
669 #ifdef LRECORD_CONS | |
670 dbg_Lisp_Type_Cons = 101, | |
671 #else | |
672 dbg_Lisp_Type_Cons = Lisp_Type_Cons, | |
673 lrecord_cons = 201, | |
674 #endif | |
675 #ifdef LRECORD_STRING | |
676 dbg_Lisp_Type_String = 102, | |
677 #else | |
678 dbg_Lisp_Type_String = Lisp_Type_String, | |
679 lrecord_string = 202, | |
680 #endif | |
681 #ifdef LRECORD_VECTOR | |
682 dbg_Lisp_Type_Vector = 103, | |
683 #else | |
684 dbg_Lisp_Type_Vector = Lisp_Type_Vector, | |
685 lrecord_vector = 203, | |
686 #endif | |
687 #ifdef LRECORD_SYMBOL | |
688 dbg_Lisp_Type_Symbol = 104, | |
689 #else | |
690 dbg_Lisp_Type_Symbol = Lisp_Type_Symbol, | |
691 lrecord_symbol = 204, | |
692 #endif | |
693 #ifndef MULE | |
694 lrecord_char_table_entry = 205, | |
695 lrecord_charset = 206, | |
696 lrecord_coding_system = 207, | |
697 #endif | |
698 #ifndef HAVE_TOOLBARS | |
699 lrecord_toolbar_button = 208, | |
700 lrecord_toolbar_data = 209, | |
701 #endif | |
702 #ifndef HAVE_TOOLTALK | |
703 lrecord_tooltalk_message = 210, | |
704 lrecord_tooltalk_pattern = 211, | |
705 #endif | |
706 #ifndef HAVE_DATABASE | |
707 lrecord_database = 212, | |
708 #endif | |
709 dbg_valbits = VALBITS, | |
710 dbg_gctypebits = GCTYPEBITS | |
711 /* If we don't have an actual object of this enum, pgcc (and perhaps | |
712 other compilers) might optimize away the entire type declaration :-( */ | |
713 } dbg_dummy; | |
653 | 714 |
654 | 715 |
655 /**********************************************************************/ | 716 /**********************************************************************/ |
656 /* Fixed-size type macros */ | 717 /* Fixed-size type macros */ |
657 /**********************************************************************/ | 718 /**********************************************************************/ |
817 /* If we released our reserve (due to running out of memory), | 878 /* If we released our reserve (due to running out of memory), |
818 and we have a fair amount free once again, | 879 and we have a fair amount free once again, |
819 try to set aside another reserve in case we run out once more. | 880 try to set aside another reserve in case we run out once more. |
820 | 881 |
821 This is called when a relocatable block is freed in ralloc.c. */ | 882 This is called when a relocatable block is freed in ralloc.c. */ |
822 | 883 void refill_memory_reserve (void); |
823 void | 884 void |
824 refill_memory_reserve () | 885 refill_memory_reserve () |
825 { | 886 { |
826 if (breathing_space == 0) | 887 if (breathing_space == 0) |
827 breathing_space = (char *) malloc (4096 - MALLOC_OVERHEAD); | 888 breathing_space = (char *) malloc (4096 - MALLOC_OVERHEAD); |
1038 static Lisp_Object | 1099 static Lisp_Object |
1039 mark_cons (Lisp_Object obj, void (*markobj) (Lisp_Object)) | 1100 mark_cons (Lisp_Object obj, void (*markobj) (Lisp_Object)) |
1040 { | 1101 { |
1041 if (NILP (XCDR (obj))) | 1102 if (NILP (XCDR (obj))) |
1042 return XCAR (obj); | 1103 return XCAR (obj); |
1043 else | 1104 |
1044 (markobj) (XCAR (obj)); | 1105 (markobj) (XCAR (obj)); |
1045 return XCDR (obj); | 1106 return XCDR (obj); |
1046 } | 1107 } |
1047 | 1108 |
1048 static int | 1109 static int |
1049 cons_equal (Lisp_Object ob1, Lisp_Object ob2, int depth) | 1110 cons_equal (Lisp_Object ob1, Lisp_Object ob2, int depth) |
1050 { | 1111 { |
1051 while (internal_equal (XCAR (ob1), XCAR (ob2), depth + 1)) | 1112 while (internal_equal (XCAR (ob1), XCAR (ob2), depth + 1)) |
1052 { | 1113 { |
1053 ob1 = XCDR(ob1); | 1114 ob1 = XCDR (ob1); |
1054 ob2 = XCDR(ob2); | 1115 ob2 = XCDR (ob2); |
1055 if (! CONSP (ob1) || ! CONSP (ob2)) | 1116 if (! CONSP (ob1) || ! CONSP (ob2)) |
1056 return internal_equal (ob1, ob2, depth + 1); | 1117 return internal_equal (ob1, ob2, depth + 1); |
1057 } | 1118 } |
1058 return 0; | 1119 return 0; |
1059 } | 1120 } |
1074 Create a new cons, give it CAR and CDR as components, and return it. | 1135 Create a new cons, give it CAR and CDR as components, and return it. |
1075 */ | 1136 */ |
1076 (car, cdr)) | 1137 (car, cdr)) |
1077 { | 1138 { |
1078 /* This cannot GC. */ | 1139 /* This cannot GC. */ |
1079 Lisp_Object val = Qnil; | 1140 Lisp_Object val; |
1080 struct Lisp_Cons *c; | 1141 struct Lisp_Cons *c; |
1081 | 1142 |
1082 ALLOCATE_FIXED_TYPE (cons, struct Lisp_Cons, c); | 1143 ALLOCATE_FIXED_TYPE (cons, struct Lisp_Cons, c); |
1083 #ifdef LRECORD_CONS | 1144 #ifdef LRECORD_CONS |
1084 set_lheader_implementation (&(c->lheader), lrecord_cons); | 1145 set_lheader_implementation (&(c->lheader), lrecord_cons); |
1093 going to free later, and is useful when trying to track down | 1154 going to free later, and is useful when trying to track down |
1094 "real" consing. */ | 1155 "real" consing. */ |
1095 Lisp_Object | 1156 Lisp_Object |
1096 noseeum_cons (Lisp_Object car, Lisp_Object cdr) | 1157 noseeum_cons (Lisp_Object car, Lisp_Object cdr) |
1097 { | 1158 { |
1098 Lisp_Object val = Qnil; | 1159 Lisp_Object val; |
1099 struct Lisp_Cons *c; | 1160 struct Lisp_Cons *c; |
1100 | 1161 |
1101 NOSEEUM_ALLOCATE_FIXED_TYPE (cons, struct Lisp_Cons, c); | 1162 NOSEEUM_ALLOCATE_FIXED_TYPE (cons, struct Lisp_Cons, c); |
1102 #ifdef LRECORD_CONS | 1163 #ifdef LRECORD_CONS |
1103 set_lheader_implementation (&(c->lheader), lrecord_cons); | 1164 set_lheader_implementation (&(c->lheader), lrecord_cons); |
1131 | 1192 |
1132 Lisp_Object | 1193 Lisp_Object |
1133 list2 (Lisp_Object obj0, Lisp_Object obj1) | 1194 list2 (Lisp_Object obj0, Lisp_Object obj1) |
1134 { | 1195 { |
1135 /* This cannot GC. */ | 1196 /* This cannot GC. */ |
1136 return Fcons (obj0, list1 (obj1)); | 1197 return Fcons (obj0, Fcons (obj1, Qnil)); |
1137 } | 1198 } |
1138 | 1199 |
1139 Lisp_Object | 1200 Lisp_Object |
1140 list3 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2) | 1201 list3 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2) |
1141 { | 1202 { |
1142 /* This cannot GC. */ | 1203 /* This cannot GC. */ |
1143 return Fcons (obj0, list2 (obj1, obj2)); | 1204 return Fcons (obj0, Fcons (obj1, Fcons (obj2, Qnil))); |
1144 } | 1205 } |
1145 | 1206 |
1146 static Lisp_Object | 1207 Lisp_Object |
1147 cons3 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2) | 1208 cons3 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2) |
1148 { | 1209 { |
1149 /* This cannot GC. */ | 1210 /* This cannot GC. */ |
1150 return Fcons (obj0, Fcons (obj1, obj2)); | 1211 return Fcons (obj0, Fcons (obj1, obj2)); |
1151 } | 1212 } |
1152 | 1213 |
1153 Lisp_Object | 1214 Lisp_Object |
1215 acons (Lisp_Object key, Lisp_Object value, Lisp_Object alist) | |
1216 { | |
1217 return Fcons (Fcons (key, value), alist); | |
1218 } | |
1219 | |
1220 Lisp_Object | |
1154 list4 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2, Lisp_Object obj3) | 1221 list4 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2, Lisp_Object obj3) |
1155 { | 1222 { |
1156 /* This cannot GC. */ | 1223 /* This cannot GC. */ |
1157 return Fcons (obj0, list3 (obj1, obj2, obj3)); | 1224 return Fcons (obj0, Fcons (obj1, Fcons (obj2, Fcons (obj3, Qnil)))); |
1158 } | 1225 } |
1159 | 1226 |
1160 Lisp_Object | 1227 Lisp_Object |
1161 list5 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2, Lisp_Object obj3, | 1228 list5 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2, Lisp_Object obj3, |
1162 Lisp_Object obj4) | 1229 Lisp_Object obj4) |
1163 { | 1230 { |
1164 /* This cannot GC. */ | 1231 /* This cannot GC. */ |
1165 return Fcons (obj0, list4 (obj1, obj2, obj3, obj4)); | 1232 return Fcons (obj0, Fcons (obj1, Fcons (obj2, Fcons (obj3, Fcons (obj4, Qnil))))); |
1166 } | 1233 } |
1167 | 1234 |
1168 Lisp_Object | 1235 Lisp_Object |
1169 list6 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2, Lisp_Object obj3, | 1236 list6 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2, Lisp_Object obj3, |
1170 Lisp_Object obj4, Lisp_Object obj5) | 1237 Lisp_Object obj4, Lisp_Object obj5) |
1171 { | 1238 { |
1172 /* This cannot GC. */ | 1239 /* This cannot GC. */ |
1173 return Fcons (obj0, list5 (obj1, obj2, obj3, obj4, obj5)); | 1240 return Fcons (obj0, Fcons (obj1, Fcons (obj2, Fcons (obj3, Fcons (obj4, Fcons (obj5, Qnil)))))); |
1174 } | 1241 } |
1175 | 1242 |
1176 DEFUN ("make-list", Fmake_list, 2, 2, 0, /* | 1243 DEFUN ("make-list", Fmake_list, 2, 2, 0, /* |
1177 Return a newly created list of length LENGTH, with each element being INIT. | 1244 Return a new list of length LENGTH, with each element being INIT. |
1178 */ | 1245 */ |
1179 (length, init)) | 1246 (length, init)) |
1180 { | 1247 { |
1181 Lisp_Object val; | |
1182 int size; | |
1183 | |
1184 CHECK_NATNUM (length); | 1248 CHECK_NATNUM (length); |
1185 size = XINT (length); | 1249 |
1186 | 1250 { |
1187 val = Qnil; | 1251 Lisp_Object val = Qnil; |
1188 while (size-- > 0) | 1252 int size = XINT (length); |
1189 val = Fcons (init, val); | 1253 |
1190 return val; | 1254 while (size-- > 0) |
1255 val = Fcons (init, val); | |
1256 return val; | |
1257 } | |
1191 } | 1258 } |
1192 | 1259 |
1193 | 1260 |
1194 /**********************************************************************/ | 1261 /**********************************************************************/ |
1195 /* Float allocation */ | 1262 /* Float allocation */ |
1232 for (i = 0; i < len - 1; i++) | 1299 for (i = 0; i < len - 1; i++) |
1233 (markobj) (ptr->contents[i]); | 1300 (markobj) (ptr->contents[i]); |
1234 return (len > 0) ? ptr->contents[len - 1] : Qnil; | 1301 return (len > 0) ? ptr->contents[len - 1] : Qnil; |
1235 } | 1302 } |
1236 | 1303 |
1237 static unsigned int | 1304 static size_t |
1238 size_vector (CONST void *lheader) | 1305 size_vector (CONST void *lheader) |
1239 { | 1306 { |
1240 CONST struct Lisp_Vector *p = lheader; | 1307 /* * -1 because struct Lisp_Vector includes 1 slot */ |
1241 /* | |
1242 * -1 because struct Lisp_Vector includes 1 slot | |
1243 */ | |
1244 return sizeof (struct Lisp_Vector) + | 1308 return sizeof (struct Lisp_Vector) + |
1245 ((p->size - 1) * sizeof (Lisp_Object)) ; | 1309 ((((struct Lisp_Vector *) lheader)->size - 1) * sizeof (Lisp_Object)); |
1246 } | 1310 } |
1247 | 1311 |
1248 static int | 1312 static int |
1249 vector_equal (Lisp_Object o1, Lisp_Object o2, int depth) | 1313 vector_equal (Lisp_Object o1, Lisp_Object o2, int depth) |
1250 { | 1314 { |
1273 0, | 1337 0, |
1274 size_vector, struct Lisp_Vector); | 1338 size_vector, struct Lisp_Vector); |
1275 | 1339 |
1276 /* #### should allocate `small' vectors from a frob-block */ | 1340 /* #### should allocate `small' vectors from a frob-block */ |
1277 static struct Lisp_Vector * | 1341 static struct Lisp_Vector * |
1278 make_vector_internal (EMACS_INT sizei) | 1342 make_vector_internal (size_t sizei) |
1279 { | 1343 { |
1280 EMACS_INT sizem = (sizeof (struct Lisp_Vector) | 1344 size_t sizem = (sizeof (struct Lisp_Vector) |
1281 /* -1 because struct Lisp_Vector includes 1 slot */ | 1345 /* -1 because struct Lisp_Vector includes 1 slot */ |
1282 + (sizei - 1) * sizeof (Lisp_Object) | 1346 + (sizei - 1) * sizeof (Lisp_Object)); |
1283 ); | 1347 struct Lisp_Vector *p = |
1284 struct Lisp_Vector *p = alloc_lcrecord (sizem, lrecord_vector); | 1348 (struct Lisp_Vector *) alloc_lcrecord (sizem, lrecord_vector); |
1285 | 1349 |
1286 p->size = sizei; | 1350 p->size = sizei; |
1287 return p; | 1351 return p; |
1288 } | 1352 } |
1289 | 1353 |
1291 | 1355 |
1292 static Lisp_Object all_vectors; | 1356 static Lisp_Object all_vectors; |
1293 | 1357 |
1294 /* #### should allocate `small' vectors from a frob-block */ | 1358 /* #### should allocate `small' vectors from a frob-block */ |
1295 static struct Lisp_Vector * | 1359 static struct Lisp_Vector * |
1296 make_vector_internal (EMACS_INT sizei) | 1360 make_vector_internal (size_t sizei) |
1297 { | 1361 { |
1298 EMACS_INT sizem = (sizeof (struct Lisp_Vector) | 1362 size_t sizem = (sizeof (struct Lisp_Vector) |
1299 /* -1 because struct Lisp_Vector includes 1 slot, | 1363 /* -1 because struct Lisp_Vector includes 1 slot, |
1300 * +1 to account for vector_next */ | 1364 * +1 to account for vector_next */ |
1301 + (sizei - 1 + 1) * sizeof (Lisp_Object) | 1365 + (sizei - 1 + 1) * sizeof (Lisp_Object)); |
1302 ); | |
1303 struct Lisp_Vector *p = (struct Lisp_Vector *) allocate_lisp_storage (sizem); | 1366 struct Lisp_Vector *p = (struct Lisp_Vector *) allocate_lisp_storage (sizem); |
1304 | 1367 |
1305 INCREMENT_CONS_COUNTER (sizem, "vector"); | 1368 INCREMENT_CONS_COUNTER (sizem, "vector"); |
1306 | 1369 |
1307 p->size = sizei; | 1370 p->size = sizei; |
1313 #endif /* ! LRECORD_VECTOR */ | 1376 #endif /* ! LRECORD_VECTOR */ |
1314 | 1377 |
1315 Lisp_Object | 1378 Lisp_Object |
1316 make_vector (EMACS_INT length, Lisp_Object init) | 1379 make_vector (EMACS_INT length, Lisp_Object init) |
1317 { | 1380 { |
1318 EMACS_INT elt; | 1381 int elt; |
1319 Lisp_Object vector = Qnil; | 1382 Lisp_Object vector; |
1320 struct Lisp_Vector *p; | 1383 struct Lisp_Vector *p; |
1321 | 1384 |
1322 if (length < 0) | 1385 if (length < 0) |
1323 length = XINT (wrong_type_argument (Qnatnump, make_int (length))); | 1386 length = XINT (wrong_type_argument (Qnatnump, make_int (length))); |
1324 | 1387 |
1344 | 1407 |
1345 return vector; | 1408 return vector; |
1346 } | 1409 } |
1347 | 1410 |
1348 DEFUN ("make-vector", Fmake_vector, 2, 2, 0, /* | 1411 DEFUN ("make-vector", Fmake_vector, 2, 2, 0, /* |
1349 Return a newly created vector of length LENGTH, with each element being INIT. | 1412 Return a new vector of length LENGTH, with each element being INIT. |
1350 See also the function `vector'. | 1413 See also the function `vector'. |
1351 */ | 1414 */ |
1352 (length, init)) | 1415 (length, init)) |
1353 { | 1416 { |
1354 if (!INTP (length) || XINT (length) < 0) | 1417 CHECK_NATNUM (length); |
1355 length = wrong_type_argument (Qnatnump, length); | |
1356 | |
1357 return make_vector (XINT (length), init); | 1418 return make_vector (XINT (length), init); |
1358 } | 1419 } |
1359 | 1420 |
1360 DEFUN ("vector", Fvector, 0, MANY, 0, /* | 1421 DEFUN ("vector", Fvector, 0, MANY, 0, /* |
1361 Return a newly created vector with specified arguments as elements. | 1422 Return a newly created vector with specified arguments as elements. |
1362 Any number of arguments, even zero arguments, are allowed. | 1423 Any number of arguments, even zero arguments, are allowed. |
1363 */ | 1424 */ |
1364 (int nargs, Lisp_Object *args)) | 1425 (int nargs, Lisp_Object *args)) |
1365 { | 1426 { |
1366 Lisp_Object vector = Qnil; | 1427 Lisp_Object vector; |
1367 int elt; | 1428 int elt; |
1368 struct Lisp_Vector *p; | 1429 struct Lisp_Vector *p = make_vector_internal (nargs); |
1369 | |
1370 p = make_vector_internal (nargs); | |
1371 XSETVECTOR (vector, p); | |
1372 | 1430 |
1373 for (elt = 0; elt < nargs; elt++) | 1431 for (elt = 0; elt < nargs; elt++) |
1374 vector_data(p)[elt] = args[elt]; | 1432 vector_data(p)[elt] = args[elt]; |
1375 | 1433 |
1434 XSETVECTOR (vector, p); | |
1376 return vector; | 1435 return vector; |
1377 } | 1436 } |
1378 | 1437 |
1379 Lisp_Object | 1438 Lisp_Object |
1380 vector1 (Lisp_Object obj0) | 1439 vector1 (Lisp_Object obj0) |
1398 args[0] = obj0; | 1457 args[0] = obj0; |
1399 args[1] = obj1; | 1458 args[1] = obj1; |
1400 args[2] = obj2; | 1459 args[2] = obj2; |
1401 return Fvector (3, args); | 1460 return Fvector (3, args); |
1402 } | 1461 } |
1462 | |
1463 #if 0 /* currently unused */ | |
1403 | 1464 |
1404 Lisp_Object | 1465 Lisp_Object |
1405 vector4 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2, | 1466 vector4 (Lisp_Object obj0, Lisp_Object obj1, Lisp_Object obj2, |
1406 Lisp_Object obj3) | 1467 Lisp_Object obj3) |
1407 { | 1468 { |
1470 args[5] = obj5; | 1531 args[5] = obj5; |
1471 args[6] = obj6; | 1532 args[6] = obj6; |
1472 args[7] = obj7; | 1533 args[7] = obj7; |
1473 return Fvector (8, args); | 1534 return Fvector (8, args); |
1474 } | 1535 } |
1536 #endif /* unused */ | |
1475 | 1537 |
1476 /**********************************************************************/ | 1538 /**********************************************************************/ |
1477 /* Bit Vector allocation */ | 1539 /* Bit Vector allocation */ |
1478 /**********************************************************************/ | 1540 /**********************************************************************/ |
1479 | 1541 |
1480 static Lisp_Object all_bit_vectors; | 1542 static Lisp_Object all_bit_vectors; |
1481 | 1543 |
1482 /* #### should allocate `small' bit vectors from a frob-block */ | 1544 /* #### should allocate `small' bit vectors from a frob-block */ |
1483 static struct Lisp_Bit_Vector * | 1545 static struct Lisp_Bit_Vector * |
1484 make_bit_vector_internal (EMACS_INT sizei) | 1546 make_bit_vector_internal (size_t sizei) |
1485 { | 1547 { |
1486 EMACS_INT sizem = (sizeof (struct Lisp_Bit_Vector) + | 1548 size_t sizem = sizeof (struct Lisp_Bit_Vector) + |
1487 /* -1 because struct Lisp_Bit_Vector includes 1 slot */ | 1549 /* -1 because struct Lisp_Bit_Vector includes 1 slot */ |
1488 sizeof (long) * (BIT_VECTOR_LONG_STORAGE (sizei) - 1)); | 1550 sizeof (long) * (BIT_VECTOR_LONG_STORAGE (sizei) - 1); |
1489 struct Lisp_Bit_Vector *p = | 1551 struct Lisp_Bit_Vector *p = |
1490 (struct Lisp_Bit_Vector *) allocate_lisp_storage (sizem); | 1552 (struct Lisp_Bit_Vector *) allocate_lisp_storage (sizem); |
1491 set_lheader_implementation (&(p->lheader), lrecord_bit_vector); | 1553 set_lheader_implementation (&(p->lheader), lrecord_bit_vector); |
1492 | 1554 |
1493 INCREMENT_CONS_COUNTER (sizem, "bit-vector"); | 1555 INCREMENT_CONS_COUNTER (sizem, "bit-vector"); |
1502 } | 1564 } |
1503 | 1565 |
1504 Lisp_Object | 1566 Lisp_Object |
1505 make_bit_vector (EMACS_INT length, Lisp_Object init) | 1567 make_bit_vector (EMACS_INT length, Lisp_Object init) |
1506 { | 1568 { |
1507 Lisp_Object bit_vector = Qnil; | 1569 Lisp_Object bit_vector; |
1508 struct Lisp_Bit_Vector *p; | 1570 struct Lisp_Bit_Vector *p; |
1509 EMACS_INT num_longs; | 1571 EMACS_INT num_longs; |
1510 | |
1511 if (length < 0) | |
1512 length = XINT (wrong_type_argument (Qnatnump, make_int (length))); | |
1513 | 1572 |
1514 CHECK_BIT (init); | 1573 CHECK_BIT (init); |
1515 | 1574 |
1516 num_longs = BIT_VECTOR_LONG_STORAGE (length); | 1575 num_longs = BIT_VECTOR_LONG_STORAGE (length); |
1517 p = make_bit_vector_internal (length); | 1576 p = make_bit_vector_internal (length); |
1533 } | 1592 } |
1534 | 1593 |
1535 Lisp_Object | 1594 Lisp_Object |
1536 make_bit_vector_from_byte_vector (unsigned char *bytevec, EMACS_INT length) | 1595 make_bit_vector_from_byte_vector (unsigned char *bytevec, EMACS_INT length) |
1537 { | 1596 { |
1538 Lisp_Object bit_vector = Qnil; | 1597 Lisp_Object bit_vector; |
1539 struct Lisp_Bit_Vector *p; | 1598 struct Lisp_Bit_Vector *p; |
1540 EMACS_INT i; | 1599 int i; |
1541 | 1600 |
1542 if (length < 0) | 1601 if (length < 0) |
1543 length = XINT (wrong_type_argument (Qnatnump, make_int (length))); | 1602 length = XINT (wrong_type_argument (Qnatnump, make_int (length))); |
1544 | 1603 |
1545 p = make_bit_vector_internal (length); | 1604 p = make_bit_vector_internal (length); |
1550 | 1609 |
1551 return bit_vector; | 1610 return bit_vector; |
1552 } | 1611 } |
1553 | 1612 |
1554 DEFUN ("make-bit-vector", Fmake_bit_vector, 2, 2, 0, /* | 1613 DEFUN ("make-bit-vector", Fmake_bit_vector, 2, 2, 0, /* |
1555 Return a newly created bit vector of length LENGTH. | 1614 Return a new bit vector of length LENGTH. with each bit being INIT. |
1556 Each element is set to INIT. See also the function `bit-vector'. | 1615 Each element is set to INIT. See also the function `bit-vector'. |
1557 */ | 1616 */ |
1558 (length, init)) | 1617 (length, init)) |
1559 { | 1618 { |
1560 if (!INTP (length) || XINT (length) < 0) | 1619 CONCHECK_NATNUM (length); |
1561 length = wrong_type_argument (Qnatnump, length); | |
1562 | 1620 |
1563 return make_bit_vector (XINT (length), init); | 1621 return make_bit_vector (XINT (length), init); |
1564 } | 1622 } |
1565 | 1623 |
1566 DEFUN ("bit-vector", Fbit_vector, 0, MANY, 0, /* | 1624 DEFUN ("bit-vector", Fbit_vector, 0, MANY, 0, /* |
1567 Return a newly created bit vector with specified arguments as elements. | 1625 Return a newly created bit vector with specified arguments as elements. |
1568 Any number of arguments, even zero arguments, are allowed. | 1626 Any number of arguments, even zero arguments, are allowed. |
1569 */ | 1627 */ |
1570 (int nargs, Lisp_Object *args)) | 1628 (int nargs, Lisp_Object *args)) |
1571 { | 1629 { |
1572 Lisp_Object bit_vector = Qnil; | 1630 Lisp_Object bit_vector; |
1573 int elt; | 1631 int elt; |
1574 struct Lisp_Bit_Vector *p; | 1632 struct Lisp_Bit_Vector *p; |
1575 | 1633 |
1576 for (elt = 0; elt < nargs; elt++) | 1634 for (elt = 0; elt < nargs; elt++) |
1577 CHECK_BIT (args[elt]); | 1635 CHECK_BIT (args[elt]); |
1578 | 1636 |
1579 p = make_bit_vector_internal (nargs); | 1637 p = make_bit_vector_internal (nargs); |
1580 XSETBIT_VECTOR (bit_vector, p); | |
1581 | 1638 |
1582 for (elt = 0; elt < nargs; elt++) | 1639 for (elt = 0; elt < nargs; elt++) |
1583 set_bit_vector_bit (p, elt, !ZEROP (args[elt])); | 1640 set_bit_vector_bit (p, elt, !ZEROP (args[elt])); |
1584 | 1641 |
1642 XSETBIT_VECTOR (bit_vector, p); | |
1585 return bit_vector; | 1643 return bit_vector; |
1586 } | 1644 } |
1587 | 1645 |
1588 | 1646 |
1589 /**********************************************************************/ | 1647 /**********************************************************************/ |
1596 static Lisp_Object | 1654 static Lisp_Object |
1597 make_compiled_function (int make_pure) | 1655 make_compiled_function (int make_pure) |
1598 { | 1656 { |
1599 struct Lisp_Compiled_Function *b; | 1657 struct Lisp_Compiled_Function *b; |
1600 Lisp_Object new; | 1658 Lisp_Object new; |
1601 int size = sizeof (struct Lisp_Compiled_Function); | 1659 size_t size = sizeof (struct Lisp_Compiled_Function); |
1602 | 1660 |
1603 if (make_pure && check_purespace (size)) | 1661 if (make_pure && check_purespace (size)) |
1604 { | 1662 { |
1605 b = (struct Lisp_Compiled_Function *) (PUREBEG + pureptr); | 1663 b = (struct Lisp_Compiled_Function *) (PUREBEG + pure_bytes_used); |
1606 set_lheader_implementation (&(b->lheader), lrecord_compiled_function); | 1664 set_lheader_implementation (&(b->lheader), lrecord_compiled_function); |
1607 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION | 1665 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION |
1608 b->lheader.pure = 1; | 1666 b->lheader.pure = 1; |
1609 #endif | 1667 #endif |
1610 pureptr += size; | 1668 pure_bytes_used += size; |
1611 bump_purestat (&purestat_bytecode, size); | 1669 bump_purestat (&purestat_bytecode, size); |
1612 } | 1670 } |
1613 else | 1671 else |
1614 { | 1672 { |
1615 ALLOCATE_FIXED_TYPE (compiled_function, struct Lisp_Compiled_Function, | 1673 ALLOCATE_FIXED_TYPE (compiled_function, struct Lisp_Compiled_Function, |
1630 XSETCOMPILED_FUNCTION (new, b); | 1688 XSETCOMPILED_FUNCTION (new, b); |
1631 return new; | 1689 return new; |
1632 } | 1690 } |
1633 | 1691 |
1634 DEFUN ("make-byte-code", Fmake_byte_code, 4, MANY, 0, /* | 1692 DEFUN ("make-byte-code", Fmake_byte_code, 4, MANY, 0, /* |
1635 Create a compiled-function object. | 1693 Return a new compiled-function object. |
1636 Usage: (arglist instructions constants stack-size | 1694 Usage: (arglist instructions constants stack-size |
1637 &optional doc-string interactive-spec) | 1695 &optional doc-string interactive-spec) |
1638 Note that, unlike all other emacs-lisp functions, calling this with five | 1696 Note that, unlike all other emacs-lisp functions, calling this with five |
1639 arguments is NOT the same as calling it with six arguments, the last of | 1697 arguments is NOT the same as calling it with six arguments, the last of |
1640 which is nil. If the INTERACTIVE arg is specified as nil, then that means | 1698 which is nil. If the INTERACTIVE arg is specified as nil, then that means |
1652 */ | 1710 */ |
1653 Lisp_Object arglist = args[0]; | 1711 Lisp_Object arglist = args[0]; |
1654 Lisp_Object instructions = args[1]; | 1712 Lisp_Object instructions = args[1]; |
1655 Lisp_Object constants = args[2]; | 1713 Lisp_Object constants = args[2]; |
1656 Lisp_Object stack_size = args[3]; | 1714 Lisp_Object stack_size = args[3]; |
1657 Lisp_Object doc_string = ((nargs > 4) ? args[4] : Qnil); | 1715 Lisp_Object doc_string = (nargs > 4) ? args[4] : Qnil; |
1658 Lisp_Object interactive = ((nargs > 5) ? args[5] : Qunbound); | 1716 Lisp_Object interactive = (nargs > 5) ? args[5] : Qunbound; |
1659 /* Don't purecopy the doc references in instructions because it's | 1717 /* Don't purecopy the doc references in instructions because it's |
1660 wasteful; they will get fixed up later. | 1718 wasteful; they will get fixed up later. |
1661 | 1719 |
1662 #### If something goes wrong and they don't get fixed up, | 1720 #### If something goes wrong and they don't get fixed up, |
1663 we're screwed, because pure stuff isn't marked and thus the | 1721 we're screwed, because pure stuff isn't marked and thus the |
1844 allocate_extent (void) | 1902 allocate_extent (void) |
1845 { | 1903 { |
1846 struct extent *e; | 1904 struct extent *e; |
1847 | 1905 |
1848 ALLOCATE_FIXED_TYPE (extent, struct extent, e); | 1906 ALLOCATE_FIXED_TYPE (extent, struct extent, e); |
1849 /* memset (e, 0, sizeof (struct extent)); */ | 1907 /* xzero (*e); */ |
1850 set_lheader_implementation (&(e->lheader), lrecord_extent); | 1908 set_lheader_implementation (&(e->lheader), lrecord_extent); |
1851 extent_object (e) = Qnil; | 1909 extent_object (e) = Qnil; |
1852 set_extent_start (e, -1); | 1910 set_extent_start (e, -1); |
1853 set_extent_end (e, -1); | 1911 set_extent_end (e, -1); |
1854 e->plist = Qnil; | 1912 e->plist = Qnil; |
1855 | 1913 |
1856 memset (&e->flags, 0, sizeof (e->flags)); | 1914 xzero (e->flags); |
1857 | 1915 |
1858 extent_face (e) = Qnil; | 1916 extent_face (e) = Qnil; |
1859 e->flags.end_open = 1; /* default is for endpoints to behave like markers */ | 1917 e->flags.end_open = 1; /* default is for endpoints to behave like markers */ |
1860 e->flags.detachable = 1; | 1918 e->flags.detachable = 1; |
1861 | 1919 |
1890 | 1948 |
1891 DECLARE_FIXED_TYPE_ALLOC (marker, struct Lisp_Marker); | 1949 DECLARE_FIXED_TYPE_ALLOC (marker, struct Lisp_Marker); |
1892 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_marker 1000 | 1950 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_marker 1000 |
1893 | 1951 |
1894 DEFUN ("make-marker", Fmake_marker, 0, 0, 0, /* | 1952 DEFUN ("make-marker", Fmake_marker, 0, 0, 0, /* |
1895 Return a newly allocated marker which does not point at any place. | 1953 Return a new marker which does not point at any place. |
1896 */ | 1954 */ |
1897 ()) | 1955 ()) |
1898 { | 1956 { |
1899 Lisp_Object val; | 1957 Lisp_Object val; |
1900 struct Lisp_Marker *p; | 1958 struct Lisp_Marker *p; |
1962 } | 2020 } |
1963 | 2021 |
1964 static int | 2022 static int |
1965 string_equal (Lisp_Object o1, Lisp_Object o2, int depth) | 2023 string_equal (Lisp_Object o1, Lisp_Object o2, int depth) |
1966 { | 2024 { |
1967 Bytecount len = XSTRING_LENGTH (o1); | 2025 Bytecount len; |
1968 if (len != XSTRING_LENGTH (o2)) | 2026 return (((len = XSTRING_LENGTH (o1)) == XSTRING_LENGTH (o2)) && |
1969 return 0; | 2027 !memcmp (XSTRING_DATA (o1), XSTRING_DATA (o2), len)); |
1970 if (memcmp (XSTRING_DATA (o1), XSTRING_DATA (o2), len)) | |
1971 return 0; | |
1972 return 1; | |
1973 } | 2028 } |
1974 | 2029 |
1975 DEFINE_BASIC_LRECORD_IMPLEMENTATION ("string", string, | 2030 DEFINE_BASIC_LRECORD_IMPLEMENTATION ("string", string, |
1976 mark_string, print_string, | 2031 mark_string, print_string, |
1977 /* | 2032 /* |
1987 0, string_equal, 0, | 2042 0, string_equal, 0, |
1988 struct Lisp_String); | 2043 struct Lisp_String); |
1989 #endif /* LRECORD_STRING */ | 2044 #endif /* LRECORD_STRING */ |
1990 | 2045 |
1991 /* String blocks contain this many useful bytes. */ | 2046 /* String blocks contain this many useful bytes. */ |
1992 #define STRING_CHARS_BLOCK_SIZE \ | 2047 #define STRING_CHARS_BLOCK_SIZE \ |
1993 (8192 - MALLOC_OVERHEAD - ((2 * sizeof (struct string_chars_block *)) \ | 2048 ((Bytecount) (8192 - MALLOC_OVERHEAD - \ |
1994 + sizeof (EMACS_INT))) | 2049 ((2 * sizeof (struct string_chars_block *)) \ |
2050 + sizeof (EMACS_INT)))) | |
1995 /* Block header for small strings. */ | 2051 /* Block header for small strings. */ |
1996 struct string_chars_block | 2052 struct string_chars_block |
1997 { | 2053 { |
1998 EMACS_INT pos; | 2054 EMACS_INT pos; |
1999 struct string_chars_block *next; | 2055 struct string_chars_block *next; |
2155 if (delta == 0) | 2211 if (delta == 0) |
2156 /* simplest case: no size change. */ | 2212 /* simplest case: no size change. */ |
2157 return; | 2213 return; |
2158 else | 2214 else |
2159 { | 2215 { |
2160 EMACS_INT oldfullsize = STRING_FULLSIZE (string_length (s)); | 2216 Bytecount oldfullsize = STRING_FULLSIZE (string_length (s)); |
2161 EMACS_INT newfullsize = STRING_FULLSIZE (string_length (s) + delta); | 2217 Bytecount newfullsize = STRING_FULLSIZE (string_length (s) + delta); |
2162 | 2218 |
2163 if (oldfullsize == newfullsize) | 2219 if (oldfullsize == newfullsize) |
2164 { | 2220 { |
2165 /* next simplest case; size change but the necessary | 2221 /* next simplest case; size change but the necessary |
2166 allocation size won't change (up or down; code somewhere | 2222 allocation size won't change (up or down; code somewhere |
2238 Terminate now just to make sure. */ | 2294 Terminate now just to make sure. */ |
2239 string_data (s)[string_length (s)] = '\0'; | 2295 string_data (s)[string_length (s)] = '\0'; |
2240 | 2296 |
2241 if (pos >= 0) | 2297 if (pos >= 0) |
2242 { | 2298 { |
2243 Lisp_Object string = Qnil; | 2299 Lisp_Object string; |
2244 | 2300 |
2245 XSETSTRING (string, s); | 2301 XSETSTRING (string, s); |
2246 /* We also have to adjust all of the extent indices after the | 2302 /* We also have to adjust all of the extent indices after the |
2247 place we did the change. We say "pos - 1" because | 2303 place we did the change. We say "pos - 1" because |
2248 adjust_extents() is exclusive of the starting position | 2304 adjust_extents() is exclusive of the starting position |
2276 } | 2332 } |
2277 | 2333 |
2278 #endif /* MULE */ | 2334 #endif /* MULE */ |
2279 | 2335 |
2280 DEFUN ("make-string", Fmake_string, 2, 2, 0, /* | 2336 DEFUN ("make-string", Fmake_string, 2, 2, 0, /* |
2281 Return a newly created string of length LENGTH, with each element being INIT. | 2337 Return a new string of length LENGTH, with each character being INIT. |
2282 LENGTH must be an integer and INIT must be a character. | 2338 LENGTH must be an integer and INIT must be a character. |
2283 */ | 2339 */ |
2284 (length, init)) | 2340 (length, init)) |
2285 { | 2341 { |
2286 Lisp_Object val; | 2342 Lisp_Object val; |
2308 } | 2364 } |
2309 return val; | 2365 return val; |
2310 } | 2366 } |
2311 | 2367 |
2312 /* Take some raw memory, which MUST already be in internal format, | 2368 /* Take some raw memory, which MUST already be in internal format, |
2313 and package it up it into a Lisp string. */ | 2369 and package it up into a Lisp string. */ |
2314 Lisp_Object | 2370 Lisp_Object |
2315 make_string (CONST Bufbyte *contents, Bytecount length) | 2371 make_string (CONST Bufbyte *contents, Bytecount length) |
2316 { | 2372 { |
2317 Lisp_Object val; | 2373 Lisp_Object val; |
2318 | 2374 |
2330 and convert it into a Lisp string. */ | 2386 and convert it into a Lisp string. */ |
2331 Lisp_Object | 2387 Lisp_Object |
2332 make_ext_string (CONST Extbyte *contents, EMACS_INT length, | 2388 make_ext_string (CONST Extbyte *contents, EMACS_INT length, |
2333 enum external_data_format fmt) | 2389 enum external_data_format fmt) |
2334 { | 2390 { |
2335 CONST Bufbyte *intstr; | 2391 Bufbyte *intstr; |
2336 Bytecount intlen; | 2392 Bytecount intlen; |
2337 | 2393 |
2338 GET_CHARPTR_INT_DATA_ALLOCA (contents, length, fmt, intstr, intlen); | 2394 GET_CHARPTR_INT_DATA_ALLOCA (contents, length, fmt, intstr, intlen); |
2339 return make_string (intstr, intlen); | 2395 return make_string (intstr, intlen); |
2340 } | 2396 } |
2348 | 2404 |
2349 Lisp_Object | 2405 Lisp_Object |
2350 build_ext_string (CONST char *str, enum external_data_format fmt) | 2406 build_ext_string (CONST char *str, enum external_data_format fmt) |
2351 { | 2407 { |
2352 /* Some strlen's crash and burn if passed null. */ | 2408 /* Some strlen's crash and burn if passed null. */ |
2353 return make_ext_string ((Extbyte *) str, (str ? strlen(str) : 0), fmt); | 2409 return make_ext_string ((CONST Extbyte *) str, (str ? strlen(str) : 0), fmt); |
2354 } | 2410 } |
2355 | 2411 |
2356 Lisp_Object | 2412 Lisp_Object |
2357 build_translated_string (CONST char *str) | 2413 build_translated_string (CONST char *str) |
2358 { | 2414 { |
2430 | 2486 |
2431 DEFINE_LRECORD_IMPLEMENTATION ("lcrecord-list", lcrecord_list, | 2487 DEFINE_LRECORD_IMPLEMENTATION ("lcrecord-list", lcrecord_list, |
2432 mark_lcrecord_list, internal_object_printer, | 2488 mark_lcrecord_list, internal_object_printer, |
2433 0, 0, 0, struct lcrecord_list); | 2489 0, 0, 0, struct lcrecord_list); |
2434 Lisp_Object | 2490 Lisp_Object |
2435 make_lcrecord_list (int size, | 2491 make_lcrecord_list (size_t size, |
2436 CONST struct lrecord_implementation *implementation) | 2492 CONST struct lrecord_implementation *implementation) |
2437 { | 2493 { |
2438 struct lcrecord_list *p = alloc_lcrecord_type (struct lcrecord_list, | 2494 struct lcrecord_list *p = alloc_lcrecord_type (struct lcrecord_list, |
2439 lrecord_lcrecord_list); | 2495 lrecord_lcrecord_list); |
2440 Lisp_Object val = Qnil; | 2496 Lisp_Object val; |
2441 | 2497 |
2442 p->implementation = implementation; | 2498 p->implementation = implementation; |
2443 p->size = size; | 2499 p->size = size; |
2444 p->free = Qnil; | 2500 p->free = Qnil; |
2445 XSETLCRECORD_LIST (val, p); | 2501 XSETLCRECORD_LIST (val, p); |
2478 free_header->lcheader.free = 0; | 2534 free_header->lcheader.free = 0; |
2479 return val; | 2535 return val; |
2480 } | 2536 } |
2481 else | 2537 else |
2482 { | 2538 { |
2483 Lisp_Object val = Qnil; | 2539 Lisp_Object val; |
2484 | 2540 |
2485 XSETOBJ (val, Lisp_Type_Record, | 2541 XSETOBJ (val, Lisp_Type_Record, |
2486 alloc_lcrecord (list->size, list->implementation)); | 2542 alloc_lcrecord (list->size, list->implementation)); |
2487 return val; | 2543 return val; |
2488 } | 2544 } |
2527 make_pure_string (CONST Bufbyte *data, Bytecount length, | 2583 make_pure_string (CONST Bufbyte *data, Bytecount length, |
2528 Lisp_Object plist, int no_need_to_copy_data) | 2584 Lisp_Object plist, int no_need_to_copy_data) |
2529 { | 2585 { |
2530 Lisp_Object new; | 2586 Lisp_Object new; |
2531 struct Lisp_String *s; | 2587 struct Lisp_String *s; |
2532 int size = (sizeof (struct Lisp_String) + ((no_need_to_copy_data) | 2588 size_t size = sizeof (struct Lisp_String) + |
2533 ? 0 | 2589 (no_need_to_copy_data ? 0 : (length + 1)); /* + 1 for terminating 0 */ |
2534 /* + 1 for terminating 0 */ | |
2535 : (length + 1))); | |
2536 size = ALIGN_SIZE (size, ALIGNOF (Lisp_Object)); | 2590 size = ALIGN_SIZE (size, ALIGNOF (Lisp_Object)); |
2537 | 2591 |
2538 if (symbols_initialized && !pure_lossage) | 2592 if (symbols_initialized && !pure_lossage) |
2539 { | 2593 { |
2540 /* Try to share some names. Saves a few kbytes. */ | 2594 /* Try to share some names. Saves a few kbytes. */ |
2549 } | 2603 } |
2550 | 2604 |
2551 if (!check_purespace (size)) | 2605 if (!check_purespace (size)) |
2552 return make_string (data, length); | 2606 return make_string (data, length); |
2553 | 2607 |
2554 s = (struct Lisp_String *) (PUREBEG + pureptr); | 2608 s = (struct Lisp_String *) (PUREBEG + pure_bytes_used); |
2555 #ifdef LRECORD_STRING | 2609 #ifdef LRECORD_STRING |
2556 set_lheader_implementation (&(s->lheader), lrecord_string); | 2610 set_lheader_implementation (&(s->lheader), lrecord_string); |
2557 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION | 2611 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION |
2558 s->lheader.pure = 1; | 2612 s->lheader.pure = 1; |
2559 #endif | 2613 #endif |
2568 set_string_data (s, (Bufbyte *) s + sizeof (struct Lisp_String)); | 2622 set_string_data (s, (Bufbyte *) s + sizeof (struct Lisp_String)); |
2569 memcpy (string_data (s), data, length); | 2623 memcpy (string_data (s), data, length); |
2570 set_string_byte (s, length, 0); | 2624 set_string_byte (s, length, 0); |
2571 } | 2625 } |
2572 s->plist = Qnil; | 2626 s->plist = Qnil; |
2573 pureptr += size; | 2627 pure_bytes_used += size; |
2574 | 2628 |
2575 #ifdef PURESTAT | 2629 #ifdef PURESTAT |
2576 bump_purestat (&purestat_string_all, size); | 2630 bump_purestat (&purestat_string_all, size); |
2577 if (purecopying_for_bytecode) | 2631 if (purecopying_for_bytecode) |
2578 bump_purestat (&purestat_string_other_function, size); | 2632 bump_purestat (&purestat_string_other_function, size); |
2608 struct Lisp_Cons *c; | 2662 struct Lisp_Cons *c; |
2609 | 2663 |
2610 if (!check_purespace (sizeof (struct Lisp_Cons))) | 2664 if (!check_purespace (sizeof (struct Lisp_Cons))) |
2611 return Fcons (Fpurecopy (car), Fpurecopy (cdr)); | 2665 return Fcons (Fpurecopy (car), Fpurecopy (cdr)); |
2612 | 2666 |
2613 c = (struct Lisp_Cons *) (PUREBEG + pureptr); | 2667 c = (struct Lisp_Cons *) (PUREBEG + pure_bytes_used); |
2614 #ifdef LRECORD_CONS | 2668 #ifdef LRECORD_CONS |
2615 set_lheader_implementation (&(c->lheader), lrecord_cons); | 2669 set_lheader_implementation (&(c->lheader), lrecord_cons); |
2616 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION | 2670 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION |
2617 c->lheader.pure = 1; | 2671 c->lheader.pure = 1; |
2618 #endif | 2672 #endif |
2619 #endif | 2673 #endif |
2620 pureptr += sizeof (struct Lisp_Cons); | 2674 pure_bytes_used += sizeof (struct Lisp_Cons); |
2621 bump_purestat (&purestat_cons, sizeof (struct Lisp_Cons)); | 2675 bump_purestat (&purestat_cons, sizeof (struct Lisp_Cons)); |
2622 | 2676 |
2623 c->car = Fpurecopy (car); | 2677 c->car = Fpurecopy (car); |
2624 c->cdr = Fpurecopy (cdr); | 2678 c->cdr = Fpurecopy (cdr); |
2625 XSETCONS (new, c); | 2679 XSETCONS (new, c); |
2627 } | 2681 } |
2628 | 2682 |
2629 Lisp_Object | 2683 Lisp_Object |
2630 pure_list (int nargs, Lisp_Object *args) | 2684 pure_list (int nargs, Lisp_Object *args) |
2631 { | 2685 { |
2632 Lisp_Object foo = Qnil; | 2686 Lisp_Object val = Qnil; |
2633 | 2687 |
2634 for (--nargs; nargs >= 0; nargs--) | 2688 for (--nargs; nargs >= 0; nargs--) |
2635 foo = pure_cons (args[nargs], foo); | 2689 val = pure_cons (args[nargs], val); |
2636 | 2690 |
2637 return foo; | 2691 return val; |
2638 } | 2692 } |
2639 | 2693 |
2640 #ifdef LISP_FLOAT_TYPE | 2694 #ifdef LISP_FLOAT_TYPE |
2641 | 2695 |
2642 Lisp_Object | 2696 static Lisp_Object |
2643 make_pure_float (double num) | 2697 make_pure_float (double num) |
2644 { | 2698 { |
2645 struct Lisp_Float *f; | 2699 struct Lisp_Float *f; |
2646 Lisp_Object val; | 2700 Lisp_Object val; |
2647 | 2701 |
2648 /* Make sure that PUREBEG + pureptr is aligned on at least a sizeof | 2702 /* Make sure that PUREBEG + pure_bytes_used is aligned on at least a sizeof |
2649 (double) boundary. Some architectures (like the sparc) require | 2703 (double) boundary. Some architectures (like the sparc) require |
2650 this, and I suspect that floats are rare enough that it's no | 2704 this, and I suspect that floats are rare enough that it's no |
2651 tragedy for those that don't. */ | 2705 tragedy for those that don't. */ |
2652 { | 2706 { |
2653 #if defined (__GNUC__) && (__GNUC__ >= 2) | 2707 #if defined (__GNUC__) && (__GNUC__ >= 2) |
2663 should be ok because presumably there is padding in the layout | 2717 should be ok because presumably there is padding in the layout |
2664 of the struct to account for this. | 2718 of the struct to account for this. |
2665 */ | 2719 */ |
2666 int alignment = sizeof (float_data (f)); | 2720 int alignment = sizeof (float_data (f)); |
2667 #endif /* !GNUC */ | 2721 #endif /* !GNUC */ |
2668 char *p = ((char *) PUREBEG + pureptr); | 2722 char *p = ((char *) PUREBEG + pure_bytes_used); |
2669 | 2723 |
2670 p = (char *) (((unsigned EMACS_INT) p + alignment - 1) & - alignment); | 2724 p = (char *) (((EMACS_UINT) p + alignment - 1) & - alignment); |
2671 pureptr = p - (char *) PUREBEG; | 2725 pure_bytes_used = p - (char *) PUREBEG; |
2672 } | 2726 } |
2673 | 2727 |
2674 if (!check_purespace (sizeof (struct Lisp_Float))) | 2728 if (!check_purespace (sizeof (struct Lisp_Float))) |
2675 return make_float (num); | 2729 return make_float (num); |
2676 | 2730 |
2677 f = (struct Lisp_Float *) (PUREBEG + pureptr); | 2731 f = (struct Lisp_Float *) (PUREBEG + pure_bytes_used); |
2678 set_lheader_implementation (&(f->lheader), lrecord_float); | 2732 set_lheader_implementation (&(f->lheader), lrecord_float); |
2679 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION | 2733 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION |
2680 f->lheader.pure = 1; | 2734 f->lheader.pure = 1; |
2681 #endif | 2735 #endif |
2682 pureptr += sizeof (struct Lisp_Float); | 2736 pure_bytes_used += sizeof (struct Lisp_Float); |
2683 bump_purestat (&purestat_float, sizeof (struct Lisp_Float)); | 2737 bump_purestat (&purestat_float, sizeof (struct Lisp_Float)); |
2684 | 2738 |
2685 float_next (f) = ((struct Lisp_Float *) -1); | 2739 float_next (f) = ((struct Lisp_Float *) -1); |
2686 float_data (f) = num; | 2740 float_data (f) = num; |
2687 XSETFLOAT (val, f); | 2741 XSETFLOAT (val, f); |
2689 } | 2743 } |
2690 | 2744 |
2691 #endif /* LISP_FLOAT_TYPE */ | 2745 #endif /* LISP_FLOAT_TYPE */ |
2692 | 2746 |
2693 Lisp_Object | 2747 Lisp_Object |
2694 make_pure_vector (EMACS_INT len, Lisp_Object init) | 2748 make_pure_vector (size_t len, Lisp_Object init) |
2695 { | 2749 { |
2696 Lisp_Object new; | 2750 Lisp_Object new; |
2697 struct Lisp_Vector *v; | 2751 struct Lisp_Vector *v; |
2698 EMACS_INT size = (sizeof (struct Lisp_Vector) | 2752 size_t size = (sizeof (struct Lisp_Vector) |
2699 + (len - 1) * sizeof (Lisp_Object)); | 2753 + (len - 1) * sizeof (Lisp_Object)); |
2700 | 2754 |
2701 init = Fpurecopy (init); | 2755 init = Fpurecopy (init); |
2702 | 2756 |
2703 if (!check_purespace (size)) | 2757 if (!check_purespace (size)) |
2704 return make_vector (len, init); | 2758 return make_vector (len, init); |
2705 | 2759 |
2706 v = (struct Lisp_Vector *) (PUREBEG + pureptr); | 2760 v = (struct Lisp_Vector *) (PUREBEG + pure_bytes_used); |
2707 #ifdef LRECORD_VECTOR | 2761 #ifdef LRECORD_VECTOR |
2708 set_lheader_implementation (&(v->header.lheader), lrecord_vector); | 2762 set_lheader_implementation (&(v->header.lheader), lrecord_vector); |
2709 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION | 2763 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION |
2710 v->header.lheader.pure = 1; | 2764 v->header.lheader.pure = 1; |
2711 #endif | 2765 #endif |
2712 #endif | 2766 #endif |
2713 pureptr += size; | 2767 pure_bytes_used += size; |
2714 bump_purestat (&purestat_vector_all, size); | 2768 bump_purestat (&purestat_vector_all, size); |
2715 | 2769 |
2716 v->size = len; | 2770 v->size = len; |
2717 | 2771 |
2718 for (size = 0; size < len; size++) | 2772 for (size = 0; size < len; size++) |
2725 #if 0 | 2779 #if 0 |
2726 /* Presently unused */ | 2780 /* Presently unused */ |
2727 void * | 2781 void * |
2728 alloc_pure_lrecord (int size, struct lrecord_implementation *implementation) | 2782 alloc_pure_lrecord (int size, struct lrecord_implementation *implementation) |
2729 { | 2783 { |
2730 struct lrecord_header *header = (void *) (PUREBEG + pureptr); | 2784 struct lrecord_header *header = (void *) (PUREBEG + pure_bytes_used); |
2731 | 2785 |
2732 if (pureptr + size > get_PURESIZE()) | 2786 if (pure_bytes_used + size > get_PURESIZE()) |
2733 pure_storage_exhausted (); | 2787 pure_storage_exhausted (); |
2734 | 2788 |
2735 set_lheader_implementation (header, implementation); | 2789 set_lheader_implementation (header, implementation); |
2736 header->next = 0; | 2790 header->next = 0; |
2737 return header; | 2791 return header; |
2859 } | 2913 } |
2860 | 2914 |
2861 | 2915 |
2862 | 2916 |
2863 static void | 2917 static void |
2864 puresize_adjust_h (long int puresize) | 2918 puresize_adjust_h (size_t puresize) |
2865 { | 2919 { |
2866 FILE *stream = fopen ("puresize-adjust.h", "w"); | 2920 FILE *stream = fopen ("puresize-adjust.h", "w"); |
2867 | 2921 |
2868 if (stream == NULL) | 2922 if (stream == NULL) |
2869 report_file_error ("Opening puresize adjustment file", | 2923 report_file_error ("Opening puresize adjustment file", |
2871 | 2925 |
2872 fprintf (stream, | 2926 fprintf (stream, |
2873 "/*\tDo not edit this file!\n" | 2927 "/*\tDo not edit this file!\n" |
2874 "\tAutomatically generated by XEmacs */\n" | 2928 "\tAutomatically generated by XEmacs */\n" |
2875 "# define PURESIZE_ADJUSTMENT (%ld)\n", | 2929 "# define PURESIZE_ADJUSTMENT (%ld)\n", |
2876 puresize - RAW_PURESIZE); | 2930 (long) (puresize - RAW_PURESIZE)); |
2877 fclose (stream); | 2931 fclose (stream); |
2878 } | 2932 } |
2879 | 2933 |
2880 void | 2934 void |
2881 report_pure_usage (int report_impurities, | 2935 report_pure_usage (int report_impurities, |
2886 if (pure_lossage) | 2940 if (pure_lossage) |
2887 { | 2941 { |
2888 message ("\n****\tPure Lisp storage exhausted!\n" | 2942 message ("\n****\tPure Lisp storage exhausted!\n" |
2889 "\tPurespace usage: %ld of %ld\n" | 2943 "\tPurespace usage: %ld of %ld\n" |
2890 "****", | 2944 "****", |
2891 get_PURESIZE()+pure_lossage, (long) get_PURESIZE()); | 2945 (long) get_PURESIZE() + pure_lossage, |
2892 if (die_if_pure_storage_exceeded) { | 2946 (long) get_PURESIZE()); |
2893 puresize_adjust_h (get_PURESIZE() + pure_lossage); | 2947 if (die_if_pure_storage_exceeded) |
2948 { | |
2949 puresize_adjust_h (get_PURESIZE() + pure_lossage); | |
2894 #ifdef HEAP_IN_DATA | 2950 #ifdef HEAP_IN_DATA |
2895 sheap_adjust_h(); | 2951 sheap_adjust_h(); |
2896 #endif | 2952 #endif |
2897 rc = -1; | 2953 rc = -1; |
2898 } | 2954 } |
2899 } | 2955 } |
2900 else | 2956 else |
2901 { | 2957 { |
2902 int lost = (get_PURESIZE() - pureptr) / 1024; | 2958 size_t lost = (get_PURESIZE() - pure_bytes_used) / 1024; |
2903 char buf[200]; | 2959 char buf[200]; |
2904 /* extern Lisp_Object Vemacs_beta_version; */ | 2960 /* extern Lisp_Object Vemacs_beta_version; */ |
2905 /* This used to be NILP(Vemacs_beta_version) ? 512 : 4; */ | 2961 /* This used to be NILP(Vemacs_beta_version) ? 512 : 4; */ |
2906 #ifndef PURESIZE_SLOP | 2962 #ifndef PURESIZE_SLOP |
2907 #define PURESIZE_SLOP 0 | 2963 #define PURESIZE_SLOP 0 |
2908 #endif | 2964 #endif |
2909 int slop = PURESIZE_SLOP; | 2965 size_t slop = PURESIZE_SLOP; |
2910 | 2966 |
2911 sprintf (buf, "Purespace usage: %ld of %ld (%d%%", | 2967 sprintf (buf, "Purespace usage: %ld of %ld (%d%%", |
2912 pureptr, (long) get_PURESIZE(), | 2968 (long) pure_bytes_used, |
2913 (int) (pureptr / (get_PURESIZE() / 100.0) + 0.5)); | 2969 (long) get_PURESIZE(), |
2970 (int) (pure_bytes_used / (get_PURESIZE() / 100.0) + 0.5)); | |
2914 if (lost > ((slop ? slop : 1) / 1024)) { | 2971 if (lost > ((slop ? slop : 1) / 1024)) { |
2915 sprintf (buf + strlen (buf), " -- %dk wasted", lost); | 2972 sprintf (buf + strlen (buf), " -- %dk wasted", lost); |
2916 if (die_if_pure_storage_exceeded) { | 2973 if (die_if_pure_storage_exceeded) { |
2917 puresize_adjust_h (pureptr + slop); | 2974 puresize_adjust_h (pure_bytes_used + slop); |
2918 #ifdef HEAP_IN_DATA | 2975 #ifdef HEAP_IN_DATA |
2919 sheap_adjust_h(); | 2976 sheap_adjust_h(); |
2920 #endif | 2977 #endif |
2921 rc = -1; | 2978 rc = -1; |
2922 } | 2979 } |
2971 sprintf(buf, "%s:", purestats[j]->name); | 3028 sprintf(buf, "%s:", purestats[j]->name); |
2972 message (" %-26s %5d %7d %2d%%", | 3029 message (" %-26s %5d %7d %2d%%", |
2973 buf, | 3030 buf, |
2974 purestats[j]->nobjects, | 3031 purestats[j]->nobjects, |
2975 purestats[j]->nbytes, | 3032 purestats[j]->nbytes, |
2976 (int) (purestats[j]->nbytes / (pureptr / 100.0) + 0.5)); | 3033 (int) (purestats[j]->nbytes / (pure_bytes_used / 100.0) + 0.5)); |
2977 } | 3034 } |
2978 } | 3035 } |
2979 #endif /* PURESTAT */ | 3036 #endif /* PURESTAT */ |
2980 | 3037 |
2981 | 3038 |
3229 { | 3286 { |
3230 idiot_c_doesnt_have_closures += pure_sizeof (obj, 1); | 3287 idiot_c_doesnt_have_closures += pure_sizeof (obj, 1); |
3231 } | 3288 } |
3232 #endif /* unused */ | 3289 #endif /* unused */ |
3233 | 3290 |
3234 static int | 3291 static size_t |
3235 pure_string_sizeof(Lisp_Object obj) | 3292 pure_string_sizeof (Lisp_Object obj) |
3236 { | 3293 { |
3237 struct Lisp_String *ptr = XSTRING (obj); | 3294 struct Lisp_String *ptr = XSTRING (obj); |
3238 int size = string_length (ptr); | 3295 |
3239 | 3296 if (string_data (ptr) != (Bufbyte *) ptr + sizeof (*ptr)) |
3240 if (string_data (ptr) != | |
3241 (unsigned char *) ptr + sizeof (struct Lisp_String)) | |
3242 { | 3297 { |
3243 /* string-data not allocated contiguously. | 3298 /* string-data not allocated contiguously. |
3244 Probably (better be!!) a pointer constant "C" data. */ | 3299 Probably (better be!!) a pointer constant "C" data. */ |
3245 size = sizeof (struct Lisp_String); | 3300 return sizeof (*ptr); |
3246 } | 3301 } |
3247 else | 3302 else |
3248 { | 3303 { |
3249 size = sizeof (struct Lisp_String) + size + 1; | 3304 size_t size = sizeof (*ptr) + string_length (ptr) + 1; |
3250 size = ALIGN_SIZE (size, sizeof (Lisp_Object)); | 3305 size = ALIGN_SIZE (size, sizeof (Lisp_Object)); |
3251 } | 3306 return size; |
3252 return size; | 3307 } |
3253 } | 3308 } |
3254 | 3309 |
3255 /* recurse arg isn't actually used */ | 3310 /* recurse arg isn't actually used */ |
3256 static int | 3311 static size_t |
3257 pure_sizeof (Lisp_Object obj /*, int recurse */) | 3312 pure_sizeof (Lisp_Object obj /*, int recurse */) |
3258 { | 3313 { |
3259 int total = 0; | 3314 size_t total = 0; |
3260 | 3315 |
3261 /*tail_recurse: */ | 3316 /*tail_recurse: */ |
3262 if (!POINTER_TYPE_P (XTYPE (obj)) | 3317 if (!POINTER_TYPE_P (XTYPE (obj)) |
3263 || !PURIFIED (XPNTR (obj))) | 3318 || !PURIFIED (XPNTR (obj))) |
3264 return total; | 3319 return total; |
3270 switch (XTYPE (obj)) | 3325 switch (XTYPE (obj)) |
3271 { | 3326 { |
3272 | 3327 |
3273 #ifndef LRECORD_STRING | 3328 #ifndef LRECORD_STRING |
3274 case Lisp_Type_String: | 3329 case Lisp_Type_String: |
3275 { | 3330 total += pure_string_sizeof (obj); |
3276 total += pure_string_sizeof (obj); | |
3277 } | |
3278 break; | 3331 break; |
3279 #endif /* ! LRECORD_STRING */ | 3332 #endif /* ! LRECORD_STRING */ |
3280 | 3333 |
3281 #ifndef LRECORD_VECTOR | 3334 #ifndef LRECORD_VECTOR |
3282 case Lisp_Type_Vector: | 3335 case Lisp_Type_Vector: |
3397 | 3450 |
3398 int | 3451 int |
3399 lrecord_type_index (CONST struct lrecord_implementation *implementation) | 3452 lrecord_type_index (CONST struct lrecord_implementation *implementation) |
3400 { | 3453 { |
3401 int type_index = *(implementation->lrecord_type_index); | 3454 int type_index = *(implementation->lrecord_type_index); |
3402 /* Have to do this circuitous and validation test because of problems | 3455 /* Have to do this circuitous validation test because of problems |
3403 dumping out initialized variables (ie can't set xxx_type_index to -1 | 3456 dumping out initialized variables (ie can't set xxx_type_index to -1 |
3404 because that would make xxx_type_index read-only in a dumped emacs. */ | 3457 because that would make xxx_type_index read-only in a dumped emacs. */ |
3405 if (type_index < 0 || type_index > max_lrecord_type | 3458 if (type_index < 0 || type_index > max_lrecord_type |
3406 || lrecord_implementations_table[type_index] != implementation) | 3459 || lrecord_implementations_table[type_index] != implementation) |
3407 { | 3460 { |
3452 assert (!free_p); | 3505 assert (!free_p); |
3453 lcrecord_stats[type_index].instances_on_free_list++; | 3506 lcrecord_stats[type_index].instances_on_free_list++; |
3454 } | 3507 } |
3455 else | 3508 else |
3456 { | 3509 { |
3457 unsigned int sz = (implementation->size_in_bytes_method | 3510 size_t sz = (implementation->size_in_bytes_method |
3458 ? ((implementation->size_in_bytes_method) (h)) | 3511 ? ((implementation->size_in_bytes_method) (h)) |
3459 : implementation->static_size); | 3512 : implementation->static_size); |
3460 | 3513 |
3461 if (free_p) | 3514 if (free_p) |
3462 { | 3515 { |
3463 lcrecord_stats[type_index].instances_freed++; | 3516 lcrecord_stats[type_index].instances_freed++; |
3464 lcrecord_stats[type_index].bytes_freed += sz; | 3517 lcrecord_stats[type_index].bytes_freed += sz; |
4236 | 4289 |
4237 } | 4290 } |
4238 | 4291 |
4239 /* Clearing for disksave. */ | 4292 /* Clearing for disksave. */ |
4240 | 4293 |
4241 extern Lisp_Object Vprocess_environment; | |
4242 extern Lisp_Object Vdoc_directory; | |
4243 extern Lisp_Object Vconfigure_info_directory; | |
4244 extern Lisp_Object Vload_path; | |
4245 extern Lisp_Object Vload_history; | |
4246 extern Lisp_Object Vshell_file_name; | |
4247 | |
4248 void | 4294 void |
4249 disksave_object_finalization (void) | 4295 disksave_object_finalization (void) |
4250 { | 4296 { |
4251 /* It's important that certain information from the environment not get | 4297 /* It's important that certain information from the environment not get |
4252 dumped with the executable (pathnames, environment variables, etc.). | 4298 dumped with the executable (pathnames, environment variables, etc.). |
4279 disksave_object_finalization_1 (); | 4325 disksave_object_finalization_1 (); |
4280 | 4326 |
4281 #if 0 /* I don't see any point in this. The purespace starts out all 0's */ | 4327 #if 0 /* I don't see any point in this. The purespace starts out all 0's */ |
4282 /* Zero out the unused portion of purespace */ | 4328 /* Zero out the unused portion of purespace */ |
4283 if (!pure_lossage) | 4329 if (!pure_lossage) |
4284 memset ( (char *) (PUREBEG + pureptr), 0, | 4330 memset ( (char *) (PUREBEG + pure_bytes_used), 0, |
4285 (((char *) (PUREBEG + get_PURESIZE())) - | 4331 (((char *) (PUREBEG + get_PURESIZE())) - |
4286 ((char *) (PUREBEG + pureptr)))); | 4332 ((char *) (PUREBEG + pure_bytes_used)))); |
4287 #endif | 4333 #endif |
4288 | 4334 |
4289 /* Zero out the uninitialized (really, unused) part of the containers | 4335 /* Zero out the uninitialized (really, unused) part of the containers |
4290 for the live strings. */ | 4336 for the live strings. */ |
4291 { | 4337 { |
4323 { | 4369 { |
4324 char stack_top_variable; | 4370 char stack_top_variable; |
4325 extern char *stack_bottom; | 4371 extern char *stack_bottom; |
4326 int i; | 4372 int i; |
4327 struct frame *f; | 4373 struct frame *f; |
4328 int speccount = specpdl_depth (); | 4374 int speccount; |
4329 Lisp_Object pre_gc_cursor = Qnil; | 4375 int cursor_changed; |
4376 Lisp_Object pre_gc_cursor; | |
4330 struct gcpro gcpro1; | 4377 struct gcpro gcpro1; |
4331 | 4378 |
4332 int cursor_changed = 0; | 4379 if (gc_in_progress |
4333 | 4380 || gc_currently_forbidden |
4334 if (gc_in_progress != 0) | 4381 || in_display |
4382 || preparing_for_armageddon) | |
4335 return; | 4383 return; |
4336 | 4384 |
4337 if (gc_currently_forbidden || in_display) | 4385 pre_gc_cursor = Qnil; |
4338 return; | 4386 cursor_changed = 0; |
4339 | |
4340 if (preparing_for_armageddon) | |
4341 return; | |
4342 | 4387 |
4343 /* This function cannot be called inside GC so we move to after the */ | 4388 /* This function cannot be called inside GC so we move to after the */ |
4344 /* above tests */ | 4389 /* above tests */ |
4345 f = selected_frame (); | 4390 f = selected_frame (); |
4346 | 4391 |
4347 GCPRO1 (pre_gc_cursor); | 4392 GCPRO1 (pre_gc_cursor); |
4348 | 4393 |
4349 /* Very important to prevent GC during any of the following | 4394 /* Very important to prevent GC during any of the following |
4350 stuff that might run Lisp code; otherwise, we'll likely | 4395 stuff that might run Lisp code; otherwise, we'll likely |
4351 have infinite GC recursion. */ | 4396 have infinite GC recursion. */ |
4397 speccount = specpdl_depth (); | |
4352 record_unwind_protect (restore_gc_inhibit, | 4398 record_unwind_protect (restore_gc_inhibit, |
4353 make_int (gc_currently_forbidden)); | 4399 make_int (gc_currently_forbidden)); |
4354 gc_currently_forbidden = 1; | 4400 gc_currently_forbidden = 1; |
4355 | 4401 |
4356 if (!gc_hooks_inhibited) | 4402 if (!gc_hooks_inhibited) |
4400 #if MAX_SAVE_STACK > 0 | 4446 #if MAX_SAVE_STACK > 0 |
4401 | 4447 |
4402 /* Save a copy of the contents of the stack, for debugging. */ | 4448 /* Save a copy of the contents of the stack, for debugging. */ |
4403 if (!purify_flag) | 4449 if (!purify_flag) |
4404 { | 4450 { |
4405 i = &stack_top_variable - stack_bottom; | 4451 /* Static buffer in which we save a copy of the C stack at each GC. */ |
4406 if (i < 0) i = -i; | 4452 static char *stack_copy; |
4407 if (i < MAX_SAVE_STACK) | 4453 static size_t stack_copy_size; |
4454 | |
4455 ptrdiff_t stack_diff = &stack_top_variable - stack_bottom; | |
4456 size_t stack_size = (stack_diff > 0 ? stack_diff : -stack_diff); | |
4457 if (stack_size < MAX_SAVE_STACK) | |
4408 { | 4458 { |
4409 if (stack_copy == 0) | 4459 if (stack_copy_size < stack_size) |
4410 stack_copy = (char *) malloc (stack_copy_size = i); | |
4411 else if (stack_copy_size < i) | |
4412 stack_copy = (char *) realloc (stack_copy, (stack_copy_size = i)); | |
4413 if (stack_copy) | |
4414 { | 4460 { |
4415 if ((int) (&stack_top_variable - stack_bottom) > 0) | 4461 stack_copy = (char *) xrealloc (stack_copy, stack_size); |
4416 memcpy (stack_copy, stack_bottom, i); | 4462 stack_copy_size = stack_size; |
4417 else | |
4418 memcpy (stack_copy, &stack_top_variable, i); | |
4419 } | 4463 } |
4464 | |
4465 memcpy (stack_copy, | |
4466 stack_diff > 0 ? stack_bottom : &stack_top_variable, | |
4467 stack_size); | |
4420 } | 4468 } |
4421 } | 4469 } |
4422 #endif /* MAX_SAVE_STACK > 0 */ | 4470 #endif /* MAX_SAVE_STACK > 0 */ |
4423 | 4471 |
4424 /* Do some totally ad-hoc resource clearing. */ | 4472 /* Do some totally ad-hoc resource clearing. */ |
4550 /* now stop inhibiting GC */ | 4598 /* now stop inhibiting GC */ |
4551 unbind_to (speccount, Qnil); | 4599 unbind_to (speccount, Qnil); |
4552 | 4600 |
4553 if (!breathing_space) | 4601 if (!breathing_space) |
4554 { | 4602 { |
4555 breathing_space = (void *) malloc (4096 - MALLOC_OVERHEAD); | 4603 breathing_space = malloc (4096 - MALLOC_OVERHEAD); |
4556 } | 4604 } |
4557 | 4605 |
4558 UNGCPRO; | 4606 UNGCPRO; |
4559 return; | 4607 return; |
4560 } | 4608 } |
4587 (pl) = gc_plist_hack ((name), s, (pl)); \ | 4635 (pl) = gc_plist_hack ((name), s, (pl)); \ |
4588 } | 4636 } |
4589 | 4637 |
4590 DEFUN ("garbage-collect", Fgarbage_collect, 0, 0, "", /* | 4638 DEFUN ("garbage-collect", Fgarbage_collect, 0, 0, "", /* |
4591 Reclaim storage for Lisp objects no longer needed. | 4639 Reclaim storage for Lisp objects no longer needed. |
4592 Returns info on amount of space in use: | 4640 Return info on amount of space in use: |
4593 ((USED-CONSES . FREE-CONSES) (USED-SYMS . FREE-SYMS) | 4641 ((USED-CONSES . FREE-CONSES) (USED-SYMS . FREE-SYMS) |
4594 (USED-MARKERS . FREE-MARKERS) USED-STRING-CHARS USED-VECTOR-SLOTS | 4642 (USED-MARKERS . FREE-MARKERS) USED-STRING-CHARS USED-VECTOR-SLOTS |
4595 PLIST) | 4643 PLIST) |
4596 where `PLIST' is a list of alternating keyword/value pairs providing | 4644 where `PLIST' is a list of alternating keyword/value pairs providing |
4597 more detailed information. | 4645 more detailed information. |
4599 `gc-cons-threshold' bytes of Lisp data since previous garbage collection. | 4647 `gc-cons-threshold' bytes of Lisp data since previous garbage collection. |
4600 */ | 4648 */ |
4601 ()) | 4649 ()) |
4602 { | 4650 { |
4603 Lisp_Object pl = Qnil; | 4651 Lisp_Object pl = Qnil; |
4604 Lisp_Object ret[6]; | |
4605 int i; | 4652 int i; |
4606 #ifdef LRECORD_VECTOR | 4653 #ifdef LRECORD_VECTOR |
4607 int gc_count_vector_total_size = 0; | 4654 int gc_count_vector_total_size = 0; |
4608 #endif | 4655 #endif |
4609 | 4656 |
4610 if (purify_flag && pure_lossage) | 4657 if (purify_flag && pure_lossage) |
4611 { | 4658 return Qnil; |
4612 return Qnil; | |
4613 } | |
4614 | 4659 |
4615 garbage_collect_1 (); | 4660 garbage_collect_1 (); |
4616 | 4661 |
4617 for (i = 0; i < last_lrecord_type_index_assigned; i++) | 4662 for (i = 0; i < last_lrecord_type_index_assigned; i++) |
4618 { | 4663 { |
4706 HACK_O_MATIC (cons, "cons-storage", pl); | 4751 HACK_O_MATIC (cons, "cons-storage", pl); |
4707 pl = gc_plist_hack ("conses-free", gc_count_num_cons_freelist, pl); | 4752 pl = gc_plist_hack ("conses-free", gc_count_num_cons_freelist, pl); |
4708 pl = gc_plist_hack ("conses-used", gc_count_num_cons_in_use, pl); | 4753 pl = gc_plist_hack ("conses-used", gc_count_num_cons_in_use, pl); |
4709 | 4754 |
4710 /* The things we do for backwards-compatibility */ | 4755 /* The things we do for backwards-compatibility */ |
4711 ret[0] = Fcons (make_int (gc_count_num_cons_in_use), | 4756 return |
4712 make_int (gc_count_num_cons_freelist)); | 4757 list6 (Fcons (make_int (gc_count_num_cons_in_use), |
4713 ret[1] = Fcons (make_int (gc_count_num_symbol_in_use), | 4758 make_int (gc_count_num_cons_freelist)), |
4714 make_int (gc_count_num_symbol_freelist)); | 4759 Fcons (make_int (gc_count_num_symbol_in_use), |
4715 ret[2] = Fcons (make_int (gc_count_num_marker_in_use), | 4760 make_int (gc_count_num_symbol_freelist)), |
4716 make_int (gc_count_num_marker_freelist)); | 4761 Fcons (make_int (gc_count_num_marker_in_use), |
4717 ret[3] = make_int (gc_count_string_total_size); | 4762 make_int (gc_count_num_marker_freelist)), |
4718 ret[4] = make_int (gc_count_vector_total_size); | 4763 make_int (gc_count_string_total_size), |
4719 ret[5] = pl; | 4764 make_int (gc_count_vector_total_size), |
4720 return Flist (6, ret); | 4765 pl); |
4721 } | 4766 } |
4722 #undef HACK_O_MATIC | 4767 #undef HACK_O_MATIC |
4723 | 4768 |
4724 DEFUN ("consing-since-gc", Fconsing_since_gc, 0, 0, "", /* | 4769 DEFUN ("consing-since-gc", Fconsing_since_gc, 0, 0, "", /* |
4725 Return the number of bytes consed since the last garbage collection. | 4770 Return the number of bytes consed since the last garbage collection. |
4753 (WINDOWP (obj) && !WINDOW_LIVE_P (XWINDOW (obj))) || | 4798 (WINDOWP (obj) && !WINDOW_LIVE_P (XWINDOW (obj))) || |
4754 (DEVICEP (obj) && !DEVICE_LIVE_P (XDEVICE (obj))) || | 4799 (DEVICEP (obj) && !DEVICE_LIVE_P (XDEVICE (obj))) || |
4755 (CONSOLEP (obj) && !CONSOLE_LIVE_P (XCONSOLE (obj))) || | 4800 (CONSOLEP (obj) && !CONSOLE_LIVE_P (XCONSOLE (obj))) || |
4756 (EVENTP (obj) && !EVENT_LIVE_P (XEVENT (obj))) || | 4801 (EVENTP (obj) && !EVENT_LIVE_P (XEVENT (obj))) || |
4757 (EXTENTP (obj) && !EXTENT_LIVE_P (XEXTENT (obj)))); | 4802 (EXTENTP (obj) && !EXTENT_LIVE_P (XEXTENT (obj)))); |
4758 | |
4759 } | 4803 } |
4760 | 4804 |
4761 #ifdef MEMORY_USAGE_STATS | 4805 #ifdef MEMORY_USAGE_STATS |
4762 | 4806 |
4763 /* Attempt to determine the actual amount of space that is used for | 4807 /* Attempt to determine the actual amount of space that is used for |
4790 for want of better data is that sizeof (void *), or maybe | 4834 for want of better data is that sizeof (void *), or maybe |
4791 2 * sizeof (void *), is required as overhead and that | 4835 2 * sizeof (void *), is required as overhead and that |
4792 blocks are allocated in the minimum required size except | 4836 blocks are allocated in the minimum required size except |
4793 that some minimum block size is imposed (e.g. 16 bytes). */ | 4837 that some minimum block size is imposed (e.g. 16 bytes). */ |
4794 | 4838 |
4795 int | 4839 size_t |
4796 malloced_storage_size (void *ptr, int claimed_size, | 4840 malloced_storage_size (void *ptr, size_t claimed_size, |
4797 struct overhead_stats *stats) | 4841 struct overhead_stats *stats) |
4798 { | 4842 { |
4799 int orig_claimed_size = claimed_size; | 4843 size_t orig_claimed_size = claimed_size; |
4800 | 4844 |
4801 #ifdef GNU_MALLOC | 4845 #ifdef GNU_MALLOC |
4802 | 4846 |
4803 if (claimed_size < 2 * sizeof (void *)) | 4847 if (claimed_size < 2 * sizeof (void *)) |
4804 claimed_size = 2 * sizeof (void *); | 4848 claimed_size = 2 * sizeof (void *); |
4823 claimed_size *= 2; | 4867 claimed_size *= 2; |
4824 log--; | 4868 log--; |
4825 } | 4869 } |
4826 /* We have to come up with some average about the amount of | 4870 /* We have to come up with some average about the amount of |
4827 blocks used. */ | 4871 blocks used. */ |
4828 if ((rand () & 4095) < claimed_size) | 4872 if ((size_t) (rand () & 4095) < claimed_size) |
4829 claimed_size += 3 * sizeof (void *); | 4873 claimed_size += 3 * sizeof (void *); |
4830 } | 4874 } |
4831 else | 4875 else |
4832 { | 4876 { |
4833 claimed_size += 4095; | 4877 claimed_size += 4095; |
4874 stats->malloc_overhead += claimed_size - orig_claimed_size; | 4918 stats->malloc_overhead += claimed_size - orig_claimed_size; |
4875 } | 4919 } |
4876 return claimed_size; | 4920 return claimed_size; |
4877 } | 4921 } |
4878 | 4922 |
4879 int | 4923 size_t |
4880 fixed_type_block_overhead (int size) | 4924 fixed_type_block_overhead (size_t size) |
4881 { | 4925 { |
4882 int per_block = TYPE_ALLOC_SIZE (cons, unsigned char); | 4926 size_t per_block = TYPE_ALLOC_SIZE (cons, unsigned char); |
4883 int overhead = 0; | 4927 size_t overhead = 0; |
4884 int storage_size = malloced_storage_size (0, per_block, 0); | 4928 size_t storage_size = malloced_storage_size (0, per_block, 0); |
4885 while (size >= per_block) | 4929 while (size >= per_block) |
4886 { | 4930 { |
4887 size -= per_block; | 4931 size -= per_block; |
4888 overhead += sizeof (void *) + per_block - storage_size; | 4932 overhead += sizeof (void *) + per_block - storage_size; |
4889 | |
4890 } | 4933 } |
4891 if (rand () % per_block < size) | 4934 if (rand () % per_block < size) |
4892 overhead += sizeof (void *) + per_block - storage_size; | 4935 overhead += sizeof (void *) + per_block - storage_size; |
4893 return overhead; | 4936 return overhead; |
4894 } | 4937 } |
4924 * defined subr lrecords were initialized with lheader->type == 0. | 4967 * defined subr lrecords were initialized with lheader->type == 0. |
4925 * See subr_lheader_initializer in lisp.h. Force type index 0 to be | 4968 * See subr_lheader_initializer in lisp.h. Force type index 0 to be |
4926 * assigned to lrecord_subr so that those predefined indexes match | 4969 * assigned to lrecord_subr so that those predefined indexes match |
4927 * reality. | 4970 * reality. |
4928 */ | 4971 */ |
4929 (void) lrecord_type_index (lrecord_subr); | 4972 lrecord_type_index (lrecord_subr); |
4930 assert (*(lrecord_subr[0].lrecord_type_index) == 0); | 4973 assert (*(lrecord_subr[0].lrecord_type_index) == 0); |
4931 /* | 4974 /* |
4932 * The same is true for symbol_value_forward objects, except the | 4975 * The same is true for symbol_value_forward objects, except the |
4933 * type is 1. | 4976 * type is 1. |
4934 */ | 4977 */ |
4935 (void) lrecord_type_index (lrecord_symbol_value_forward); | 4978 lrecord_type_index (lrecord_symbol_value_forward); |
4936 assert (*(lrecord_symbol_value_forward[0].lrecord_type_index) == 1); | 4979 assert (*(lrecord_symbol_value_forward[0].lrecord_type_index) == 1); |
4937 #endif | 4980 #endif /* USE_INDEXED_LRECORD_IMPLEMENTATION */ |
4938 | 4981 |
4939 symbols_initialized = 0; | 4982 symbols_initialized = 0; |
4940 | 4983 |
4941 gc_generation_number[0] = 0; | 4984 gc_generation_number[0] = 0; |
4942 /* purify_flag 1 is correct even if CANNOT_DUMP. | 4985 /* purify_flag 1 is correct even if CANNOT_DUMP. |
4943 * loadup.el will set to nil at end. */ | 4986 * loadup.el will set to nil at end. */ |
4944 purify_flag = 1; | 4987 purify_flag = 1; |
4945 pureptr = 0; | 4988 pure_bytes_used = 0; |
4946 pure_lossage = 0; | 4989 pure_lossage = 0; |
4947 breathing_space = 0; | 4990 breathing_space = 0; |
4948 #ifndef LRECORD_VECTOR | 4991 #ifndef LRECORD_VECTOR |
4949 XSETINT (all_vectors, 0); /* Qzero may not be set yet. */ | 4992 XSETINT (all_vectors, 0); /* Qzero may not be set yet. */ |
4950 #endif | 4993 #endif |
5048 prevent garbage collection during a part of the program. | 5091 prevent garbage collection during a part of the program. |
5049 | 5092 |
5050 See also `consing-since-gc'. | 5093 See also `consing-since-gc'. |
5051 */ ); | 5094 */ ); |
5052 | 5095 |
5053 DEFVAR_INT ("pure-bytes-used", &pureptr /* | 5096 DEFVAR_INT ("pure-bytes-used", &pure_bytes_used /* |
5054 Number of bytes of sharable Lisp data allocated so far. | 5097 Number of bytes of sharable Lisp data allocated so far. |
5055 */ ); | 5098 */ ); |
5056 | 5099 |
5057 #if 0 | 5100 #if 0 |
5058 DEFVAR_INT ("data-bytes-used", &malloc_sbrk_used /* | 5101 DEFVAR_INT ("data-bytes-used", &malloc_sbrk_used /* |