comparison src/alloc.c @ 438:84b14dcb0985 r21-2-27

Import from CVS: tag r21-2-27
author cvs
date Mon, 13 Aug 2007 11:32:25 +0200
parents 3ecd8885ac67
children 8de8e3f6228a
comparison
equal deleted inserted replaced
437:e2a4e8b94b82 438:84b14dcb0985
494 /************************************************************************/ 494 /************************************************************************/
495 /* Debugger support */ 495 /* Debugger support */
496 /************************************************************************/ 496 /************************************************************************/
497 /* Give gdb/dbx enough information to decode Lisp Objects. We make 497 /* Give gdb/dbx enough information to decode Lisp Objects. We make
498 sure certain symbols are always defined, so gdb doesn't complain 498 sure certain symbols are always defined, so gdb doesn't complain
499 about expressions in src/gdbinit. See src/gdbinit or src/dbxrc to 499 about expressions in src/.gdbinit. See src/.gdbinit or src/.dbxrc
500 see how this is used. */ 500 to see how this is used. */
501 501
502 EMACS_UINT dbg_valmask = ((1UL << VALBITS) - 1) << GCBITS; 502 EMACS_UINT dbg_valmask = ((1UL << VALBITS) - 1) << GCBITS;
503 EMACS_UINT dbg_typemask = (1UL << GCTYPEBITS) - 1; 503 EMACS_UINT dbg_typemask = (1UL << GCTYPEBITS) - 1;
504 504
505 #ifdef USE_UNION_TYPE 505 #ifdef USE_UNION_TYPE
1718 strings (since EVERY REFERENCE to a short string needed to be GCPRO'd so 1718 strings (since EVERY REFERENCE to a short string needed to be GCPRO'd so
1719 that the reference would get relocated). 1719 that the reference would get relocated).
1720 1720
1721 This new method makes things somewhat bigger, but it is MUCH safer. */ 1721 This new method makes things somewhat bigger, but it is MUCH safer. */
1722 1722
1723 DECLARE_FIXED_TYPE_ALLOC (string, struct Lisp_String); 1723 DECLARE_FIXED_TYPE_ALLOC (string, Lisp_String);
1724 /* strings are used and freed quite often */ 1724 /* strings are used and freed quite often */
1725 /* #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_string 10000 */ 1725 /* #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_string 10000 */
1726 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_string 1000 1726 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_string 1000
1727 1727
1728 static Lisp_Object 1728 static Lisp_Object
1729 mark_string (Lisp_Object obj) 1729 mark_string (Lisp_Object obj)
1730 { 1730 {
1731 struct Lisp_String *ptr = XSTRING (obj); 1731 Lisp_String *ptr = XSTRING (obj);
1732 1732
1733 if (CONSP (ptr->plist) && EXTENT_INFOP (XCAR (ptr->plist))) 1733 if (CONSP (ptr->plist) && EXTENT_INFOP (XCAR (ptr->plist)))
1734 flush_cached_extent_info (XCAR (ptr->plist)); 1734 flush_cached_extent_info (XCAR (ptr->plist));
1735 return ptr->plist; 1735 return ptr->plist;
1736 } 1736 }
1762 * finalization when using 1762 * finalization when using
1763 * SWEEP_FIXED_TYPE_BLOCK(). 1763 * SWEEP_FIXED_TYPE_BLOCK().
1764 */ 1764 */
1765 0, string_equal, 0, 1765 0, string_equal, 0,
1766 string_description, 1766 string_description,
1767 struct Lisp_String); 1767 Lisp_String);
1768 1768
1769 /* String blocks contain this many useful bytes. */ 1769 /* String blocks contain this many useful bytes. */
1770 #define STRING_CHARS_BLOCK_SIZE \ 1770 #define STRING_CHARS_BLOCK_SIZE \
1771 ((Bytecount) (8192 - MALLOC_OVERHEAD - \ 1771 ((Bytecount) (8192 - MALLOC_OVERHEAD - \
1772 ((2 * sizeof (struct string_chars_block *)) \ 1772 ((2 * sizeof (struct string_chars_block *)) \
1787 1787
1788 /* If SIZE is the length of a string, this returns how many bytes 1788 /* If SIZE is the length of a string, this returns how many bytes
1789 * the string occupies in string_chars_block->string_chars 1789 * the string occupies in string_chars_block->string_chars
1790 * (including alignment padding). 1790 * (including alignment padding).
1791 */ 1791 */
1792 #define STRING_FULLSIZE(s) \ 1792 #define STRING_FULLSIZE(size) \
1793 ALIGN_SIZE (((s) + 1 + sizeof (struct Lisp_String *)),\ 1793 ALIGN_SIZE (((size) + 1 + sizeof (Lisp_String *)),\
1794 ALIGNOF (struct Lisp_String *)) 1794 ALIGNOF (Lisp_String *))
1795 1795
1796 #define BIG_STRING_FULLSIZE_P(fullsize) ((fullsize) >= STRING_CHARS_BLOCK_SIZE) 1796 #define BIG_STRING_FULLSIZE_P(fullsize) ((fullsize) >= STRING_CHARS_BLOCK_SIZE)
1797 #define BIG_STRING_SIZE_P(size) (BIG_STRING_FULLSIZE_P (STRING_FULLSIZE(size))) 1797 #define BIG_STRING_SIZE_P(size) (BIG_STRING_FULLSIZE_P (STRING_FULLSIZE(size)))
1798 1798
1799 #define CHARS_TO_STRING_CHAR(x) \
1800 ((struct string_chars *) \
1801 (((char *) (x)) - (slot_offset (struct string_chars, chars[0]))))
1802
1803
1804 struct string_chars 1799 struct string_chars
1805 { 1800 {
1806 struct Lisp_String *string; 1801 Lisp_String *string;
1807 unsigned char chars[1]; 1802 unsigned char chars[1];
1808 }; 1803 };
1809 1804
1810 struct unused_string_chars 1805 struct unused_string_chars
1811 { 1806 {
1812 struct Lisp_String *string; 1807 Lisp_String *string;
1813 EMACS_INT fullsize; 1808 EMACS_INT fullsize;
1814 }; 1809 };
1815 1810
1816 static void 1811 static void
1817 init_string_chars_alloc (void) 1812 init_string_chars_alloc (void)
1822 first_string_chars_block->pos = 0; 1817 first_string_chars_block->pos = 0;
1823 current_string_chars_block = first_string_chars_block; 1818 current_string_chars_block = first_string_chars_block;
1824 } 1819 }
1825 1820
1826 static struct string_chars * 1821 static struct string_chars *
1827 allocate_string_chars_struct (struct Lisp_String *string_it_goes_with, 1822 allocate_string_chars_struct (Lisp_String *string_it_goes_with,
1828 EMACS_INT fullsize) 1823 EMACS_INT fullsize)
1829 { 1824 {
1830 struct string_chars *s_chars; 1825 struct string_chars *s_chars;
1831 1826
1832 /* Allocate the string's actual data */ 1827 if (fullsize <=
1833 if (BIG_STRING_FULLSIZE_P (fullsize)) 1828 (countof (current_string_chars_block->string_chars)
1834 { 1829 - current_string_chars_block->pos))
1835 s_chars = (struct string_chars *) xmalloc (fullsize);
1836 }
1837 else if (fullsize <=
1838 (countof (current_string_chars_block->string_chars)
1839 - current_string_chars_block->pos))
1840 { 1830 {
1841 /* This string can fit in the current string chars block */ 1831 /* This string can fit in the current string chars block */
1842 s_chars = (struct string_chars *) 1832 s_chars = (struct string_chars *)
1843 (current_string_chars_block->string_chars 1833 (current_string_chars_block->string_chars
1844 + current_string_chars_block->pos); 1834 + current_string_chars_block->pos);
1866 } 1856 }
1867 1857
1868 Lisp_Object 1858 Lisp_Object
1869 make_uninit_string (Bytecount length) 1859 make_uninit_string (Bytecount length)
1870 { 1860 {
1871 struct Lisp_String *s; 1861 Lisp_String *s;
1872 struct string_chars *s_chars;
1873 EMACS_INT fullsize = STRING_FULLSIZE (length); 1862 EMACS_INT fullsize = STRING_FULLSIZE (length);
1874 Lisp_Object val; 1863 Lisp_Object val;
1875 1864
1876 if ((length < 0) || (fullsize <= 0)) 1865 assert (length >= 0 && fullsize > 0);
1877 abort ();
1878 1866
1879 /* Allocate the string header */ 1867 /* Allocate the string header */
1880 ALLOCATE_FIXED_TYPE (string, struct Lisp_String, s); 1868 ALLOCATE_FIXED_TYPE (string, Lisp_String, s);
1881 set_lheader_implementation (&(s->lheader), &lrecord_string); 1869 set_lheader_implementation (&(s->lheader), &lrecord_string);
1882 1870
1883 s_chars = allocate_string_chars_struct (s, fullsize); 1871 set_string_data (s, BIG_STRING_FULLSIZE_P (fullsize)
1884 1872 ? xnew_array (Bufbyte, length + 1)
1885 set_string_data (s, &(s_chars->chars[0])); 1873 : allocate_string_chars_struct (s, fullsize)->chars);
1874
1886 set_string_length (s, length); 1875 set_string_length (s, length);
1887 s->plist = Qnil; 1876 s->plist = Qnil;
1888 1877
1889 set_string_byte (s, length, 0); 1878 set_string_byte (s, length, 0);
1890 1879
1901 POS < 0, resize the string but don't copy any characters. Use 1890 POS < 0, resize the string but don't copy any characters. Use
1902 this if you're planning on completely overwriting the string. 1891 this if you're planning on completely overwriting the string.
1903 */ 1892 */
1904 1893
1905 void 1894 void
1906 resize_string (struct Lisp_String *s, Bytecount pos, Bytecount delta) 1895 resize_string (Lisp_String *s, Bytecount pos, Bytecount delta)
1907 { 1896 {
1897 Bytecount oldfullsize, newfullsize;
1908 #ifdef VERIFY_STRING_CHARS_INTEGRITY 1898 #ifdef VERIFY_STRING_CHARS_INTEGRITY
1909 verify_string_chars_integrity (); 1899 verify_string_chars_integrity ();
1910 #endif 1900 #endif
1911 1901
1912 #ifdef ERROR_CHECK_BUFPOS 1902 #ifdef ERROR_CHECK_BUFPOS
1921 if (delta < 0) 1911 if (delta < 0)
1922 assert ((-delta) <= string_length (s)); 1912 assert ((-delta) <= string_length (s));
1923 } 1913 }
1924 #endif /* ERROR_CHECK_BUFPOS */ 1914 #endif /* ERROR_CHECK_BUFPOS */
1925 1915
1926 if (pos >= 0 && delta < 0)
1927 /* If DELTA < 0, the functions below will delete the characters
1928 before POS. We want to delete characters *after* POS, however,
1929 so convert this to the appropriate form. */
1930 pos += -delta;
1931
1932 if (delta == 0) 1916 if (delta == 0)
1933 /* simplest case: no size change. */ 1917 /* simplest case: no size change. */
1934 return; 1918 return;
1935 else 1919
1936 { 1920 if (pos >= 0 && delta < 0)
1937 Bytecount oldfullsize = STRING_FULLSIZE (string_length (s)); 1921 /* If DELTA < 0, the functions below will delete the characters
1938 Bytecount newfullsize = STRING_FULLSIZE (string_length (s) + delta); 1922 before POS. We want to delete characters *after* POS, however,
1939 1923 so convert this to the appropriate form. */
1940 if (oldfullsize == newfullsize) 1924 pos += -delta;
1925
1926 oldfullsize = STRING_FULLSIZE (string_length (s));
1927 newfullsize = STRING_FULLSIZE (string_length (s) + delta);
1928
1929 if (BIG_STRING_FULLSIZE_P (oldfullsize))
1930 {
1931 if (BIG_STRING_FULLSIZE_P (newfullsize))
1941 { 1932 {
1942 /* next simplest case; size change but the necessary 1933 /* Both strings are big. We can just realloc(). */
1943 allocation size won't change (up or down; code somewhere 1934 set_string_data (s, (Bufbyte *) xrealloc (string_data (s),
1944 depends on there not being any unused allocation space, 1935 string_length (s) + delta + 1));
1945 modulo any alignment constraints). */
1946 if (pos >= 0) 1936 if (pos >= 0)
1947 { 1937 {
1948 Bufbyte *addroff = pos + string_data (s); 1938 Bufbyte *addroff = pos + string_data (s);
1949 1939
1950 memmove (addroff + delta, addroff, 1940 memmove (addroff + delta, addroff,
1951 /* +1 due to zero-termination. */
1952 string_length (s) + 1 - pos); 1941 string_length (s) + 1 - pos);
1953 } 1942 }
1954 } 1943 }
1955 else if (BIG_STRING_FULLSIZE_P (oldfullsize) && 1944 else /* String has been demoted from BIG_STRING. */
1956 BIG_STRING_FULLSIZE_P (newfullsize))
1957 { 1945 {
1958 /* next simplest case; the string is big enough to be malloc()ed 1946 Bufbyte *new_data =
1959 itself, so we just realloc. 1947 allocate_string_chars_struct (s, newfullsize)->chars;
1960 1948 Bufbyte *old_data = string_data (s);
1961 It's important not to let the string get below the threshold 1949
1962 for making big strings and still remain malloc()ed; if that 1950 if (pos >= 0)
1963 were the case, repeated calls to this function on the same 1951 {
1964 string could result in memory leakage. */ 1952 memcpy (new_data, old_data, pos);
1965 set_string_data (s, (Bufbyte *) xrealloc (string_data (s), 1953 memcpy (new_data + pos + delta, old_data + pos,
1966 newfullsize)); 1954 string_length (s) + 1 - pos);
1955 }
1956 set_string_data (s, new_data);
1957 xfree (old_data);
1958 }
1959 }
1960 else /* old string is small */
1961 {
1962 if (oldfullsize == newfullsize)
1963 {
1964 /* special case; size change but the necessary
1965 allocation size won't change (up or down; code
1966 somewhere depends on there not being any unused
1967 allocation space, modulo any alignment
1968 constraints). */
1967 if (pos >= 0) 1969 if (pos >= 0)
1968 { 1970 {
1969 Bufbyte *addroff = pos + string_data (s); 1971 Bufbyte *addroff = pos + string_data (s);
1970 1972
1971 memmove (addroff + delta, addroff, 1973 memmove (addroff + delta, addroff,
1973 string_length (s) + 1 - pos); 1975 string_length (s) + 1 - pos);
1974 } 1976 }
1975 } 1977 }
1976 else 1978 else
1977 { 1979 {
1978 /* worst case. We make a new string_chars struct and copy 1980 Bufbyte *old_data = string_data (s);
1979 the string's data into it, inserting/deleting the delta 1981 Bufbyte *new_data =
1980 in the process. The old string data will either get 1982 BIG_STRING_FULLSIZE_P (newfullsize)
1981 freed by us (if it was malloc()ed) or will be reclaimed 1983 ? xnew_array (Bufbyte, string_length (s) + delta + 1)
1982 in the normal course of garbage collection. */ 1984 : allocate_string_chars_struct (s, newfullsize)->chars;
1983 struct string_chars *s_chars = 1985
1984 allocate_string_chars_struct (s, newfullsize);
1985 Bufbyte *new_addr = &(s_chars->chars[0]);
1986 Bufbyte *old_addr = string_data (s);
1987 if (pos >= 0) 1986 if (pos >= 0)
1988 { 1987 {
1989 memcpy (new_addr, old_addr, pos); 1988 memcpy (new_data, old_data, pos);
1990 memcpy (new_addr + pos + delta, old_addr + pos, 1989 memcpy (new_data + pos + delta, old_data + pos,
1991 string_length (s) + 1 - pos); 1990 string_length (s) + 1 - pos);
1992 } 1991 }
1993 set_string_data (s, new_addr); 1992 set_string_data (s, new_data);
1994 if (BIG_STRING_FULLSIZE_P (oldfullsize)) 1993
1995 xfree (old_addr); 1994 {
1996 else 1995 /* We need to mark this chunk of the string_chars_block
1997 { 1996 as unused so that compact_string_chars() doesn't
1998 /* We need to mark this chunk of the string_chars_block 1997 freak. */
1999 as unused so that compact_string_chars() doesn't 1998 struct string_chars *old_s_chars = (struct string_chars *)
2000 freak. */ 1999 ((char *) old_data - offsetof (struct string_chars, chars));
2001 struct string_chars *old_s_chars = 2000 /* Sanity check to make sure we aren't hosed by strange
2002 (struct string_chars *) ((char *) old_addr - 2001 alignment/padding. */
2003 sizeof (struct Lisp_String *)); 2002 assert (old_s_chars->string == s);
2004 /* Sanity check to make sure we aren't hosed by strange 2003 MARK_STRUCT_AS_FREE (old_s_chars);
2005 alignment/padding. */ 2004 ((struct unused_string_chars *) old_s_chars)->fullsize =
2006 assert (old_s_chars->string == s); 2005 oldfullsize;
2007 MARK_STRUCT_AS_FREE (old_s_chars); 2006 }
2008 ((struct unused_string_chars *) old_s_chars)->fullsize =
2009 oldfullsize;
2010 }
2011 } 2007 }
2012 2008 }
2013 set_string_length (s, string_length (s) + delta); 2009
2014 /* If pos < 0, the string won't be zero-terminated. 2010 set_string_length (s, string_length (s) + delta);
2015 Terminate now just to make sure. */ 2011 /* If pos < 0, the string won't be zero-terminated.
2016 string_data (s)[string_length (s)] = '\0'; 2012 Terminate now just to make sure. */
2017 2013 string_data (s)[string_length (s)] = '\0';
2018 if (pos >= 0) 2014
2019 { 2015 if (pos >= 0)
2020 Lisp_Object string; 2016 {
2021 2017 Lisp_Object string;
2022 XSETSTRING (string, s); 2018
2023 /* We also have to adjust all of the extent indices after the 2019 XSETSTRING (string, s);
2024 place we did the change. We say "pos - 1" because 2020 /* We also have to adjust all of the extent indices after the
2025 adjust_extents() is exclusive of the starting position 2021 place we did the change. We say "pos - 1" because
2026 passed to it. */ 2022 adjust_extents() is exclusive of the starting position
2027 adjust_extents (string, pos - 1, string_length (s), 2023 passed to it. */
2028 delta); 2024 adjust_extents (string, pos - 1, string_length (s),
2029 } 2025 delta);
2030 } 2026 }
2031 2027
2032 #ifdef VERIFY_STRING_CHARS_INTEGRITY 2028 #ifdef VERIFY_STRING_CHARS_INTEGRITY
2033 verify_string_chars_integrity (); 2029 verify_string_chars_integrity ();
2034 #endif 2030 #endif
2035 } 2031 }
2036 2032
2037 #ifdef MULE 2033 #ifdef MULE
2038 2034
2039 void 2035 void
2040 set_string_char (struct Lisp_String *s, Charcount i, Emchar c) 2036 set_string_char (Lisp_String *s, Charcount i, Emchar c)
2041 { 2037 {
2042 Bufbyte newstr[MAX_EMCHAR_LEN]; 2038 Bufbyte newstr[MAX_EMCHAR_LEN];
2043 Bytecount bytoff = charcount_to_bytecount (string_data (s), i); 2039 Bytecount bytoff = charcount_to_bytecount (string_data (s), i);
2044 Bytecount oldlen = charcount_to_bytecount (string_data (s) + bytoff, 1); 2040 Bytecount oldlen = charcount_to_bytecount (string_data (s) + bytoff, 1);
2045 Bytecount newlen = set_charptr_emchar (newstr, c); 2041 Bytecount newlen = set_charptr_emchar (newstr, c);
2158 } 2154 }
2159 2155
2160 Lisp_Object 2156 Lisp_Object
2161 make_string_nocopy (CONST Bufbyte *contents, Bytecount length) 2157 make_string_nocopy (CONST Bufbyte *contents, Bytecount length)
2162 { 2158 {
2163 struct Lisp_String *s; 2159 Lisp_String *s;
2164 Lisp_Object val; 2160 Lisp_Object val;
2165 2161
2166 /* Make sure we find out about bad make_string_nocopy's when they happen */ 2162 /* Make sure we find out about bad make_string_nocopy's when they happen */
2167 #if defined (ERROR_CHECK_BUFPOS) && defined (MULE) 2163 #if defined (ERROR_CHECK_BUFPOS) && defined (MULE)
2168 bytecount_to_charcount (contents, length); /* Just for the assertions */ 2164 bytecount_to_charcount (contents, length); /* Just for the assertions */
2169 #endif 2165 #endif
2170 2166
2171 /* Allocate the string header */ 2167 /* Allocate the string header */
2172 ALLOCATE_FIXED_TYPE (string, struct Lisp_String, s); 2168 ALLOCATE_FIXED_TYPE (string, Lisp_String, s);
2173 set_lheader_implementation (&(s->lheader), &lrecord_string); 2169 set_lheader_implementation (&(s->lheader), &lrecord_string);
2174 SET_C_READONLY_RECORD_HEADER (&s->lheader); 2170 SET_C_READONLY_RECORD_HEADER (&s->lheader);
2175 s->plist = Qnil; 2171 s->plist = Qnil;
2176 set_string_data (s, (Bufbyte *)contents); 2172 set_string_data (s, (Bufbyte *)contents);
2177 set_string_length (s, length); 2173 set_string_length (s, length);
2991 /* POS is the index of the next string in the block. */ 2987 /* POS is the index of the next string in the block. */
2992 while (pos < sb->pos) 2988 while (pos < sb->pos)
2993 { 2989 {
2994 struct string_chars *s_chars = 2990 struct string_chars *s_chars =
2995 (struct string_chars *) &(sb->string_chars[pos]); 2991 (struct string_chars *) &(sb->string_chars[pos]);
2996 struct Lisp_String *string; 2992 Lisp_String *string;
2997 int size; 2993 int size;
2998 int fullsize; 2994 int fullsize;
2999 2995
3000 /* If the string_chars struct is marked as free (i.e. the STRING 2996 /* If the string_chars struct is marked as free (i.e. the STRING
3001 pointer is 0xFFFFFFFF) then this is an unused chunk of string 2997 pointer is 0xFFFFFFFF) then this is an unused chunk of string
3042 while (from_pos < from_sb->pos) 3038 while (from_pos < from_sb->pos)
3043 { 3039 {
3044 struct string_chars *from_s_chars = 3040 struct string_chars *from_s_chars =
3045 (struct string_chars *) &(from_sb->string_chars[from_pos]); 3041 (struct string_chars *) &(from_sb->string_chars[from_pos]);
3046 struct string_chars *to_s_chars; 3042 struct string_chars *to_s_chars;
3047 struct Lisp_String *string; 3043 Lisp_String *string;
3048 int size; 3044 int size;
3049 int fullsize; 3045 int fullsize;
3050 3046
3051 /* If the string_chars struct is marked as free (i.e. the STRING 3047 /* If the string_chars struct is marked as free (i.e. the STRING
3052 pointer is 0xFFFFFFFF) then this is an unused chunk of string 3048 pointer is 0xFFFFFFFF) then this is an unused chunk of string
3127 3123
3128 #if 1 /* Hack to debug missing purecopy's */ 3124 #if 1 /* Hack to debug missing purecopy's */
3129 static int debug_string_purity; 3125 static int debug_string_purity;
3130 3126
3131 static void 3127 static void
3132 debug_string_purity_print (struct Lisp_String *p) 3128 debug_string_purity_print (Lisp_String *p)
3133 { 3129 {
3134 Charcount i; 3130 Charcount i;
3135 Charcount s = string_char_length (p); 3131 Charcount s = string_char_length (p);
3136 putc ('\"', stderr); 3132 putc ('\"', stderr);
3137 for (i = 0; i < s; i++) 3133 for (i = 0; i < s; i++)
3153 sweep_strings (void) 3149 sweep_strings (void)
3154 { 3150 {
3155 int num_small_used = 0, num_small_bytes = 0, num_bytes = 0; 3151 int num_small_used = 0, num_small_bytes = 0, num_bytes = 0;
3156 int debug = debug_string_purity; 3152 int debug = debug_string_purity;
3157 3153
3158 #define UNMARK_string(ptr) \ 3154 #define UNMARK_string(ptr) do { \
3159 do { struct Lisp_String *p = (ptr); \ 3155 Lisp_String *p = (ptr); \
3160 int size = string_length (p); \ 3156 size_t size = string_length (p); \
3161 UNMARK_RECORD_HEADER (&(p->lheader)); \ 3157 UNMARK_RECORD_HEADER (&(p->lheader)); \
3162 num_bytes += size; \ 3158 num_bytes += size; \
3163 if (!BIG_STRING_SIZE_P (size)) \ 3159 if (!BIG_STRING_SIZE_P (size)) \
3164 { num_small_bytes += size; \ 3160 { num_small_bytes += size; \
3165 num_small_used++; \ 3161 num_small_used++; \
3166 } \ 3162 } \
3167 if (debug) debug_string_purity_print (p); \ 3163 if (debug) \
3168 } while (0) 3164 debug_string_purity_print (p); \
3169 #define ADDITIONAL_FREE_string(p) \ 3165 } while (0)
3170 do { int size = string_length (p); \ 3166 #define ADDITIONAL_FREE_string(ptr) do { \
3171 if (BIG_STRING_SIZE_P (size)) \ 3167 size_t size = string_length (ptr); \
3172 xfree_1 (CHARS_TO_STRING_CHAR (string_data (p))); \ 3168 if (BIG_STRING_SIZE_P (size)) \
3173 } while (0) 3169 xfree (ptr->data); \
3174 3170 } while (0)
3175 SWEEP_FIXED_TYPE_BLOCK (string, struct Lisp_String); 3171
3172 SWEEP_FIXED_TYPE_BLOCK (string, Lisp_String);
3176 3173
3177 gc_count_num_short_string_in_use = num_small_used; 3174 gc_count_num_short_string_in_use = num_small_used;
3178 gc_count_string_total_size = num_bytes; 3175 gc_count_string_total_size = num_bytes;
3179 gc_count_short_string_total_size = num_small_bytes; 3176 gc_count_short_string_total_size = num_small_bytes;
3180 } 3177 }
3483 { /* staticpro() */ 3480 { /* staticpro() */
3484 int i; 3481 int i;
3485 for (i = 0; i < staticidx; i++) 3482 for (i = 0; i < staticidx; i++)
3486 mark_object (*(staticvec[i])); 3483 mark_object (*(staticvec[i]));
3487 for (i = 0; i < staticidx_nodump; i++) 3484 for (i = 0; i < staticidx_nodump; i++)
3488 mark_object (*(staticvec_nodump[i])); 3485 mark_object (*(staticvec_nodump[i]));
3489 } 3486 }
3490 3487
3491 { /* GCPRO() */ 3488 { /* GCPRO() */
3492 struct gcpro *tail; 3489 struct gcpro *tail;
3493 int i; 3490 int i;
4148 * - nb_staticpro*(relocated Lisp_Object) pointed to by staticpro 4145 * - nb_staticpro*(relocated Lisp_Object) pointed to by staticpro
4149 * - nb_structdmp*pair(void *, adr) for pointers to structures 4146 * - nb_structdmp*pair(void *, adr) for pointers to structures
4150 * - lrecord_implementations_table[] 4147 * - lrecord_implementations_table[]
4151 * - relocation table 4148 * - relocation table
4152 * - wired variable address/value couples with the count preceding the list 4149 * - wired variable address/value couples with the count preceding the list
4153 */ 4150 */
4154 typedef struct 4151 typedef struct
4155 { 4152 {
4156 char signature[8]; 4153 char signature[8];
4157 EMACS_UINT stab_offset; 4154 EMACS_UINT stab_offset;
4158 EMACS_UINT reloc_address; 4155 EMACS_UINT reloc_address;
4262 4259
4263 while ((e = pdump_hash[pos]) != 0) 4260 while ((e = pdump_hash[pos]) != 0)
4264 { 4261 {
4265 if (e->obj == obj) 4262 if (e->obj == obj)
4266 return; 4263 return;
4267 4264
4268 pos++; 4265 pos++;
4269 if (pos == PDUMP_HASHSIZE) 4266 if (pos == PDUMP_HASHSIZE)
4270 pos = 0; 4267 pos = 0;
4271 } 4268 }
4272 4269
4309 } 4306 }
4310 pdump_struct_table.list[pdump_struct_table.count].list.first = 0; 4307 pdump_struct_table.list[pdump_struct_table.count].list.first = 0;
4311 pdump_struct_table.list[pdump_struct_table.count].list.align = 8; 4308 pdump_struct_table.list[pdump_struct_table.count].list.align = 8;
4312 pdump_struct_table.list[pdump_struct_table.count].list.count = 0; 4309 pdump_struct_table.list[pdump_struct_table.count].list.count = 0;
4313 pdump_struct_table.list[pdump_struct_table.count].sdesc = sdesc; 4310 pdump_struct_table.list[pdump_struct_table.count].sdesc = sdesc;
4314 4311
4315 return &pdump_struct_table.list[pdump_struct_table.count++].list; 4312 return &pdump_struct_table.list[pdump_struct_table.count++].list;
4316 } 4313 }
4317 4314
4318 static struct { 4315 static struct {
4319 Lisp_Object obj; 4316 Lisp_Object obj;
4434 { 4431 {
4435 EMACS_INT count = desc[pos].data1; 4432 EMACS_INT count = desc[pos].data1;
4436 int i; 4433 int i;
4437 if (XD_IS_INDIRECT (count)) 4434 if (XD_IS_INDIRECT (count))
4438 count = pdump_get_indirect_count (count, desc, data); 4435 count = pdump_get_indirect_count (count, desc, data);
4439 4436
4440 for(i=0;i<count;i++) { 4437 for(i=0;i<count;i++) {
4441 const Lisp_Object *pobj = ((const Lisp_Object *)rdata) + i; 4438 const Lisp_Object *pobj = ((const Lisp_Object *)rdata) + i;
4442 Lisp_Object dobj = *pobj; 4439 Lisp_Object dobj = *pobj;
4443 4440
4444 backtrace[me].offset = (const char *)pobj - (const char *)data; 4441 backtrace[me].offset = (const char *)pobj - (const char *)data;
4445 pdump_register_object (dobj); 4442 pdump_register_object (dobj);
4446 } 4443 }
4447 break; 4444 break;
4448 } 4445 }
4452 const struct struct_description *sdesc = desc[pos].data2; 4449 const struct struct_description *sdesc = desc[pos].data2;
4453 const char *dobj = *(const char **)rdata; 4450 const char *dobj = *(const char **)rdata;
4454 if (dobj) { 4451 if (dobj) {
4455 if (XD_IS_INDIRECT (count)) 4452 if (XD_IS_INDIRECT (count))
4456 count = pdump_get_indirect_count (count, desc, data); 4453 count = pdump_get_indirect_count (count, desc, data);
4457 4454
4458 pdump_register_struct (dobj, sdesc, count); 4455 pdump_register_struct (dobj, sdesc, count);
4459 } 4456 }
4460 break; 4457 break;
4461 } 4458 }
4462 default: 4459 default:
4472 { 4469 {
4473 if (!obj || 4470 if (!obj ||
4474 !POINTER_TYPE_P (XTYPE (obj)) || 4471 !POINTER_TYPE_P (XTYPE (obj)) ||
4475 pdump_get_entry (XRECORD_LHEADER (obj))) 4472 pdump_get_entry (XRECORD_LHEADER (obj)))
4476 return; 4473 return;
4477 4474
4478 if (XRECORD_LHEADER_IMPLEMENTATION (obj)->description) 4475 if (XRECORD_LHEADER_IMPLEMENTATION (obj)->description)
4479 { 4476 {
4480 int me = depth++; 4477 int me = depth++;
4481 if (me>65536) 4478 if (me>65536)
4482 { 4479 {
4520 abort (); 4517 abort ();
4521 } 4518 }
4522 backtrace[me].obj = 0; 4519 backtrace[me].obj = 0;
4523 backtrace[me].position = 0; 4520 backtrace[me].position = 0;
4524 backtrace[me].offset = 0; 4521 backtrace[me].offset = 0;
4525 4522
4526 pdump_add_entry (pdump_get_entry_list (sdesc), 4523 pdump_add_entry (pdump_get_entry_list (sdesc),
4527 data, 4524 data,
4528 sdesc->size, 4525 sdesc->size,
4529 count, 4526 count,
4530 0); 4527 0);
4546 if (desc) 4543 if (desc)
4547 { 4544 {
4548 int pos, i; 4545 int pos, i;
4549 void *rdata; 4546 void *rdata;
4550 memcpy (pdump_buf, elmt->obj, size*count); 4547 memcpy (pdump_buf, elmt->obj, size*count);
4551 4548
4552 for (i=0; i<count; i++) 4549 for (i=0; i<count; i++)
4553 { 4550 {
4554 char *cur = ((char *)pdump_buf) + i*size; 4551 char *cur = ((char *)pdump_buf) + i*size;
4555 restart: 4552 restart:
4556 for (pos = 0; desc[pos].type != XD_END; pos++) 4553 for (pos = 0; desc[pos].type != XD_END; pos++)
4612 { 4609 {
4613 EMACS_INT count = desc[pos].data1; 4610 EMACS_INT count = desc[pos].data1;
4614 int i; 4611 int i;
4615 if (XD_IS_INDIRECT (count)) 4612 if (XD_IS_INDIRECT (count))
4616 count = pdump_get_indirect_count (count, desc, elmt->obj); 4613 count = pdump_get_indirect_count (count, desc, elmt->obj);
4617 4614
4618 for(i=0; i<count; i++) 4615 for(i=0; i<count; i++)
4619 { 4616 {
4620 Lisp_Object *pobj = ((Lisp_Object *)rdata) + i; 4617 Lisp_Object *pobj = ((Lisp_Object *)rdata) + i;
4621 Lisp_Object dobj = *pobj; 4618 Lisp_Object dobj = *pobj;
4622 if (dobj && POINTER_TYPE_P (XTYPE (dobj))) 4619 if (dobj && POINTER_TYPE_P (XTYPE (dobj)))
4679 { 4676 {
4680 EMACS_INT count = desc[pos].data1; 4677 EMACS_INT count = desc[pos].data1;
4681 int i; 4678 int i;
4682 if (XD_IS_INDIRECT (count)) 4679 if (XD_IS_INDIRECT (count))
4683 count = pdump_get_indirect_count (count, desc, data); 4680 count = pdump_get_indirect_count (count, desc, data);
4684 4681
4685 for (i=0; i<count; i++) 4682 for (i=0; i<count; i++)
4686 { 4683 {
4687 Lisp_Object *pobj = ((Lisp_Object *)rdata) + i; 4684 Lisp_Object *pobj = ((Lisp_Object *)rdata) + i;
4688 Lisp_Object dobj = *pobj; 4685 Lisp_Object dobj = *pobj;
4689 if (dobj && POINTER_TYPE_P (XTYPE (dobj))) 4686 if (dobj && POINTER_TYPE_P (XTYPE (dobj)))
4734 { 4731 {
4735 f (elmt, idesc); 4732 f (elmt, idesc);
4736 elmt = elmt->next; 4733 elmt = elmt->next;
4737 } 4734 }
4738 } 4735 }
4739 4736
4740 for (i=0; i<pdump_struct_table.count; i++) 4737 for (i=0; i<pdump_struct_table.count; i++)
4741 if (pdump_struct_table.list[i].list.align == align) { 4738 if (pdump_struct_table.list[i].list.align == align) {
4742 elmt = pdump_struct_table.list[i].list.first; 4739 elmt = pdump_struct_table.list[i].list.first;
4743 idesc = pdump_struct_table.list[i].sdesc->description; 4740 idesc = pdump_struct_table.list[i].sdesc->description;
4744 while (elmt) 4741 while (elmt)
4745 { 4742 {
4746 f (elmt, idesc); 4743 f (elmt, idesc);
4747 elmt = elmt->next; 4744 elmt = elmt->next;
4748 } 4745 }
4749 } 4746 }
4750 4747
4751 elmt = pdump_opaque_data_list.first; 4748 elmt = pdump_opaque_data_list.first;
4752 while (elmt) 4749 while (elmt)
4753 { 4750 {
4754 if (align_table[elmt->size & 255] == align) 4751 if (align_table[elmt->size & 255] == align)
4755 f (elmt, 0); 4752 f (elmt, 0);
4791 } 4788 }
4792 4789
4793 static void 4790 static void
4794 pdump_dump_itable (void) 4791 pdump_dump_itable (void)
4795 { 4792 {
4796 write (pdump_fd, lrecord_implementations_table, sizeof (lrecord_implementations_table)); 4793 write (pdump_fd, lrecord_implementations_table, sizeof (lrecord_implementations_table));
4797 } 4794 }
4798 4795
4799 static void 4796 static void
4800 pdump_dump_rtables (void) 4797 pdump_dump_rtables (void)
4801 { 4798 {
4856 { 4853 {
4857 Lisp_Object obj = pdump_get_entry (XRECORD_LHEADER (*(pdump_wirevec[i])))->save_offset; 4854 Lisp_Object obj = pdump_get_entry (XRECORD_LHEADER (*(pdump_wirevec[i])))->save_offset;
4858 write (pdump_fd, &pdump_wirevec[i], sizeof (pdump_wirevec[i])); 4855 write (pdump_fd, &pdump_wirevec[i], sizeof (pdump_wirevec[i]));
4859 write (pdump_fd, &obj, sizeof (obj)); 4856 write (pdump_fd, &obj, sizeof (obj));
4860 } 4857 }
4861 4858
4862 for (i=0; i<pdump_wireidx_list; i++) 4859 for (i=0; i<pdump_wireidx_list; i++)
4863 { 4860 {
4864 Lisp_Object obj = *(pdump_wirevec_list[i]); 4861 Lisp_Object obj = *(pdump_wirevec_list[i]);
4865 pdump_entry_list_elmt *elmt; 4862 pdump_entry_list_elmt *elmt;
4866 EMACS_INT res; 4863 EMACS_INT res;
4913 pdump_object_table[i].count = 0; 4910 pdump_object_table[i].count = 0;
4914 pdump_alert_undump_object[i] = 0; 4911 pdump_alert_undump_object[i] = 0;
4915 } 4912 }
4916 pdump_struct_table.count = 0; 4913 pdump_struct_table.count = 0;
4917 pdump_struct_table.size = -1; 4914 pdump_struct_table.size = -1;
4918 4915
4919 pdump_opaque_data_list.first = 0; 4916 pdump_opaque_data_list.first = 0;
4920 pdump_opaque_data_list.align = 8; 4917 pdump_opaque_data_list.align = 8;
4921 pdump_opaque_data_list.count = 0; 4918 pdump_opaque_data_list.count = 0;
4922 depth = 0; 4919 depth = 0;
4923 4920
4937 } 4934 }
4938 if (!none) 4935 if (!none)
4939 return; 4936 return;
4940 4937
4941 for (i=0; i<dumpstructidx; i++) 4938 for (i=0; i<dumpstructidx; i++)
4942 pdump_register_struct (*(void **)(dumpstructvec[i].data), dumpstructvec[i].desc, 1); 4939 pdump_register_struct (*(void **)(dumpstructvec[i].data), dumpstructvec[i].desc, 1);
4943 4940
4944 memcpy (hd.signature, "XEmacsDP", 8); 4941 memcpy (hd.signature, "XEmacsDP", 8);
4945 hd.reloc_address = 0; 4942 hd.reloc_address = 0;
4946 hd.nb_staticpro = staticidx; 4943 hd.nb_staticpro = staticidx;
4947 hd.nb_structdmp = dumpstructidx; 4944 hd.nb_structdmp = dumpstructidx;
4948 hd.last_type = last_lrecord_type_index_assigned; 4945 hd.last_type = last_lrecord_type_index_assigned;
4949 4946
4950 cur_offset = 256; 4947 cur_offset = 256;
4951 max_size = 0; 4948 max_size = 0;
4952 4949
4953 pdump_scan_by_alignement (pdump_allocate_offset); 4950 pdump_scan_by_alignement (pdump_allocate_offset);
4954 pdump_qnil = pdump_get_entry (XRECORD_LHEADER (Qnil)); 4951 pdump_qnil = pdump_get_entry (XRECORD_LHEADER (Qnil));
4955 4952
4956 pdump_buf = malloc (max_size); 4953 pdump_buf = malloc (max_size);
4957 pdump_fd = open ("xemacs.dmp", O_WRONLY|O_CREAT|O_TRUNC, 0666); 4954 pdump_fd = open ("xemacs.dmp", O_WRONLY|O_CREAT|O_TRUNC, 0666);
5001 #ifdef HAVE_MMAP 4998 #ifdef HAVE_MMAP
5002 pdump_start = mmap (0, length, PROT_READ|PROT_WRITE, MAP_PRIVATE, pdump_fd, 0); 4999 pdump_start = mmap (0, length, PROT_READ|PROT_WRITE, MAP_PRIVATE, pdump_fd, 0);
5003 if (pdump_start == MAP_FAILED) 5000 if (pdump_start == MAP_FAILED)
5004 pdump_start = 0; 5001 pdump_start = 0;
5005 #endif 5002 #endif
5006 5003
5007 if (!pdump_start) 5004 if (!pdump_start)
5008 { 5005 {
5009 pdump_start = (void *)((((unsigned long)(malloc(length+255))) + 255) & ~255); 5006 pdump_start = (void *)((((unsigned long)(malloc(length+255))) + 255) & ~255);
5010 read(pdump_fd, pdump_start, length); 5007 read(pdump_fd, pdump_start, length);
5011 } 5008 }