aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorGerd Moellmann2001-02-28 13:30:02 +0000
committerGerd Moellmann2001-02-28 13:30:02 +0000
commitece93c029103f1ec9c0801370afe260b791b008e (patch)
treec786ed199e24550bd8c6be2eec1ec311a91def97 /src/alloc.c
parent98423852fcb3050bdf43c67f383f9a94ac7d1b86 (diff)
downloademacs-ece93c029103f1ec9c0801370afe260b791b008e.tar.gz
emacs-ece93c029103f1ec9c0801370afe260b791b008e.zip
(toplevel): Include process.h.
(enum mem_type): Add MEM_TYPE_PROCESS, MEM_TYPE_HASH_TABLE, MEM_TYPE_FRAME, MEM_TYPE_WINDOW enumerators. (allocate_vectorlike): Make it a static function. Add parameter TYPE. (allocate_vector, allocate_hash_table, allocate_window) (allocate_frame, allocate_process, allocate_other_vector): New functions. (Fmake_vector): Call allocate_vector instead of allocate_vectorlike. (mark_maybe_pointer): New function. (mark_memory): Also mark Lisp data to which only pointers remain and not Lisp_Objects. (min_heap_address, max_heap_address): New variables. (mem_find): Return MEM_NIL if START is below min_heap_address or above max_heap_address. (mem_insert): Compute min_heap_address and max_heap_address.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c261
1 files changed, 252 insertions, 9 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 4affa42e683..4b473225f5c 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -39,6 +39,7 @@ Boston, MA 02111-1307, USA. */
39 39
40#undef HIDE_LISP_IMPLEMENTATION 40#undef HIDE_LISP_IMPLEMENTATION
41#include "lisp.h" 41#include "lisp.h"
42#include "process.h"
42#include "intervals.h" 43#include "intervals.h"
43#include "puresize.h" 44#include "puresize.h"
44#include "buffer.h" 45#include "buffer.h"
@@ -276,7 +277,14 @@ enum mem_type
276 MEM_TYPE_MISC, 277 MEM_TYPE_MISC,
277 MEM_TYPE_SYMBOL, 278 MEM_TYPE_SYMBOL,
278 MEM_TYPE_FLOAT, 279 MEM_TYPE_FLOAT,
279 MEM_TYPE_VECTOR 280 /* Keep the following vector-like types together, with
281 MEM_TYPE_WINDOW being the last, and MEM_TYPE_VECTOR the
282 first. Or change the code of live_vector_p, for instance. */
283 MEM_TYPE_VECTOR,
284 MEM_TYPE_PROCESS,
285 MEM_TYPE_HASH_TABLE,
286 MEM_TYPE_FRAME,
287 MEM_TYPE_WINDOW
280}; 288};
281 289
282#if GC_MARK_STACK || defined GC_MALLOC_CHECK 290#if GC_MARK_STACK || defined GC_MALLOC_CHECK
@@ -343,12 +351,17 @@ Lisp_Object *stack_base;
343 351
344static struct mem_node *mem_root; 352static struct mem_node *mem_root;
345 353
354/* Lowest and highest known address in the heap. */
355
356static void *min_heap_address, *max_heap_address;
357
346/* Sentinel node of the tree. */ 358/* Sentinel node of the tree. */
347 359
348static struct mem_node mem_z; 360static struct mem_node mem_z;
349#define MEM_NIL &mem_z 361#define MEM_NIL &mem_z
350 362
351static POINTER_TYPE *lisp_malloc P_ ((size_t, enum mem_type)); 363static POINTER_TYPE *lisp_malloc P_ ((size_t, enum mem_type));
364static struct Lisp_Vector *allocate_vectorlike P_ ((EMACS_INT, enum mem_type));
352static void lisp_free P_ ((POINTER_TYPE *)); 365static void lisp_free P_ ((POINTER_TYPE *));
353static void mark_stack P_ ((void)); 366static void mark_stack P_ ((void));
354static void init_stack P_ ((Lisp_Object *)); 367static void init_stack P_ ((Lisp_Object *));
@@ -398,6 +411,7 @@ static POINTER_TYPE *pure_alloc P_ ((size_t, int));
398#define ALIGN(SZ, ALIGNMENT) \ 411#define ALIGN(SZ, ALIGNMENT) \
399 (((SZ) + (ALIGNMENT) - 1) & ~((ALIGNMENT) - 1)) 412 (((SZ) + (ALIGNMENT) - 1) & ~((ALIGNMENT) - 1))
400 413
414
401 415
402/************************************************************************ 416/************************************************************************
403 Malloc 417 Malloc
@@ -2195,9 +2209,10 @@ int n_vectors;
2195/* Value is a pointer to a newly allocated Lisp_Vector structure 2209/* Value is a pointer to a newly allocated Lisp_Vector structure
2196 with room for LEN Lisp_Objects. */ 2210 with room for LEN Lisp_Objects. */
2197 2211
2198struct Lisp_Vector * 2212static struct Lisp_Vector *
2199allocate_vectorlike (len) 2213allocate_vectorlike (len, type)
2200 EMACS_INT len; 2214 EMACS_INT len;
2215 enum mem_type type;
2201{ 2216{
2202 struct Lisp_Vector *p; 2217 struct Lisp_Vector *p;
2203 size_t nbytes; 2218 size_t nbytes;
@@ -2210,7 +2225,7 @@ allocate_vectorlike (len)
2210#endif 2225#endif
2211 2226
2212 nbytes = sizeof *p + (len - 1) * sizeof p->contents[0]; 2227 nbytes = sizeof *p + (len - 1) * sizeof p->contents[0];
2213 p = (struct Lisp_Vector *) lisp_malloc (nbytes, MEM_TYPE_VECTOR); 2228 p = (struct Lisp_Vector *) lisp_malloc (nbytes, type);
2214 2229
2215#ifdef DOUG_LEA_MALLOC 2230#ifdef DOUG_LEA_MALLOC
2216 /* Back to a reasonable maximum of mmap'ed areas. */ 2231 /* Back to a reasonable maximum of mmap'ed areas. */
@@ -2228,6 +2243,94 @@ allocate_vectorlike (len)
2228} 2243}
2229 2244
2230 2245
2246/* Allocate a vector with NSLOTS slots. */
2247
2248struct Lisp_Vector *
2249allocate_vector (nslots)
2250 EMACS_INT nslots;
2251{
2252 struct Lisp_Vector *v = allocate_vectorlike (nslots, MEM_TYPE_VECTOR);
2253 v->size = nslots;
2254 return v;
2255}
2256
2257
2258/* Allocate other vector-like structures. */
2259
2260struct Lisp_Hash_Table *
2261allocate_hash_table ()
2262{
2263 EMACS_INT len = VECSIZE (struct Lisp_Hash_Table);
2264 struct Lisp_Vector *v = allocate_vectorlike (len, MEM_TYPE_HASH_TABLE);
2265 EMACS_INT i;
2266
2267 v->size = len;
2268 for (i = 0; i < len; ++i)
2269 v->contents[i] = Qnil;
2270
2271 return (struct Lisp_Hash_Table *) v;
2272}
2273
2274
2275struct window *
2276allocate_window ()
2277{
2278 EMACS_INT len = VECSIZE (struct window);
2279 struct Lisp_Vector *v = allocate_vectorlike (len, MEM_TYPE_WINDOW);
2280 EMACS_INT i;
2281
2282 for (i = 0; i < len; ++i)
2283 v->contents[i] = Qnil;
2284 v->size = len;
2285
2286 return (struct window *) v;
2287}
2288
2289
2290struct frame *
2291allocate_frame ()
2292{
2293 EMACS_INT len = VECSIZE (struct frame);
2294 struct Lisp_Vector *v = allocate_vectorlike (len, MEM_TYPE_FRAME);
2295 EMACS_INT i;
2296
2297 for (i = 0; i < len; ++i)
2298 v->contents[i] = make_number (0);
2299 v->size = len;
2300 return (struct frame *) v;
2301}
2302
2303
2304struct Lisp_Process *
2305allocate_process ()
2306{
2307 EMACS_INT len = VECSIZE (struct Lisp_Process);
2308 struct Lisp_Vector *v = allocate_vectorlike (len, MEM_TYPE_PROCESS);
2309 EMACS_INT i;
2310
2311 for (i = 0; i < len; ++i)
2312 v->contents[i] = Qnil;
2313 v->size = len;
2314
2315 return (struct Lisp_Process *) v;
2316}
2317
2318
2319struct Lisp_Vector *
2320allocate_other_vector (len)
2321 EMACS_INT len;
2322{
2323 struct Lisp_Vector *v = allocate_vectorlike (len, MEM_TYPE_VECTOR);
2324 EMACS_INT i;
2325
2326 for (i = 0; i < len; ++i)
2327 v->contents[i] = Qnil;
2328 v->size = len;
2329
2330 return v;
2331}
2332
2333
2231DEFUN ("make-vector", Fmake_vector, Smake_vector, 2, 2, 0, 2334DEFUN ("make-vector", Fmake_vector, Smake_vector, 2, 2, 0,
2232 "Return a newly created vector of length LENGTH, with each element being INIT.\n\ 2335 "Return a newly created vector of length LENGTH, with each element being INIT.\n\
2233See also the function `vector'.") 2336See also the function `vector'.")
@@ -2242,8 +2345,7 @@ See also the function `vector'.")
2242 CHECK_NATNUM (length, 0); 2345 CHECK_NATNUM (length, 0);
2243 sizei = XFASTINT (length); 2346 sizei = XFASTINT (length);
2244 2347
2245 p = allocate_vectorlike (sizei); 2348 p = allocate_vector (sizei);
2246 p->size = sizei;
2247 for (index = 0; index < sizei; index++) 2349 for (index = 0; index < sizei; index++)
2248 p->contents[index] = init; 2350 p->contents[index] = init;
2249 2351
@@ -2622,6 +2724,9 @@ mem_find (start)
2622{ 2724{
2623 struct mem_node *p; 2725 struct mem_node *p;
2624 2726
2727 if (start < min_heap_address || start > max_heap_address)
2728 return MEM_NIL;
2729
2625 /* Make the search always successful to speed up the loop below. */ 2730 /* Make the search always successful to speed up the loop below. */
2626 mem_z.start = start; 2731 mem_z.start = start;
2627 mem_z.end = (char *) start + 1; 2732 mem_z.end = (char *) start + 1;
@@ -2644,6 +2749,11 @@ mem_insert (start, end, type)
2644{ 2749{
2645 struct mem_node *c, *parent, *x; 2750 struct mem_node *c, *parent, *x;
2646 2751
2752 if (start < min_heap_address)
2753 min_heap_address = start;
2754 if (end > max_heap_address)
2755 max_heap_address = end;
2756
2647 /* See where in the tree a node for START belongs. In this 2757 /* See where in the tree a node for START belongs. In this
2648 particular application, it shouldn't happen that a node is already 2758 particular application, it shouldn't happen that a node is already
2649 present. For debugging purposes, let's check that. */ 2759 present. For debugging purposes, let's check that. */
@@ -3124,7 +3234,9 @@ live_vector_p (m, p)
3124 struct mem_node *m; 3234 struct mem_node *m;
3125 void *p; 3235 void *p;
3126{ 3236{
3127 return m->type == MEM_TYPE_VECTOR && p == m->start; 3237 return (p == m->start
3238 && m->type >= MEM_TYPE_VECTOR
3239 && m->type <= MEM_TYPE_WINDOW);
3128} 3240}
3129 3241
3130 3242
@@ -3276,14 +3388,123 @@ mark_maybe_object (obj)
3276 } 3388 }
3277 } 3389 }
3278} 3390}
3391
3392
3393/* If P points to Lisp data, mark that as live if it isn't already
3394 marked. */
3395
3396static INLINE void
3397mark_maybe_pointer (p)
3398 void *p;
3399{
3400 struct mem_node *m;
3401
3402 /* Quickly rule out some values which can't point to Lisp data. We
3403 assume that Lisp data is aligned on even addresses. */
3404 if ((EMACS_INT) p & 1)
3405 return;
3406
3407 m = mem_find (p);
3408 if (m != MEM_NIL)
3409 {
3410 Lisp_Object obj = Qnil;
3411
3412 switch (m->type)
3413 {
3414 case MEM_TYPE_NON_LISP:
3415 /* NOthing to do; not a pointer to Lisp memory. */
3416 break;
3417
3418 case MEM_TYPE_BUFFER:
3419 if (live_buffer_p (m, p)
3420 && !XMARKBIT (((struct buffer *) p)->name))
3421 XSETVECTOR (obj, p);
3422 break;
3423
3424 case MEM_TYPE_CONS:
3425 if (live_cons_p (m, p)
3426 && !XMARKBIT (((struct Lisp_Cons *) p)->car))
3427 XSETCONS (obj, p);
3428 break;
3279 3429
3280/* Mark Lisp objects in the address range START..END. */ 3430 case MEM_TYPE_STRING:
3431 if (live_string_p (m, p)
3432 && !STRING_MARKED_P ((struct Lisp_String *) p))
3433 XSETSTRING (obj, p);
3434 break;
3435
3436 case MEM_TYPE_MISC:
3437 if (live_misc_p (m, p))
3438 {
3439 Lisp_Object tem;
3440 XSETMISC (tem, p);
3441
3442 switch (XMISCTYPE (tem))
3443 {
3444 case Lisp_Misc_Marker:
3445 if (!XMARKBIT (XMARKER (tem)->chain))
3446 obj = tem;
3447 break;
3448
3449 case Lisp_Misc_Buffer_Local_Value:
3450 case Lisp_Misc_Some_Buffer_Local_Value:
3451 if (!XMARKBIT (XBUFFER_LOCAL_VALUE (tem)->realvalue))
3452 obj = tem;
3453 break;
3454
3455 case Lisp_Misc_Overlay:
3456 if (!XMARKBIT (XOVERLAY (tem)->plist))
3457 obj = tem;
3458 break;
3459 }
3460 }
3461 break;
3462
3463 case MEM_TYPE_SYMBOL:
3464 if (live_symbol_p (m, p)
3465 && !XMARKBIT (((struct Lisp_Symbol *) p)->plist))
3466 XSETSYMBOL (obj, p);
3467 break;
3468
3469 case MEM_TYPE_FLOAT:
3470 if (live_float_p (m, p)
3471 && !XMARKBIT (((struct Lisp_Float *) p)->type))
3472 XSETFLOAT (obj, p);
3473 break;
3474
3475 case MEM_TYPE_VECTOR:
3476 case MEM_TYPE_PROCESS:
3477 case MEM_TYPE_HASH_TABLE:
3478 case MEM_TYPE_FRAME:
3479 case MEM_TYPE_WINDOW:
3480 if (live_vector_p (m, p))
3481 {
3482 Lisp_Object tem;
3483 XSETVECTOR (tem, p);
3484 if (!GC_SUBRP (tem)
3485 && !(XVECTOR (tem)->size & ARRAY_MARK_FLAG))
3486 obj = tem;
3487 }
3488 break;
3489
3490 default:
3491 abort ();
3492 }
3493
3494 if (!GC_NILP (obj))
3495 mark_object (&obj);
3496 }
3497}
3498
3499
3500/* Mark Lisp objects referenced from the address range START..END. */
3281 3501
3282static void 3502static void
3283mark_memory (start, end) 3503mark_memory (start, end)
3284 void *start, *end; 3504 void *start, *end;
3285{ 3505{
3286 Lisp_Object *p; 3506 Lisp_Object *p;
3507 void **pp;
3287 3508
3288#if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES 3509#if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
3289 nzombies = 0; 3510 nzombies = 0;
@@ -3297,9 +3518,31 @@ mark_memory (start, end)
3297 start = end; 3518 start = end;
3298 end = tem; 3519 end = tem;
3299 } 3520 }
3300 3521
3522 /* Mark Lisp_Objects. */
3301 for (p = (Lisp_Object *) start; (void *) p < end; ++p) 3523 for (p = (Lisp_Object *) start; (void *) p < end; ++p)
3302 mark_maybe_object (*p); 3524 mark_maybe_object (*p);
3525
3526 /* Mark Lisp data pointed to. This is necessary because, in some
3527 situations, the C compiler optimizes Lisp objects away, so that
3528 only a pointer to them remains. Example:
3529
3530 DEFUN ("testme", Ftestme, Stestme, 0, 0, 0, "")
3531 ()
3532 {
3533 Lisp_Object obj = build_string ("test");
3534 struct Lisp_String *s = XSTRING (obj);
3535 Fgarbage_collect ();
3536 fprintf (stderr, "test `%s'\n", s->data);
3537 return Qnil;
3538 }
3539
3540 Here, `obj' isn't really used, and the compiler optimizes it
3541 away. The only reference to the life string is through the
3542 pointer `s'. */
3543
3544 for (pp = (void **) start; (void *) pp < end; ++pp)
3545 mark_maybe_pointer (*pp);
3303} 3546}
3304 3547
3305 3548