Mercurial > emacs
comparison src/alloc.c @ 20057:612cd201aea5
(gc_sweep): Free memory blocks that contain only unused
objects.
| author | Karl Heuer <kwzh@gnu.org> |
|---|---|
| date | Wed, 15 Oct 1997 23:28:06 +0000 |
| parents | 81957e8b80e2 |
| children | 1dd0bd0749b5 |
comparison
equal
deleted
inserted
replaced
| 20056:dd567e1fddd5 | 20057:612cd201aea5 |
|---|---|
| 2124 compact_strings (); | 2124 compact_strings (); |
| 2125 | 2125 |
| 2126 /* Put all unmarked conses on free list */ | 2126 /* Put all unmarked conses on free list */ |
| 2127 { | 2127 { |
| 2128 register struct cons_block *cblk; | 2128 register struct cons_block *cblk; |
| 2129 struct cons_block **cprev = &cons_block; | |
| 2129 register int lim = cons_block_index; | 2130 register int lim = cons_block_index; |
| 2130 register int num_free = 0, num_used = 0; | 2131 register int num_free = 0, num_used = 0; |
| 2131 | 2132 |
| 2132 cons_free_list = 0; | 2133 cons_free_list = 0; |
| 2133 | 2134 |
| 2134 for (cblk = cons_block; cblk; cblk = cblk->next) | 2135 for (cblk = cons_block; cblk; cblk = *cprev) |
| 2135 { | 2136 { |
| 2136 register int i; | 2137 register int i; |
| 2138 int this_free = 0; | |
| 2137 for (i = 0; i < lim; i++) | 2139 for (i = 0; i < lim; i++) |
| 2138 if (!XMARKBIT (cblk->conses[i].car)) | 2140 if (!XMARKBIT (cblk->conses[i].car)) |
| 2139 { | 2141 { |
| 2140 num_free++; | 2142 num_free++; |
| 2143 this_free++; | |
| 2141 *(struct Lisp_Cons **)&cblk->conses[i].cdr = cons_free_list; | 2144 *(struct Lisp_Cons **)&cblk->conses[i].cdr = cons_free_list; |
| 2142 cons_free_list = &cblk->conses[i]; | 2145 cons_free_list = &cblk->conses[i]; |
| 2143 } | 2146 } |
| 2144 else | 2147 else |
| 2145 { | 2148 { |
| 2146 num_used++; | 2149 num_used++; |
| 2147 XUNMARK (cblk->conses[i].car); | 2150 XUNMARK (cblk->conses[i].car); |
| 2148 } | 2151 } |
| 2149 lim = CONS_BLOCK_SIZE; | 2152 lim = CONS_BLOCK_SIZE; |
| 2153 /* If this block contains only free conses and we have already | |
| 2154 seen more than two blocks worth of free conses then deallocate | |
| 2155 this block. */ | |
| 2156 if (this_free == CONS_BLOCK_SIZE && num_free > 2*CONS_BLOCK_SIZE) | |
| 2157 { | |
| 2158 num_free -= CONS_BLOCK_SIZE; | |
| 2159 *cprev = cblk->next; | |
| 2160 /* Unhook from the free list. */ | |
| 2161 cons_free_list = *(struct Lisp_Cons **) &cblk->conses[0].cdr; | |
| 2162 xfree (cblk); | |
| 2163 } | |
| 2164 else | |
| 2165 cprev = &cblk->next; | |
| 2150 } | 2166 } |
| 2151 total_conses = num_used; | 2167 total_conses = num_used; |
| 2152 total_free_conses = num_free; | 2168 total_free_conses = num_free; |
| 2153 } | 2169 } |
| 2154 | 2170 |
| 2155 #ifdef LISP_FLOAT_TYPE | 2171 #ifdef LISP_FLOAT_TYPE |
| 2156 /* Put all unmarked floats on free list */ | 2172 /* Put all unmarked floats on free list */ |
| 2157 { | 2173 { |
| 2158 register struct float_block *fblk; | 2174 register struct float_block *fblk; |
| 2175 struct float_block **fprev = &float_block; | |
| 2159 register int lim = float_block_index; | 2176 register int lim = float_block_index; |
| 2160 register int num_free = 0, num_used = 0; | 2177 register int num_free = 0, num_used = 0; |
| 2161 | 2178 |
| 2162 float_free_list = 0; | 2179 float_free_list = 0; |
| 2163 | 2180 |
| 2164 for (fblk = float_block; fblk; fblk = fblk->next) | 2181 for (fblk = float_block; fblk; fblk = *fprev) |
| 2165 { | 2182 { |
| 2166 register int i; | 2183 register int i; |
| 2184 int this_free = 0; | |
| 2167 for (i = 0; i < lim; i++) | 2185 for (i = 0; i < lim; i++) |
| 2168 if (!XMARKBIT (fblk->floats[i].type)) | 2186 if (!XMARKBIT (fblk->floats[i].type)) |
| 2169 { | 2187 { |
| 2170 num_free++; | 2188 num_free++; |
| 2189 this_free++; | |
| 2171 *(struct Lisp_Float **)&fblk->floats[i].data = float_free_list; | 2190 *(struct Lisp_Float **)&fblk->floats[i].data = float_free_list; |
| 2172 float_free_list = &fblk->floats[i]; | 2191 float_free_list = &fblk->floats[i]; |
| 2173 } | 2192 } |
| 2174 else | 2193 else |
| 2175 { | 2194 { |
| 2176 num_used++; | 2195 num_used++; |
| 2177 XUNMARK (fblk->floats[i].type); | 2196 XUNMARK (fblk->floats[i].type); |
| 2178 } | 2197 } |
| 2179 lim = FLOAT_BLOCK_SIZE; | 2198 lim = FLOAT_BLOCK_SIZE; |
| 2199 /* If this block contains only free floats and we have already | |
| 2200 seen more than two blocks worth of free floats then deallocate | |
| 2201 this block. */ | |
| 2202 if (this_free == FLOAT_BLOCK_SIZE && num_free > 2*FLOAT_BLOCK_SIZE) | |
| 2203 { | |
| 2204 num_free -= FLOAT_BLOCK_SIZE; | |
| 2205 *fprev = fblk->next; | |
| 2206 /* Unhook from the free list. */ | |
| 2207 float_free_list = *(struct Lisp_Float **) &fblk->floats[0].data; | |
| 2208 xfree (fblk); | |
| 2209 } | |
| 2210 else | |
| 2211 fprev = &fblk->next; | |
| 2180 } | 2212 } |
| 2181 total_floats = num_used; | 2213 total_floats = num_used; |
| 2182 total_free_floats = num_free; | 2214 total_free_floats = num_free; |
| 2183 } | 2215 } |
| 2184 #endif /* LISP_FLOAT_TYPE */ | 2216 #endif /* LISP_FLOAT_TYPE */ |
| 2185 | 2217 |
| 2186 #ifdef USE_TEXT_PROPERTIES | 2218 #ifdef USE_TEXT_PROPERTIES |
| 2187 /* Put all unmarked intervals on free list */ | 2219 /* Put all unmarked intervals on free list */ |
| 2188 { | 2220 { |
| 2189 register struct interval_block *iblk; | 2221 register struct interval_block *iblk; |
| 2222 struct interval_block **iprev = &interval_block; | |
| 2190 register int lim = interval_block_index; | 2223 register int lim = interval_block_index; |
| 2191 register int num_free = 0, num_used = 0; | 2224 register int num_free = 0, num_used = 0; |
| 2192 | 2225 |
| 2193 interval_free_list = 0; | 2226 interval_free_list = 0; |
| 2194 | 2227 |
| 2195 for (iblk = interval_block; iblk; iblk = iblk->next) | 2228 for (iblk = interval_block; iblk; iblk = *iprev) |
| 2196 { | 2229 { |
| 2197 register int i; | 2230 register int i; |
| 2231 int this_free = 0; | |
| 2198 | 2232 |
| 2199 for (i = 0; i < lim; i++) | 2233 for (i = 0; i < lim; i++) |
| 2200 { | 2234 { |
| 2201 if (! XMARKBIT (iblk->intervals[i].plist)) | 2235 if (! XMARKBIT (iblk->intervals[i].plist)) |
| 2202 { | 2236 { |
| 2203 iblk->intervals[i].parent = interval_free_list; | 2237 iblk->intervals[i].parent = interval_free_list; |
| 2204 interval_free_list = &iblk->intervals[i]; | 2238 interval_free_list = &iblk->intervals[i]; |
| 2205 num_free++; | 2239 num_free++; |
| 2240 this_free++; | |
| 2206 } | 2241 } |
| 2207 else | 2242 else |
| 2208 { | 2243 { |
| 2209 num_used++; | 2244 num_used++; |
| 2210 XUNMARK (iblk->intervals[i].plist); | 2245 XUNMARK (iblk->intervals[i].plist); |
| 2211 } | 2246 } |
| 2212 } | 2247 } |
| 2213 lim = INTERVAL_BLOCK_SIZE; | 2248 lim = INTERVAL_BLOCK_SIZE; |
| 2249 /* If this block contains only free intervals and we have already | |
| 2250 seen more than two blocks worth of free intervals then | |
| 2251 deallocate this block. */ | |
| 2252 if (this_free == INTERVAL_BLOCK_SIZE | |
| 2253 && num_free > 2*INTERVAL_BLOCK_SIZE) | |
| 2254 { | |
| 2255 num_free -= INTERVAL_BLOCK_SIZE; | |
| 2256 *iprev = iblk->next; | |
| 2257 /* Unhook from the free list. */ | |
| 2258 interval_free_list = iblk->intervals[0].parent; | |
| 2259 xfree (iblk); | |
| 2260 } | |
| 2261 else | |
| 2262 iprev = &iblk->next; | |
| 2214 } | 2263 } |
| 2215 total_intervals = num_used; | 2264 total_intervals = num_used; |
| 2216 total_free_intervals = num_free; | 2265 total_free_intervals = num_free; |
| 2217 } | 2266 } |
| 2218 #endif /* USE_TEXT_PROPERTIES */ | 2267 #endif /* USE_TEXT_PROPERTIES */ |
| 2219 | 2268 |
| 2220 /* Put all unmarked symbols on free list */ | 2269 /* Put all unmarked symbols on free list */ |
| 2221 { | 2270 { |
| 2222 register struct symbol_block *sblk; | 2271 register struct symbol_block *sblk; |
| 2272 struct symbol_block **sprev = &symbol_block; | |
| 2223 register int lim = symbol_block_index; | 2273 register int lim = symbol_block_index; |
| 2224 register int num_free = 0, num_used = 0; | 2274 register int num_free = 0, num_used = 0; |
| 2225 | 2275 |
| 2226 symbol_free_list = 0; | 2276 symbol_free_list = 0; |
| 2227 | 2277 |
| 2228 for (sblk = symbol_block; sblk; sblk = sblk->next) | 2278 for (sblk = symbol_block; sblk; sblk = *sprev) |
| 2229 { | 2279 { |
| 2230 register int i; | 2280 register int i; |
| 2281 int this_free = 0; | |
| 2231 for (i = 0; i < lim; i++) | 2282 for (i = 0; i < lim; i++) |
| 2232 if (!XMARKBIT (sblk->symbols[i].plist)) | 2283 if (!XMARKBIT (sblk->symbols[i].plist)) |
| 2233 { | 2284 { |
| 2234 *(struct Lisp_Symbol **)&sblk->symbols[i].value = symbol_free_list; | 2285 *(struct Lisp_Symbol **)&sblk->symbols[i].value = symbol_free_list; |
| 2235 symbol_free_list = &sblk->symbols[i]; | 2286 symbol_free_list = &sblk->symbols[i]; |
| 2236 num_free++; | 2287 num_free++; |
| 2288 this_free++; | |
| 2237 } | 2289 } |
| 2238 else | 2290 else |
| 2239 { | 2291 { |
| 2240 num_used++; | 2292 num_used++; |
| 2241 sblk->symbols[i].name | 2293 sblk->symbols[i].name |
| 2242 = XSTRING (*(Lisp_Object *) &sblk->symbols[i].name); | 2294 = XSTRING (*(Lisp_Object *) &sblk->symbols[i].name); |
| 2243 XUNMARK (sblk->symbols[i].plist); | 2295 XUNMARK (sblk->symbols[i].plist); |
| 2244 } | 2296 } |
| 2245 lim = SYMBOL_BLOCK_SIZE; | 2297 lim = SYMBOL_BLOCK_SIZE; |
| 2298 /* If this block contains only free symbols and we have already | |
| 2299 seen more than two blocks worth of free symbols then deallocate | |
| 2300 this block. */ | |
| 2301 if (this_free == SYMBOL_BLOCK_SIZE && num_free > 2*SYMBOL_BLOCK_SIZE) | |
| 2302 { | |
| 2303 num_free -= SYMBOL_BLOCK_SIZE; | |
| 2304 *sprev = sblk->next; | |
| 2305 /* Unhook from the free list. */ | |
| 2306 symbol_free_list = *(struct Lisp_Symbol **)&sblk->symbols[0].value; | |
| 2307 xfree (sblk); | |
| 2308 } | |
| 2309 else | |
| 2310 sprev = &sblk->next; | |
| 2246 } | 2311 } |
| 2247 total_symbols = num_used; | 2312 total_symbols = num_used; |
| 2248 total_free_symbols = num_free; | 2313 total_free_symbols = num_free; |
| 2249 } | 2314 } |
| 2250 | 2315 |
| 2252 /* Put all unmarked markers on free list. | 2317 /* Put all unmarked markers on free list. |
| 2253 Unchain each one first from the buffer it points into, | 2318 Unchain each one first from the buffer it points into, |
| 2254 but only if it's a real marker. */ | 2319 but only if it's a real marker. */ |
| 2255 { | 2320 { |
| 2256 register struct marker_block *mblk; | 2321 register struct marker_block *mblk; |
| 2322 struct marker_block **mprev = &marker_block; | |
| 2257 register int lim = marker_block_index; | 2323 register int lim = marker_block_index; |
| 2258 register int num_free = 0, num_used = 0; | 2324 register int num_free = 0, num_used = 0; |
| 2259 | 2325 |
| 2260 marker_free_list = 0; | 2326 marker_free_list = 0; |
| 2261 | 2327 |
| 2262 for (mblk = marker_block; mblk; mblk = mblk->next) | 2328 for (mblk = marker_block; mblk; mblk = *mprev) |
| 2263 { | 2329 { |
| 2264 register int i; | 2330 register int i; |
| 2331 int this_free = 0; | |
| 2265 EMACS_INT already_free = -1; | 2332 EMACS_INT already_free = -1; |
| 2266 | 2333 |
| 2267 for (i = 0; i < lim; i++) | 2334 for (i = 0; i < lim; i++) |
| 2268 { | 2335 { |
| 2269 Lisp_Object *markword; | 2336 Lisp_Object *markword; |
| 2303 but this might catch bugs faster. */ | 2370 but this might catch bugs faster. */ |
| 2304 mblk->markers[i].u_marker.type = Lisp_Misc_Free; | 2371 mblk->markers[i].u_marker.type = Lisp_Misc_Free; |
| 2305 mblk->markers[i].u_free.chain = marker_free_list; | 2372 mblk->markers[i].u_free.chain = marker_free_list; |
| 2306 marker_free_list = &mblk->markers[i]; | 2373 marker_free_list = &mblk->markers[i]; |
| 2307 num_free++; | 2374 num_free++; |
| 2375 this_free++; | |
| 2308 } | 2376 } |
| 2309 else | 2377 else |
| 2310 { | 2378 { |
| 2311 num_used++; | 2379 num_used++; |
| 2312 if (markword) | 2380 if (markword) |
| 2313 XUNMARK (*markword); | 2381 XUNMARK (*markword); |
| 2314 } | 2382 } |
| 2315 } | 2383 } |
| 2316 lim = MARKER_BLOCK_SIZE; | 2384 lim = MARKER_BLOCK_SIZE; |
| 2385 /* If this block contains only free markers and we have already | |
| 2386 seen more than two blocks worth of free markers then deallocate | |
| 2387 this block. */ | |
| 2388 if (this_free == MARKER_BLOCK_SIZE && num_free > 2*MARKER_BLOCK_SIZE) | |
| 2389 { | |
| 2390 num_free -= MARKER_BLOCK_SIZE; | |
| 2391 *mprev = mblk->next; | |
| 2392 /* Unhook from the free list. */ | |
| 2393 marker_free_list = mblk->markers[0].u_free.chain; | |
| 2394 xfree (mblk); | |
| 2395 } | |
| 2396 else | |
| 2397 mprev = &mblk->next; | |
| 2317 } | 2398 } |
| 2318 | 2399 |
| 2319 total_markers = num_used; | 2400 total_markers = num_used; |
| 2320 total_free_markers = num_free; | 2401 total_free_markers = num_free; |
| 2321 } | 2402 } |
