Mercurial > hg > xemacs-beta
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); |