comparison src/gc.c @ 5169:6c6d78781d59

cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup -------------------- ChangeLog entries follow: -------------------- src/ChangeLog addition: 2010-03-24 Ben Wing <ben@xemacs.org> * array.h: * array.h (XD_LISP_DYNARR_DESC): * dumper.c (pdump_register_sub): * dumper.c (pdump_store_new_pointer_offsets): * dumper.c (pdump_reloc_one_mc): * elhash.c: * gc.c (lispdesc_one_description_line_size): * gc.c (kkcc_marking): * lrecord.h: * lrecord.h (IF_NEW_GC): * lrecord.h (enum memory_description_type): * lrecord.h (enum data_description_entry_flags): * lrecord.h (struct opaque_convert_functions): Rename XD_LISP_OBJECT_BLOCK_PTR to XD_INLINE_LISP_OBJECT_BLOCK_PTR and document it in lrecord.h. * data.c: * data.c (finish_marking_weak_lists): * data.c (continue_marking_ephemerons): * data.c (finish_marking_ephemerons): * elhash.c (MARK_OBJ): * gc.c: * gc.c (lispdesc_indirect_count_1): * gc.c (struct): * gc.c (kkcc_bt_push): * gc.c (kkcc_gc_stack_push): * gc.c (kkcc_gc_stack_push_lisp_object): * gc.c (kkcc_gc_stack_repush_dirty_object): * gc.c (KKCC_DO_CHECK_FREE): * gc.c (mark_object_maybe_checking_free): * gc.c (mark_struct_contents): * gc.c (mark_lisp_object_block_contents): * gc.c (register_for_finalization): * gc.c (mark_object): * gc.h: * lisp.h: * profile.c: * profile.c (mark_profiling_info_maphash): Clean up KKCC code related to DEBUG_XEMACS. Rename kkcc_backtrace() to kkcc_backtrace_1() and add two params: a `size' arg to control how many stack elements to print and a `detailed' arg to control whether Lisp objects are printed using `debug_print()'. Create front-ends to kkcc_backtrace_1() -- kkcc_detailed_backtrace(), kkcc_short_backtrace(), kkcc_detailed_backtrace_full(), kkcc_short_backtrace_full(), as well as shortened versions kbt(), kbts(), kbtf(), kbtsf() -- to call it with various parameter values. Add an `is_lisp' field to the stack and backtrace structures and use it to keep track of whether an object pushed onto the stack is a Lisp object or a non-Lisp structure; in kkcc_backtrace_1(), don't try to print a non-Lisp structure as a Lisp object. * elhash.c: * extents.c: * file-coding.c: * lrecord.h: * lrecord.h (IF_NEW_GC): * marker.c: * marker.c (Fmarker_buffer): * mule-coding.c: * number.c: * rangetab.c: * specifier.c: New macros IF_OLD_GC(), IF_NEW_GC() to simplify declaration of Lisp objects when a finalizer may exist in one but not the other. Use them appropriately. * extents.c (finalize_extent_info): Don't zero out data->soe and data->extents before trying to free, else we get memory leaks. * lrecord.h (enum lrecord_type): Make the first lrecord type have value 1 not 0 so that 0 remains without implementation and attempts to interpret zeroed memory as a Lisp object will be more obvious. * array.c (Dynarr_free): * device-msw.c (msprinter_delete_device): * device-tty.c (free_tty_device_struct): * device-tty.c (tty_delete_device): * dialog-msw.c (handle_directory_dialog_box): * dialog-x.c: * emacs.c (free_argc_argv): * emodules.c (attempt_module_delete): * file-coding.c (chain_finalize_coding_stream_1): * file-coding.c (chain_finalize_coding_stream): * glyphs-eimage.c: * glyphs-eimage.c (jpeg_instantiate_unwind): * glyphs-eimage.c (gif_instantiate_unwind): * glyphs-eimage.c (png_instantiate_unwind): * glyphs-eimage.c (tiff_instantiate_unwind): * imgproc.c: * imgproc.c (build_EImage_quantable): * insdel.c (uninit_buffer_text): * mule-coding.c (iso2022_finalize_detection_state): * objects-tty.c (tty_finalize_color_instance): * objects-tty.c (tty_finalize_font_instance): * objects-tty.c (tty_font_list): * process.c: * process.c (finalize_process): * redisplay.c (add_propagation_runes): * scrollbar-gtk.c: * scrollbar-gtk.c (gtk_free_scrollbar_instance): * scrollbar-gtk.c (gtk_release_scrollbar_instance): * scrollbar-msw.c: * scrollbar-msw.c (mswindows_free_scrollbar_instance): * scrollbar-msw.c (unshow_that_mofo): * scrollbar-x.c (x_free_scrollbar_instance): * scrollbar-x.c (x_release_scrollbar_instance): * select-x.c: * select-x.c (x_handle_selection_request): * syntax.c: * syntax.c (uninit_buffer_syntax_cache): * text.h (eifree): If possible, whenever we call xfree() on a field in a structure, set the field to 0 afterwards. A lot of code is written so that it checks the value being freed to see if it is non-zero before freeing it -- doing this and setting the value to 0 afterwards ensures (a) we won't try to free twice if the cleanup code is called twice; (b) if the object itself stays around, KKCC won't crash when attempting to mark the freed field. * rangetab.c: Add a finalization method when not NEW_GC to avoid memory leaks. (#### We still get memory leaks when NEW_GC; need to convert gap array to Lisp object).
author Ben Wing <ben@xemacs.org>
date Wed, 24 Mar 2010 01:22:51 -0500
parents cf900a2f1fa3
children 71ee43b8a74d
comparison
equal deleted inserted replaced
5168:cf900a2f1fa3 5169:6c6d78781d59
379 count = * (long *) irdata; 379 count = * (long *) irdata;
380 break; 380 break;
381 default: 381 default:
382 stderr_out ("Unsupported count type : %d (line = %d, code = %ld)\n", 382 stderr_out ("Unsupported count type : %d (line = %d, code = %ld)\n",
383 idesc[line].type, line, (long) code); 383 idesc[line].type, line, (long) code);
384 #if defined(USE_KKCC) && defined(DEBUG_XEMACS) 384 #if defined (USE_KKCC) && defined (DEBUG_XEMACS)
385 if (gc_in_progress) 385 if (gc_in_progress)
386 kkcc_backtrace (); 386 kkcc_detailed_backtrace ();
387 #endif 387 #endif
388 #ifdef PDUMP 388 #ifdef PDUMP
389 if (in_pdump) 389 if (in_pdump)
390 pdump_backtrace (); 390 pdump_backtrace ();
391 #endif 391 #endif
434 case XD_LO_LINK: 434 case XD_LO_LINK:
435 return sizeof (Lisp_Object); 435 return sizeof (Lisp_Object);
436 case XD_OPAQUE_PTR: 436 case XD_OPAQUE_PTR:
437 return sizeof (void *); 437 return sizeof (void *);
438 #ifdef NEW_GC 438 #ifdef NEW_GC
439 case XD_LISP_OBJECT_BLOCK_PTR: 439 case XD_INLINE_LISP_OBJECT_BLOCK_PTR:
440 #endif /* NEW_GC */ 440 #endif /* NEW_GC */
441 case XD_BLOCK_PTR: 441 case XD_BLOCK_PTR:
442 { 442 {
443 EMACS_INT val = lispdesc_indirect_count (desc1->data1, desc, obj); 443 EMACS_INT val = lispdesc_indirect_count (desc1->data1, desc, obj);
444 return val * sizeof (void *); 444 return val * sizeof (void *);
614 typedef struct 614 typedef struct
615 { 615 {
616 void *obj; 616 void *obj;
617 const struct memory_description *desc; 617 const struct memory_description *desc;
618 int pos; 618 int pos;
619 int is_lisp;
619 } kkcc_bt_stack_entry; 620 } kkcc_bt_stack_entry;
620 621
621 static kkcc_bt_stack_entry *kkcc_bt; 622 static kkcc_bt_stack_entry *kkcc_bt;
622 static int kkcc_bt_stack_size; 623 static int kkcc_bt_stack_size;
623 static int kkcc_bt_depth = 0; 624 static int kkcc_bt_depth = 0;
635 kkcc_bt_stack_size); 636 kkcc_bt_stack_size);
636 ABORT (); 637 ABORT ();
637 } 638 }
638 } 639 }
639 640
640 void 641 /* Workhorse backtrace function. Not static because may potentially be
641 kkcc_backtrace (void) 642 called from a debugger. */
643
644 void kkcc_backtrace_1 (int size, int detailed);
645 void
646 kkcc_backtrace_1 (int size, int detailed)
642 { 647 {
643 int i; 648 int i;
644 stderr_out ("KKCC mark stack backtrace :\n"); 649 stderr_out ("KKCC mark stack backtrace :\n");
645 for (i = kkcc_bt_depth - 1; i >= 0; i--) 650 for (i = kkcc_bt_depth - 1; i >= kkcc_bt_depth - size && i >= 0; i--)
646 { 651 {
647 Lisp_Object obj = wrap_pointer_1 (kkcc_bt[i].obj); 652 Lisp_Object obj = wrap_pointer_1 (kkcc_bt[i].obj);
648 stderr_out (" [%d]", i); 653 stderr_out (" [%d] ", i);
649 if ((XRECORD_LHEADER (obj)->type >= lrecord_type_last_built_in_type) 654 if (!kkcc_bt[i].is_lisp)
650 || (!LRECORDP (obj)) 655 stderr_out ("non Lisp Object");
651 || (!XRECORD_LHEADER_IMPLEMENTATION (obj))) 656 else if (!LRECORDP (obj))
657 stderr_out ("Lisp Object, non-record");
658 else if (XRECORD_LHEADER (obj)->type >= lrecord_type_last_built_in_type
659 || (!XRECORD_LHEADER_IMPLEMENTATION (obj)))
660 stderr_out ("WARNING! Bad Lisp Object type %d",
661 XRECORD_LHEADER (obj)->type);
662 else
663 stderr_out ("%s", XRECORD_LHEADER_IMPLEMENTATION (obj)->name);
664 if (detailed && kkcc_bt[i].is_lisp)
652 { 665 {
653 stderr_out (" non Lisp Object"); 666 stderr_out (" ");
654 } 667 debug_print (obj);
655 else
656 {
657 stderr_out (" %s",
658 XRECORD_LHEADER_IMPLEMENTATION (obj)->name);
659 } 668 }
660 stderr_out (" (addr: %p, desc: %p, ", 669 stderr_out (" (addr: %p, desc: %p, ",
661 (void *) kkcc_bt[i].obj, 670 (void *) kkcc_bt[i].obj,
662 (void *) kkcc_bt[i].desc); 671 (void *) kkcc_bt[i].desc);
663 if (kkcc_bt[i].pos >= 0) 672 if (kkcc_bt[i].pos >= 0)
668 else if (kkcc_bt[i].pos == -2) 677 else if (kkcc_bt[i].pos == -2)
669 stderr_out ("dirty object)\n"); 678 stderr_out ("dirty object)\n");
670 } 679 }
671 } 680 }
672 681
682 /* Various front ends onto kkcc_backtrace_1(), meant to be called from
683 a debugger.
684
685 The variants are:
686
687 normal vs _full(): Normal displays up to the topmost 100 items on the
688 stack, whereas full displays all items (even if there are thousands)
689
690 _detailed_() vs _short_(): Detailed here means print out the actual
691 Lisp objects on the stack using debug_print() in addition to their type,
692 whereas short means only show the type
693 */
694
695 void
696 kkcc_detailed_backtrace (void)
697 {
698 kkcc_backtrace_1 (100, 1);
699 }
700
701 void kkcc_short_backtrace (void);
702 void
703 kkcc_short_backtrace (void)
704 {
705 kkcc_backtrace_1 (100, 0);
706 }
707
708 void kkcc_detailed_backtrace_full (void);
709 void
710 kkcc_detailed_backtrace_full (void)
711 {
712 kkcc_backtrace_1 (kkcc_bt_depth, 1);
713 }
714
715 void kkcc_short_backtrace_full (void);
716 void
717 kkcc_short_backtrace_full (void)
718 {
719 kkcc_backtrace_1 (kkcc_bt_depth, 0);
720 }
721
722 /* Short versions for ease in calling from a debugger */
723
724 void kbt (void);
725 void
726 kbt (void)
727 {
728 kkcc_detailed_backtrace ();
729 }
730
731 void kbts (void);
732 void
733 kbts (void)
734 {
735 kkcc_short_backtrace ();
736 }
737
738 void kbtf (void);
739 void
740 kbtf (void)
741 {
742 kkcc_detailed_backtrace_full ();
743 }
744
745 void kbtsf (void);
746 void
747 kbtsf (void)
748 {
749 kkcc_short_backtrace_full ();
750 }
751
673 static void 752 static void
674 kkcc_bt_stack_realloc (void) 753 kkcc_bt_stack_realloc (void)
675 { 754 {
676 kkcc_bt_stack_size *= 2; 755 kkcc_bt_stack_size *= 2;
677 kkcc_bt = (kkcc_bt_stack_entry *) 756 kkcc_bt = (kkcc_bt_stack_entry *)
691 kkcc_bt = 0; 770 kkcc_bt = 0;
692 kkcc_bt_stack_size = 0; 771 kkcc_bt_stack_size = 0;
693 } 772 }
694 773
695 static void 774 static void
696 kkcc_bt_push (void *obj, const struct memory_description *desc, 775 kkcc_bt_push (void *obj, const struct memory_description *desc,
697 int level, int pos) 776 int is_lisp DECLARE_KKCC_DEBUG_ARGS)
698 { 777 {
699 kkcc_bt_depth = level; 778 kkcc_bt_depth = level;
700 kkcc_bt[kkcc_bt_depth].obj = obj; 779 kkcc_bt[kkcc_bt_depth].obj = obj;
701 kkcc_bt[kkcc_bt_depth].desc = desc; 780 kkcc_bt[kkcc_bt_depth].desc = desc;
702 kkcc_bt[kkcc_bt_depth].pos = pos; 781 kkcc_bt[kkcc_bt_depth].pos = pos;
782 kkcc_bt[kkcc_bt_depth].is_lisp = is_lisp;
703 kkcc_bt_depth++; 783 kkcc_bt_depth++;
704 if (kkcc_bt_depth >= kkcc_bt_stack_size) 784 if (kkcc_bt_depth >= kkcc_bt_stack_size)
705 kkcc_bt_stack_realloc (); 785 kkcc_bt_stack_realloc ();
706 } 786 }
707 787
708 #else /* not DEBUG_XEMACS */ 788 #else /* not DEBUG_XEMACS */
709 #define kkcc_bt_init() 789 #define kkcc_bt_init()
710 #define kkcc_bt_push(obj, desc, level, pos) 790 #define kkcc_bt_push(obj, desc)
711 #endif /* not DEBUG_XEMACS */ 791 #endif /* not DEBUG_XEMACS */
712 792
713 /* Object memory descriptions are in the lrecord_implementation structure. 793 /* Object memory descriptions are in the lrecord_implementation structure.
714 But copying them to a parallel array is much more cache-friendly. */ 794 But copying them to a parallel array is much more cache-friendly. */
715 const struct memory_description *lrecord_memory_descriptions[countof (lrecord_implementations_table)]; 795 const struct memory_description *lrecord_memory_descriptions[countof (lrecord_implementations_table)];
722 void *data; 802 void *data;
723 const struct memory_description *desc; 803 const struct memory_description *desc;
724 #ifdef DEBUG_XEMACS 804 #ifdef DEBUG_XEMACS
725 int level; 805 int level;
726 int pos; 806 int pos;
807 int is_lisp;
727 #endif 808 #endif
728 } kkcc_gc_stack_entry; 809 } kkcc_gc_stack_entry;
729 810
730 811
731 static kkcc_gc_stack_entry *kkcc_gc_stack_ptr; 812 static kkcc_gc_stack_entry *kkcc_gc_stack_ptr;
797 } 878 }
798 xfree_1 (old_ptr); 879 xfree_1 (old_ptr);
799 } 880 }
800 881
801 static void 882 static void
802 #ifdef DEBUG_XEMACS 883 kkcc_gc_stack_push (void *data, const struct memory_description *desc
803 kkcc_gc_stack_push_1 (void *data, const struct memory_description *desc, 884 DECLARE_KKCC_DEBUG_ARGS)
804 int level, int pos)
805 #else
806 kkcc_gc_stack_push_1 (void *data, const struct memory_description *desc)
807 #endif
808 { 885 {
809 #ifdef NEW_GC 886 #ifdef NEW_GC
810 GC_STAT_ENQUEUED; 887 GC_STAT_ENQUEUED;
811 #endif /* NEW_GC */ 888 #endif /* NEW_GC */
812 if (KKCC_GC_STACK_FULL) 889 if (KKCC_GC_STACK_FULL)
819 kkcc_gc_stack_ptr[kkcc_gc_stack_rear].pos = pos; 896 kkcc_gc_stack_ptr[kkcc_gc_stack_rear].pos = pos;
820 #endif 897 #endif
821 } 898 }
822 899
823 #ifdef DEBUG_XEMACS 900 #ifdef DEBUG_XEMACS
824 #define kkcc_gc_stack_push(data, desc, level, pos) \ 901
825 kkcc_gc_stack_push_1 (data, desc, level, pos) 902 static inline void
826 #else 903 kkcc_gc_stack_push_0 (void *data, const struct memory_description *desc,
827 #define kkcc_gc_stack_push(data, desc, level, pos) \ 904 int is_lisp DECLARE_KKCC_DEBUG_ARGS)
828 kkcc_gc_stack_push_1 (data, desc) 905 {
829 #endif 906 kkcc_gc_stack_push (data, desc KKCC_DEBUG_ARGS);
907 kkcc_gc_stack_ptr[kkcc_gc_stack_rear].is_lisp = is_lisp;
908 }
909
910 static inline void
911 kkcc_gc_stack_push_lisp (void *data, const struct memory_description *desc
912 DECLARE_KKCC_DEBUG_ARGS)
913 {
914 kkcc_gc_stack_push_0 (data, desc, 1 KKCC_DEBUG_ARGS);
915 }
916
917 static inline void
918 kkcc_gc_stack_push_nonlisp (void *data, const struct memory_description *desc
919 DECLARE_KKCC_DEBUG_ARGS)
920 {
921 kkcc_gc_stack_push_0 (data, desc, 0 KKCC_DEBUG_ARGS);
922 }
923
924 #else /* not DEBUG_XEMACS */
925
926 static inline void
927 kkcc_gc_stack_push_lisp (void *data, const struct memory_description *desc)
928 {
929 kkcc_gc_stack_push (data, desc);
930 }
931
932 static inline void
933 kkcc_gc_stack_push_nonlisp (void *data, const struct memory_description *desc)
934 {
935 kkcc_gc_stack_push (data, desc);
936 }
937
938 #endif /* (not) DEBUG_XEMACS */
830 939
831 static kkcc_gc_stack_entry * 940 static kkcc_gc_stack_entry *
832 kkcc_gc_stack_pop (void) 941 kkcc_gc_stack_pop (void)
833 { 942 {
834 if (KKCC_GC_STACK_EMPTY) 943 if (KKCC_GC_STACK_EMPTY)
848 } 957 }
849 #endif 958 #endif
850 } 959 }
851 960
852 void 961 void
853 #ifdef DEBUG_XEMACS 962 kkcc_gc_stack_push_lisp_object (Lisp_Object obj DECLARE_KKCC_DEBUG_ARGS)
854 kkcc_gc_stack_push_lisp_object_1 (Lisp_Object obj, int level, int pos)
855 #else
856 kkcc_gc_stack_push_lisp_object_1 (Lisp_Object obj)
857 #endif
858 { 963 {
859 if (XTYPE (obj) == Lisp_Type_Record) 964 if (XTYPE (obj) == Lisp_Type_Record)
860 { 965 {
861 struct lrecord_header *lheader = XRECORD_LHEADER (obj); 966 struct lrecord_header *lheader = XRECORD_LHEADER (obj);
862 const struct memory_description *desc; 967 const struct memory_description *desc;
867 #ifdef NEW_GC 972 #ifdef NEW_GC
868 MARK_GREY (lheader); 973 MARK_GREY (lheader);
869 #else /* not NEW_GC */ 974 #else /* not NEW_GC */
870 MARK_RECORD_HEADER (lheader); 975 MARK_RECORD_HEADER (lheader);
871 #endif /* not NEW_GC */ 976 #endif /* not NEW_GC */
872 kkcc_gc_stack_push ((void *) lheader, desc, level, pos); 977 kkcc_gc_stack_push_lisp ((void *) lheader, desc KKCC_DEBUG_ARGS);
873 } 978 }
874 } 979 }
875 } 980 }
876 981
877 #ifdef NEW_GC 982 #ifdef NEW_GC
878 #ifdef DEBUG_XEMACS 983
879 #define kkcc_gc_stack_push_lisp_object(obj, level, pos) \ 984 void
880 kkcc_gc_stack_push_lisp_object_1 (obj, level, pos) 985 kkcc_gc_stack_repush_dirty_object (Lisp_Object obj DECLARE_KKCC_DEBUG_ARGS)
881 #else
882 #define kkcc_gc_stack_push_lisp_object(obj, level, pos) \
883 kkcc_gc_stack_push_lisp_object_1 (obj)
884 #endif
885
886 void
887 #ifdef DEBUG_XEMACS
888 kkcc_gc_stack_repush_dirty_object_1 (Lisp_Object obj, int level, int pos)
889 #else
890 kkcc_gc_stack_repush_dirty_object_1 (Lisp_Object obj)
891 #endif
892 { 986 {
893 if (XTYPE (obj) == Lisp_Type_Record) 987 if (XTYPE (obj) == Lisp_Type_Record)
894 { 988 {
895 struct lrecord_header *lheader = XRECORD_LHEADER (obj); 989 struct lrecord_header *lheader = XRECORD_LHEADER (obj);
896 const struct memory_description *desc; 990 const struct memory_description *desc;
897 GC_STAT_REPUSHED; 991 GC_STAT_REPUSHED;
898 GC_CHECK_LHEADER_INVARIANTS (lheader); 992 GC_CHECK_LHEADER_INVARIANTS (lheader);
899 desc = RECORD_DESCRIPTION (lheader); 993 desc = RECORD_DESCRIPTION (lheader);
900 MARK_GREY (lheader); 994 MARK_GREY (lheader);
901 kkcc_gc_stack_push ((void*) lheader, desc, level, pos); 995 kkcc_gc_stack_push_lisp ((void*) lheader, desc KKCC_DEBUG_ARGS);
902 } 996 }
903 } 997 }
904 #endif /* NEW_GC */ 998 #endif /* NEW_GC */
905 999
906 #ifdef ERROR_CHECK_GC 1000 #ifdef ERROR_CHECK_GC
912 struct lrecord_header *lheader = XRECORD_LHEADER (obj); \ 1006 struct lrecord_header *lheader = XRECORD_LHEADER (obj); \
913 GC_CHECK_NOT_FREE (lheader); \ 1007 GC_CHECK_NOT_FREE (lheader); \
914 } \ 1008 } \
915 } while (0) 1009 } while (0)
916 #else 1010 #else
917 #define KKCC_DO_CHECK_FREE(obj, allow_free) 1011 #define KKCC_DO_CHECK_FREE(obj, allow_free) DO_NOTHING
918 #endif 1012 #endif
919 1013
920 #ifdef ERROR_CHECK_GC 1014 static inline void
921 #ifdef DEBUG_XEMACS 1015 mark_object_maybe_checking_free (Lisp_Object obj, int allow_free
922 static void 1016 DECLARE_KKCC_DEBUG_ARGS)
923 mark_object_maybe_checking_free_1 (Lisp_Object obj, int allow_free,
924 int level, int pos)
925 #else
926 static void
927 mark_object_maybe_checking_free_1 (Lisp_Object obj, int allow_free)
928 #endif
929 { 1017 {
930 KKCC_DO_CHECK_FREE (obj, allow_free); 1018 KKCC_DO_CHECK_FREE (obj, allow_free);
931 kkcc_gc_stack_push_lisp_object (obj, level, pos); 1019 kkcc_gc_stack_push_lisp_object (obj KKCC_DEBUG_ARGS);
932 } 1020 }
933
934 #ifdef DEBUG_XEMACS
935 #define mark_object_maybe_checking_free(obj, allow_free, level, pos) \
936 mark_object_maybe_checking_free_1 (obj, allow_free, level, pos)
937 #else
938 #define mark_object_maybe_checking_free(obj, allow_free, level, pos) \
939 mark_object_maybe_checking_free_1 (obj, allow_free)
940 #endif
941 #else /* not ERROR_CHECK_GC */
942 #define mark_object_maybe_checking_free(obj, allow_free, level, pos) \
943 kkcc_gc_stack_push_lisp_object (obj, level, pos)
944 #endif /* not ERROR_CHECK_GC */
945
946 1021
947 /* This function loops all elements of a struct pointer and calls 1022 /* This function loops all elements of a struct pointer and calls
948 mark_with_description with each element. */ 1023 mark_with_description with each element. */
949 static void 1024 static void
950 #ifdef DEBUG_XEMACS 1025 mark_struct_contents (const void *data,
951 mark_struct_contents_1 (const void *data,
952 const struct sized_memory_description *sdesc, 1026 const struct sized_memory_description *sdesc,
953 int count, int level, int pos) 1027 int count DECLARE_KKCC_DEBUG_ARGS)
954 #else
955 mark_struct_contents_1 (const void *data,
956 const struct sized_memory_description *sdesc,
957 int count)
958 #endif
959 { 1028 {
960 int i; 1029 int i;
961 Bytecount elsize; 1030 Bytecount elsize;
962 elsize = lispdesc_block_size (data, sdesc); 1031 elsize = lispdesc_block_size (data, sdesc);
963 1032
964 for (i = 0; i < count; i++) 1033 for (i = 0; i < count; i++)
965 { 1034 {
966 kkcc_gc_stack_push (((char *) data) + elsize * i, sdesc->description, 1035 kkcc_gc_stack_push_nonlisp (((char *) data) + elsize * i,
967 level, pos); 1036 sdesc->description
968 } 1037 KKCC_DEBUG_ARGS);
969 } 1038 }
970 1039 }
971 #ifdef DEBUG_XEMACS
972 #define mark_struct_contents(data, sdesc, count, level, pos) \
973 mark_struct_contents_1 (data, sdesc, count, level, pos)
974 #else
975 #define mark_struct_contents(data, sdesc, count, level, pos) \
976 mark_struct_contents_1 (data, sdesc, count)
977 #endif
978
979 1040
980 #ifdef NEW_GC 1041 #ifdef NEW_GC
981 /* This function loops all elements of a struct pointer and calls 1042 /* This function loops all elements of a struct pointer and calls
982 mark_with_description with each element. */ 1043 mark_with_description with each element. */
983 static void 1044 static void
984 #ifdef DEBUG_XEMACS 1045 mark_lisp_object_block_contents (const void *data,
985 mark_lisp_object_block_contents_1 (const void *data, 1046 const struct sized_memory_description *sdesc,
986 const struct sized_memory_description *sdesc, 1047 int count DECLARE_KKCC_DEBUG_ARGS)
987 int count, int level, int pos)
988 #else
989 mark_lisp_object_block_contents_1 (const void *data,
990 const struct sized_memory_description *sdesc,
991 int count)
992 #endif
993 { 1048 {
994 int i; 1049 int i;
995 Bytecount elsize; 1050 Bytecount elsize;
996 elsize = lispdesc_block_size (data, sdesc); 1051 elsize = lispdesc_block_size (data, sdesc);
997 1052
1005 GC_CHECK_LHEADER_INVARIANTS (lheader); 1060 GC_CHECK_LHEADER_INVARIANTS (lheader);
1006 desc = sdesc->description; 1061 desc = sdesc->description;
1007 if (! MARKED_RECORD_HEADER_P (lheader)) 1062 if (! MARKED_RECORD_HEADER_P (lheader))
1008 { 1063 {
1009 MARK_GREY (lheader); 1064 MARK_GREY (lheader);
1010 kkcc_gc_stack_push ((void *) lheader, desc, level, pos); 1065 kkcc_gc_stack_push_lisp ((void *) lheader, desc KKCC_DEBUG_ARGS);
1011 } 1066 }
1012 } 1067 }
1013 } 1068 }
1014 } 1069 }
1015 1070
1016 #ifdef DEBUG_XEMACS
1017 #define mark_lisp_object_block_contents(data, sdesc, count, level, pos) \
1018 mark_lisp_object_block_contents_1 (data, sdesc, count, level, pos)
1019 #else
1020 #define mark_lisp_object_block_contents(data, sdesc, count, level, pos) \
1021 mark_lisp_object_block_contents_1 (data, sdesc, count)
1022 #endif
1023 #endif /* not NEW_GC */ 1071 #endif /* not NEW_GC */
1024 1072
1025 /* This function implements the KKCC mark algorithm. 1073 /* This function implements the KKCC mark algorithm.
1026 Instead of calling mark_object, all the alive Lisp_Objects are pushed 1074 Instead of calling mark_object, all the alive Lisp_Objects are pushed
1027 on the kkcc_gc_stack. This function processes all elements on the stack 1075 on the kkcc_gc_stack. This function processes all elements on the stack
1044 { 1092 {
1045 data = stack_entry->data; 1093 data = stack_entry->data;
1046 desc = stack_entry->desc; 1094 desc = stack_entry->desc;
1047 #ifdef DEBUG_XEMACS 1095 #ifdef DEBUG_XEMACS
1048 level = stack_entry->level + 1; 1096 level = stack_entry->level + 1;
1097 kkcc_bt_push (data, desc, stack_entry->is_lisp, stack_entry->level,
1098 stack_entry->pos);
1099 #else
1100 kkcc_bt_push (data, desc);
1049 #endif 1101 #endif
1050 kkcc_bt_push (data, desc, stack_entry->level, stack_entry->pos);
1051 1102
1052 #ifdef NEW_GC 1103 #ifdef NEW_GC
1053 /* Mark black if object is currently grey. This first checks, 1104 /* Mark black if object is currently grey. This first checks,
1054 if the object is really allocated on the mc-heap. If it is, 1105 if the object is really allocated on the mc-heap. If it is,
1055 it can be marked black; if it is not, it cannot be marked. */ 1106 it can be marked black; if it is not, it cannot be marked. */
1096 can be used for untagged pointers. They might be NULL, 1147 can be used for untagged pointers. They might be NULL,
1097 though. */ 1148 though. */
1098 if (EQ (*stored_obj, Qnull_pointer)) 1149 if (EQ (*stored_obj, Qnull_pointer))
1099 break; 1150 break;
1100 #ifdef NEW_GC 1151 #ifdef NEW_GC
1101 mark_object_maybe_checking_free (*stored_obj, 0, level, pos); 1152 mark_object_maybe_checking_free (*stored_obj, 0
1153 KKCC_DEBUG_ARGS);
1102 #else /* not NEW_GC */ 1154 #else /* not NEW_GC */
1103 mark_object_maybe_checking_free 1155 mark_object_maybe_checking_free
1104 (*stored_obj, (desc1->flags) & XD_FLAG_FREE_LISP_OBJECT, 1156 (*stored_obj, (desc1->flags) & XD_FLAG_FREE_LISP_OBJECT
1105 level, pos); 1157 KKCC_DEBUG_ARGS);
1106 #endif /* not NEW_GC */ 1158 #endif /* not NEW_GC */
1107 break; 1159 break;
1108 } 1160 }
1109 case XD_LISP_OBJECT_ARRAY: 1161 case XD_LISP_OBJECT_ARRAY:
1110 { 1162 {
1119 1171
1120 if (EQ (*stored_obj, Qnull_pointer)) 1172 if (EQ (*stored_obj, Qnull_pointer))
1121 break; 1173 break;
1122 #ifdef NEW_GC 1174 #ifdef NEW_GC
1123 mark_object_maybe_checking_free 1175 mark_object_maybe_checking_free
1124 (*stored_obj, 0, level, pos); 1176 (*stored_obj, 0 KKCC_DEBUG_ARGS);
1125 #else /* not NEW_GC */ 1177 #else /* not NEW_GC */
1126 mark_object_maybe_checking_free 1178 mark_object_maybe_checking_free
1127 (*stored_obj, (desc1->flags) & XD_FLAG_FREE_LISP_OBJECT, 1179 (*stored_obj, (desc1->flags) & XD_FLAG_FREE_LISP_OBJECT
1128 level, pos); 1180 KKCC_DEBUG_ARGS);
1129 #endif /* not NEW_GC */ 1181 #endif /* not NEW_GC */
1130 } 1182 }
1131 break; 1183 break;
1132 } 1184 }
1133 #ifdef NEW_GC 1185 #ifdef NEW_GC
1134 case XD_LISP_OBJECT_BLOCK_PTR: 1186 case XD_INLINE_LISP_OBJECT_BLOCK_PTR:
1135 { 1187 {
1136 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc, 1188 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc,
1137 data); 1189 data);
1138 const struct sized_memory_description *sdesc = 1190 const struct sized_memory_description *sdesc =
1139 lispdesc_indirect_description (data, desc1->data2.descr); 1191 lispdesc_indirect_description (data, desc1->data2.descr);
1140 const char *dobj = * (const char **) rdata; 1192 const char *dobj = * (const char **) rdata;
1141 if (dobj) 1193 if (dobj)
1142 mark_lisp_object_block_contents 1194 mark_lisp_object_block_contents
1143 (dobj, sdesc, count, level, pos); 1195 (dobj, sdesc, count KKCC_DEBUG_ARGS);
1144 break; 1196 break;
1145 } 1197 }
1146 #endif /* NEW_GC */ 1198 #endif /* NEW_GC */
1147 case XD_BLOCK_PTR: 1199 case XD_BLOCK_PTR:
1148 { 1200 {
1150 data); 1202 data);
1151 const struct sized_memory_description *sdesc = 1203 const struct sized_memory_description *sdesc =
1152 lispdesc_indirect_description (data, desc1->data2.descr); 1204 lispdesc_indirect_description (data, desc1->data2.descr);
1153 const char *dobj = * (const char **) rdata; 1205 const char *dobj = * (const char **) rdata;
1154 if (dobj) 1206 if (dobj)
1155 mark_struct_contents (dobj, sdesc, count, level, pos); 1207 mark_struct_contents (dobj, sdesc, count KKCC_DEBUG_ARGS);
1156 break; 1208 break;
1157 } 1209 }
1158 case XD_BLOCK_ARRAY: 1210 case XD_BLOCK_ARRAY:
1159 { 1211 {
1160 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc, 1212 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc,
1161 data); 1213 data);
1162 const struct sized_memory_description *sdesc = 1214 const struct sized_memory_description *sdesc =
1163 lispdesc_indirect_description (data, desc1->data2.descr); 1215 lispdesc_indirect_description (data, desc1->data2.descr);
1164 1216
1165 mark_struct_contents (rdata, sdesc, count, level, pos); 1217 mark_struct_contents (rdata, sdesc, count KKCC_DEBUG_ARGS);
1166 break; 1218 break;
1167 } 1219 }
1168 case XD_UNION: 1220 case XD_UNION:
1169 case XD_UNION_DYNAMIC_SIZE: 1221 case XD_UNION_DYNAMIC_SIZE:
1170 desc1 = lispdesc_process_xd_union (desc1, desc, data); 1222 desc1 = lispdesc_process_xd_union (desc1, desc, data);
1172 goto union_switcheroo; 1224 goto union_switcheroo;
1173 break; 1225 break;
1174 1226
1175 default: 1227 default:
1176 stderr_out ("Unsupported description type : %d\n", desc1->type); 1228 stderr_out ("Unsupported description type : %d\n", desc1->type);
1177 kkcc_backtrace (); 1229 kkcc_detailed_backtrace ();
1178 ABORT (); 1230 ABORT ();
1179 } 1231 }
1180 } 1232 }
1181 1233
1182 #ifdef NEW_GC 1234 #ifdef NEW_GC
1395 rest = rest->next; 1447 rest = rest->next;
1396 } 1448 }
1397 } 1449 }
1398 /* Keep objects alive that need to be finalized by marking 1450 /* Keep objects alive that need to be finalized by marking
1399 Vfinalizers_to_run transitively. */ 1451 Vfinalizers_to_run transitively. */
1400 kkcc_gc_stack_push_lisp_object (Vfinalizers_to_run, 0, -1); 1452 kkcc_gc_stack_push_lisp_object_0 (Vfinalizers_to_run);
1401 kkcc_marking (0); 1453 kkcc_marking (0);
1402 } 1454 }
1403 1455
1404 void 1456 void
1405 run_finalizers (void) 1457 run_finalizers (void)
1617 #endif /* NEW_GC */ 1669 #endif /* NEW_GC */
1618 1670
1619 /* Mark all the special slots that serve as the roots of accessibility. */ 1671 /* Mark all the special slots that serve as the roots of accessibility. */
1620 1672
1621 #ifdef USE_KKCC 1673 #ifdef USE_KKCC
1622 # define mark_object(obj) kkcc_gc_stack_push_lisp_object (obj, 0, -1) 1674 # define mark_object(obj) kkcc_gc_stack_push_lisp_object_0 (obj)
1623 #endif /* USE_KKCC */ 1675 #endif /* USE_KKCC */
1624 1676
1625 { /* staticpro() */ 1677 { /* staticpro() */
1626 Lisp_Object **p = Dynarr_begin (staticpros); 1678 Lisp_Object **p = Dynarr_begin (staticpros);
1627 Elemcount len = Dynarr_length (staticpros); 1679 Elemcount len = Dynarr_length (staticpros);