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 }