comparison src/alloc.c @ 183:e121b013d1f0 r20-3b18

Import from CVS: tag r20-3b18
author cvs
date Mon, 13 Aug 2007 09:54:23 +0200
parents 6075d714658b
children 3d6bfa290dbd
comparison
equal deleted inserted replaced
182:f07455f06202 183:e121b013d1f0
90 consing_since_gc += __sz__; \ 90 consing_since_gc += __sz__; \
91 cadillac_record_backtrace (2, __sz__); \ 91 cadillac_record_backtrace (2, __sz__); \
92 } while (0) 92 } while (0)
93 #else 93 #else
94 #define INCREMENT_CONS_COUNTER_1(size) (consing_since_gc += (size)) 94 #define INCREMENT_CONS_COUNTER_1(size) (consing_since_gc += (size))
95 #endif 95 #endif /* EMACS_BTL */
96 96
97 #define debug_allocation_backtrace() \ 97 #define debug_allocation_backtrace() \
98 do { \ 98 do { \
99 if (debug_allocation_backtrace_length > 0) \ 99 if (debug_allocation_backtrace_length > 0) \
100 debug_short_backtrace (debug_allocation_backtrace_length); \ 100 debug_short_backtrace (debug_allocation_backtrace_length); \
240 static int purecopying_for_bytecode; 240 static int purecopying_for_bytecode;
241 241
242 static int pure_sizeof (Lisp_Object /*, int recurse */); 242 static int pure_sizeof (Lisp_Object /*, int recurse */);
243 243
244 /* Keep statistics on how much of what is in purespace */ 244 /* Keep statistics on how much of what is in purespace */
245 struct purestat 245 static struct purestat
246 { 246 {
247 int nobjects; 247 int nobjects;
248 int nbytes; 248 int nbytes;
249 CONST char *name; 249 CONST char *name;
250 }; 250 }
251 251 purestat_cons = {0, 0, "cons cells"},
252 #define FMH(s,n) static struct purestat s = { 0, 0, n } 252 purestat_float = {0, 0, "float objects"},
253 FMH (purestat_cons, "cons cells:"); 253 purestat_string_pname = {0, 0, "symbol-name strings"},
254 FMH (purestat_float, "float objects:"); 254 purestat_bytecode = {0, 0, "compiled-function objects"},
255 FMH (purestat_string_pname, "symbol-name strings:"); 255 purestat_string_bytecodes = {0, 0, "byte-code strings"},
256 FMH (purestat_bytecode, "compiled-function objects:"); 256 purestat_vector_bytecode_constants = {0, 0, "byte-constant vectors"},
257 FMH (purestat_string_bytecodes, "byte-code strings:"); 257 purestat_string_interactive = {0, 0, "interactive strings"},
258 FMH (purestat_vector_bytecode_constants, "byte-constant vectors:");
259 FMH (purestat_string_interactive, "interactive strings:");
260 #ifdef I18N3 258 #ifdef I18N3
261 FMH (purestat_string_domain, "domain strings:"); 259 purestat_string_domain = {0, 0, "domain strings"},
262 #endif 260 #endif
263 FMH (purestat_string_documentation, "documentation strings:"); 261 purestat_string_documentation = {0, 0, "documentation strings"},
264 FMH (purestat_string_other_function, "other function strings:"); 262 purestat_string_other_function = {0, 0, "other function strings"},
265 FMH (purestat_vector_other, "other vectors:"); 263 purestat_vector_other = {0, 0, "other vectors"},
266 FMH (purestat_string_other, "other strings:"); 264 purestat_string_other = {0, 0, "other strings"},
267 FMH (purestat_string_all, "all strings:"); 265 purestat_string_all = {0, 0, "all strings"},
268 FMH (purestat_vector_all, "all vectors:"); 266 purestat_vector_all = {0, 0, "all vectors"};
269 267
270 static struct purestat *purestats[] = 268 static struct purestat *purestats[] =
271 { 269 {
272 &purestat_cons, 270 &purestat_cons,
273 &purestat_float, 271 &purestat_float,
285 &purestat_string_other, 283 &purestat_string_other,
286 0, 284 0,
287 &purestat_string_all, 285 &purestat_string_all,
288 &purestat_vector_all 286 &purestat_vector_all
289 }; 287 };
290 #undef FMH
291 288
292 static void 289 static void
293 bump_purestat (struct purestat *purestat, int nbytes) 290 bump_purestat (struct purestat *purestat, int nbytes)
294 { 291 {
295 if (pure_lossage) return; 292 if (pure_lossage) return;
317 static void *breathing_space; 314 static void *breathing_space;
318 315
319 void 316 void
320 release_breathing_space (void) 317 release_breathing_space (void)
321 { 318 {
322 if (breathing_space) 319 if (breathing_space)
323 { 320 {
324 void *tmp = breathing_space; 321 void *tmp = breathing_space;
325 breathing_space = 0; 322 breathing_space = 0;
326 xfree (tmp); 323 xfree (tmp);
327 } 324 }
421 /* Unbelievably, calling free() on 0xDEADBEEF doesn't cause an 418 /* Unbelievably, calling free() on 0xDEADBEEF doesn't cause an
422 error until much later on for many system mallocs, such as 419 error until much later on for many system mallocs, such as
423 the one that comes with Solaris 2.3. FMH!! */ 420 the one that comes with Solaris 2.3. FMH!! */
424 assert (block != (void *) 0xDEADBEEF); 421 assert (block != (void *) 0xDEADBEEF);
425 assert (block); 422 assert (block);
426 #endif 423 #endif /* ERROR_CHECK_MALLOC */
427 free (block); 424 free (block);
428 } 425 }
429 426
430 #if INTBITS == 32 427 #if INTBITS == 32
431 # define FOUR_BYTE_TYPE unsigned int 428 # define FOUR_BYTE_TYPE unsigned int
449 deadbeef_memory (void *ptr, unsigned long size) 446 deadbeef_memory (void *ptr, unsigned long size)
450 { 447 {
451 unsigned long long_length = size / sizeof (FOUR_BYTE_TYPE); 448 unsigned long long_length = size / sizeof (FOUR_BYTE_TYPE);
452 unsigned long i; 449 unsigned long i;
453 unsigned long bytes_left_over = size - sizeof (FOUR_BYTE_TYPE) * long_length; 450 unsigned long bytes_left_over = size - sizeof (FOUR_BYTE_TYPE) * long_length;
454 451
455 for (i = 0; i < long_length; i++) 452 for (i = 0; i < long_length; i++)
456 ((FOUR_BYTE_TYPE *) ptr)[i] = 0xdeadbeef; 453 ((FOUR_BYTE_TYPE *) ptr)[i] = 0xdeadbeef;
457 for (i = i; i < bytes_left_over; i++) 454 for (i = i; i < bytes_left_over; i++)
458 ((unsigned char *) ptr + long_length)[i] = deadbeef_as_char[i]; 455 ((unsigned char *) ptr + long_length)[i] = deadbeef_as_char[i];
459 } 456 }
460 457
461 #else 458 #else /* !ERROR_CHECK_GC */
459
462 460
463 #define deadbeef_memory(ptr, size) 461 #define deadbeef_memory(ptr, size)
464 462
465 #endif 463 #endif /* !ERROR_CHECK_GC */
466 464
467 #ifdef xstrdup 465 #ifdef xstrdup
468 #undef xstrdup 466 #undef xstrdup
469 #endif 467 #endif
470 468
516 do { (((lheader)->implementation)--); } while (0) 514 do { (((lheader)->implementation)--); } while (0)
517 515
518 516
519 /* lrecords are chained together through their "next.v" field. 517 /* lrecords are chained together through their "next.v" field.
520 * After doing the mark phase, the GC will walk this linked 518 * After doing the mark phase, the GC will walk this linked
521 * list and free any record which hasn't been marked 519 * list and free any record which hasn't been marked
522 */ 520 */
523 static struct lcrecord_header *all_lcrecords; 521 static struct lcrecord_header *all_lcrecords;
524 522
525 void * 523 void *
526 alloc_lcrecord (int size, CONST struct lrecord_implementation *implementation) 524 alloc_lcrecord (int size, CONST struct lrecord_implementation *implementation)
598 { 596 {
599 if (header->lheader.implementation->finalizer && !header->free) 597 if (header->lheader.implementation->finalizer && !header->free)
600 ((header->lheader.implementation->finalizer) (header, 1)); 598 ((header->lheader.implementation->finalizer) (header, 1));
601 } 599 }
602 } 600 }
603 601
604 602
605 /* This must not be called -- it just serves as for EQ test 603 /* This must not be called -- it just serves as for EQ test
606 * If lheader->implementation->finalizer is this_marks_a_marked_record, 604 * If lheader->implementation->finalizer is this_marks_a_marked_record,
607 * then lrecord has been marked by the GC sweeper 605 * then lrecord has been marked by the GC sweeper
608 * header->implementation is put back to its correct value by 606 * header->implementation is put back to its correct value by
675 make more sense) are malloc()ed separately and not stored in 673 make more sense) are malloc()ed separately and not stored in
676 string_chars_blocks. Furthermore, no one string stretches across 674 string_chars_blocks. Furthermore, no one string stretches across
677 two string_chars_blocks. 675 two string_chars_blocks.
678 676
679 Vectors are each malloc()ed separately, similar to lcrecords. 677 Vectors are each malloc()ed separately, similar to lcrecords.
680 678
681 In the following discussion, we use conses, but it applies equally 679 In the following discussion, we use conses, but it applies equally
682 well to the other fixed-size types. 680 well to the other fixed-size types.
683 681
684 We store cons cells inside of cons_blocks, allocating a new 682 We store cons cells inside of cons_blocks, allocating a new
685 cons_block with malloc() whenever necessary. Cons cells reclaimed 683 cons_block with malloc() whenever necessary. Cons cells reclaimed
791 #elif defined (rcheck) 789 #elif defined (rcheck)
792 #define MALLOC_OVERHEAD 20 790 #define MALLOC_OVERHEAD 20
793 #else 791 #else
794 #define MALLOC_OVERHEAD 8 792 #define MALLOC_OVERHEAD 8
795 #endif 793 #endif
796 #endif 794 #endif /* MALLOC_OVERHEAD */
797 795
798 #ifdef ALLOC_NO_POOLS 796 #ifdef ALLOC_NO_POOLS
799 # define TYPE_ALLOC_SIZE(type, structtype) 1 797 # define TYPE_ALLOC_SIZE(type, structtype) 1
800 #else 798 #else
801 # define TYPE_ALLOC_SIZE(type, structtype) \ 799 # define TYPE_ALLOC_SIZE(type, structtype) \
802 ((2048 - MALLOC_OVERHEAD - sizeof (struct type##_block *)) \ 800 ((2048 - MALLOC_OVERHEAD - sizeof (struct type##_block *)) \
803 / sizeof (structtype)) 801 / sizeof (structtype))
804 #endif 802 #endif /* ALLOC_NO_POOLS */
805 803
806 #define DECLARE_FIXED_TYPE_ALLOC(type, structtype) \ 804 #define DECLARE_FIXED_TYPE_ALLOC(type, structtype) \
807 \ 805 \
808 struct type##_block \ 806 struct type##_block \
809 { \ 807 { \
871 else \ 869 else \
872 ALLOCATE_FIXED_TYPE_FROM_BLOCK (type, result); \ 870 ALLOCATE_FIXED_TYPE_FROM_BLOCK (type, result); \
873 MARK_STRUCT_AS_NOT_FREE (result); \ 871 MARK_STRUCT_AS_NOT_FREE (result); \
874 } while (0) 872 } while (0)
875 873
876 #else 874 #else /* !ERROR_CHECK_GC */
877 875
878 #define ALLOCATE_FIXED_TYPE_1(type, structtype, result) \ 876 #define ALLOCATE_FIXED_TYPE_1(type, structtype, result) \
879 do \ 877 do \
880 { \ 878 { \
881 if (type##_free_list) \ 879 if (type##_free_list) \
887 else \ 885 else \
888 ALLOCATE_FIXED_TYPE_FROM_BLOCK (type, result); \ 886 ALLOCATE_FIXED_TYPE_FROM_BLOCK (type, result); \
889 MARK_STRUCT_AS_NOT_FREE (result); \ 887 MARK_STRUCT_AS_NOT_FREE (result); \
890 } while (0) 888 } while (0)
891 889
892 #endif 890 #endif /* !ERROR_CHECK_GC */
893 891
894 #define ALLOCATE_FIXED_TYPE(type, structtype, result) \ 892 #define ALLOCATE_FIXED_TYPE(type, structtype, result) \
895 do \ 893 do \
896 { \ 894 { \
897 ALLOCATE_FIXED_TYPE_1 (type, structtype, result); \ 895 ALLOCATE_FIXED_TYPE_1 (type, structtype, result); \
913 be a pointer, and the pointer will be misaligned. 911 be a pointer, and the pointer will be misaligned.
914 912
915 Even if Emacs is run on some weirdo system that allows and allocates 913 Even if Emacs is run on some weirdo system that allows and allocates
916 byte-aligned pointers, this pointer is at the very top of the address 914 byte-aligned pointers, this pointer is at the very top of the address
917 space and so it's almost inconceivable that it could ever be valid. */ 915 space and so it's almost inconceivable that it could ever be valid. */
918 916
919 #if INTBITS == 32 917 #if INTBITS == 32
920 # define INVALID_POINTER_VALUE 0xFFFFFFFF 918 # define INVALID_POINTER_VALUE 0xFFFFFFFF
921 #elif INTBITS == 48 919 #elif INTBITS == 48
922 # define INVALID_POINTER_VALUE 0xFFFFFFFFFFFF 920 # define INVALID_POINTER_VALUE 0xFFFFFFFFFFFF
923 #elif INTBITS == 64 921 #elif INTBITS == 64
952 else \ 950 else \
953 type##_free_list = ptr; \ 951 type##_free_list = ptr; \
954 type##_free_list_tail = ptr; \ 952 type##_free_list_tail = ptr; \
955 } while (0) 953 } while (0)
956 954
957 #else 955 #else /* !ERROR_CHECK_GC */
958 956
959 #define PUT_FIXED_TYPE_ON_FREE_LIST(type, structtype, ptr) \ 957 #define PUT_FIXED_TYPE_ON_FREE_LIST(type, structtype, ptr) \
960 do { * (structtype **) ((char *) ptr + sizeof (void *)) = \ 958 do { * (structtype **) ((char *) ptr + sizeof (void *)) = \
961 type##_free_list; \ 959 type##_free_list; \
962 type##_free_list = ptr; \ 960 type##_free_list = ptr; \
963 } while (0) 961 } while (0)
964 962
965 #endif 963 #endif /* !ERROR_CHECK_GC */
966 964
967 /* TYPE and STRUCTTYPE are the same as in ALLOCATE_FIXED_TYPE(). */ 965 /* TYPE and STRUCTTYPE are the same as in ALLOCATE_FIXED_TYPE(). */
968 966
969 #define FREE_FIXED_TYPE(type, structtype, ptr) \ 967 #define FREE_FIXED_TYPE(type, structtype, ptr) \
970 do { structtype *_weird_ = (ptr); \ 968 do { structtype *_weird_ = (ptr); \
987 #define FREE_FIXED_TYPE_WHEN_NOT_IN_GC(type, structtype, ptr) \ 985 #define FREE_FIXED_TYPE_WHEN_NOT_IN_GC(type, structtype, ptr) \
988 do { FREE_FIXED_TYPE (type, structtype, ptr); \ 986 do { FREE_FIXED_TYPE (type, structtype, ptr); \
989 DECREMENT_CONS_COUNTER (sizeof (structtype)); \ 987 DECREMENT_CONS_COUNTER (sizeof (structtype)); \
990 gc_count_num_##type##_freelist++; \ 988 gc_count_num_##type##_freelist++; \
991 } while (0) 989 } while (0)
992 990
993 991
994 992
995 /**********************************************************************/ 993 /**********************************************************************/
996 /* Cons allocation */ 994 /* Cons allocation */
997 /**********************************************************************/ 995 /**********************************************************************/
1524 the objects are sitting on Vload_force_doc_string_list, which 1522 the objects are sitting on Vload_force_doc_string_list, which
1525 is staticpro'd, so we're OK. */ 1523 is staticpro'd, so we're OK. */
1526 int purecopy_instructions = 1; 1524 int purecopy_instructions = 1;
1527 1525
1528 if (nargs > 6) 1526 if (nargs > 6)
1529 return Fsignal (Qwrong_number_of_arguments, 1527 return Fsignal (Qwrong_number_of_arguments,
1530 list2 (intern ("make-byte-code"), make_int (nargs))); 1528 list2 (intern ("make-byte-code"), make_int (nargs)));
1531 1529
1532 CHECK_LIST (arglist); 1530 CHECK_LIST (arglist);
1533 /* instructions is a string or a cons (string . int) for a 1531 /* instructions is a string or a cons (string . int) for a
1534 lazy-loaded function. */ 1532 lazy-loaded function. */
1587 if (STRINGP (interactive)) 1585 if (STRINGP (interactive))
1588 bump_purestat (&purestat_string_interactive, 1586 bump_purestat (&purestat_string_interactive,
1589 pure_sizeof (interactive)); 1587 pure_sizeof (interactive));
1590 #endif /* PURESTAT */ 1588 #endif /* PURESTAT */
1591 } 1589 }
1592 1590
1593 { 1591 {
1594 int docp = !NILP (doc_string); 1592 int docp = !NILP (doc_string);
1595 int intp = !UNBOUNDP (interactive); 1593 int intp = !UNBOUNDP (interactive);
1596 #ifdef I18N3 1594 #ifdef I18N3
1597 int domp = !NILP (Vfile_domain); 1595 int domp = !NILP (Vfile_domain);
1619 Vload_file_name_internal_the_purecopy = 1617 Vload_file_name_internal_the_purecopy =
1620 Fpurecopy (Ffile_name_nondirectory (Vload_file_name_internal)); 1618 Fpurecopy (Ffile_name_nondirectory (Vload_file_name_internal));
1621 b->annotated = Vload_file_name_internal_the_purecopy; 1619 b->annotated = Vload_file_name_internal_the_purecopy;
1622 UNGCPRO; 1620 UNGCPRO;
1623 } 1621 }
1624 #endif 1622 #endif /* COMPILED_FUNCTION_ANNOTATION_HACK */
1625 1623
1626 #ifdef I18N3 1624 #ifdef I18N3
1627 if (docp && intp && domp) 1625 if (docp && intp && domp)
1628 b->doc_and_interactive = (((purify_flag) ? pure_cons : Fcons) 1626 b->doc_and_interactive = (((purify_flag) ? pure_cons : Fcons)
1629 (doc_string, 1627 (doc_string,
1733 set_lheader_implementation (&(e->lheader), lrecord_event); 1731 set_lheader_implementation (&(e->lheader), lrecord_event);
1734 1732
1735 XSETEVENT (val, e); 1733 XSETEVENT (val, e);
1736 return val; 1734 return val;
1737 } 1735 }
1738 1736
1739 1737
1740 /**********************************************************************/ 1738 /**********************************************************************/
1741 /* Marker allocation */ 1739 /* Marker allocation */
1742 /**********************************************************************/ 1740 /**********************************************************************/
1743 1741
1783 1781
1784 /**********************************************************************/ 1782 /**********************************************************************/
1785 /* String allocation */ 1783 /* String allocation */
1786 /**********************************************************************/ 1784 /**********************************************************************/
1787 1785
1788 /* The data for "short" strings generally resides inside of structs of type 1786 /* The data for "short" strings generally resides inside of structs of type
1789 string_chars_block. The Lisp_String structure is allocated just like any 1787 string_chars_block. The Lisp_String structure is allocated just like any
1790 other Lisp object (except for vectors), and these are freelisted when 1788 other Lisp object (except for vectors), and these are freelisted when
1791 they get garbage collected. The data for short strings get compacted, 1789 they get garbage collected. The data for short strings get compacted,
1792 but the data for large strings do not. 1790 but the data for large strings do not.
1793 1791
1794 Previously Lisp_String structures were relocated, but this caused a lot 1792 Previously Lisp_String structures were relocated, but this caused a lot
1795 of bus-errors because the C code didn't include enough GCPRO's for 1793 of bus-errors because the C code didn't include enough GCPRO's for
1796 strings (since EVERY REFERENCE to a short string needed to be GCPRO'd so 1794 strings (since EVERY REFERENCE to a short string needed to be GCPRO'd so
1797 that the reference would get relocated). 1795 that the reference would get relocated).
1850 }; 1848 };
1851 1849
1852 static void 1850 static void
1853 init_string_chars_alloc (void) 1851 init_string_chars_alloc (void)
1854 { 1852 {
1855 first_string_chars_block = 1853 first_string_chars_block =
1856 (struct string_chars_block *) xmalloc (sizeof (struct string_chars_block)); 1854 (struct string_chars_block *) xmalloc (sizeof (struct string_chars_block));
1857 first_string_chars_block->prev = 0; 1855 first_string_chars_block->prev = 0;
1858 first_string_chars_block->next = 0; 1856 first_string_chars_block->next = 0;
1859 first_string_chars_block->pos = 0; 1857 first_string_chars_block->pos = 0;
1860 current_string_chars_block = first_string_chars_block; 1858 current_string_chars_block = first_string_chars_block;
1882 current_string_chars_block->pos += fullsize; 1880 current_string_chars_block->pos += fullsize;
1883 } 1881 }
1884 else 1882 else
1885 { 1883 {
1886 /* Make a new current string chars block */ 1884 /* Make a new current string chars block */
1887 struct string_chars_block *new 1885 struct string_chars_block *new
1888 = (struct string_chars_block *) 1886 = (struct string_chars_block *)
1889 xmalloc (sizeof (struct string_chars_block)); 1887 xmalloc (sizeof (struct string_chars_block));
1890 1888
1891 current_string_chars_block->next = new; 1889 current_string_chars_block->next = new;
1892 new->prev = current_string_chars_block; 1890 new->prev = current_string_chars_block;
1893 new->next = 0; 1891 new->next = 0;
1894 current_string_chars_block = new; 1892 current_string_chars_block = new;
1895 new->pos = fullsize; 1893 new->pos = fullsize;
1921 s_chars = allocate_string_chars_struct (s, fullsize); 1919 s_chars = allocate_string_chars_struct (s, fullsize);
1922 1920
1923 set_string_data (s, &(s_chars->chars[0])); 1921 set_string_data (s, &(s_chars->chars[0]));
1924 set_string_length (s, length); 1922 set_string_length (s, length);
1925 s->plist = Qnil; 1923 s->plist = Qnil;
1926 1924
1927 set_string_byte (s, length, 0); 1925 set_string_byte (s, length, 0);
1928 1926
1929 XSETSTRING (val, s); 1927 XSETSTRING (val, s);
1930 return val; 1928 return val;
1931 } 1929 }
1932 1930
1933 #ifdef VERIFY_STRING_CHARS_INTEGRITY 1931 #ifdef VERIFY_STRING_CHARS_INTEGRITY
1934 static void verify_string_chars_integrity (void); 1932 static void verify_string_chars_integrity (void);
1935 #endif 1933 #endif
1936 1934
1937 /* Resize the string S so that DELTA bytes can be inserted starting 1935 /* Resize the string S so that DELTA bytes can be inserted starting
1938 at POS. If DELTA < 0, it means deletion starting at POS. If 1936 at POS. If DELTA < 0, it means deletion starting at POS. If
1939 POS < 0, resize the string but don't copy any characters. Use 1937 POS < 0, resize the string but don't copy any characters. Use
1940 this if you're planning on completely overwriting the string. 1938 this if you're planning on completely overwriting the string.
1941 */ 1939 */
1957 else 1955 else
1958 { 1956 {
1959 if (delta < 0) 1957 if (delta < 0)
1960 assert ((-delta) <= string_length (s)); 1958 assert ((-delta) <= string_length (s));
1961 } 1959 }
1962 #endif 1960 #endif /* ERROR_CHECK_BUFPOS */
1963 1961
1964 if (pos >= 0 && delta < 0) 1962 if (pos >= 0 && delta < 0)
1965 /* If DELTA < 0, the functions below will delete the characters 1963 /* If DELTA < 0, the functions below will delete the characters
1966 before POS. We want to delete characters *after* POS, however, 1964 before POS. We want to delete characters *after* POS, however,
1967 so convert this to the appropriate form. */ 1965 so convert this to the appropriate form. */
1981 allocation size won't change (up or down; code somewhere 1979 allocation size won't change (up or down; code somewhere
1982 depends on there not being any unused allocation space, 1980 depends on there not being any unused allocation space,
1983 modulo any alignment constraints). */ 1981 modulo any alignment constraints). */
1984 if (pos >= 0) 1982 if (pos >= 0)
1985 { 1983 {
1986 Bufbyte *addroff = pos + string_data (s); 1984 Bufbyte *addroff = pos + string_data (s);
1987 1985
1988 memmove (addroff + delta, addroff, 1986 memmove (addroff + delta, addroff,
1989 /* +1 due to zero-termination. */ 1987 /* +1 due to zero-termination. */
1990 string_length (s) + 1 - pos); 1988 string_length (s) + 1 - pos);
1991 } 1989 }
2002 string could result in memory leakage. */ 2000 string could result in memory leakage. */
2003 set_string_data (s, (Bufbyte *) xrealloc (string_data (s), 2001 set_string_data (s, (Bufbyte *) xrealloc (string_data (s),
2004 newfullsize)); 2002 newfullsize));
2005 if (pos >= 0) 2003 if (pos >= 0)
2006 { 2004 {
2007 Bufbyte *addroff = pos + string_data (s); 2005 Bufbyte *addroff = pos + string_data (s);
2008 2006
2009 memmove (addroff + delta, addroff, 2007 memmove (addroff + delta, addroff,
2010 /* +1 due to zero-termination. */ 2008 /* +1 due to zero-termination. */
2011 string_length (s) + 1 - pos); 2009 string_length (s) + 1 - pos);
2012 } 2010 }
2134 2132
2135 /* Make sure we find out about bad make_string's when they happen */ 2133 /* Make sure we find out about bad make_string's when they happen */
2136 #if defined (ERROR_CHECK_BUFPOS) && defined (MULE) 2134 #if defined (ERROR_CHECK_BUFPOS) && defined (MULE)
2137 bytecount_to_charcount (contents, length); /* Just for the assertions */ 2135 bytecount_to_charcount (contents, length); /* Just for the assertions */
2138 #endif 2136 #endif
2139 2137
2140 val = make_uninit_string (length); 2138 val = make_uninit_string (length);
2141 memcpy (XSTRING_DATA (val), contents, length); 2139 memcpy (XSTRING_DATA (val), contents, length);
2142 return val; 2140 return val;
2143 } 2141 }
2144 2142
2257 #endif /* ERROR_CHECK_GC */ 2255 #endif /* ERROR_CHECK_GC */
2258 2256
2259 MARK_RECORD_HEADER (lheader); 2257 MARK_RECORD_HEADER (lheader);
2260 chain = free_header->chain; 2258 chain = free_header->chain;
2261 } 2259 }
2262 2260
2263 return Qnil; 2261 return Qnil;
2264 } 2262 }
2265 2263
2266 Lisp_Object 2264 Lisp_Object
2267 make_lcrecord_list (int size, 2265 make_lcrecord_list (int size,
2303 /* The type of the lcrecord must be right. */ 2301 /* The type of the lcrecord must be right. */
2304 assert (implementation == list->implementation); 2302 assert (implementation == list->implementation);
2305 /* So must the size. */ 2303 /* So must the size. */
2306 assert (implementation->static_size == 0 2304 assert (implementation->static_size == 0
2307 || implementation->static_size == list->size); 2305 || implementation->static_size == list->size);
2308 #endif 2306 #endif /* ERROR_CHECK_GC */
2309 list->free = free_header->chain; 2307 list->free = free_header->chain;
2310 free_header->lcheader.free = 0; 2308 free_header->lcheader.free = 0;
2311 return val; 2309 return val;
2312 } 2310 }
2313 else 2311 else
2337 if (implementation->size_in_bytes_method) 2335 if (implementation->size_in_bytes_method)
2338 assert (((implementation->size_in_bytes_method) (lheader)) 2336 assert (((implementation->size_in_bytes_method) (lheader))
2339 == list->size); 2337 == list->size);
2340 else 2338 else
2341 assert (implementation->static_size == list->size); 2339 assert (implementation->static_size == list->size);
2342 #endif 2340 #endif /* ERROR_CHECK_GC */
2343 2341
2344 if (implementation->finalizer) 2342 if (implementation->finalizer)
2345 ((implementation->finalizer) (lheader, 0)); 2343 ((implementation->finalizer) (lheader, 0));
2346 free_header->chain = list->free; 2344 free_header->chain = list->free;
2347 free_header->lcheader.free = 1; 2345 free_header->lcheader.free = 1;
2359 make_pure_string (CONST Bufbyte *data, Bytecount length, 2357 make_pure_string (CONST Bufbyte *data, Bytecount length,
2360 Lisp_Object plist, int no_need_to_copy_data) 2358 Lisp_Object plist, int no_need_to_copy_data)
2361 { 2359 {
2362 Lisp_Object new; 2360 Lisp_Object new;
2363 struct Lisp_String *s; 2361 struct Lisp_String *s;
2364 int size = (sizeof (struct Lisp_String) + ((no_need_to_copy_data) 2362 int size = (sizeof (struct Lisp_String) + ((no_need_to_copy_data)
2365 ? 0 2363 ? 0
2366 /* + 1 for terminating 0 */ 2364 /* + 1 for terminating 0 */
2367 : (length + 1))); 2365 : (length + 1)));
2368 size = ALIGN_SIZE (size, ALIGNOF (Lisp_Object)); 2366 size = ALIGN_SIZE (size, ALIGNOF (Lisp_Object));
2369 2367
2370 if (symbols_initialized && !pure_lossage) 2368 if (symbols_initialized && !pure_lossage)
2400 2398
2401 #ifdef PURESTAT 2399 #ifdef PURESTAT
2402 bump_purestat (&purestat_string_all, size); 2400 bump_purestat (&purestat_string_all, size);
2403 if (purecopying_for_bytecode) 2401 if (purecopying_for_bytecode)
2404 bump_purestat (&purestat_string_other_function, size); 2402 bump_purestat (&purestat_string_other_function, size);
2405 #endif 2403 #endif /* PURESTAT */
2406 2404
2407 /* Do this after the official "completion" of the purecopying. */ 2405 /* Do this after the official "completion" of the purecopying. */
2408 s->plist = Fpurecopy (plist); 2406 s->plist = Fpurecopy (plist);
2409 2407
2410 XSETSTRING (new, s); 2408 XSETSTRING (new, s);
2480 that the `double' slot in it is supposed to be aligned to; this 2478 that the `double' slot in it is supposed to be aligned to; this
2481 should be ok because presumably there is padding in the layout 2479 should be ok because presumably there is padding in the layout
2482 of the struct to account for this. 2480 of the struct to account for this.
2483 */ 2481 */
2484 int alignment = sizeof (float_data (f)); 2482 int alignment = sizeof (float_data (f));
2485 #endif 2483 #endif /* !GNUC */
2486 char *p = ((char *) PUREBEG + pureptr); 2484 char *p = ((char *) PUREBEG + pureptr);
2487 2485
2488 p = (char *) (((unsigned EMACS_INT) p + alignment - 1) & - alignment); 2486 p = (char *) (((unsigned EMACS_INT) p + alignment - 1) & - alignment);
2489 pureptr = p - (char *) PUREBEG; 2487 pureptr = p - (char *) PUREBEG;
2490 } 2488 }
2541 2539
2542 set_lheader_implementation (header, implementation); 2540 set_lheader_implementation (header, implementation);
2543 header->next = 0; 2541 header->next = 0;
2544 return header; 2542 return header;
2545 } 2543 }
2546 #endif 2544 #endif /* unused */
2547 2545
2548 2546
2549 2547
2550 DEFUN ("purecopy", Fpurecopy, 1, 1, 0, /* 2548 DEFUN ("purecopy", Fpurecopy, 1, 1, 0, /*
2551 Make a copy of OBJECT in pure storage. 2549 Make a copy of OBJECT in pure storage.
2610 } 2608 }
2611 2609
2612 2610
2613 2611
2614 static void 2612 static void
2615 PURESIZE_h(long int puresize) 2613 puresize_adjust_h (long int puresize)
2616 { 2614 {
2617 int fd; 2615 FILE *stream = fopen ("puresize-adjust.h", "w");
2618 char *PURESIZE_h_file = "puresize_adjust.h"; 2616
2619 char *WARNING = "/* This file is generated by XEmacs, DO NOT MODIFY!!! */\n"; 2617 if (stream == NULL)
2620 char define_PURESIZE[256]; 2618 report_file_error ("Opening puresize adjustment file",
2621 2619 Fcons (build_string ("puresize-adjust.h"), Qnil));
2622 if ((fd = open(PURESIZE_h_file, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) { 2620
2623 report_file_error("Can't write PURESIZE_ADJUSTMENT", 2621 fprintf (stream,
2624 Fcons(build_ext_string(PURESIZE_h_file, FORMAT_FILENAME), 2622 "/*\tDo not edit this file!\n"
2625 Qnil)); 2623 "\tAutomatically generated by XEmacs */\n"
2626 } 2624 "# define PURESIZE_ADJUSTMENT (%ld)\n",
2627 2625 puresize - RAW_PURESIZE);
2628 write(fd, WARNING, strlen(WARNING)); 2626 fclose (stream);
2629 sprintf(define_PURESIZE, "# define PURESIZE_ADJUSTMENT (%ld)\n",
2630 puresize - RAW_PURESIZE);
2631 write(fd, define_PURESIZE, strlen(define_PURESIZE));
2632 close(fd);
2633 } 2627 }
2634 2628
2635 void 2629 void
2636 report_pure_usage (int report_impurities, 2630 report_pure_usage (int report_impurities,
2637 int die_if_pure_storage_exceeded) 2631 int die_if_pure_storage_exceeded)
2639 int rc = 0; 2633 int rc = 0;
2640 2634
2641 if (pure_lossage) 2635 if (pure_lossage)
2642 { 2636 {
2643 message ("\n****\tPure Lisp storage exhausted!\n" 2637 message ("\n****\tPure Lisp storage exhausted!\n"
2644 "\tPurespace usage: %ld of %ld\n" 2638 "\tPurespace usage: %ld of %ld\n"
2645 "****", 2639 "****",
2646 get_PURESIZE()+pure_lossage, (long) get_PURESIZE()); 2640 get_PURESIZE()+pure_lossage, (long) get_PURESIZE());
2647 if (die_if_pure_storage_exceeded) { 2641 if (die_if_pure_storage_exceeded) {
2648 PURESIZE_h(get_PURESIZE() + pure_lossage); 2642 puresize_adjust_h (get_PURESIZE() + pure_lossage);
2649 rc = -1; 2643 rc = -1;
2650 } 2644 }
2651 } 2645 }
2652 else 2646 else
2653 { 2647 {
2658 pureptr, (long) get_PURESIZE(), 2652 pureptr, (long) get_PURESIZE(),
2659 (int) (pureptr / (get_PURESIZE() / 100.0) + 0.5)); 2653 (int) (pureptr / (get_PURESIZE() / 100.0) + 0.5));
2660 if (lost > 2) { 2654 if (lost > 2) {
2661 sprintf (buf + strlen (buf), " -- %dk wasted", lost); 2655 sprintf (buf + strlen (buf), " -- %dk wasted", lost);
2662 if (die_if_pure_storage_exceeded) { 2656 if (die_if_pure_storage_exceeded) {
2663 PURESIZE_h(pureptr + 16); 2657 puresize_adjust_h (pureptr + 16);
2664 rc = -1; 2658 rc = -1;
2665 } 2659 }
2666 } 2660 }
2667 2661
2668 strcat (buf, ")."); 2662 strcat (buf, ").");
2669 message ("%s", buf); 2663 message ("%s", buf);
2670 } 2664 }
2671 2665
2672 #ifdef PURESTAT 2666 #ifdef PURESTAT
2667
2668 purestat_vector_other.nbytes =
2669 purestat_vector_all.nbytes -
2670 purestat_vector_bytecode_constants.nbytes;
2671 purestat_vector_other.nobjects =
2672 purestat_vector_all.nobjects -
2673 purestat_vector_bytecode_constants.nobjects;
2674
2675 purestat_string_other.nbytes =
2676 purestat_string_all.nbytes -
2677 (purestat_string_pname.nbytes +
2678 purestat_string_bytecodes.nbytes +
2679 purestat_string_interactive.nbytes +
2680 purestat_string_documentation.nbytes +
2681 #ifdef I18N3
2682 purestat_string_domain.nbytes +
2683 #endif
2684 purestat_string_other_function.nbytes);
2685
2686 purestat_string_other.nobjects =
2687 purestat_string_all.nobjects -
2688 (purestat_string_pname.nobjects +
2689 purestat_string_bytecodes.nobjects +
2690 purestat_string_interactive.nobjects +
2691 purestat_string_documentation.nobjects +
2692 #ifdef I18N3
2693 purestat_string_domain.nobjects +
2694 #endif
2695 purestat_string_other_function.nobjects);
2696
2697 message (" %-26s Total Bytes", "");
2698
2673 { 2699 {
2674 int iii; 2700 int j;
2675 2701
2676 purestat_vector_other.nbytes = 2702 for (j = 0; j < countof (purestats); j++)
2677 purestat_vector_all.nbytes - purestat_vector_bytecode_constants.nbytes; 2703 if (!purestats[j])
2678 purestat_vector_other.nobjects =
2679 purestat_vector_all.nobjects -
2680 purestat_vector_bytecode_constants.nobjects;
2681
2682 purestat_string_other.nbytes =
2683 purestat_string_all.nbytes - (purestat_string_pname.nbytes +
2684 purestat_string_bytecodes.nbytes +
2685 purestat_string_interactive.nbytes +
2686 purestat_string_documentation.nbytes +
2687 #ifdef I18N3
2688 purestat_string_domain.nbytes +
2689 #endif
2690 purestat_string_other_function.nbytes);
2691 purestat_string_other.nobjects =
2692 purestat_string_all.nobjects - (purestat_string_pname.nobjects +
2693 purestat_string_bytecodes.nobjects +
2694 purestat_string_interactive.nobjects +
2695 purestat_string_documentation.nobjects +
2696 #ifdef I18N3
2697 purestat_string_domain.nobjects +
2698 #endif
2699 purestat_string_other_function.nobjects);
2700
2701 message (" %-24stotal: bytes:", "");
2702
2703 for (iii = 0; iii < countof (purestats); iii++)
2704 if (!purestats[iii])
2705 clear_message (); 2704 clear_message ();
2706 else 2705 else
2707 message (" %-24s%5d %7d %2d%%", 2706 {
2708 purestats[iii]->name, 2707 char buf [100];
2709 purestats[iii]->nobjects, 2708 sprintf(buf, "%s:", purestats[j]->name);
2710 purestats[iii]->nbytes, 2709 message (" %-26s %5d %7d %2d%%",
2711 (int) (purestats[iii]->nbytes / (pureptr / 100.0) + 0.5)); 2710 buf,
2711 purestats[j]->nobjects,
2712 purestats[j]->nbytes,
2713 (int) (purestats[j]->nbytes / (pureptr / 100.0) + 0.5));
2714 }
2712 } 2715 }
2713 #endif /* PURESTAT */ 2716 #endif /* PURESTAT */
2714 2717
2715 2718
2716 if (report_impurities) 2719 if (report_impurities)
2730 char *s = buf; 2733 char *s = buf;
2731 memcpy (buf, string_data (XSYMBOL (Fcar (tem))->name), 2734 memcpy (buf, string_data (XSYMBOL (Fcar (tem))->name),
2732 string_length (XSYMBOL (Fcar (tem))->name) + 1); 2735 string_length (XSYMBOL (Fcar (tem))->name) + 1);
2733 while (*s++) if (*s == '-') *s = ' '; 2736 while (*s++) if (*s == '-') *s = ' ';
2734 s--; *s++ = ':'; *s = 0; 2737 s--; *s++ = ':'; *s = 0;
2735 message (" %-32s%6d", buf, total); 2738 message (" %-33s %6d", buf, total);
2736 } 2739 }
2737 tem = Fcdr (Fcdr (tem)); 2740 tem = Fcdr (Fcdr (tem));
2738 } 2741 }
2739 else /* WTF?! */ 2742 else /* WTF?! */
2740 { 2743 {
2746 garbage_collect_1 (); /* GC garbage_collect's garbage */ 2749 garbage_collect_1 (); /* GC garbage_collect's garbage */
2747 } 2750 }
2748 clear_message (); 2751 clear_message ();
2749 2752
2750 if (rc < 0) { 2753 if (rc < 0) {
2751 (void)unlink("SATISFIED"); 2754 unlink("SATISFIED");
2752 /* Current build process on NT does */ 2755 /* Current build process on NT does */
2753 /* not know how to restart itself. */ 2756 /* not know how to restart itself. */
2754 /* --marcpa */ 2757 /* --marcpa */
2755 #ifndef WINDOWSNT 2758 #ifndef WINDOWSNT
2756 fatal ("Pure size adjusted, Don't Panic! I will restart the `make'"); 2759 fatal ("Pure size adjusted, Don't Panic! I will restart the `make'");
2757 #endif 2760 #endif
2758 } else if (pure_lossage && die_if_pure_storage_exceeded) { 2761 } else if (pure_lossage && die_if_pure_storage_exceeded) {
2759 fatal ("Pure storage exhausted"); 2762 fatal ("Pure storage exhausted");
2786 } 2789 }
2787 2790
2788 2791
2789 /* Mark reference to a Lisp_Object. If the object referred to has not been 2792 /* Mark reference to a Lisp_Object. If the object referred to has not been
2790 seen yet, recursively mark all the references contained in it. */ 2793 seen yet, recursively mark all the references contained in it. */
2791 2794
2792 static void 2795 static void
2793 mark_object (Lisp_Object obj) 2796 mark_object (Lisp_Object obj)
2794 { 2797 {
2795 tail_recurse: 2798 tail_recurse:
2796 2799
2938 mark_object (rest); 2941 mark_object (rest);
2939 } 2942 }
2940 2943
2941 2944
2942 #ifdef PURESTAT 2945 #ifdef PURESTAT
2943 /* Simpler than mark-object, because pure structure can't 2946 /* Simpler than mark-object, because pure structure can't
2944 have any circularities 2947 have any circularities */
2945 */
2946 2948
2947 #if 0 /* unused */ 2949 #if 0 /* unused */
2948 static int idiot_c_doesnt_have_closures; 2950 static int idiot_c_doesnt_have_closures;
2949 static void 2951 static void
2950 idiot_c (Lisp_Object obj) 2952 idiot_c (Lisp_Object obj)
2976 int size = string_length (ptr); 2978 int size = string_length (ptr);
2977 2979
2978 if (string_data (ptr) != 2980 if (string_data (ptr) !=
2979 (unsigned char *) ptr + sizeof (struct Lisp_String)) 2981 (unsigned char *) ptr + sizeof (struct Lisp_String))
2980 { 2982 {
2981 /* string-data not allocated contiguously. 2983 /* string-data not allocated contiguously.
2982 Probably (better be!!) a pointer constant "C" data. */ 2984 Probably (better be!!) a pointer constant "C" data. */
2983 size = sizeof (struct Lisp_String); 2985 size = sizeof (struct Lisp_String);
2984 } 2986 }
2985 else 2987 else
2986 { 2988 {
2999 total += (sizeof (struct Lisp_Vector) 3001 total += (sizeof (struct Lisp_Vector)
3000 + (len - 1) * sizeof (Lisp_Object)); 3002 + (len - 1) * sizeof (Lisp_Object));
3001 #if 0 /* unused */ 3003 #if 0 /* unused */
3002 if (!recurse) 3004 if (!recurse)
3003 break; 3005 break;
3004 { 3006 {
3005 int i; 3007 int i;
3006 for (i = 0; i < len - 1; i++) 3008 for (i = 0; i < len - 1; i++)
3007 total += pure_sizeof (ptr->contents[i], 1); 3009 total += pure_sizeof (ptr->contents[i], 1);
3008 } 3010 }
3009 if (len > 0) 3011 if (len > 0)
3036 3038
3037 idiot_c_doesnt_have_closures = 0; 3039 idiot_c_doesnt_have_closures = 0;
3038 obj = ((implementation->marker) (obj, idiot_c)); 3040 obj = ((implementation->marker) (obj, idiot_c));
3039 total += idiot_c_doesnt_have_closures; 3041 total += idiot_c_doesnt_have_closures;
3040 idiot_c_doesnt_have_closures = old; 3042 idiot_c_doesnt_have_closures = old;
3041 3043
3042 if (!NILP (obj)) goto tail_recurse; 3044 if (!NILP (obj)) goto tail_recurse;
3043 } 3045 }
3044 #endif /* unused */ 3046 #endif /* unused */
3045 } 3047 }
3046 break; 3048 break;
3227 *used = num_used; 3229 *used = num_used;
3228 /* *total = total_size; */ 3230 /* *total = total_size; */
3229 } 3231 }
3230 3232
3231 static void 3233 static void
3232 sweep_vectors_1 (Lisp_Object *prev, 3234 sweep_vectors_1 (Lisp_Object *prev,
3233 int *used, int *total, int *storage) 3235 int *used, int *total, int *storage)
3234 { 3236 {
3235 Lisp_Object vector; 3237 Lisp_Object vector;
3236 int num_used = 0; 3238 int num_used = 0;
3237 int total_size = 0; 3239 int total_size = 0;
3265 *total = total_size; 3267 *total = total_size;
3266 *storage = total_storage; 3268 *storage = total_storage;
3267 } 3269 }
3268 3270
3269 static void 3271 static void
3270 sweep_bit_vectors_1 (Lisp_Object *prev, 3272 sweep_bit_vectors_1 (Lisp_Object *prev,
3271 int *used, int *total, int *storage) 3273 int *used, int *total, int *storage)
3272 { 3274 {
3273 Lisp_Object bit_vector; 3275 Lisp_Object bit_vector;
3274 int num_used = 0; 3276 int num_used = 0;
3275 int total_size = 0; 3277 int total_size = 0;
3352 \ 3354 \
3353 gc_count_num_##typename##_in_use = num_used; \ 3355 gc_count_num_##typename##_in_use = num_used; \
3354 gc_count_num_##typename##_freelist = num_free; \ 3356 gc_count_num_##typename##_freelist = num_free; \
3355 } while (0) 3357 } while (0)
3356 3358
3357 #else 3359 #else /* !ERROR_CHECK_GC */
3358 3360
3359 #define SWEEP_FIXED_TYPE_BLOCK(typename, obj_type) \ 3361 #define SWEEP_FIXED_TYPE_BLOCK(typename, obj_type) \
3360 do { \ 3362 do { \
3361 struct typename##_block *_frob_current; \ 3363 struct typename##_block *_frob_current; \
3362 struct typename##_block **_frob_prev; \ 3364 struct typename##_block **_frob_prev; \
3427 \ 3429 \
3428 gc_count_num_##typename##_in_use = num_used; \ 3430 gc_count_num_##typename##_in_use = num_used; \
3429 gc_count_num_##typename##_freelist = num_free; \ 3431 gc_count_num_##typename##_freelist = num_free; \
3430 } while (0) 3432 } while (0)
3431 3433
3432 #endif 3434 #endif /* !ERROR_CHECK_GC */
3433 3435
3434 3436
3435 3437
3436 3438
3437 static void 3439 static void
3455 a chain pointer to the next cons on the list, which has cleverly 3457 a chain pointer to the next cons on the list, which has cleverly
3456 had all its 0's and 1's inverted. This allows for a quick 3458 had all its 0's and 1's inverted. This allows for a quick
3457 check to make sure we're not freeing something already freed. */ 3459 check to make sure we're not freeing something already freed. */
3458 if (POINTER_TYPE_P (XTYPE (ptr->car))) 3460 if (POINTER_TYPE_P (XTYPE (ptr->car)))
3459 ASSERT_VALID_POINTER (XPNTR (ptr->car)); 3461 ASSERT_VALID_POINTER (XPNTR (ptr->car));
3460 #endif 3462 #endif /* ERROR_CHECK_GC */
3463
3461 #ifndef ALLOC_NO_POOLS 3464 #ifndef ALLOC_NO_POOLS
3462 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (cons, struct Lisp_Cons, ptr); 3465 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (cons, struct Lisp_Cons, ptr);
3463 #endif /* ALLOC_NO_POOLS */ 3466 #endif /* ALLOC_NO_POOLS */
3464 } 3467 }
3465 3468
3581 #ifdef ERROR_CHECK_GC 3584 #ifdef ERROR_CHECK_GC
3582 /* Perhaps this will catch freeing an already-freed marker. */ 3585 /* Perhaps this will catch freeing an already-freed marker. */
3583 Lisp_Object temmy; 3586 Lisp_Object temmy;
3584 XSETMARKER (temmy, ptr); 3587 XSETMARKER (temmy, ptr);
3585 assert (GC_MARKERP (temmy)); 3588 assert (GC_MARKERP (temmy));
3586 #endif 3589 #endif /* ERROR_CHECK_GC */
3590
3587 #ifndef ALLOC_NO_POOLS 3591 #ifndef ALLOC_NO_POOLS
3588 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (marker, struct Lisp_Marker, ptr); 3592 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (marker, struct Lisp_Marker, ptr);
3589 #endif /* ALLOC_NO_POOLS */ 3593 #endif /* ALLOC_NO_POOLS */
3590 } 3594 }
3591 3595
3605 { 3609 {
3606 int pos = 0; 3610 int pos = 0;
3607 /* POS is the index of the next string in the block. */ 3611 /* POS is the index of the next string in the block. */
3608 while (pos < sb->pos) 3612 while (pos < sb->pos)
3609 { 3613 {
3610 struct string_chars *s_chars = 3614 struct string_chars *s_chars =
3611 (struct string_chars *) &(sb->string_chars[pos]); 3615 (struct string_chars *) &(sb->string_chars[pos]);
3612 struct Lisp_String *string; 3616 struct Lisp_String *string;
3613 int size; 3617 int size;
3614 int fullsize; 3618 int fullsize;
3615 3619
3655 { 3659 {
3656 int from_pos = 0; 3660 int from_pos = 0;
3657 /* FROM_POS is the index of the next string in the block. */ 3661 /* FROM_POS is the index of the next string in the block. */
3658 while (from_pos < from_sb->pos) 3662 while (from_pos < from_sb->pos)
3659 { 3663 {
3660 struct string_chars *from_s_chars = 3664 struct string_chars *from_s_chars =
3661 (struct string_chars *) &(from_sb->string_chars[from_pos]); 3665 (struct string_chars *) &(from_sb->string_chars[from_pos]);
3662 struct string_chars *to_s_chars; 3666 struct string_chars *to_s_chars;
3663 struct Lisp_String *string; 3667 struct Lisp_String *string;
3664 int size; 3668 int size;
3665 int fullsize; 3669 int fullsize;
3704 { 3708 {
3705 to_sb->pos = to_pos; 3709 to_sb->pos = to_pos;
3706 to_sb = to_sb->next; 3710 to_sb = to_sb->next;
3707 to_pos = 0; 3711 to_pos = 0;
3708 } 3712 }
3709 3713
3710 /* Compute new address of this string 3714 /* Compute new address of this string
3711 and update TO_POS for the space being used. */ 3715 and update TO_POS for the space being used. */
3712 to_s_chars = (struct string_chars *) &(to_sb->string_chars[to_pos]); 3716 to_s_chars = (struct string_chars *) &(to_sb->string_chars[to_pos]);
3713 3717
3714 /* Copy the string_chars to the new place. */ 3718 /* Copy the string_chars to the new place. */
3715 if (from_s_chars != to_s_chars) 3719 if (from_s_chars != to_s_chars)
3716 memmove (to_s_chars, from_s_chars, fullsize); 3720 memmove (to_s_chars, from_s_chars, fullsize);
3717 3721
3718 /* Relocate FROM_S_CHARS's reference */ 3722 /* Relocate FROM_S_CHARS's reference */
3719 set_string_data (string, &(to_s_chars->chars[0])); 3723 set_string_data (string, &(to_s_chars->chars[0]));
3720 3724
3721 from_pos += fullsize; 3725 from_pos += fullsize;
3722 to_pos += fullsize; 3726 to_pos += fullsize;
3723 } 3727 }
3724 } 3728 }
3725 3729
3726 /* Set current to the last string chars block still used and 3730 /* Set current to the last string chars block still used and
3727 free any that follow. */ 3731 free any that follow. */
3728 { 3732 {
3729 struct string_chars_block *victim; 3733 struct string_chars_block *victim;
3730 3734
3731 for (victim = to_sb->next; victim; ) 3735 for (victim = to_sb->next; victim; )
3760 else 3764 else
3761 stderr_out ("%c", ch); 3765 stderr_out ("%c", ch);
3762 } 3766 }
3763 stderr_out ("\"\n"); 3767 stderr_out ("\"\n");
3764 } 3768 }
3765 #endif 3769 #endif /* 1 */
3766 3770
3767 3771
3768 static void 3772 static void
3769 sweep_strings (void) 3773 sweep_strings (void)
3770 { 3774 {
4169 char *msg = (STRINGP (Vgc_message) 4173 char *msg = (STRINGP (Vgc_message)
4170 ? GETTEXT ((char *) XSTRING_DATA (Vgc_message)) 4174 ? GETTEXT ((char *) XSTRING_DATA (Vgc_message))
4171 : 0); 4175 : 0);
4172 4176
4173 /* Show "...done" only if the echo area would otherwise be empty. */ 4177 /* Show "...done" only if the echo area would otherwise be empty. */
4174 if (NILP (clear_echo_area (selected_frame (), 4178 if (NILP (clear_echo_area (selected_frame (),
4175 Qgarbage_collecting, 0))) 4179 Qgarbage_collecting, 0)))
4176 { 4180 {
4177 Lisp_Object args[2], whole_msg; 4181 Lisp_Object args[2], whole_msg;
4178 args[0] = build_string (msg ? msg : 4182 args[0] = build_string (msg ? msg :
4179 GETTEXT ((CONST char *) 4183 GETTEXT ((CONST char *)
4204 of the garbage collector by noting that PC is between &garbage_collect_1 4208 of the garbage collector by noting that PC is between &garbage_collect_1
4205 and &BTL_after_garbage_collect_1_stub. So this fn must be right here. 4209 and &BTL_after_garbage_collect_1_stub. So this fn must be right here.
4206 There's not any other way to know the address of the end of a function. 4210 There's not any other way to know the address of the end of a function.
4207 */ 4211 */
4208 void BTL_after_garbage_collect_1_stub () { abort (); } 4212 void BTL_after_garbage_collect_1_stub () { abort (); }
4209 #endif 4213 #endif /* EMACS_BTL */
4210 4214
4211 /* Debugging aids. */ 4215 /* Debugging aids. */
4212 4216
4213 static Lisp_Object 4217 static Lisp_Object
4214 gc_plist_hack (CONST char *name, int value, Lisp_Object tail) 4218 gc_plist_hack (CONST char *name, int value, Lisp_Object tail)
4230 DEFUN ("garbage-collect", Fgarbage_collect, 0, 0, "", /* 4234 DEFUN ("garbage-collect", Fgarbage_collect, 0, 0, "", /*
4231 Reclaim storage for Lisp objects no longer needed. 4235 Reclaim storage for Lisp objects no longer needed.
4232 Returns info on amount of space in use: 4236 Returns info on amount of space in use:
4233 ((USED-CONSES . FREE-CONSES) (USED-SYMS . FREE-SYMS) 4237 ((USED-CONSES . FREE-CONSES) (USED-SYMS . FREE-SYMS)
4234 (USED-MARKERS . FREE-MARKERS) USED-STRING-CHARS USED-VECTOR-SLOTS 4238 (USED-MARKERS . FREE-MARKERS) USED-STRING-CHARS USED-VECTOR-SLOTS
4235 PLIST) 4239 PLIST)
4236 where `PLIST' is a list of alternating keyword/value pairs providing 4240 where `PLIST' is a list of alternating keyword/value pairs providing
4237 more detailed information. 4241 more detailed information.
4238 Garbage collection happens automatically if you cons more than 4242 Garbage collection happens automatically if you cons more than
4239 `gc-cons-threshold' bytes of Lisp data since previous garbage collection. 4243 `gc-cons-threshold' bytes of Lisp data since previous garbage collection.
4240 */ 4244 */
4251 4255
4252 garbage_collect_1 (); 4256 garbage_collect_1 ();
4253 4257
4254 for (i = 0; i < last_lrecord_type_index_assigned; i++) 4258 for (i = 0; i < last_lrecord_type_index_assigned; i++)
4255 { 4259 {
4256 if (lcrecord_stats[i].bytes_in_use != 0 4260 if (lcrecord_stats[i].bytes_in_use != 0
4257 || lcrecord_stats[i].bytes_freed != 0 4261 || lcrecord_stats[i].bytes_freed != 0
4258 || lcrecord_stats[i].instances_on_free_list != 0) 4262 || lcrecord_stats[i].instances_on_free_list != 0)
4259 { 4263 {
4260 char buf [255]; 4264 char buf [255];
4261 CONST char *name = lrecord_implementations_table[i]->name; 4265 CONST char *name = lrecord_implementations_table[i]->name;
4297 HACK_O_MATIC (float, "float-storage", pl); 4301 HACK_O_MATIC (float, "float-storage", pl);
4298 pl = gc_plist_hack ("floats-free", gc_count_num_float_freelist, pl); 4302 pl = gc_plist_hack ("floats-free", gc_count_num_float_freelist, pl);
4299 pl = gc_plist_hack ("floats-used", gc_count_num_float_in_use, pl); 4303 pl = gc_plist_hack ("floats-used", gc_count_num_float_in_use, pl);
4300 #endif /* LISP_FLOAT_TYPE */ 4304 #endif /* LISP_FLOAT_TYPE */
4301 HACK_O_MATIC (string, "string-header-storage", pl); 4305 HACK_O_MATIC (string, "string-header-storage", pl);
4302 pl = gc_plist_hack ("long-strings-total-length", 4306 pl = gc_plist_hack ("long-strings-total-length",
4303 gc_count_string_total_size 4307 gc_count_string_total_size
4304 - gc_count_short_string_total_size, pl); 4308 - gc_count_short_string_total_size, pl);
4305 HACK_O_MATIC (string_chars, "short-string-storage", pl); 4309 HACK_O_MATIC (string_chars, "short-string-storage", pl);
4306 pl = gc_plist_hack ("short-strings-total-length", 4310 pl = gc_plist_hack ("short-strings-total-length",
4307 gc_count_short_string_total_size, pl); 4311 gc_count_short_string_total_size, pl);
4308 pl = gc_plist_hack ("strings-free", gc_count_num_string_freelist, pl); 4312 pl = gc_plist_hack ("strings-free", gc_count_num_string_freelist, pl);
4309 pl = gc_plist_hack ("long-strings-used", 4313 pl = gc_plist_hack ("long-strings-used",
4310 gc_count_num_string_in_use 4314 gc_count_num_string_in_use
4311 - gc_count_num_short_string_in_use, pl); 4315 - gc_count_num_short_string_in_use, pl);
4312 pl = gc_plist_hack ("short-strings-used", 4316 pl = gc_plist_hack ("short-strings-used",
4313 gc_count_num_short_string_in_use, pl); 4317 gc_count_num_short_string_in_use, pl);
4314 4318
4315 HACK_O_MATIC (compiled_function, "compiled-function-storage", pl); 4319 HACK_O_MATIC (compiled_function, "compiled-function-storage", pl);
4316 pl = gc_plist_hack ("compiled-functions-free", 4320 pl = gc_plist_hack ("compiled-functions-free",
4317 gc_count_num_compiled_function_freelist, pl); 4321 gc_count_num_compiled_function_freelist, pl);
4318 pl = gc_plist_hack ("compiled-functions-used", 4322 pl = gc_plist_hack ("compiled-functions-used",
4319 gc_count_num_compiled_function_in_use, pl); 4323 gc_count_num_compiled_function_in_use, pl);
4320 4324
4321 pl = gc_plist_hack ("vector-storage", gc_count_vector_storage, pl); 4325 pl = gc_plist_hack ("vector-storage", gc_count_vector_storage, pl);
4322 pl = gc_plist_hack ("vectors-total-length", 4326 pl = gc_plist_hack ("vectors-total-length",
4323 gc_count_vector_total_size, pl); 4327 gc_count_vector_total_size, pl);
4324 pl = gc_plist_hack ("vectors-used", gc_count_num_vector_used, pl); 4328 pl = gc_plist_hack ("vectors-used", gc_count_num_vector_used, pl);
4325 4329
4326 pl = gc_plist_hack ("bit-vector-storage", gc_count_bit_vector_storage, pl); 4330 pl = gc_plist_hack ("bit-vector-storage", gc_count_bit_vector_storage, pl);
4327 pl = gc_plist_hack ("bit-vectors-total-length", 4331 pl = gc_plist_hack ("bit-vectors-total-length",
4328 gc_count_bit_vector_total_size, pl); 4332 gc_count_bit_vector_total_size, pl);
4329 pl = gc_plist_hack ("bit-vectors-used", gc_count_num_bit_vector_used, pl); 4333 pl = gc_plist_hack ("bit-vectors-used", gc_count_num_bit_vector_used, pl);
4330 4334
4331 HACK_O_MATIC (symbol, "symbol-storage", pl); 4335 HACK_O_MATIC (symbol, "symbol-storage", pl);
4332 pl = gc_plist_hack ("symbols-free", gc_count_num_symbol_freelist, pl); 4336 pl = gc_plist_hack ("symbols-free", gc_count_num_symbol_freelist, pl);
4359 */ 4363 */
4360 ()) 4364 ())
4361 { 4365 {
4362 return make_int (consing_since_gc); 4366 return make_int (consing_since_gc);
4363 } 4367 }
4364 4368
4365 DEFUN ("memory-limit", Fmemory_limit, 0, 0, "", /* 4369 DEFUN ("memory-limit", Fmemory_limit, 0, 0, "", /*
4366 Return the address of the last byte Emacs has allocated, divided by 1024. 4370 Return the address of the last byte Emacs has allocated, divided by 1024.
4367 This may be helpful in debugging Emacs's memory usage. 4371 This may be helpful in debugging Emacs's memory usage.
4368 The value is divided by 1024 to make sure it will fit in a lisp integer. 4372 The value is divided by 1024 to make sure it will fit in a lisp integer.
4369 */ 4373 */
4382 (WINDOWP (obj) && !WINDOW_LIVE_P (XWINDOW (obj))) || 4386 (WINDOWP (obj) && !WINDOW_LIVE_P (XWINDOW (obj))) ||
4383 (DEVICEP (obj) && !DEVICE_LIVE_P (XDEVICE (obj))) || 4387 (DEVICEP (obj) && !DEVICE_LIVE_P (XDEVICE (obj))) ||
4384 (CONSOLEP (obj) && !CONSOLE_LIVE_P (XCONSOLE (obj))) || 4388 (CONSOLEP (obj) && !CONSOLE_LIVE_P (XCONSOLE (obj))) ||
4385 (EVENTP (obj) && !EVENT_LIVE_P (XEVENT (obj))) || 4389 (EVENTP (obj) && !EVENT_LIVE_P (XEVENT (obj))) ||
4386 (EXTENTP (obj) && !EXTENT_LIVE_P (XEXTENT (obj)))); 4390 (EXTENTP (obj) && !EXTENT_LIVE_P (XEXTENT (obj))));
4387 4391
4388 } 4392 }
4389 4393
4390 #ifdef MEMORY_USAGE_STATS 4394 #ifdef MEMORY_USAGE_STATS
4391 4395
4392 /* Attempt to determine the actual amount of space that is used for 4396 /* Attempt to determine the actual amount of space that is used for
4537 if (! purestats[iii]) continue; 4541 if (! purestats[iii]) continue;
4538 purestats[iii]->nobjects = 0; 4542 purestats[iii]->nobjects = 0;
4539 purestats[iii]->nbytes = 0; 4543 purestats[iii]->nbytes = 0;
4540 } 4544 }
4541 purecopying_for_bytecode = 0; 4545 purecopying_for_bytecode = 0;
4542 #endif 4546 #endif /* PURESTAT */
4543 4547
4544 last_lrecord_type_index_assigned = -1; 4548 last_lrecord_type_index_assigned = -1;
4545 for (iii = 0; iii < countof (lrecord_implementations_table); iii++) 4549 for (iii = 0; iii < countof (lrecord_implementations_table); iii++)
4546 { 4550 {
4547 lrecord_implementations_table[iii] = 0; 4551 lrecord_implementations_table[iii] = 0;
4548 } 4552 }
4549 4553
4550 symbols_initialized = 0; 4554 symbols_initialized = 0;
4551 4555
4552 gc_generation_number[0] = 0; 4556 gc_generation_number[0] = 0;
4553 /* purify_flag 1 is correct even if CANNOT_DUMP. 4557 /* purify_flag 1 is correct even if CANNOT_DUMP.
4554 * loadup.el will set to nil at end. */ 4558 * loadup.el will set to nil at end. */
4555 purify_flag = 1; 4559 purify_flag = 1;
4556 pureptr = 0; 4560 pureptr = 0;
4599 ERROR_ME_NOT. 4603 ERROR_ME_NOT.
4600 really_unlikely_name_to_have_accidentally_in_a_non_errb_structure = 42; 4604 really_unlikely_name_to_have_accidentally_in_a_non_errb_structure = 42;
4601 ERROR_ME_WARN. 4605 ERROR_ME_WARN.
4602 really_unlikely_name_to_have_accidentally_in_a_non_errb_structure = 4606 really_unlikely_name_to_have_accidentally_in_a_non_errb_structure =
4603 3333632; 4607 3333632;
4604 #endif 4608 #endif /* ERROR_CHECK_TYPECHECK */
4605 } 4609 }
4606 4610
4607 void 4611 void
4608 reinit_alloc (void) 4612 reinit_alloc (void)
4609 { 4613 {