Mercurial > hg > xemacs-beta
comparison src/alloc.c @ 371:cc15677e0335 r21-2b1
Import from CVS: tag r21-2b1
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:03:08 +0200 |
parents | 1d62742628b6 |
children | a300bb07d72d |
comparison
equal
deleted
inserted
replaced
370:bd866891f083 | 371:cc15677e0335 |
---|---|
53 #include "glyphs.h" | 53 #include "glyphs.h" |
54 #include "redisplay.h" | 54 #include "redisplay.h" |
55 #include "specifier.h" | 55 #include "specifier.h" |
56 #include "sysfile.h" | 56 #include "sysfile.h" |
57 #include "window.h" | 57 #include "window.h" |
58 | |
59 #include <stddef.h> | |
60 | 58 |
61 #ifdef DOUG_LEA_MALLOC | 59 #ifdef DOUG_LEA_MALLOC |
62 #include <malloc.h> | 60 #include <malloc.h> |
63 #endif | 61 #endif |
64 | 62 |
634 return imp == type || imp == type + 1; | 632 return imp == type || imp == type + 1; |
635 #endif | 633 #endif |
636 } | 634 } |
637 | 635 |
638 | 636 |
639 /************************************************************************/ | 637 /**********************************************************************/ |
640 /* Debugger support */ | 638 /* Debugger support */ |
641 /************************************************************************/ | 639 /**********************************************************************/ |
642 /* Give gdb/dbx enough information to decode Lisp Objects. We make | 640 /* Give gdb/dbx enough information to decode Lisp Objects. |
643 sure certain symbols are always defined, so gdb doesn't complain | 641 We make sure certain symbols are defined, so gdb doesn't complain |
644 about expressions in src/gdbinit. See src/gdbinit or src/dbxrc to | 642 about expressions in src/gdbinit. Values are randomly chosen. |
645 see how this is used. */ | 643 See src/gdbinit or src/dbxrc to see how this is used. */ |
646 | 644 |
645 enum dbg_constants | |
646 { | |
647 #ifdef USE_MINIMAL_TAGBITS | 647 #ifdef USE_MINIMAL_TAGBITS |
648 EMACS_UINT dbg_valmask = ((1UL << VALBITS) - 1) << GCBITS; | 648 dbg_valmask = (EMACS_INT) (((1UL << VALBITS) - 1) << GCBITS), |
649 EMACS_UINT dbg_typemask = (1UL << GCTYPEBITS) - 1; | 649 dbg_typemask = (EMACS_INT) ((1UL << GCTYPEBITS) - 1), |
650 unsigned char dbg_USE_MINIMAL_TAGBITS = 1; | 650 dbg_USE_MINIMAL_TAGBITS = 1, |
651 unsigned char Lisp_Type_Int = 100; | 651 dbg_Lisp_Type_Int = 100, |
652 #else /* ! USE_MIMIMAL_TAGBITS */ | |
653 dbg_valmask = (EMACS_INT) ((1UL << VALBITS) - 1), | |
654 dbg_typemask = (EMACS_INT) (((1UL << GCTYPEBITS) - 1) << (VALBITS + GCMARKBITS)), | |
655 dbg_USE_MINIMAL_TAGBITS = 0, | |
656 dbg_Lisp_Type_Int = Lisp_Type_Int, | |
657 #endif /* ! USE_MIMIMAL_TAGBITS */ | |
658 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION | |
659 dbg_USE_INDEXED_LRECORD_IMPLEMENTATION = 1, | |
652 #else | 660 #else |
653 EMACS_UINT dbg_valmask = (1UL << VALBITS) - 1; | 661 dbg_USE_INDEXED_LRECORD_IMPLEMENTATION = 0, |
654 EMACS_UINT dbg_typemask = ((1UL << GCTYPEBITS) - 1) << (VALBITS + GCMARKBITS); | 662 #endif |
655 unsigned char dbg_USE_MINIMAL_TAGBITS = 0; | 663 dbg_Lisp_Type_Char = Lisp_Type_Char, |
656 #endif | 664 dbg_Lisp_Type_Record = Lisp_Type_Record, |
657 | 665 #ifdef LRECORD_CONS |
658 #ifdef USE_UNION_TYPE | 666 dbg_Lisp_Type_Cons = 101, |
659 unsigned char dbg_USE_UNION_TYPE = 1; | |
660 #else | 667 #else |
661 unsigned char dbg_USE_UNION_TYPE = 0; | 668 dbg_Lisp_Type_Cons = Lisp_Type_Cons, |
662 #endif | 669 lrecord_cons = 201, |
663 | 670 #endif |
664 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION | 671 #ifdef LRECORD_STRING |
665 unsigned char dbg_USE_INDEXED_LRECORD_IMPLEMENTATION = 1; | 672 dbg_Lisp_Type_String = 102, |
666 #else | 673 #else |
667 unsigned char dbg_USE_INDEXED_LRECORD_IMPLEMENTATION = 0; | 674 dbg_Lisp_Type_String = Lisp_Type_String, |
668 #endif | 675 lrecord_string = 202, |
669 | 676 #endif |
670 #ifdef LRECORD_CONS | 677 #ifdef LRECORD_VECTOR |
671 unsigned char Lisp_Type_Cons = 101; | 678 dbg_Lisp_Type_Vector = 103, |
672 #else | 679 #else |
673 unsigned char lrecord_cons; | 680 dbg_Lisp_Type_Vector = Lisp_Type_Vector, |
674 #endif | 681 lrecord_vector = 203, |
675 | 682 #endif |
676 #ifdef LRECORD_STRING | 683 #ifdef LRECORD_SYMBOL |
677 unsigned char Lisp_Type_String = 102; | 684 dbg_Lisp_Type_Symbol = 104, |
678 #else | 685 #else |
679 unsigned char lrecord_string; | 686 dbg_Lisp_Type_Symbol = Lisp_Type_Symbol, |
680 #endif | 687 lrecord_symbol = 204, |
681 | 688 #endif |
682 #ifdef LRECORD_VECTOR | |
683 unsigned char Lisp_Type_Vector = 103; | |
684 #else | |
685 unsigned char lrecord_vector; | |
686 #endif | |
687 | |
688 #ifdef LRECORD_SYMBOL | |
689 unsigned char Lisp_Type_Symbol = 104; | |
690 #else | |
691 unsigned char lrecord_symbol; | |
692 #endif | |
693 | |
694 #ifndef MULE | 689 #ifndef MULE |
695 unsigned char lrecord_char_table_entry; | 690 lrecord_char_table_entry = 205, |
696 unsigned char lrecord_charset; | 691 lrecord_charset = 206, |
697 #ifndef FILE_CODING | 692 lrecord_coding_system = 207, |
698 unsigned char lrecord_coding_system; | 693 #endif |
699 #endif | |
700 #endif | |
701 | |
702 #ifndef HAVE_TOOLBARS | 694 #ifndef HAVE_TOOLBARS |
703 unsigned char lrecord_toolbar_button; | 695 lrecord_toolbar_button = 208, |
704 #endif | 696 #endif |
705 | 697 #ifndef HAVE_TOOLTALK |
706 #ifndef TOOLTALK | 698 lrecord_tooltalk_message = 210, |
707 unsigned char lrecord_tooltalk_message; | 699 lrecord_tooltalk_pattern = 211, |
708 unsigned char lrecord_tooltalk_pattern; | 700 #endif |
709 #endif | |
710 | |
711 #ifndef HAVE_DATABASE | 701 #ifndef HAVE_DATABASE |
712 unsigned char lrecord_database; | 702 lrecord_database = 212, |
713 #endif | 703 #endif |
714 | 704 dbg_valbits = VALBITS, |
715 unsigned char dbg_valbits = VALBITS; | 705 dbg_gctypebits = GCTYPEBITS |
716 unsigned char dbg_gctypebits = GCTYPEBITS; | 706 /* If we don't have an actual object of this enum, pgcc (and perhaps |
717 | 707 other compilers) might optimize away the entire type declaration :-( */ |
718 /* Macros turned into functions for ease of debugging. | 708 } dbg_dummy; |
719 Debuggers don't know about macros! */ | |
720 int dbg_eq (Lisp_Object obj1, Lisp_Object obj2); | |
721 int | |
722 dbg_eq (Lisp_Object obj1, Lisp_Object obj2) | |
723 { | |
724 return EQ (obj1, obj2); | |
725 } | |
726 | 709 |
727 | 710 |
728 /**********************************************************************/ | 711 /**********************************************************************/ |
729 /* Fixed-size type macros */ | 712 /* Fixed-size type macros */ |
730 /**********************************************************************/ | 713 /**********************************************************************/ |
1020 | 1003 |
1021 Even if Emacs is run on some weirdo system that allows and allocates | 1004 Even if Emacs is run on some weirdo system that allows and allocates |
1022 byte-aligned pointers, this pointer is at the very top of the address | 1005 byte-aligned pointers, this pointer is at the very top of the address |
1023 space and so it's almost inconceivable that it could ever be valid. */ | 1006 space and so it's almost inconceivable that it could ever be valid. */ |
1024 | 1007 |
1025 #if SIZEOF_LONG == 4 | 1008 #if INTBITS == 32 |
1026 # define INVALID_POINTER_VALUE 0xFFFFFFFFUL | 1009 # define INVALID_POINTER_VALUE 0xFFFFFFFF |
1027 #elif SIZEOF_LONG == 8 | 1010 #elif INTBITS == 48 |
1028 # define INVALID_POINTER_VALUE 0xFFFFFFFFFFFFFFFFUL | 1011 # define INVALID_POINTER_VALUE 0xFFFFFFFFFFFF |
1012 #elif INTBITS == 64 | |
1013 # define INVALID_POINTER_VALUE 0xFFFFFFFFFFFFFFFF | |
1029 #else | 1014 #else |
1030 You have some weird system and need to supply a reasonable value here. | 1015 You have some weird system and need to supply a reasonable value here. |
1031 #endif | 1016 #endif |
1032 | 1017 |
1033 /* The construct (* (void **) (ptr)) would cause aliasing problems | |
1034 with modern optimizing compilers like `gcc -O3 -fstrict-aliasing'. | |
1035 But `char *' can legally alias any pointer. Hence this union trick... | |
1036 | |
1037 It turned out that the union trick was not good enough for xlC -O3; | |
1038 and it is questionable whether it really complies with the C standard. | |
1039 so we use memset instead, which should be safe from optimizations. */ | |
1040 typedef union { char c; void *p; } *aliasing_voidpp; | |
1041 #define ALIASING_VOIDPP_DEREFERENCE(ptr) \ | |
1042 (((aliasing_voidpp) (ptr))->p) | |
1043 #define FREE_STRUCT_P(ptr) \ | 1018 #define FREE_STRUCT_P(ptr) \ |
1044 (ALIASING_VOIDPP_DEREFERENCE (ptr) == (void *) INVALID_POINTER_VALUE) | 1019 (* (void **) ptr == (void *) INVALID_POINTER_VALUE) |
1045 #define MARK_STRUCT_AS_FREE(ptr) memset (ptr, 0xff, sizeof (void *)) | 1020 #define MARK_STRUCT_AS_FREE(ptr) \ |
1046 #define MARK_STRUCT_AS_NOT_FREE(ptr) memset (ptr, 0x00, sizeof (void *)) | 1021 (* (void **) ptr = (void *) INVALID_POINTER_VALUE) |
1022 #define MARK_STRUCT_AS_NOT_FREE(ptr) \ | |
1023 (* (void **) ptr = 0) | |
1047 | 1024 |
1048 #ifdef ERROR_CHECK_GC | 1025 #ifdef ERROR_CHECK_GC |
1049 | 1026 |
1050 #define PUT_FIXED_TYPE_ON_FREE_LIST(type, structtype, ptr) \ | 1027 #define PUT_FIXED_TYPE_ON_FREE_LIST(type, structtype, ptr) \ |
1051 do { if (type##_free_list_tail) \ | 1028 do { if (type##_free_list_tail) \ |
1899 #endif | 1876 #endif |
1900 p->name = XSTRING (str); | 1877 p->name = XSTRING (str); |
1901 p->plist = Qnil; | 1878 p->plist = Qnil; |
1902 p->value = Qunbound; | 1879 p->value = Qunbound; |
1903 p->function = Qunbound; | 1880 p->function = Qunbound; |
1904 p->obarray_flags = 0; | 1881 p->obarray = Qnil; |
1905 symbol_next (p) = 0; | 1882 symbol_next (p) = 0; |
1906 XSETSYMBOL (val, p); | 1883 XSETSYMBOL (val, p); |
1907 return val; | 1884 return val; |
1908 } | 1885 } |
1909 | 1886 |
1910 | 1887 |
2088 ALIGNOF (struct Lisp_String *)) | 2065 ALIGNOF (struct Lisp_String *)) |
2089 | 2066 |
2090 #define BIG_STRING_FULLSIZE_P(fullsize) ((fullsize) >= STRING_CHARS_BLOCK_SIZE) | 2067 #define BIG_STRING_FULLSIZE_P(fullsize) ((fullsize) >= STRING_CHARS_BLOCK_SIZE) |
2091 #define BIG_STRING_SIZE_P(size) (BIG_STRING_FULLSIZE_P (STRING_FULLSIZE(size))) | 2068 #define BIG_STRING_SIZE_P(size) (BIG_STRING_FULLSIZE_P (STRING_FULLSIZE(size))) |
2092 | 2069 |
2070 #define CHARS_TO_STRING_CHAR(x) \ | |
2071 ((struct string_chars *) \ | |
2072 (((char *) (x)) - (slot_offset (struct string_chars, chars[0])))) | |
2073 | |
2074 | |
2093 struct string_chars | 2075 struct string_chars |
2094 { | 2076 { |
2095 struct Lisp_String *string; | 2077 struct Lisp_String *string; |
2096 unsigned char chars[1]; | 2078 unsigned char chars[1]; |
2097 }; | 2079 }; |
2116 allocate_string_chars_struct (struct Lisp_String *string_it_goes_with, | 2098 allocate_string_chars_struct (struct Lisp_String *string_it_goes_with, |
2117 EMACS_INT fullsize) | 2099 EMACS_INT fullsize) |
2118 { | 2100 { |
2119 struct string_chars *s_chars; | 2101 struct string_chars *s_chars; |
2120 | 2102 |
2121 if (fullsize <= | 2103 /* Allocate the string's actual data */ |
2122 (countof (current_string_chars_block->string_chars) | 2104 if (BIG_STRING_FULLSIZE_P (fullsize)) |
2123 - current_string_chars_block->pos)) | 2105 { |
2106 s_chars = (struct string_chars *) xmalloc (fullsize); | |
2107 } | |
2108 else if (fullsize <= | |
2109 (countof (current_string_chars_block->string_chars) | |
2110 - current_string_chars_block->pos)) | |
2124 { | 2111 { |
2125 /* This string can fit in the current string chars block */ | 2112 /* This string can fit in the current string chars block */ |
2126 s_chars = (struct string_chars *) | 2113 s_chars = (struct string_chars *) |
2127 (current_string_chars_block->string_chars | 2114 (current_string_chars_block->string_chars |
2128 + current_string_chars_block->pos); | 2115 + current_string_chars_block->pos); |
2151 | 2138 |
2152 Lisp_Object | 2139 Lisp_Object |
2153 make_uninit_string (Bytecount length) | 2140 make_uninit_string (Bytecount length) |
2154 { | 2141 { |
2155 struct Lisp_String *s; | 2142 struct Lisp_String *s; |
2143 struct string_chars *s_chars; | |
2156 EMACS_INT fullsize = STRING_FULLSIZE (length); | 2144 EMACS_INT fullsize = STRING_FULLSIZE (length); |
2157 Lisp_Object val; | 2145 Lisp_Object val; |
2158 | 2146 |
2159 assert (length >= 0 && fullsize > 0); | 2147 if ((length < 0) || (fullsize <= 0)) |
2148 abort (); | |
2160 | 2149 |
2161 /* Allocate the string header */ | 2150 /* Allocate the string header */ |
2162 ALLOCATE_FIXED_TYPE (string, struct Lisp_String, s); | 2151 ALLOCATE_FIXED_TYPE (string, struct Lisp_String, s); |
2163 #ifdef LRECORD_STRING | 2152 #ifdef LRECORD_STRING |
2164 set_lheader_implementation (&(s->lheader), lrecord_string); | 2153 set_lheader_implementation (&(s->lheader), lrecord_string); |
2165 #endif | 2154 #endif |
2166 | 2155 |
2167 set_string_data (s, BIG_STRING_FULLSIZE_P (fullsize) | 2156 s_chars = allocate_string_chars_struct (s, fullsize); |
2168 ? xnew_array (Bufbyte, length + 1) | 2157 |
2169 : allocate_string_chars_struct (s, fullsize)->chars); | 2158 set_string_data (s, &(s_chars->chars[0])); |
2170 | |
2171 set_string_length (s, length); | 2159 set_string_length (s, length); |
2172 s->plist = Qnil; | 2160 s->plist = Qnil; |
2173 | 2161 |
2174 set_string_byte (s, length, 0); | 2162 set_string_byte (s, length, 0); |
2175 | 2163 |
2188 */ | 2176 */ |
2189 | 2177 |
2190 void | 2178 void |
2191 resize_string (struct Lisp_String *s, Bytecount pos, Bytecount delta) | 2179 resize_string (struct Lisp_String *s, Bytecount pos, Bytecount delta) |
2192 { | 2180 { |
2193 Bytecount oldfullsize, newfullsize; | |
2194 #ifdef VERIFY_STRING_CHARS_INTEGRITY | 2181 #ifdef VERIFY_STRING_CHARS_INTEGRITY |
2195 verify_string_chars_integrity (); | 2182 verify_string_chars_integrity (); |
2196 #endif | 2183 #endif |
2197 | 2184 |
2198 #ifdef ERROR_CHECK_BUFPOS | 2185 #ifdef ERROR_CHECK_BUFPOS |
2207 if (delta < 0) | 2194 if (delta < 0) |
2208 assert ((-delta) <= string_length (s)); | 2195 assert ((-delta) <= string_length (s)); |
2209 } | 2196 } |
2210 #endif /* ERROR_CHECK_BUFPOS */ | 2197 #endif /* ERROR_CHECK_BUFPOS */ |
2211 | 2198 |
2199 if (pos >= 0 && delta < 0) | |
2200 /* If DELTA < 0, the functions below will delete the characters | |
2201 before POS. We want to delete characters *after* POS, however, | |
2202 so convert this to the appropriate form. */ | |
2203 pos += -delta; | |
2204 | |
2212 if (delta == 0) | 2205 if (delta == 0) |
2213 /* simplest case: no size change. */ | 2206 /* simplest case: no size change. */ |
2214 return; | 2207 return; |
2215 | 2208 else |
2216 if (pos >= 0 && delta < 0) | 2209 { |
2217 /* If DELTA < 0, the functions below will delete the characters | 2210 Bytecount oldfullsize = STRING_FULLSIZE (string_length (s)); |
2218 before POS. We want to delete characters *after* POS, however, | 2211 Bytecount newfullsize = STRING_FULLSIZE (string_length (s) + delta); |
2219 so convert this to the appropriate form. */ | 2212 |
2220 pos += -delta; | 2213 if (oldfullsize == newfullsize) |
2221 | |
2222 oldfullsize = STRING_FULLSIZE (string_length (s)); | |
2223 newfullsize = STRING_FULLSIZE (string_length (s) + delta); | |
2224 | |
2225 if (BIG_STRING_FULLSIZE_P (oldfullsize)) | |
2226 { | |
2227 if (BIG_STRING_FULLSIZE_P (newfullsize)) | |
2228 { | 2214 { |
2229 /* Both strings are big. We can just realloc(). | 2215 /* next simplest case; size change but the necessary |
2230 But careful! If the string is shrinking, we have to | 2216 allocation size won't change (up or down; code somewhere |
2231 memmove() _before_ realloc(), and if growing, we have to | 2217 depends on there not being any unused allocation space, |
2232 memmove() _after_ realloc() - otherwise the access is | 2218 modulo any alignment constraints). */ |
2233 illegal, and we might crash. */ | |
2234 Bytecount len = string_length (s) + 1 - pos; | |
2235 | |
2236 if (delta < 0 && pos >= 0) | |
2237 memmove (string_data (s) + pos + delta, string_data (s) + pos, len); | |
2238 set_string_data (s, (Bufbyte *) xrealloc (string_data (s), | |
2239 string_length (s) + delta + 1)); | |
2240 if (delta > 0 && pos >= 0) | |
2241 memmove (string_data (s) + pos + delta, string_data (s) + pos, len); | |
2242 } | |
2243 else /* String has been demoted from BIG_STRING. */ | |
2244 { | |
2245 Bufbyte *new_data = | |
2246 allocate_string_chars_struct (s, newfullsize)->chars; | |
2247 Bufbyte *old_data = string_data (s); | |
2248 | |
2249 if (pos >= 0) | 2219 if (pos >= 0) |
2250 { | 2220 { |
2251 memcpy (new_data, old_data, pos); | 2221 Bufbyte *addroff = pos + string_data (s); |
2252 memcpy (new_data + pos + delta, old_data + pos, | 2222 |
2253 string_length (s) + 1 - pos); | 2223 memmove (addroff + delta, addroff, |
2224 /* +1 due to zero-termination. */ | |
2225 string_length (s) + 1 - pos); | |
2254 } | 2226 } |
2255 set_string_data (s, new_data); | |
2256 xfree (old_data); | |
2257 } | 2227 } |
2258 } | 2228 else if (BIG_STRING_FULLSIZE_P (oldfullsize) && |
2259 else /* old string is small */ | 2229 BIG_STRING_FULLSIZE_P (newfullsize)) |
2260 { | |
2261 if (oldfullsize == newfullsize) | |
2262 { | 2230 { |
2263 /* special case; size change but the necessary | 2231 /* next simplest case; the string is big enough to be malloc()ed |
2264 allocation size won't change (up or down; code | 2232 itself, so we just realloc. |
2265 somewhere depends on there not being any unused | 2233 |
2266 allocation space, modulo any alignment | 2234 It's important not to let the string get below the threshold |
2267 constraints). */ | 2235 for making big strings and still remain malloc()ed; if that |
2236 were the case, repeated calls to this function on the same | |
2237 string could result in memory leakage. */ | |
2238 set_string_data (s, (Bufbyte *) xrealloc (string_data (s), | |
2239 newfullsize)); | |
2268 if (pos >= 0) | 2240 if (pos >= 0) |
2269 { | 2241 { |
2270 Bufbyte *addroff = pos + string_data (s); | 2242 Bufbyte *addroff = pos + string_data (s); |
2271 | 2243 |
2272 memmove (addroff + delta, addroff, | 2244 memmove (addroff + delta, addroff, |
2274 string_length (s) + 1 - pos); | 2246 string_length (s) + 1 - pos); |
2275 } | 2247 } |
2276 } | 2248 } |
2277 else | 2249 else |
2278 { | 2250 { |
2279 Bufbyte *old_data = string_data (s); | 2251 /* worst case. We make a new string_chars struct and copy |
2280 Bufbyte *new_data = | 2252 the string's data into it, inserting/deleting the delta |
2281 BIG_STRING_FULLSIZE_P (newfullsize) | 2253 in the process. The old string data will either get |
2282 ? xnew_array (Bufbyte, string_length (s) + delta + 1) | 2254 freed by us (if it was malloc()ed) or will be reclaimed |
2283 : allocate_string_chars_struct (s, newfullsize)->chars; | 2255 in the normal course of garbage collection. */ |
2284 | 2256 struct string_chars *s_chars = |
2257 allocate_string_chars_struct (s, newfullsize); | |
2258 Bufbyte *new_addr = &(s_chars->chars[0]); | |
2259 Bufbyte *old_addr = string_data (s); | |
2285 if (pos >= 0) | 2260 if (pos >= 0) |
2286 { | 2261 { |
2287 memcpy (new_data, old_data, pos); | 2262 memcpy (new_addr, old_addr, pos); |
2288 memcpy (new_data + pos + delta, old_data + pos, | 2263 memcpy (new_addr + pos + delta, old_addr + pos, |
2289 string_length (s) + 1 - pos); | 2264 string_length (s) + 1 - pos); |
2290 } | 2265 } |
2291 set_string_data (s, new_data); | 2266 set_string_data (s, new_addr); |
2292 | 2267 if (BIG_STRING_FULLSIZE_P (oldfullsize)) |
2293 { | 2268 xfree (old_addr); |
2294 /* We need to mark this chunk of the string_chars_block | 2269 else |
2295 as unused so that compact_string_chars() doesn't | 2270 { |
2296 freak. */ | 2271 /* We need to mark this chunk of the string_chars_block |
2297 struct string_chars *old_s_chars = (struct string_chars *) | 2272 as unused so that compact_string_chars() doesn't |
2298 ((char *) old_data - offsetof (struct string_chars, chars)); | 2273 freak. */ |
2299 /* Sanity check to make sure we aren't hosed by strange | 2274 struct string_chars *old_s_chars = |
2300 alignment/padding. */ | 2275 (struct string_chars *) ((char *) old_addr - |
2301 assert (old_s_chars->string == s); | 2276 sizeof (struct Lisp_String *)); |
2302 MARK_STRUCT_AS_FREE (old_s_chars); | 2277 /* Sanity check to make sure we aren't hosed by strange |
2303 ((struct unused_string_chars *) old_s_chars)->fullsize = | 2278 alignment/padding. */ |
2304 oldfullsize; | 2279 assert (old_s_chars->string == s); |
2305 } | 2280 MARK_STRUCT_AS_FREE (old_s_chars); |
2281 ((struct unused_string_chars *) old_s_chars)->fullsize = | |
2282 oldfullsize; | |
2283 } | |
2306 } | 2284 } |
2307 } | 2285 |
2308 | 2286 set_string_length (s, string_length (s) + delta); |
2309 set_string_length (s, string_length (s) + delta); | 2287 /* If pos < 0, the string won't be zero-terminated. |
2310 /* If pos < 0, the string won't be zero-terminated. | 2288 Terminate now just to make sure. */ |
2311 Terminate now just to make sure. */ | 2289 string_data (s)[string_length (s)] = '\0'; |
2312 string_data (s)[string_length (s)] = '\0'; | 2290 |
2313 | 2291 if (pos >= 0) |
2314 if (pos >= 0) | 2292 { |
2315 { | 2293 Lisp_Object string; |
2316 Lisp_Object string; | 2294 |
2317 | 2295 XSETSTRING (string, s); |
2318 XSETSTRING (string, s); | 2296 /* We also have to adjust all of the extent indices after the |
2319 /* We also have to adjust all of the extent indices after the | 2297 place we did the change. We say "pos - 1" because |
2320 place we did the change. We say "pos - 1" because | 2298 adjust_extents() is exclusive of the starting position |
2321 adjust_extents() is exclusive of the starting position | 2299 passed to it. */ |
2322 passed to it. */ | 2300 adjust_extents (string, pos - 1, string_length (s), |
2323 adjust_extents (string, pos - 1, string_length (s), | 2301 delta); |
2324 delta); | 2302 } |
2325 } | 2303 } |
2326 | 2304 |
2327 #ifdef VERIFY_STRING_CHARS_INTEGRITY | 2305 #ifdef VERIFY_STRING_CHARS_INTEGRITY |
2328 verify_string_chars_integrity (); | 2306 verify_string_chars_integrity (); |
2329 #endif | 2307 #endif |
2912 else if (FLOATP (obj)) | 2890 else if (FLOATP (obj)) |
2913 return make_pure_float (float_data (XFLOAT (obj))); | 2891 return make_pure_float (float_data (XFLOAT (obj))); |
2914 #endif /* LISP_FLOAT_TYPE */ | 2892 #endif /* LISP_FLOAT_TYPE */ |
2915 else if (SYMBOLP (obj)) | 2893 else if (SYMBOLP (obj)) |
2916 { | 2894 { |
2917 int mask = XSYMBOL_OBARRAY_FLAGS (obj); | |
2918 /* | 2895 /* |
2919 * Symbols can't be made pure (and thus read-only), | 2896 * Symbols can't be made pure (and thus read-only), |
2920 * because assigning to their function, value or plist | 2897 * because assigning to their function, value or plist |
2921 * slots would produce a SEGV in the dumped XEmacs. So | 2898 * slots would produced a SEGV in the dumped XEmacs. So |
2922 * we previously would just return the symbol unchanged. | 2899 * we previously would just return the symbol unchanged. |
2923 * | 2900 * |
2924 * But purified aggregate objects like lists and vectors | 2901 * But purified aggregate objects like lists and vectors |
2925 * can contain uninterned symbols. If there are no | 2902 * can contain uninterned symbols. If there are no |
2926 * other non-pure references to the symbol, then the | 2903 * other non-pure references to the symbol, then the |
2931 * that is referenced by a pure object. All such | 2908 * that is referenced by a pure object. All such |
2932 * symbols are stored in the hashtable pointed to by | 2909 * symbols are stored in the hashtable pointed to by |
2933 * Vpure_uninterned_symbol_table, which is itself | 2910 * Vpure_uninterned_symbol_table, which is itself |
2934 * staticpro'd. | 2911 * staticpro'd. |
2935 */ | 2912 */ |
2936 if (!(mask & 1)) | 2913 if (!NILP (XSYMBOL (obj)->obarray)) |
2937 /* Symbol is not interned anywhere. Keep a reference to the | 2914 return obj; |
2938 end of time. */ | 2915 Fputhash (obj, Qnil, Vpure_uninterned_symbol_table); |
2939 Fputhash (obj, Qnil, Vpure_uninterned_symbol_table); | |
2940 | |
2941 /* Mark symbol as being referenced by a pure structure. | |
2942 Funintern() will recognize this mark and place the symbol to | |
2943 Vpure_uninterned_symbol_table at the time of uninterning. */ | |
2944 XSYMBOL (obj)->obarray_flags = mask | 4; | |
2945 | |
2946 return obj; | 2916 return obj; |
2947 } | 2917 } |
2948 else | 2918 else |
2949 signal_simple_error ("Can't purecopy %S", obj); | 2919 signal_simple_error ("Can't purecopy %S", obj); |
2950 } | 2920 } |
4182 if (debug) debug_string_purity_print (p); \ | 4152 if (debug) debug_string_purity_print (p); \ |
4183 } while (0) | 4153 } while (0) |
4184 # define ADDITIONAL_FREE_string(p) \ | 4154 # define ADDITIONAL_FREE_string(p) \ |
4185 do { int size = string_length (p); \ | 4155 do { int size = string_length (p); \ |
4186 if (BIG_STRING_SIZE_P (size)) \ | 4156 if (BIG_STRING_SIZE_P (size)) \ |
4187 xfree (p->_data); \ | 4157 xfree_1 (CHARS_TO_STRING_CHAR (string_data (p))); \ |
4188 } while (0) | 4158 } while (0) |
4189 | 4159 |
4190 #else | 4160 #else |
4191 | 4161 |
4192 # define MARKED_string_P(ptr) XMARKBIT ((ptr)->plist) | 4162 # define MARKED_string_P(ptr) XMARKBIT ((ptr)->plist) |
4202 if (debug) debug_string_purity_print (p); \ | 4172 if (debug) debug_string_purity_print (p); \ |
4203 } while (0) | 4173 } while (0) |
4204 # define ADDITIONAL_FREE_string(p) \ | 4174 # define ADDITIONAL_FREE_string(p) \ |
4205 do { int size = string_length (p); \ | 4175 do { int size = string_length (p); \ |
4206 if (BIG_STRING_SIZE_P (size)) \ | 4176 if (BIG_STRING_SIZE_P (size)) \ |
4207 xfree (p->_data); \ | 4177 xfree_1 (CHARS_TO_STRING_CHAR (string_data (p))); \ |
4208 } while (0) | 4178 } while (0) |
4209 | 4179 |
4210 #endif /* ! LRECORD_STRING */ | 4180 #endif /* ! LRECORD_STRING */ |
4211 | 4181 |
4212 SWEEP_FIXED_TYPE_BLOCK (string, struct Lisp_String); | 4182 SWEEP_FIXED_TYPE_BLOCK (string, struct Lisp_String); |
4340 Vdoc_directory = Qnil; | 4310 Vdoc_directory = Qnil; |
4341 Vconfigure_info_directory = Qnil; | 4311 Vconfigure_info_directory = Qnil; |
4342 Vexec_path = Qnil; | 4312 Vexec_path = Qnil; |
4343 Vload_path = Qnil; | 4313 Vload_path = Qnil; |
4344 /* Vdump_load_path = Qnil; */ | 4314 /* Vdump_load_path = Qnil; */ |
4345 /* Release hash tables for locate_file */ | |
4346 Fset (intern ("early-package-load-path"), Qnil); | |
4347 Fset (intern ("late-package-load-path"), Qnil); | |
4348 Fset (intern ("last-package-load-path"), Qnil); | |
4349 uncache_home_directory(); | 4315 uncache_home_directory(); |
4350 | 4316 |
4351 #if defined(LOADHIST) && !(defined(LOADHIST_DUMPED) || \ | 4317 #if defined(LOADHIST) && !(defined(LOADHIST_DUMPED) || \ |
4352 defined(LOADHIST_BUILTIN)) | 4318 defined(LOADHIST_BUILTIN)) |
4353 Vload_history = Qnil; | 4319 Vload_history = Qnil; |