Mercurial > hg > xemacs-beta
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 } |
