comparison src/alloc.c @ 361:7347b34c275b r21-1-10

Import from CVS: tag r21-1-10
author cvs
date Mon, 13 Aug 2007 10:58:40 +0200
parents 8bec6624d99b
children 1d62742628b6
comparison
equal deleted inserted replaced
360:0f00b38cfccb 361:7347b34c275b
2082 ALIGNOF (struct Lisp_String *)) 2082 ALIGNOF (struct Lisp_String *))
2083 2083
2084 #define BIG_STRING_FULLSIZE_P(fullsize) ((fullsize) >= STRING_CHARS_BLOCK_SIZE) 2084 #define BIG_STRING_FULLSIZE_P(fullsize) ((fullsize) >= STRING_CHARS_BLOCK_SIZE)
2085 #define BIG_STRING_SIZE_P(size) (BIG_STRING_FULLSIZE_P (STRING_FULLSIZE(size))) 2085 #define BIG_STRING_SIZE_P(size) (BIG_STRING_FULLSIZE_P (STRING_FULLSIZE(size)))
2086 2086
2087 #define CHARS_TO_STRING_CHAR(x) \
2088 ((struct string_chars *) \
2089 (((char *) (x)) - (slot_offset (struct string_chars, chars[0]))))
2090
2091
2092 struct string_chars 2087 struct string_chars
2093 { 2088 {
2094 struct Lisp_String *string; 2089 struct Lisp_String *string;
2095 unsigned char chars[1]; 2090 unsigned char chars[1];
2096 }; 2091 };
2115 allocate_string_chars_struct (struct Lisp_String *string_it_goes_with, 2110 allocate_string_chars_struct (struct Lisp_String *string_it_goes_with,
2116 EMACS_INT fullsize) 2111 EMACS_INT fullsize)
2117 { 2112 {
2118 struct string_chars *s_chars; 2113 struct string_chars *s_chars;
2119 2114
2120 /* Allocate the string's actual data */ 2115 if (fullsize <=
2121 if (BIG_STRING_FULLSIZE_P (fullsize)) 2116 (countof (current_string_chars_block->string_chars)
2122 { 2117 - current_string_chars_block->pos))
2123 s_chars = (struct string_chars *) xmalloc (fullsize);
2124 }
2125 else if (fullsize <=
2126 (countof (current_string_chars_block->string_chars)
2127 - current_string_chars_block->pos))
2128 { 2118 {
2129 /* This string can fit in the current string chars block */ 2119 /* This string can fit in the current string chars block */
2130 s_chars = (struct string_chars *) 2120 s_chars = (struct string_chars *)
2131 (current_string_chars_block->string_chars 2121 (current_string_chars_block->string_chars
2132 + current_string_chars_block->pos); 2122 + current_string_chars_block->pos);
2155 2145
2156 Lisp_Object 2146 Lisp_Object
2157 make_uninit_string (Bytecount length) 2147 make_uninit_string (Bytecount length)
2158 { 2148 {
2159 struct Lisp_String *s; 2149 struct Lisp_String *s;
2160 struct string_chars *s_chars;
2161 EMACS_INT fullsize = STRING_FULLSIZE (length); 2150 EMACS_INT fullsize = STRING_FULLSIZE (length);
2162 Lisp_Object val; 2151 Lisp_Object val;
2163 2152
2164 if ((length < 0) || (fullsize <= 0)) 2153 assert (length >= 0 && fullsize > 0);
2165 abort ();
2166 2154
2167 /* Allocate the string header */ 2155 /* Allocate the string header */
2168 ALLOCATE_FIXED_TYPE (string, struct Lisp_String, s); 2156 ALLOCATE_FIXED_TYPE (string, struct Lisp_String, s);
2169 #ifdef LRECORD_STRING 2157 #ifdef LRECORD_STRING
2170 set_lheader_implementation (&(s->lheader), lrecord_string); 2158 set_lheader_implementation (&(s->lheader), lrecord_string);
2171 #endif 2159 #endif
2172 2160
2173 s_chars = allocate_string_chars_struct (s, fullsize); 2161 set_string_data (s, BIG_STRING_FULLSIZE_P (fullsize)
2174 2162 ? xnew_array (Bufbyte, length + 1)
2175 set_string_data (s, &(s_chars->chars[0])); 2163 : allocate_string_chars_struct (s, fullsize)->chars);
2164
2176 set_string_length (s, length); 2165 set_string_length (s, length);
2177 s->plist = Qnil; 2166 s->plist = Qnil;
2178 2167
2179 set_string_byte (s, length, 0); 2168 set_string_byte (s, length, 0);
2180 2169
2193 */ 2182 */
2194 2183
2195 void 2184 void
2196 resize_string (struct Lisp_String *s, Bytecount pos, Bytecount delta) 2185 resize_string (struct Lisp_String *s, Bytecount pos, Bytecount delta)
2197 { 2186 {
2187 Bytecount oldfullsize, newfullsize;
2198 #ifdef VERIFY_STRING_CHARS_INTEGRITY 2188 #ifdef VERIFY_STRING_CHARS_INTEGRITY
2199 verify_string_chars_integrity (); 2189 verify_string_chars_integrity ();
2200 #endif 2190 #endif
2201 2191
2202 #ifdef ERROR_CHECK_BUFPOS 2192 #ifdef ERROR_CHECK_BUFPOS
2211 if (delta < 0) 2201 if (delta < 0)
2212 assert ((-delta) <= string_length (s)); 2202 assert ((-delta) <= string_length (s));
2213 } 2203 }
2214 #endif /* ERROR_CHECK_BUFPOS */ 2204 #endif /* ERROR_CHECK_BUFPOS */
2215 2205
2216 if (pos >= 0 && delta < 0)
2217 /* If DELTA < 0, the functions below will delete the characters
2218 before POS. We want to delete characters *after* POS, however,
2219 so convert this to the appropriate form. */
2220 pos += -delta;
2221
2222 if (delta == 0) 2206 if (delta == 0)
2223 /* simplest case: no size change. */ 2207 /* simplest case: no size change. */
2224 return; 2208 return;
2225 else 2209
2226 { 2210 if (pos >= 0 && delta < 0)
2227 Bytecount oldfullsize = STRING_FULLSIZE (string_length (s)); 2211 /* If DELTA < 0, the functions below will delete the characters
2228 Bytecount newfullsize = STRING_FULLSIZE (string_length (s) + delta); 2212 before POS. We want to delete characters *after* POS, however,
2229 2213 so convert this to the appropriate form. */
2214 pos += -delta;
2215
2216 oldfullsize = STRING_FULLSIZE (string_length (s));
2217 newfullsize = STRING_FULLSIZE (string_length (s) + delta);
2218
2219 if (BIG_STRING_FULLSIZE_P (oldfullsize))
2220 {
2221 if (BIG_STRING_FULLSIZE_P (newfullsize))
2222 {
2223 /* Both strings are big. We can just realloc().
2224 But careful! If the string is shrinking, we have to
2225 memmove() _before_ realloc(), and if growing, we have to
2226 memmove() _after_ realloc() - otherwise the access is
2227 illegal, and we might crash. */
2228 Bytecount len = string_length (s) + 1 - pos;
2229
2230 if (delta < 0 && pos >= 0)
2231 memmove (string_data (s) + pos + delta, string_data (s) + pos, len);
2232 set_string_data (s, (Bufbyte *) xrealloc (string_data (s),
2233 string_length (s) + delta + 1));
2234 if (delta > 0 && pos >= 0)
2235 memmove (string_data (s) + pos + delta, string_data (s) + pos, len);
2236 }
2237 else /* String has been demoted from BIG_STRING. */
2238 {
2239 Bufbyte *new_data =
2240 allocate_string_chars_struct (s, newfullsize)->chars;
2241 Bufbyte *old_data = string_data (s);
2242
2243 if (pos >= 0)
2244 {
2245 memcpy (new_data, old_data, pos);
2246 memcpy (new_data + pos + delta, old_data + pos,
2247 string_length (s) + 1 - pos);
2248 }
2249 set_string_data (s, new_data);
2250 xfree (old_data);
2251 }
2252 }
2253 else /* old string is small */
2254 {
2230 if (oldfullsize == newfullsize) 2255 if (oldfullsize == newfullsize)
2231 { 2256 {
2232 /* next simplest case; size change but the necessary 2257 /* special case; size change but the necessary
2233 allocation size won't change (up or down; code somewhere 2258 allocation size won't change (up or down; code
2234 depends on there not being any unused allocation space, 2259 somewhere depends on there not being any unused
2235 modulo any alignment constraints). */ 2260 allocation space, modulo any alignment
2236 if (pos >= 0) 2261 constraints). */
2237 {
2238 Bufbyte *addroff = pos + string_data (s);
2239
2240 memmove (addroff + delta, addroff,
2241 /* +1 due to zero-termination. */
2242 string_length (s) + 1 - pos);
2243 }
2244 }
2245 else if (BIG_STRING_FULLSIZE_P (oldfullsize) &&
2246 BIG_STRING_FULLSIZE_P (newfullsize))
2247 {
2248 /* next simplest case; the string is big enough to be malloc()ed
2249 itself, so we just realloc.
2250
2251 It's important not to let the string get below the threshold
2252 for making big strings and still remain malloc()ed; if that
2253 were the case, repeated calls to this function on the same
2254 string could result in memory leakage. */
2255 set_string_data (s, (Bufbyte *) xrealloc (string_data (s),
2256 newfullsize));
2257 if (pos >= 0) 2262 if (pos >= 0)
2258 { 2263 {
2259 Bufbyte *addroff = pos + string_data (s); 2264 Bufbyte *addroff = pos + string_data (s);
2260 2265
2261 memmove (addroff + delta, addroff, 2266 memmove (addroff + delta, addroff,
2263 string_length (s) + 1 - pos); 2268 string_length (s) + 1 - pos);
2264 } 2269 }
2265 } 2270 }
2266 else 2271 else
2267 { 2272 {
2268 /* worst case. We make a new string_chars struct and copy 2273 Bufbyte *old_data = string_data (s);
2269 the string's data into it, inserting/deleting the delta 2274 Bufbyte *new_data =
2270 in the process. The old string data will either get 2275 BIG_STRING_FULLSIZE_P (newfullsize)
2271 freed by us (if it was malloc()ed) or will be reclaimed 2276 ? xnew_array (Bufbyte, string_length (s) + delta + 1)
2272 in the normal course of garbage collection. */ 2277 : allocate_string_chars_struct (s, newfullsize)->chars;
2273 struct string_chars *s_chars = 2278
2274 allocate_string_chars_struct (s, newfullsize);
2275 Bufbyte *new_addr = &(s_chars->chars[0]);
2276 Bufbyte *old_addr = string_data (s);
2277 if (pos >= 0) 2279 if (pos >= 0)
2278 { 2280 {
2279 memcpy (new_addr, old_addr, pos); 2281 memcpy (new_data, old_data, pos);
2280 memcpy (new_addr + pos + delta, old_addr + pos, 2282 memcpy (new_data + pos + delta, old_data + pos,
2281 string_length (s) + 1 - pos); 2283 string_length (s) + 1 - pos);
2282 } 2284 }
2283 set_string_data (s, new_addr); 2285 set_string_data (s, new_data);
2284 if (BIG_STRING_FULLSIZE_P (oldfullsize)) 2286
2285 xfree (old_addr); 2287 {
2286 else 2288 /* We need to mark this chunk of the string_chars_block
2287 { 2289 as unused so that compact_string_chars() doesn't
2288 /* We need to mark this chunk of the string_chars_block 2290 freak. */
2289 as unused so that compact_string_chars() doesn't 2291 struct string_chars *old_s_chars = (struct string_chars *)
2290 freak. */ 2292 ((char *) old_data - offsetof (struct string_chars, chars));
2291 struct string_chars *old_s_chars = 2293 /* Sanity check to make sure we aren't hosed by strange
2292 (struct string_chars *) ((char *) old_addr - 2294 alignment/padding. */
2293 sizeof (struct Lisp_String *)); 2295 assert (old_s_chars->string == s);
2294 /* Sanity check to make sure we aren't hosed by strange 2296 MARK_STRUCT_AS_FREE (old_s_chars);
2295 alignment/padding. */ 2297 ((struct unused_string_chars *) old_s_chars)->fullsize =
2296 assert (old_s_chars->string == s); 2298 oldfullsize;
2297 MARK_STRUCT_AS_FREE (old_s_chars); 2299 }
2298 ((struct unused_string_chars *) old_s_chars)->fullsize =
2299 oldfullsize;
2300 }
2301 } 2300 }
2302 2301 }
2303 set_string_length (s, string_length (s) + delta); 2302
2304 /* If pos < 0, the string won't be zero-terminated. 2303 set_string_length (s, string_length (s) + delta);
2305 Terminate now just to make sure. */ 2304 /* If pos < 0, the string won't be zero-terminated.
2306 string_data (s)[string_length (s)] = '\0'; 2305 Terminate now just to make sure. */
2307 2306 string_data (s)[string_length (s)] = '\0';
2308 if (pos >= 0) 2307
2309 { 2308 if (pos >= 0)
2310 Lisp_Object string; 2309 {
2311 2310 Lisp_Object string;
2312 XSETSTRING (string, s); 2311
2313 /* We also have to adjust all of the extent indices after the 2312 XSETSTRING (string, s);
2314 place we did the change. We say "pos - 1" because 2313 /* We also have to adjust all of the extent indices after the
2315 adjust_extents() is exclusive of the starting position 2314 place we did the change. We say "pos - 1" because
2316 passed to it. */ 2315 adjust_extents() is exclusive of the starting position
2317 adjust_extents (string, pos - 1, string_length (s), 2316 passed to it. */
2318 delta); 2317 adjust_extents (string, pos - 1, string_length (s),
2319 } 2318 delta);
2320 } 2319 }
2321 2320
2322 #ifdef VERIFY_STRING_CHARS_INTEGRITY 2321 #ifdef VERIFY_STRING_CHARS_INTEGRITY
2323 verify_string_chars_integrity (); 2322 verify_string_chars_integrity ();
2324 #endif 2323 #endif
4177 if (debug) debug_string_purity_print (p); \ 4176 if (debug) debug_string_purity_print (p); \
4178 } while (0) 4177 } while (0)
4179 # define ADDITIONAL_FREE_string(p) \ 4178 # define ADDITIONAL_FREE_string(p) \
4180 do { int size = string_length (p); \ 4179 do { int size = string_length (p); \
4181 if (BIG_STRING_SIZE_P (size)) \ 4180 if (BIG_STRING_SIZE_P (size)) \
4182 xfree_1 (CHARS_TO_STRING_CHAR (string_data (p))); \ 4181 xfree (p->_data); \
4183 } while (0) 4182 } while (0)
4184 4183
4185 #else 4184 #else
4186 4185
4187 # define MARKED_string_P(ptr) XMARKBIT ((ptr)->plist) 4186 # define MARKED_string_P(ptr) XMARKBIT ((ptr)->plist)
4197 if (debug) debug_string_purity_print (p); \ 4196 if (debug) debug_string_purity_print (p); \
4198 } while (0) 4197 } while (0)
4199 # define ADDITIONAL_FREE_string(p) \ 4198 # define ADDITIONAL_FREE_string(p) \
4200 do { int size = string_length (p); \ 4199 do { int size = string_length (p); \
4201 if (BIG_STRING_SIZE_P (size)) \ 4200 if (BIG_STRING_SIZE_P (size)) \
4202 xfree_1 (CHARS_TO_STRING_CHAR (string_data (p))); \ 4201 xfree (p->_data); \
4203 } while (0) 4202 } while (0)
4204 4203
4205 #endif /* ! LRECORD_STRING */ 4204 #endif /* ! LRECORD_STRING */
4206 4205
4207 SWEEP_FIXED_TYPE_BLOCK (string, struct Lisp_String); 4206 SWEEP_FIXED_TYPE_BLOCK (string, struct Lisp_String);