aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKarl Heuer1997-10-15 23:28:06 +0000
committerKarl Heuer1997-10-15 23:28:06 +0000
commit6ca94ac976a2d6447d92f3a042920c31bf3a57cf (patch)
tree366ab3f116645e1a7ae5d8ae3243051e50929bb3 /src
parent45b94eb2e9e5b87f352e620880b79e71e3104a64 (diff)
downloademacs-6ca94ac976a2d6447d92f3a042920c31bf3a57cf.tar.gz
emacs-6ca94ac976a2d6447d92f3a042920c31bf3a57cf.zip
(gc_sweep): Free memory blocks that contain only unused
objects.
Diffstat (limited to 'src')
-rw-r--r--src/alloc.c91
1 files changed, 86 insertions, 5 deletions
diff --git a/src/alloc.c b/src/alloc.c
index e94e76d3fb2..f00e342cdde 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -2126,18 +2126,21 @@ gc_sweep ()
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 }
@@ -2147,6 +2150,19 @@ gc_sweep ()
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;
@@ -2156,18 +2172,21 @@ gc_sweep ()
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 }
@@ -2177,6 +2196,19 @@ gc_sweep ()
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;
@@ -2187,14 +2219,16 @@ gc_sweep ()
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 {
@@ -2203,6 +2237,7 @@ gc_sweep ()
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 {
@@ -2211,6 +2246,20 @@ gc_sweep ()
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;
@@ -2220,20 +2269,23 @@ gc_sweep ()
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 {
@@ -2243,6 +2295,19 @@ gc_sweep ()
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;
@@ -2254,14 +2319,16 @@ gc_sweep ()
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++)
@@ -2305,6 +2372,7 @@ gc_sweep ()
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 {
@@ -2314,6 +2382,19 @@ gc_sweep ()
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;