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 } |