comparison src/alloc.c @ 32692:0343fe9ef3ac

(toplevel) [SYSTEM_MALLOC || DOUG_LEA_MALLOC]: Undef GC_MALLOC_CHECK. (toplevel) [GC_MARK_STACK || GC_MALLOC_CHECK]: Move mem_node structure definition and related variabled to the top of the file. Include this code when GC_MALLOC_CHECK is defined. (lisp_malloc, lisp_free) [GC_MALLOC_CHECK]: Don't register/unregister allocated region. (emacs_blocked_free) [GC_MALLOC_CHECK]: Check if freeing something which isn't allocated. (emacs_blocked_malloc) [GC_MALLOC_CHECK]: Check if returning something which is already in use. (emacs_blocked_realloc) [GC_MALLOC_CHECK]: Likewise. (mem_insert) [GC_MALLOC_CHECK]: Use _malloc_internal. (mem_delete) [GC_MALLOC_CHECK]: Use _free_internal. (init_alloc_once) [GC_MALLOC_CHECK]: Call mem_init.
author Gerd Moellmann <gerd@gnu.org>
date Fri, 20 Oct 2000 15:55:14 +0000
parents 350e0378e6f9
children 52f570fdddce
comparison
equal deleted inserted replaced
32691:14c36c7829ff 32692:0343fe9ef3ac
25 /* Note that this declares bzero on OSF/1. How dumb. */ 25 /* Note that this declares bzero on OSF/1. How dumb. */
26 26
27 #include <signal.h> 27 #include <signal.h>
28 28
29 /* Define this temporarily to hunt a bug. If defined, the size of 29 /* Define this temporarily to hunt a bug. If defined, the size of
30 strings is always recorded in sdata structures so that it can be 30 strings is redundantly recorded in sdata structures so that it can
31 compared to the sizes recorded in Lisp strings. */ 31 be compared to the sizes recorded in Lisp strings. */
32 32
33 #define GC_CHECK_STRING_BYTES 1 33 #define GC_CHECK_STRING_BYTES 1
34
35 /* GC_MALLOC_CHECK defined means perform validity checks of malloc'd
36 memory. Can do this only if using gmalloc.c. */
37
38 #if defined SYSTEM_MALLOC || defined DOUG_LEA_MALLOC
39 #undef GC_MALLOC_CHECK
40 #endif
34 41
35 /* This file is part of the core Lisp implementation, and thus must 42 /* This file is part of the core Lisp implementation, and thus must
36 deal with the real data structures. If the Lisp implementation is 43 deal with the real data structures. If the Lisp implementation is
37 replaced, this file likely will not be used. */ 44 replaced, this file likely will not be used. */
38 45
276 MEM_TYPE_SYMBOL, 283 MEM_TYPE_SYMBOL,
277 MEM_TYPE_FLOAT, 284 MEM_TYPE_FLOAT,
278 MEM_TYPE_VECTOR 285 MEM_TYPE_VECTOR
279 }; 286 };
280 287
281 #if GC_MARK_STACK 288 #if GC_MARK_STACK || defined GC_MALLOC_CHECK
282 289
283 #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES 290 #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
284 #include <stdio.h> /* For fprintf. */ 291 #include <stdio.h> /* For fprintf. */
285 #endif 292 #endif
286 293
287 /* A unique object in pure space used to make some Lisp objects 294 /* A unique object in pure space used to make some Lisp objects
288 on free lists recognizable in O(1). */ 295 on free lists recognizable in O(1). */
289 296
290 Lisp_Object Vdead; 297 Lisp_Object Vdead;
291 298
292 struct mem_node; 299 #ifdef GC_MALLOC_CHECK
300
301 enum mem_type allocated_mem_type;
302 int dont_register_blocks;
303
304 #endif /* GC_MALLOC_CHECK */
305
306 /* A node in the red-black tree describing allocated memory containing
307 Lisp data. Each such block is recorded with its start and end
308 address when it is allocated, and removed from the tree when it
309 is freed.
310
311 A red-black tree is a balanced binary tree with the following
312 properties:
313
314 1. Every node is either red or black.
315 2. Every leaf is black.
316 3. If a node is red, then both of its children are black.
317 4. Every simple path from a node to a descendant leaf contains
318 the same number of black nodes.
319 5. The root is always black.
320
321 When nodes are inserted into the tree, or deleted from the tree,
322 the tree is "fixed" so that these properties are always true.
323
324 A red-black tree with N internal nodes has height at most 2
325 log(N+1). Searches, insertions and deletions are done in O(log N).
326 Please see a text book about data structures for a detailed
327 description of red-black trees. Any book worth its salt should
328 describe them. */
329
330 struct mem_node
331 {
332 struct mem_node *left, *right, *parent;
333
334 /* Start and end of allocated region. */
335 void *start, *end;
336
337 /* Node color. */
338 enum {MEM_BLACK, MEM_RED} color;
339
340 /* Memory type. */
341 enum mem_type type;
342 };
343
344 /* Base address of stack. Set in main. */
345
346 Lisp_Object *stack_base;
347
348 /* Root of the tree describing allocated Lisp memory. */
349
350 static struct mem_node *mem_root;
351
352 /* Sentinel node of the tree. */
353
354 static struct mem_node mem_z;
355 #define MEM_NIL &mem_z
356
293 static POINTER_TYPE *lisp_malloc P_ ((size_t, enum mem_type)); 357 static POINTER_TYPE *lisp_malloc P_ ((size_t, enum mem_type));
294 static void lisp_free P_ ((POINTER_TYPE *)); 358 static void lisp_free P_ ((POINTER_TYPE *));
295 static void mark_stack P_ ((void)); 359 static void mark_stack P_ ((void));
296 static void init_stack P_ ((Lisp_Object *)); 360 static void init_stack P_ ((Lisp_Object *));
297 static int live_vector_p P_ ((struct mem_node *, void *)); 361 static int live_vector_p P_ ((struct mem_node *, void *));
314 378
315 #if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS 379 #if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS
316 static void check_gcpros P_ ((void)); 380 static void check_gcpros P_ ((void));
317 #endif 381 #endif
318 382
319 #endif /* GC_MARK_STACK != 0 */ 383 #endif /* GC_MARK_STACK || GC_MALLOC_CHECK */
320 384
321 /* Recording what needs to be marked for gc. */ 385 /* Recording what needs to be marked for gc. */
322 386
323 struct gcpro *gcprolist; 387 struct gcpro *gcprolist;
324 388
513 enum mem_type type; 577 enum mem_type type;
514 { 578 {
515 register void *val; 579 register void *val;
516 580
517 BLOCK_INPUT; 581 BLOCK_INPUT;
582
583 #ifdef GC_MALLOC_CHECK
584 allocated_mem_type = type;
585 #endif
586
518 val = (void *) malloc (nbytes); 587 val = (void *) malloc (nbytes);
519 588
520 #if GC_MARK_STACK 589 #if GC_MARK_STACK && !defined GC_MALLOC_CHECK
521 if (val && type != MEM_TYPE_NON_LISP) 590 if (val && type != MEM_TYPE_NON_LISP)
522 mem_insert (val, (char *) val + nbytes, type); 591 mem_insert (val, (char *) val + nbytes, type);
523 #endif 592 #endif
524 593
525 UNBLOCK_INPUT; 594 UNBLOCK_INPUT;
526 if (!val && nbytes) 595 if (!val && nbytes)
527 memory_full (); 596 memory_full ();
528 return val; 597 return val;
529 } 598 }
547 lisp_free (block) 616 lisp_free (block)
548 POINTER_TYPE *block; 617 POINTER_TYPE *block;
549 { 618 {
550 BLOCK_INPUT; 619 BLOCK_INPUT;
551 free (block); 620 free (block);
552 #if GC_MARK_STACK 621 #if GC_MARK_STACK && !defined GC_MALLOC_CHECK
553 mem_delete (mem_find (block)); 622 mem_delete (mem_find (block));
554 #endif 623 #endif
555 UNBLOCK_INPUT; 624 UNBLOCK_INPUT;
556 } 625 }
557 626
582 static void 651 static void
583 emacs_blocked_free (ptr) 652 emacs_blocked_free (ptr)
584 void *ptr; 653 void *ptr;
585 { 654 {
586 BLOCK_INPUT; 655 BLOCK_INPUT;
656
657 #ifdef GC_MALLOC_CHECK
658 {
659 struct mem_node *m;
660
661 m = mem_find (ptr);
662 if (m == MEM_NIL || m->start != ptr)
663 {
664 fprintf (stderr,
665 "Freeing `%p' which wasn't allocated with malloc\n", ptr);
666 abort ();
667 }
668 else
669 {
670 /* fprintf (stderr, "free %p...%p (%p)\n", m->start, m->end, ptr); */
671 mem_delete (m);
672 }
673 }
674 #endif /* GC_MALLOC_CHECK */
675
587 __free_hook = old_free_hook; 676 __free_hook = old_free_hook;
588 free (ptr); 677 free (ptr);
678
589 /* If we released our reserve (due to running out of memory), 679 /* If we released our reserve (due to running out of memory),
590 and we have a fair amount free once again, 680 and we have a fair amount free once again,
591 try to set aside another reserve in case we run out once more. */ 681 try to set aside another reserve in case we run out once more. */
592 if (spare_memory == 0 682 if (spare_memory == 0
593 /* Verify there is enough space that even with the malloc 683 /* Verify there is enough space that even with the malloc
630 #ifdef DOUG_LEA_MALLOC 720 #ifdef DOUG_LEA_MALLOC
631 mallopt (M_TOP_PAD, malloc_hysteresis * 4096); 721 mallopt (M_TOP_PAD, malloc_hysteresis * 4096);
632 #else 722 #else
633 __malloc_extra_blocks = malloc_hysteresis; 723 __malloc_extra_blocks = malloc_hysteresis;
634 #endif 724 #endif
725
635 value = (void *) malloc (size); 726 value = (void *) malloc (size);
727
728 #ifdef GC_MALLOC_CHECK
729 {
730 struct mem_node *m = mem_find (value);
731 if (m != MEM_NIL)
732 {
733 fprintf (stderr, "Malloc returned %p which is already in use\n",
734 value);
735 fprintf (stderr, "Region in use is %p...%p, %u bytes, type %d\n",
736 m->start, m->end, (char *) m->end - (char *) m->start,
737 m->type);
738 abort ();
739 }
740
741 if (!dont_register_blocks)
742 {
743 mem_insert (value, (char *) value + max (1, size), allocated_mem_type);
744 allocated_mem_type = MEM_TYPE_NON_LISP;
745 }
746 }
747 #endif /* GC_MALLOC_CHECK */
748
636 __malloc_hook = emacs_blocked_malloc; 749 __malloc_hook = emacs_blocked_malloc;
637 UNBLOCK_INPUT; 750 UNBLOCK_INPUT;
638 751
752 /* fprintf (stderr, "%p malloc\n", value); */
639 return value; 753 return value;
640 } 754 }
641 755
642 756
643 /* This function is the realloc hook that Emacs uses. */ 757 /* This function is the realloc hook that Emacs uses. */
649 { 763 {
650 void *value; 764 void *value;
651 765
652 BLOCK_INPUT; 766 BLOCK_INPUT;
653 __realloc_hook = old_realloc_hook; 767 __realloc_hook = old_realloc_hook;
768
769 #ifdef GC_MALLOC_CHECK
770 if (ptr)
771 {
772 struct mem_node *m = mem_find (ptr);
773 if (m == MEM_NIL || m->start != ptr)
774 {
775 fprintf (stderr,
776 "Realloc of %p which wasn't allocated with malloc\n",
777 ptr);
778 abort ();
779 }
780
781 mem_delete (m);
782 }
783
784 /* fprintf (stderr, "%p -> realloc\n", ptr); */
785
786 /* Prevent malloc from registering blocks. */
787 dont_register_blocks = 1;
788 #endif /* GC_MALLOC_CHECK */
789
654 value = (void *) realloc (ptr, size); 790 value = (void *) realloc (ptr, size);
791
792 #ifdef GC_MALLOC_CHECK
793 dont_register_blocks = 0;
794
795 {
796 struct mem_node *m = mem_find (value);
797 if (m != MEM_NIL)
798 {
799 fprintf (stderr, "Realloc returns memory that is already in use\n");
800 abort ();
801 }
802
803 /* Can't handle zero size regions in the red-black tree. */
804 mem_insert (value, (char *) value + max (size, 1), MEM_TYPE_NON_LISP);
805 }
806
807 /* fprintf (stderr, "%p <- realloc\n", value); */
808 #endif /* GC_MALLOC_CHECK */
809
655 __realloc_hook = emacs_blocked_realloc; 810 __realloc_hook = emacs_blocked_realloc;
656 UNBLOCK_INPUT; 811 UNBLOCK_INPUT;
657 812
658 return value; 813 return value;
659 } 814 }
2373 2528
2374 /************************************************************************ 2529 /************************************************************************
2375 C Stack Marking 2530 C Stack Marking
2376 ************************************************************************/ 2531 ************************************************************************/
2377 2532
2378 #if GC_MARK_STACK
2379
2380
2381 /* Base address of stack. Set in main. */
2382
2383 Lisp_Object *stack_base;
2384
2385 /* A node in the red-black tree describing allocated memory containing
2386 Lisp data. Each such block is recorded with its start and end
2387 address when it is allocated, and removed from the tree when it
2388 is freed.
2389
2390 A red-black tree is a balanced binary tree with the following
2391 properties:
2392
2393 1. Every node is either red or black.
2394 2. Every leaf is black.
2395 3. If a node is red, then both of its children are black.
2396 4. Every simple path from a node to a descendant leaf contains
2397 the same number of black nodes.
2398 5. The root is always black.
2399
2400 When nodes are inserted into the tree, or deleted from the tree,
2401 the tree is "fixed" so that these properties are always true.
2402
2403 A red-black tree with N internal nodes has height at most 2
2404 log(N+1). Searches, insertions and deletions are done in O(log N).
2405 Please see a text book about data structures for a detailed
2406 description of red-black trees. Any book worth its salt should
2407 describe them. */
2408
2409 struct mem_node
2410 {
2411 struct mem_node *left, *right, *parent;
2412
2413 /* Start and end of allocated region. */
2414 void *start, *end;
2415
2416 /* Node color. */
2417 enum {MEM_BLACK, MEM_RED} color;
2418
2419 /* Memory type. */
2420 enum mem_type type;
2421 };
2422
2423 /* Root of the tree describing allocated Lisp memory. */
2424
2425 static struct mem_node *mem_root;
2426
2427 /* Sentinel node of the tree. */
2428
2429 static struct mem_node mem_z;
2430 #define MEM_NIL &mem_z
2431
2432
2433 /* Initialize this part of alloc.c. */ 2533 /* Initialize this part of alloc.c. */
2434 2534
2435 static void 2535 static void
2436 mem_init () 2536 mem_init ()
2437 { 2537 {
2499 } 2599 }
2500 2600
2501 #endif /* GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS */ 2601 #endif /* GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS */
2502 2602
2503 /* Create a new node. */ 2603 /* Create a new node. */
2604 #ifdef GC_MALLOC_CHECK
2605 x = (struct mem_node *) _malloc_internal (sizeof *x);
2606 if (x == NULL)
2607 abort ();
2608 #else
2504 x = (struct mem_node *) xmalloc (sizeof *x); 2609 x = (struct mem_node *) xmalloc (sizeof *x);
2610 #endif
2505 x->start = start; 2611 x->start = start;
2506 x->end = end; 2612 x->end = end;
2507 x->type = type; 2613 x->type = type;
2508 x->parent = parent; 2614 x->parent = parent;
2509 x->left = x->right = MEM_NIL; 2615 x->left = x->right = MEM_NIL;
2520 else 2626 else
2521 mem_root = x; 2627 mem_root = x;
2522 2628
2523 /* Re-establish red-black tree properties. */ 2629 /* Re-establish red-black tree properties. */
2524 mem_insert_fixup (x); 2630 mem_insert_fixup (x);
2631
2525 return x; 2632 return x;
2526 } 2633 }
2527 2634
2528 2635
2529 /* Re-establish the red-black properties of the tree, and thereby 2636 /* Re-establish the red-black properties of the tree, and thereby
2719 z->type = y->type; 2826 z->type = y->type;
2720 } 2827 }
2721 2828
2722 if (y->color == MEM_BLACK) 2829 if (y->color == MEM_BLACK)
2723 mem_delete_fixup (x); 2830 mem_delete_fixup (x);
2831
2832 #ifdef GC_MALLOC_CHECK
2833 _free_internal (y);
2834 #else
2724 xfree (y); 2835 xfree (y);
2836 #endif
2725 } 2837 }
2726 2838
2727 2839
2728 /* Re-establish the red-black properties of the tree, after a 2840 /* Re-establish the red-black properties of the tree, after a
2729 deletion. */ 2841 deletion. */
2959 return (m->type == MEM_TYPE_BUFFER 3071 return (m->type == MEM_TYPE_BUFFER
2960 && p == m->start 3072 && p == m->start
2961 && !NILP (((struct buffer *) p)->name)); 3073 && !NILP (((struct buffer *) p)->name));
2962 } 3074 }
2963 3075
3076 #if GC_MARK_STACK
2964 3077
2965 #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES 3078 #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
2966 3079
2967 /* Array of objects that are kept alive because the C stack contains 3080 /* Array of objects that are kept alive because the C stack contains
2968 a pattern that looks like a reference to them . */ 3081 a pattern that looks like a reference to them . */
4905 void 5018 void
4906 init_alloc_once () 5019 init_alloc_once ()
4907 { 5020 {
4908 /* Used to do Vpurify_flag = Qt here, but Qt isn't set up yet! */ 5021 /* Used to do Vpurify_flag = Qt here, but Qt isn't set up yet! */
4909 pure_bytes_used = 0; 5022 pure_bytes_used = 0;
4910 #if GC_MARK_STACK 5023 #if GC_MARK_STACK || defined GC_MALLOC_CHECK
4911 mem_init (); 5024 mem_init ();
4912 Vdead = make_pure_string ("DEAD", 4, 4, 0); 5025 Vdead = make_pure_string ("DEAD", 4, 4, 0);
4913 #endif 5026 #endif
4914 #ifdef HAVE_SHM 5027 #ifdef HAVE_SHM
4915 pure_size = PURESIZE; 5028 pure_size = PURESIZE;