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;