diff options
| author | Karl Heuer | 1997-10-15 23:28:06 +0000 |
|---|---|---|
| committer | Karl Heuer | 1997-10-15 23:28:06 +0000 |
| commit | 6ca94ac976a2d6447d92f3a042920c31bf3a57cf (patch) | |
| tree | 366ab3f116645e1a7ae5d8ae3243051e50929bb3 /src/alloc.c | |
| parent | 45b94eb2e9e5b87f352e620880b79e71e3104a64 (diff) | |
| download | emacs-6ca94ac976a2d6447d92f3a042920c31bf3a57cf.tar.gz emacs-6ca94ac976a2d6447d92f3a042920c31bf3a57cf.zip | |
(gc_sweep): Free memory blocks that contain only unused
objects.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 91 |
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; |