Mercurial > emacs
comparison src/alloc.c @ 28365:a72abbd8dc16
(mark_maybe_object): New function.
(mark_memory): Use it.
(SETJMP_WILL_LIKELY_WORK, SETJMP_WILL_NOT_WORK): New macros.
(setjmp_tested_p, longjmp_done): New variables.
(test_setjmp): New function.
(mark_stack) [!GC_SETJMP_WORKS]: Call test_setjmp.
(init_alloc): Initialize setjmp_tested_p and longjmp_done.
author | Gerd Moellmann <gerd@gnu.org> |
---|---|
date | Mon, 27 Mar 2000 19:42:47 +0000 |
parents | fd13be8ae190 |
children | 7a3e8a76057b |
comparison
equal
deleted
inserted
replaced
28364:e24d2e75dea0 | 28365:a72abbd8dc16 |
---|---|
294 static int live_string_p P_ ((struct mem_node *, void *)); | 294 static int live_string_p P_ ((struct mem_node *, void *)); |
295 static int live_cons_p P_ ((struct mem_node *, void *)); | 295 static int live_cons_p P_ ((struct mem_node *, void *)); |
296 static int live_symbol_p P_ ((struct mem_node *, void *)); | 296 static int live_symbol_p P_ ((struct mem_node *, void *)); |
297 static int live_float_p P_ ((struct mem_node *, void *)); | 297 static int live_float_p P_ ((struct mem_node *, void *)); |
298 static int live_misc_p P_ ((struct mem_node *, void *)); | 298 static int live_misc_p P_ ((struct mem_node *, void *)); |
299 static void mark_maybe_object P_ ((Lisp_Object)); | |
299 static void mark_memory P_ ((void *, void *)); | 300 static void mark_memory P_ ((void *, void *)); |
300 static void mem_init P_ ((void)); | 301 static void mem_init P_ ((void)); |
301 static struct mem_node *mem_insert P_ ((void *, void *, enum mem_type)); | 302 static struct mem_node *mem_insert P_ ((void *, void *, enum mem_type)); |
302 static void mem_insert_fixup P_ ((struct mem_node *)); | 303 static void mem_insert_fixup P_ ((struct mem_node *)); |
303 static void mem_rotate_left P_ ((struct mem_node *)); | 304 static void mem_rotate_left P_ ((struct mem_node *)); |
2821 } | 2822 } |
2822 | 2823 |
2823 #endif /* GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES */ | 2824 #endif /* GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES */ |
2824 | 2825 |
2825 | 2826 |
2827 /* Mark OBJ if we can prove it's a Lisp_Object. */ | |
2828 | |
2829 static INLINE void | |
2830 mark_maybe_object (obj) | |
2831 Lisp_Object obj; | |
2832 { | |
2833 void *po = (void *) XPNTR (obj); | |
2834 struct mem_node *m = mem_find (po); | |
2835 | |
2836 if (m != MEM_NIL) | |
2837 { | |
2838 int mark_p = 0; | |
2839 | |
2840 switch (XGCTYPE (obj)) | |
2841 { | |
2842 case Lisp_String: | |
2843 mark_p = (live_string_p (m, po) | |
2844 && !STRING_MARKED_P ((struct Lisp_String *) po)); | |
2845 break; | |
2846 | |
2847 case Lisp_Cons: | |
2848 mark_p = (live_cons_p (m, po) | |
2849 && !XMARKBIT (XCONS (obj)->car)); | |
2850 break; | |
2851 | |
2852 case Lisp_Symbol: | |
2853 mark_p = (live_symbol_p (m, po) | |
2854 && !XMARKBIT (XSYMBOL (obj)->plist)); | |
2855 break; | |
2856 | |
2857 case Lisp_Float: | |
2858 mark_p = (live_float_p (m, po) | |
2859 && !XMARKBIT (XFLOAT (obj)->type)); | |
2860 break; | |
2861 | |
2862 case Lisp_Vectorlike: | |
2863 /* Note: can't check GC_BUFFERP before we know it's a | |
2864 buffer because checking that dereferences the pointer | |
2865 PO which might point anywhere. */ | |
2866 if (live_vector_p (m, po)) | |
2867 mark_p = (!GC_SUBRP (obj) | |
2868 && !(XVECTOR (obj)->size & ARRAY_MARK_FLAG)); | |
2869 else if (live_buffer_p (m, po)) | |
2870 mark_p = GC_BUFFERP (obj) && !XMARKBIT (XBUFFER (obj)->name); | |
2871 break; | |
2872 | |
2873 case Lisp_Misc: | |
2874 if (live_misc_p (m, po)) | |
2875 { | |
2876 switch (XMISCTYPE (obj)) | |
2877 { | |
2878 case Lisp_Misc_Marker: | |
2879 mark_p = !XMARKBIT (XMARKER (obj)->chain); | |
2880 break; | |
2881 | |
2882 case Lisp_Misc_Buffer_Local_Value: | |
2883 case Lisp_Misc_Some_Buffer_Local_Value: | |
2884 mark_p = !XMARKBIT (XBUFFER_LOCAL_VALUE (obj)->realvalue); | |
2885 break; | |
2886 | |
2887 case Lisp_Misc_Overlay: | |
2888 mark_p = !XMARKBIT (XOVERLAY (obj)->plist); | |
2889 break; | |
2890 } | |
2891 } | |
2892 break; | |
2893 } | |
2894 | |
2895 if (mark_p) | |
2896 { | |
2897 #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES | |
2898 if (nzombies < MAX_ZOMBIES) | |
2899 zombies[nzombies] = *p; | |
2900 ++nzombies; | |
2901 #endif | |
2902 mark_object (&obj); | |
2903 } | |
2904 } | |
2905 } | |
2906 | |
2826 /* Mark Lisp objects in the address range START..END. */ | 2907 /* Mark Lisp objects in the address range START..END. */ |
2827 | 2908 |
2828 static void | 2909 static void |
2829 mark_memory (start, end) | 2910 mark_memory (start, end) |
2830 void *start, *end; | 2911 void *start, *end; |
2841 { | 2922 { |
2842 void *tem = start; | 2923 void *tem = start; |
2843 start = end; | 2924 start = end; |
2844 end = tem; | 2925 end = tem; |
2845 } | 2926 } |
2846 | 2927 |
2847 for (p = (Lisp_Object *) start; (void *) p < end; ++p) | 2928 for (p = (Lisp_Object *) start; (void *) p < end; ++p) |
2848 { | 2929 mark_maybe_object (*p); |
2849 void *po = (void *) XPNTR (*p); | 2930 } |
2850 struct mem_node *m = mem_find (po); | 2931 |
2851 | 2932 |
2852 if (m != MEM_NIL) | 2933 #if !defined GC_SAVE_REGISTERS_ON_STACK && !defined GC_SETJMP_WORKS |
2934 | |
2935 static int setjmp_tested_p, longjmps_done; | |
2936 | |
2937 #define SETJMP_WILL_LIKELY_WORK "\ | |
2938 \n\ | |
2939 Emacs garbage collector has been changed to use conservative stack\n\ | |
2940 marking. Emacs has determined that the method it uses to do the\n\ | |
2941 marking will likely work on your system, but this isn't sure.\n\ | |
2942 \n\ | |
2943 If you are a system-programmer, or can get the help of a local wizard\n\ | |
2944 who is, please take a look at the function mark_stack in alloc.c, and\n\ | |
2945 verify that the methods used are appropriate for your system.\n\ | |
2946 \n\ | |
2947 Please mail the result to <gerd@gnu.org>.\n\ | |
2948 " | |
2949 | |
2950 #define SETJMP_WILL_NOT_WORK "\ | |
2951 \n\ | |
2952 Emacs garbage collector has been changed to use conservative stack\n\ | |
2953 marking. Emacs has determined that the default method it uses to do the\n\ | |
2954 marking will not work on your system. We will need a system-dependent\n\ | |
2955 solution for your system.\n\ | |
2956 \n\ | |
2957 Please take a look at the function mark_stack in alloc.c, and\n\ | |
2958 try to find a way to make it work on your system.\n\ | |
2959 Please mail the result to <gerd@gnu.org>.\n\ | |
2960 " | |
2961 | |
2962 | |
2963 /* Perform a quick check if it looks like setjmp saves registers in a | |
2964 jmp_buf. Print a message to stderr saying so. When this test | |
2965 succeeds, this is _not_ a proof that setjmp is sufficient for | |
2966 conservative stack marking. Only the sources or a disassembly | |
2967 can prove that. */ | |
2968 | |
2969 static void | |
2970 test_setjmp () | |
2971 { | |
2972 char buf[10]; | |
2973 register int x; | |
2974 jmp_buf jbuf; | |
2975 int result = 0; | |
2976 | |
2977 /* Arrange for X to be put in a register. */ | |
2978 sprintf (buf, "1"); | |
2979 x = strlen (buf); | |
2980 x = 2 * x - 1; | |
2981 | |
2982 setjmp (jbuf); | |
2983 if (longjmps_done == 1) | |
2984 { | |
2985 /* Came here after the longjmp at the end of the function. | |
2986 | |
2987 If x == 1, the longjmp has restored the register to its | |
2988 value before the setjmp, and we can hope that setjmp | |
2989 saves all such registers in the jmp_buf, although that | |
2990 isn't sure. | |
2991 | |
2992 For other values of X, either something really strange is | |
2993 taking place, or the setjmp just didn't save the register. */ | |
2994 | |
2995 if (x == 1) | |
2996 fprintf (stderr, SETJMP_WILL_LIKELY_WORK); | |
2997 else | |
2853 { | 2998 { |
2854 int mark_p = 0; | 2999 fprintf (stderr, SETJMP_WILL_NOT_WORK); |
2855 | 3000 exit (1); |
2856 switch (XGCTYPE (*p)) | |
2857 { | |
2858 case Lisp_String: | |
2859 mark_p = (live_string_p (m, po) | |
2860 && !STRING_MARKED_P ((struct Lisp_String *) po)); | |
2861 break; | |
2862 | |
2863 case Lisp_Cons: | |
2864 mark_p = (live_cons_p (m, po) | |
2865 && !XMARKBIT (XCONS (*p)->car)); | |
2866 break; | |
2867 | |
2868 case Lisp_Symbol: | |
2869 mark_p = (live_symbol_p (m, po) | |
2870 && !XMARKBIT (XSYMBOL (*p)->plist)); | |
2871 break; | |
2872 | |
2873 case Lisp_Float: | |
2874 mark_p = (live_float_p (m, po) | |
2875 && !XMARKBIT (XFLOAT (*p)->type)); | |
2876 break; | |
2877 | |
2878 case Lisp_Vectorlike: | |
2879 /* Note: can't check GC_BUFFERP before we know it's a | |
2880 buffer because checking that dereferences the pointer | |
2881 PO which might point anywhere. */ | |
2882 if (live_vector_p (m, po)) | |
2883 mark_p = (!GC_SUBRP (*p) | |
2884 && !(XVECTOR (*p)->size & ARRAY_MARK_FLAG)); | |
2885 else if (live_buffer_p (m, po)) | |
2886 mark_p = GC_BUFFERP (*p) && !XMARKBIT (XBUFFER (*p)->name); | |
2887 break; | |
2888 | |
2889 case Lisp_Misc: | |
2890 if (live_misc_p (m, po)) | |
2891 { | |
2892 switch (XMISCTYPE (*p)) | |
2893 { | |
2894 case Lisp_Misc_Marker: | |
2895 mark_p = !XMARKBIT (XMARKER (*p)->chain); | |
2896 break; | |
2897 | |
2898 case Lisp_Misc_Buffer_Local_Value: | |
2899 case Lisp_Misc_Some_Buffer_Local_Value: | |
2900 mark_p = !XMARKBIT (XBUFFER_LOCAL_VALUE (*p)->realvalue); | |
2901 break; | |
2902 | |
2903 case Lisp_Misc_Overlay: | |
2904 mark_p = !XMARKBIT (XOVERLAY (*p)->plist); | |
2905 break; | |
2906 } | |
2907 } | |
2908 break; | |
2909 } | |
2910 | |
2911 if (mark_p) | |
2912 { | |
2913 #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES | |
2914 if (nzombies < MAX_ZOMBIES) | |
2915 zombies[nzombies] = *p; | |
2916 ++nzombies; | |
2917 #endif | |
2918 mark_object (p); | |
2919 } | |
2920 } | 3001 } |
2921 } | 3002 } |
2922 } | 3003 |
3004 ++longjmps_done; | |
3005 x = 2; | |
3006 if (longjmps_done == 1) | |
3007 longjmp (jbuf, 1); | |
3008 } | |
3009 | |
3010 #endif /* not GC_SAVE_REGISTERS_ON_STACK && not GC_SETJMP_WORKS */ | |
2923 | 3011 |
2924 | 3012 |
2925 #if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS | 3013 #if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS |
2926 | 3014 |
2927 /* Abort if anything GCPRO'd doesn't survive the GC. */ | 3015 /* Abort if anything GCPRO'd doesn't survive the GC. */ |
2954 } | 3042 } |
2955 | 3043 |
2956 #endif /* GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES */ | 3044 #endif /* GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES */ |
2957 | 3045 |
2958 | 3046 |
2959 /* Mark live Lisp objects on the C stack. */ | 3047 /* Mark live Lisp objects on the C stack. |
3048 | |
3049 There are several system-dependent problems to consider when | |
3050 porting this to new architectures: | |
3051 | |
3052 Processor Registers | |
3053 | |
3054 We have to mark Lisp objects in CPU registers that can hold local | |
3055 variables or are used to pass parameters. | |
3056 | |
3057 If GC_SAVE_REGISTERS_ON_STACK is defined, it should expand to | |
3058 something that either saves relevant registers on the stack, or | |
3059 calls mark_maybe_object passing it each register's contents. | |
3060 | |
3061 If GC_SAVE_REGISTERS_ON_STACK is not defined, the current | |
3062 implementation assumes that calling setjmp saves registers we need | |
3063 to see in a jmp_buf which itself lies on the stack. This doesn't | |
3064 have to be true! It must be verified for each system, possibly | |
3065 by taking a look at the source code of setjmp. | |
3066 | |
3067 Stack Layout | |
3068 | |
3069 Architectures differ in the way their processor stack is organized. | |
3070 For example, the stack might look like this | |
3071 | |
3072 +----------------+ | |
3073 | Lisp_Object | size = 4 | |
3074 +----------------+ | |
3075 | something else | size = 2 | |
3076 +----------------+ | |
3077 | Lisp_Object | size = 4 | |
3078 +----------------+ | |
3079 | ... | | |
3080 | |
3081 In such a case, not every Lisp_Object will be aligned equally. To | |
3082 find all Lisp_Object on the stack it won't be sufficient to walk | |
3083 the stack in steps of 4 bytes. Instead, two passes will be | |
3084 necessary, one starting at the start of the stack, and a second | |
3085 pass starting at the start of the stack + 2. Likewise, if the | |
3086 minimal alignment of Lisp_Objects on the stack is 1, four passes | |
3087 would be necessary, each one starting with one byte more offset | |
3088 from the stack start. | |
3089 | |
3090 The current code assumes by default that Lisp_Objects are aligned | |
3091 equally on the stack. */ | |
2960 | 3092 |
2961 static void | 3093 static void |
2962 mark_stack () | 3094 mark_stack () |
2963 { | 3095 { |
2964 jmp_buf j; | 3096 jmp_buf j; |
2974 /* Save registers that we need to see on the stack. We need to see | 3106 /* Save registers that we need to see on the stack. We need to see |
2975 registers used to hold register variables and registers used to | 3107 registers used to hold register variables and registers used to |
2976 pass parameters. */ | 3108 pass parameters. */ |
2977 #ifdef GC_SAVE_REGISTERS_ON_STACK | 3109 #ifdef GC_SAVE_REGISTERS_ON_STACK |
2978 GC_SAVE_REGISTERS_ON_STACK (end); | 3110 GC_SAVE_REGISTERS_ON_STACK (end); |
2979 #else | 3111 #else /* not GC_SAVE_REGISTERS_ON_STACK */ |
3112 | |
3113 #ifndef GC_SETJMP_WORKS /* If it hasn't been checked yet that | |
3114 setjmp will definitely work, test it | |
3115 and print a message with the result | |
3116 of the test. */ | |
3117 if (!setjmp_tested_p) | |
3118 { | |
3119 setjmp_tested_p = 1; | |
3120 test_setjmp (); | |
3121 } | |
3122 #endif /* GC_SETJMP_WORKS */ | |
3123 | |
2980 setjmp (j); | 3124 setjmp (j); |
2981 end = stack_grows_down_p ? (char *) &j + sizeof j : (char *) &j; | 3125 end = stack_grows_down_p ? (char *) &j + sizeof j : (char *) &j; |
3126 #endif /* not GC_SAVE_REGISTERS_ON_STACK */ | |
3127 | |
3128 /* This assumes that the stack is a contiguous region in memory. If | |
3129 that's not the case, something has to be done here to iterate | |
3130 over the stack segments. */ | |
3131 #if GC_LISP_OBJECT_ALIGNMENT == 1 | |
3132 mark_memory (stack_base, end); | |
3133 mark_memory ((char *) stack_base + 1, end); | |
3134 mark_memory ((char *) stack_base + 2, end); | |
3135 mark_memory ((char *) stack_base + 3, end); | |
3136 #elif GC_LISP_OBJECT_ALIGNMENT == 2 | |
3137 mark_memory (stack_base, end); | |
3138 mark_memory ((char *) stack_base + 2, end); | |
3139 #else | |
3140 mark_memory (stack_base, end); | |
2982 #endif | 3141 #endif |
2983 | |
2984 /* This assumes that the stack is a contiguous region in memory. If | |
2985 that's not the case, something has to be done here to iterate over | |
2986 the stack segments. */ | |
2987 mark_memory (stack_base, end); | |
2988 | 3142 |
2989 #if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS | 3143 #if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS |
2990 check_gcpros (); | 3144 check_gcpros (); |
2991 #endif | 3145 #endif |
2992 } | 3146 } |
4546 void | 4700 void |
4547 init_alloc () | 4701 init_alloc () |
4548 { | 4702 { |
4549 gcprolist = 0; | 4703 gcprolist = 0; |
4550 byte_stack_list = 0; | 4704 byte_stack_list = 0; |
4705 #if GC_MARK_STACK | |
4706 #if !defined GC_SAVE_REGISTERS_ON_STACK && !defined GC_SETJMP_WORKS | |
4707 setjmp_tested_p = longjmps_done = 0; | |
4708 #endif | |
4709 #endif | |
4551 } | 4710 } |
4552 | 4711 |
4553 void | 4712 void |
4554 syms_of_alloc () | 4713 syms_of_alloc () |
4555 { | 4714 { |