diff options
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 267 |
1 files changed, 13 insertions, 254 deletions
diff --git a/src/alloc.c b/src/alloc.c index 91b4c6e1515..3ab2a6e3843 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -69,11 +69,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 69 | static bool valgrind_p; | 69 | static bool valgrind_p; |
| 70 | #endif | 70 | #endif |
| 71 | 71 | ||
| 72 | /* GC_CHECK_MARKED_OBJECTS means do sanity checks on allocated objects. | 72 | /* GC_CHECK_MARKED_OBJECTS means do sanity checks on allocated objects. */ |
| 73 | Doable only if GC_MARK_STACK. */ | ||
| 74 | #if ! GC_MARK_STACK | ||
| 75 | # undef GC_CHECK_MARKED_OBJECTS | ||
| 76 | #endif | ||
| 77 | 73 | ||
| 78 | /* GC_MALLOC_CHECK defined means perform validity checks of malloc'd | 74 | /* GC_MALLOC_CHECK defined means perform validity checks of malloc'd |
| 79 | memory. Can do this only if using gmalloc.c and if not checking | 75 | memory. Can do this only if using gmalloc.c and if not checking |
| @@ -298,8 +294,6 @@ enum mem_type | |||
| 298 | MEM_TYPE_SPARE | 294 | MEM_TYPE_SPARE |
| 299 | }; | 295 | }; |
| 300 | 296 | ||
| 301 | #if GC_MARK_STACK || defined GC_MALLOC_CHECK | ||
| 302 | |||
| 303 | /* A unique object in pure space used to make some Lisp objects | 297 | /* A unique object in pure space used to make some Lisp objects |
| 304 | on free lists recognizable in O(1). */ | 298 | on free lists recognizable in O(1). */ |
| 305 | 299 | ||
| @@ -380,16 +374,10 @@ static void mem_delete (struct mem_node *); | |||
| 380 | static void mem_delete_fixup (struct mem_node *); | 374 | static void mem_delete_fixup (struct mem_node *); |
| 381 | static struct mem_node *mem_find (void *); | 375 | static struct mem_node *mem_find (void *); |
| 382 | 376 | ||
| 383 | #endif /* GC_MARK_STACK || GC_MALLOC_CHECK */ | ||
| 384 | |||
| 385 | #ifndef DEADP | 377 | #ifndef DEADP |
| 386 | # define DEADP(x) 0 | 378 | # define DEADP(x) 0 |
| 387 | #endif | 379 | #endif |
| 388 | 380 | ||
| 389 | /* Recording what needs to be marked for gc. */ | ||
| 390 | |||
| 391 | struct gcpro *gcprolist; | ||
| 392 | |||
| 393 | /* Addresses of staticpro'd variables. Initialize it to a nonzero | 381 | /* Addresses of staticpro'd variables. Initialize it to a nonzero |
| 394 | value; otherwise some compilers put it into BSS. */ | 382 | value; otherwise some compilers put it into BSS. */ |
| 395 | 383 | ||
| @@ -965,7 +953,7 @@ lisp_malloc (size_t nbytes, enum mem_type type) | |||
| 965 | } | 953 | } |
| 966 | #endif | 954 | #endif |
| 967 | 955 | ||
| 968 | #if GC_MARK_STACK && !defined GC_MALLOC_CHECK | 956 | #ifndef GC_MALLOC_CHECK |
| 969 | if (val && type != MEM_TYPE_NON_LISP) | 957 | if (val && type != MEM_TYPE_NON_LISP) |
| 970 | mem_insert (val, (char *) val + nbytes, type); | 958 | mem_insert (val, (char *) val + nbytes, type); |
| 971 | #endif | 959 | #endif |
| @@ -985,7 +973,7 @@ lisp_free (void *block) | |||
| 985 | { | 973 | { |
| 986 | MALLOC_BLOCK_INPUT; | 974 | MALLOC_BLOCK_INPUT; |
| 987 | free (block); | 975 | free (block); |
| 988 | #if GC_MARK_STACK && !defined GC_MALLOC_CHECK | 976 | #ifndef GC_MALLOC_CHECK |
| 989 | mem_delete (mem_find (block)); | 977 | mem_delete (mem_find (block)); |
| 990 | #endif | 978 | #endif |
| 991 | MALLOC_UNBLOCK_INPUT; | 979 | MALLOC_UNBLOCK_INPUT; |
| @@ -1190,7 +1178,7 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) | |||
| 1190 | val = free_ablock; | 1178 | val = free_ablock; |
| 1191 | free_ablock = free_ablock->x.next_free; | 1179 | free_ablock = free_ablock->x.next_free; |
| 1192 | 1180 | ||
| 1193 | #if GC_MARK_STACK && !defined GC_MALLOC_CHECK | 1181 | #ifndef GC_MALLOC_CHECK |
| 1194 | if (type != MEM_TYPE_NON_LISP) | 1182 | if (type != MEM_TYPE_NON_LISP) |
| 1195 | mem_insert (val, (char *) val + nbytes, type); | 1183 | mem_insert (val, (char *) val + nbytes, type); |
| 1196 | #endif | 1184 | #endif |
| @@ -1210,7 +1198,7 @@ lisp_align_free (void *block) | |||
| 1210 | struct ablocks *abase = ABLOCK_ABASE (ablock); | 1198 | struct ablocks *abase = ABLOCK_ABASE (ablock); |
| 1211 | 1199 | ||
| 1212 | MALLOC_BLOCK_INPUT; | 1200 | MALLOC_BLOCK_INPUT; |
| 1213 | #if GC_MARK_STACK && !defined GC_MALLOC_CHECK | 1201 | #ifndef GC_MALLOC_CHECK |
| 1214 | mem_delete (mem_find (block)); | 1202 | mem_delete (mem_find (block)); |
| 1215 | #endif | 1203 | #endif |
| 1216 | /* Put on free list. */ | 1204 | /* Put on free list. */ |
| @@ -2499,9 +2487,7 @@ void | |||
| 2499 | free_cons (struct Lisp_Cons *ptr) | 2487 | free_cons (struct Lisp_Cons *ptr) |
| 2500 | { | 2488 | { |
| 2501 | ptr->u.chain = cons_free_list; | 2489 | ptr->u.chain = cons_free_list; |
| 2502 | #if GC_MARK_STACK | ||
| 2503 | ptr->car = Vdead; | 2490 | ptr->car = Vdead; |
| 2504 | #endif | ||
| 2505 | cons_free_list = ptr; | 2491 | cons_free_list = ptr; |
| 2506 | consing_since_gc -= sizeof *ptr; | 2492 | consing_since_gc -= sizeof *ptr; |
| 2507 | total_free_conses++; | 2493 | total_free_conses++; |
| @@ -2849,7 +2835,7 @@ allocate_vector_block (void) | |||
| 2849 | { | 2835 | { |
| 2850 | struct vector_block *block = xmalloc (sizeof *block); | 2836 | struct vector_block *block = xmalloc (sizeof *block); |
| 2851 | 2837 | ||
| 2852 | #if GC_MARK_STACK && !defined GC_MALLOC_CHECK | 2838 | #ifndef GC_MALLOC_CHECK |
| 2853 | mem_insert (block->data, block->data + VECTOR_BLOCK_BYTES, | 2839 | mem_insert (block->data, block->data + VECTOR_BLOCK_BYTES, |
| 2854 | MEM_TYPE_VECTOR_BLOCK); | 2840 | MEM_TYPE_VECTOR_BLOCK); |
| 2855 | #endif | 2841 | #endif |
| @@ -3058,7 +3044,7 @@ sweep_vectors (void) | |||
| 3058 | if (free_this_block) | 3044 | if (free_this_block) |
| 3059 | { | 3045 | { |
| 3060 | *bprev = block->next; | 3046 | *bprev = block->next; |
| 3061 | #if GC_MARK_STACK && !defined GC_MALLOC_CHECK | 3047 | #ifndef GC_MALLOC_CHECK |
| 3062 | mem_delete (mem_find (block->data)); | 3048 | mem_delete (mem_find (block->data)); |
| 3063 | #endif | 3049 | #endif |
| 3064 | xfree (block); | 3050 | xfree (block); |
| @@ -3772,14 +3758,11 @@ run_finalizer_handler (Lisp_Object args) | |||
| 3772 | static void | 3758 | static void |
| 3773 | run_finalizer_function (Lisp_Object function) | 3759 | run_finalizer_function (Lisp_Object function) |
| 3774 | { | 3760 | { |
| 3775 | struct gcpro gcpro1; | ||
| 3776 | ptrdiff_t count = SPECPDL_INDEX (); | 3761 | ptrdiff_t count = SPECPDL_INDEX (); |
| 3777 | 3762 | ||
| 3778 | GCPRO1 (function); | ||
| 3779 | specbind (Qinhibit_quit, Qt); | 3763 | specbind (Qinhibit_quit, Qt); |
| 3780 | internal_condition_case_1 (call0, function, Qt, run_finalizer_handler); | 3764 | internal_condition_case_1 (call0, function, Qt, run_finalizer_handler); |
| 3781 | unbind_to (count, Qnil); | 3765 | unbind_to (count, Qnil); |
| 3782 | UNGCPRO; | ||
| 3783 | } | 3766 | } |
| 3784 | 3767 | ||
| 3785 | static void | 3768 | static void |
| @@ -3918,8 +3901,6 @@ refill_memory_reserve (void) | |||
| 3918 | C Stack Marking | 3901 | C Stack Marking |
| 3919 | ************************************************************************/ | 3902 | ************************************************************************/ |
| 3920 | 3903 | ||
| 3921 | #if GC_MARK_STACK || defined GC_MALLOC_CHECK | ||
| 3922 | |||
| 3923 | /* Conservative C stack marking requires a method to identify possibly | 3904 | /* Conservative C stack marking requires a method to identify possibly |
| 3924 | live Lisp objects given a pointer value. We do this by keeping | 3905 | live Lisp objects given a pointer value. We do this by keeping |
| 3925 | track of blocks of Lisp data that are allocated in a red-black tree | 3906 | track of blocks of Lisp data that are allocated in a red-black tree |
| @@ -3986,26 +3967,12 @@ mem_insert (void *start, void *end, enum mem_type type) | |||
| 3986 | c = mem_root; | 3967 | c = mem_root; |
| 3987 | parent = NULL; | 3968 | parent = NULL; |
| 3988 | 3969 | ||
| 3989 | #if GC_MARK_STACK != GC_MAKE_GCPROS_NOOPS | ||
| 3990 | |||
| 3991 | while (c != MEM_NIL) | ||
| 3992 | { | ||
| 3993 | if (start >= c->start && start < c->end) | ||
| 3994 | emacs_abort (); | ||
| 3995 | parent = c; | ||
| 3996 | c = start < c->start ? c->left : c->right; | ||
| 3997 | } | ||
| 3998 | |||
| 3999 | #else /* GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS */ | ||
| 4000 | |||
| 4001 | while (c != MEM_NIL) | 3970 | while (c != MEM_NIL) |
| 4002 | { | 3971 | { |
| 4003 | parent = c; | 3972 | parent = c; |
| 4004 | c = start < c->start ? c->left : c->right; | 3973 | c = start < c->start ? c->left : c->right; |
| 4005 | } | 3974 | } |
| 4006 | 3975 | ||
| 4007 | #endif /* GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS */ | ||
| 4008 | |||
| 4009 | /* Create a new node. */ | 3976 | /* Create a new node. */ |
| 4010 | #ifdef GC_MALLOC_CHECK | 3977 | #ifdef GC_MALLOC_CHECK |
| 4011 | x = malloc (sizeof *x); | 3978 | x = malloc (sizeof *x); |
| @@ -4491,62 +4458,6 @@ live_buffer_p (struct mem_node *m, void *p) | |||
| 4491 | && !NILP (((struct buffer *) p)->name_)); | 4458 | && !NILP (((struct buffer *) p)->name_)); |
| 4492 | } | 4459 | } |
| 4493 | 4460 | ||
| 4494 | #endif /* GC_MARK_STACK || defined GC_MALLOC_CHECK */ | ||
| 4495 | |||
| 4496 | #if GC_MARK_STACK | ||
| 4497 | |||
| 4498 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES | ||
| 4499 | |||
| 4500 | /* Currently not used, but may be called from gdb. */ | ||
| 4501 | |||
| 4502 | void dump_zombies (void) EXTERNALLY_VISIBLE; | ||
| 4503 | |||
| 4504 | /* Array of objects that are kept alive because the C stack contains | ||
| 4505 | a pattern that looks like a reference to them. */ | ||
| 4506 | |||
| 4507 | #define MAX_ZOMBIES 10 | ||
| 4508 | static Lisp_Object zombies[MAX_ZOMBIES]; | ||
| 4509 | |||
| 4510 | /* Number of zombie objects. */ | ||
| 4511 | |||
| 4512 | static EMACS_INT nzombies; | ||
| 4513 | |||
| 4514 | /* Number of garbage collections. */ | ||
| 4515 | |||
| 4516 | static EMACS_INT ngcs; | ||
| 4517 | |||
| 4518 | /* Average percentage of zombies per collection. */ | ||
| 4519 | |||
| 4520 | static double avg_zombies; | ||
| 4521 | |||
| 4522 | /* Max. number of live and zombie objects. */ | ||
| 4523 | |||
| 4524 | static EMACS_INT max_live, max_zombies; | ||
| 4525 | |||
| 4526 | /* Average number of live objects per GC. */ | ||
| 4527 | |||
| 4528 | static double avg_live; | ||
| 4529 | |||
| 4530 | DEFUN ("gc-status", Fgc_status, Sgc_status, 0, 0, "", | ||
| 4531 | doc: /* Show information about live and zombie objects. */) | ||
| 4532 | (void) | ||
| 4533 | { | ||
| 4534 | Lisp_Object zombie_list = Qnil; | ||
| 4535 | for (int i = 0; i < min (MAX_ZOMBIES, nzombies); i++) | ||
| 4536 | zombie_list = Fcons (zombies[i], zombie_list); | ||
| 4537 | AUTO_STRING (format, ("%d GCs, avg live/zombies = %.2f/%.2f (%f%%)," | ||
| 4538 | " max %d/%d\nzombies: %S")); | ||
| 4539 | return CALLN (Fmessage, format, | ||
| 4540 | make_number (ngcs), make_float (avg_live), | ||
| 4541 | make_float (avg_zombies), | ||
| 4542 | make_float (avg_zombies / avg_live / 100), | ||
| 4543 | make_number (max_live), make_number (max_zombies), | ||
| 4544 | zombie_list); | ||
| 4545 | } | ||
| 4546 | |||
| 4547 | #endif /* GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES */ | ||
| 4548 | |||
| 4549 | |||
| 4550 | /* Mark OBJ if we can prove it's a Lisp_Object. */ | 4461 | /* Mark OBJ if we can prove it's a Lisp_Object. */ |
| 4551 | 4462 | ||
| 4552 | static void | 4463 | static void |
| @@ -4608,14 +4519,7 @@ mark_maybe_object (Lisp_Object obj) | |||
| 4608 | } | 4519 | } |
| 4609 | 4520 | ||
| 4610 | if (mark_p) | 4521 | if (mark_p) |
| 4611 | { | 4522 | mark_object (obj); |
| 4612 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES | ||
| 4613 | if (nzombies < MAX_ZOMBIES) | ||
| 4614 | zombies[nzombies] = obj; | ||
| 4615 | ++nzombies; | ||
| 4616 | #endif | ||
| 4617 | mark_object (obj); | ||
| 4618 | } | ||
| 4619 | } | 4523 | } |
| 4620 | } | 4524 | } |
| 4621 | 4525 | ||
| @@ -4723,10 +4627,6 @@ mark_memory (void *start, void *end) | |||
| 4723 | void **pp; | 4627 | void **pp; |
| 4724 | int i; | 4628 | int i; |
| 4725 | 4629 | ||
| 4726 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES | ||
| 4727 | nzombies = 0; | ||
| 4728 | #endif | ||
| 4729 | |||
| 4730 | /* Make START the pointer to the start of the memory region, | 4630 | /* Make START the pointer to the start of the memory region, |
| 4731 | if it isn't already. */ | 4631 | if it isn't already. */ |
| 4732 | if (end < start) | 4632 | if (end < start) |
| @@ -4847,42 +4747,6 @@ test_setjmp (void) | |||
| 4847 | #endif /* not GC_SAVE_REGISTERS_ON_STACK && not GC_SETJMP_WORKS */ | 4747 | #endif /* not GC_SAVE_REGISTERS_ON_STACK && not GC_SETJMP_WORKS */ |
| 4848 | 4748 | ||
| 4849 | 4749 | ||
| 4850 | #if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS | ||
| 4851 | |||
| 4852 | /* Abort if anything GCPRO'd doesn't survive the GC. */ | ||
| 4853 | |||
| 4854 | static void | ||
| 4855 | check_gcpros (void) | ||
| 4856 | { | ||
| 4857 | struct gcpro *p; | ||
| 4858 | ptrdiff_t i; | ||
| 4859 | |||
| 4860 | for (p = gcprolist; p; p = p->next) | ||
| 4861 | for (i = 0; i < p->nvars; ++i) | ||
| 4862 | if (!survives_gc_p (p->var[i])) | ||
| 4863 | /* FIXME: It's not necessarily a bug. It might just be that the | ||
| 4864 | GCPRO is unnecessary or should release the object sooner. */ | ||
| 4865 | emacs_abort (); | ||
| 4866 | } | ||
| 4867 | |||
| 4868 | #elif GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES | ||
| 4869 | |||
| 4870 | void | ||
| 4871 | dump_zombies (void) | ||
| 4872 | { | ||
| 4873 | int i; | ||
| 4874 | |||
| 4875 | fprintf (stderr, "\nZombies kept alive = %"pI"d:\n", nzombies); | ||
| 4876 | for (i = 0; i < min (MAX_ZOMBIES, nzombies); ++i) | ||
| 4877 | { | ||
| 4878 | fprintf (stderr, " %d = ", i); | ||
| 4879 | debug_print (zombies[i]); | ||
| 4880 | } | ||
| 4881 | } | ||
| 4882 | |||
| 4883 | #endif /* GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES */ | ||
| 4884 | |||
| 4885 | |||
| 4886 | /* Mark live Lisp objects on the C stack. | 4750 | /* Mark live Lisp objects on the C stack. |
| 4887 | 4751 | ||
| 4888 | There are several system-dependent problems to consider when | 4752 | There are several system-dependent problems to consider when |
| @@ -4945,18 +4809,8 @@ mark_stack (void *end) | |||
| 4945 | #ifdef GC_MARK_SECONDARY_STACK | 4809 | #ifdef GC_MARK_SECONDARY_STACK |
| 4946 | GC_MARK_SECONDARY_STACK (); | 4810 | GC_MARK_SECONDARY_STACK (); |
| 4947 | #endif | 4811 | #endif |
| 4948 | |||
| 4949 | #if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS | ||
| 4950 | check_gcpros (); | ||
| 4951 | #endif | ||
| 4952 | } | 4812 | } |
| 4953 | 4813 | ||
| 4954 | #else /* GC_MARK_STACK == 0 */ | ||
| 4955 | |||
| 4956 | #define mark_maybe_object(obj) emacs_abort () | ||
| 4957 | |||
| 4958 | #endif /* GC_MARK_STACK != 0 */ | ||
| 4959 | |||
| 4960 | static bool | 4814 | static bool |
| 4961 | c_symbol_p (struct Lisp_Symbol *sym) | 4815 | c_symbol_p (struct Lisp_Symbol *sym) |
| 4962 | { | 4816 | { |
| @@ -5007,9 +4861,7 @@ int | |||
| 5007 | valid_lisp_object_p (Lisp_Object obj) | 4861 | valid_lisp_object_p (Lisp_Object obj) |
| 5008 | { | 4862 | { |
| 5009 | void *p; | 4863 | void *p; |
| 5010 | #if GC_MARK_STACK | ||
| 5011 | struct mem_node *m; | 4864 | struct mem_node *m; |
| 5012 | #endif | ||
| 5013 | 4865 | ||
| 5014 | if (INTEGERP (obj)) | 4866 | if (INTEGERP (obj)) |
| 5015 | return 1; | 4867 | return 1; |
| @@ -5024,10 +4876,6 @@ valid_lisp_object_p (Lisp_Object obj) | |||
| 5024 | if (p == &buffer_defaults || p == &buffer_local_symbols) | 4876 | if (p == &buffer_defaults || p == &buffer_local_symbols) |
| 5025 | return 2; | 4877 | return 2; |
| 5026 | 4878 | ||
| 5027 | #if !GC_MARK_STACK | ||
| 5028 | return valid_pointer_p (p); | ||
| 5029 | #else | ||
| 5030 | |||
| 5031 | m = mem_find (p); | 4879 | m = mem_find (p); |
| 5032 | 4880 | ||
| 5033 | if (m == MEM_NIL) | 4881 | if (m == MEM_NIL) |
| @@ -5075,35 +4923,6 @@ valid_lisp_object_p (Lisp_Object obj) | |||
| 5075 | } | 4923 | } |
| 5076 | 4924 | ||
| 5077 | return 0; | 4925 | return 0; |
| 5078 | #endif | ||
| 5079 | } | ||
| 5080 | |||
| 5081 | /* If GC_MARK_STACK, return 1 if STR is a relocatable data of Lisp_String | ||
| 5082 | (i.e. there is a non-pure Lisp_Object X so that SDATA (X) == STR) and 0 | ||
| 5083 | if not. Otherwise we can't rely on valid_lisp_object_p and return -1. | ||
| 5084 | This function is slow and should be used for debugging purposes. */ | ||
| 5085 | |||
| 5086 | int | ||
| 5087 | relocatable_string_data_p (const char *str) | ||
| 5088 | { | ||
| 5089 | if (PURE_POINTER_P (str)) | ||
| 5090 | return 0; | ||
| 5091 | #if GC_MARK_STACK | ||
| 5092 | if (str) | ||
| 5093 | { | ||
| 5094 | struct sdata *sdata | ||
| 5095 | = (struct sdata *) (str - offsetof (struct sdata, data)); | ||
| 5096 | |||
| 5097 | if (0 < valid_pointer_p (sdata) | ||
| 5098 | && 0 < valid_pointer_p (sdata->string) | ||
| 5099 | && maybe_lisp_pointer (sdata->string)) | ||
| 5100 | return (valid_lisp_object_p | ||
| 5101 | (make_lisp_ptr (sdata->string, Lisp_String)) | ||
| 5102 | && (const char *) sdata->string->data == str); | ||
| 5103 | } | ||
| 5104 | return 0; | ||
| 5105 | #endif /* GC_MARK_STACK */ | ||
| 5106 | return -1; | ||
| 5107 | } | 4926 | } |
| 5108 | 4927 | ||
| 5109 | /*********************************************************************** | 4928 | /*********************************************************************** |
| @@ -5675,18 +5494,8 @@ garbage_collect_1 (void *end) | |||
| 5675 | xg_mark_data (); | 5494 | xg_mark_data (); |
| 5676 | #endif | 5495 | #endif |
| 5677 | 5496 | ||
| 5678 | #if (GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS \ | ||
| 5679 | || GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS) | ||
| 5680 | mark_stack (end); | 5497 | mark_stack (end); |
| 5681 | #else | 5498 | |
| 5682 | { | ||
| 5683 | register struct gcpro *tail; | ||
| 5684 | for (tail = gcprolist; tail; tail = tail->next) | ||
| 5685 | for (i = 0; i < tail->nvars; i++) | ||
| 5686 | mark_object (tail->var[i]); | ||
| 5687 | } | ||
| 5688 | mark_byte_stack (); | ||
| 5689 | #endif | ||
| 5690 | { | 5499 | { |
| 5691 | struct handler *handler; | 5500 | struct handler *handler; |
| 5692 | for (handler = handlerlist; handler; handler = handler->next) | 5501 | for (handler = handlerlist; handler; handler = handler->next) |
| @@ -5699,10 +5508,6 @@ garbage_collect_1 (void *end) | |||
| 5699 | mark_fringe_data (); | 5508 | mark_fringe_data (); |
| 5700 | #endif | 5509 | #endif |
| 5701 | 5510 | ||
| 5702 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES | ||
| 5703 | mark_stack (end); | ||
| 5704 | #endif | ||
| 5705 | |||
| 5706 | /* Everything is now marked, except for the data in font caches, | 5511 | /* Everything is now marked, except for the data in font caches, |
| 5707 | undo lists, and finalizers. The first two are compacted by | 5512 | undo lists, and finalizers. The first two are compacted by |
| 5708 | removing an items which aren't reachable otherwise. */ | 5513 | removing an items which aren't reachable otherwise. */ |
| @@ -5730,16 +5535,12 @@ garbage_collect_1 (void *end) | |||
| 5730 | 5535 | ||
| 5731 | gc_sweep (); | 5536 | gc_sweep (); |
| 5732 | 5537 | ||
| 5733 | /* Clear the mark bits that we set in certain root slots. */ | 5538 | relocate_byte_stack (); |
| 5734 | 5539 | ||
| 5735 | unmark_byte_stack (); | 5540 | /* Clear the mark bits that we set in certain root slots. */ |
| 5736 | VECTOR_UNMARK (&buffer_defaults); | 5541 | VECTOR_UNMARK (&buffer_defaults); |
| 5737 | VECTOR_UNMARK (&buffer_local_symbols); | 5542 | VECTOR_UNMARK (&buffer_local_symbols); |
| 5738 | 5543 | ||
| 5739 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES && 0 | ||
| 5740 | dump_zombies (); | ||
| 5741 | #endif | ||
| 5742 | |||
| 5743 | check_cons_list (); | 5544 | check_cons_list (); |
| 5744 | 5545 | ||
| 5745 | gc_in_progress = 0; | 5546 | gc_in_progress = 0; |
| @@ -5813,21 +5614,6 @@ garbage_collect_1 (void *end) | |||
| 5813 | }; | 5614 | }; |
| 5814 | retval = CALLMANY (Flist, total); | 5615 | retval = CALLMANY (Flist, total); |
| 5815 | 5616 | ||
| 5816 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES | ||
| 5817 | { | ||
| 5818 | /* Compute average percentage of zombies. */ | ||
| 5819 | double nlive | ||
| 5820 | = (total_conses + total_symbols + total_markers + total_strings | ||
| 5821 | + total_vectors + total_floats + total_intervals + total_buffers); | ||
| 5822 | |||
| 5823 | avg_live = (avg_live * ngcs + nlive) / (ngcs + 1); | ||
| 5824 | max_live = max (nlive, max_live); | ||
| 5825 | avg_zombies = (avg_zombies * ngcs + nzombies) / (ngcs + 1); | ||
| 5826 | max_zombies = max (nzombies, max_zombies); | ||
| 5827 | ++ngcs; | ||
| 5828 | } | ||
| 5829 | #endif | ||
| 5830 | |||
| 5831 | /* GC is complete: now we can run our finalizer callbacks. */ | 5617 | /* GC is complete: now we can run our finalizer callbacks. */ |
| 5832 | run_finalizers (&doomed_finalizers); | 5618 | run_finalizers (&doomed_finalizers); |
| 5833 | 5619 | ||
| @@ -5878,9 +5664,6 @@ returns nil, because real GC can't be done. | |||
| 5878 | See Info node `(elisp)Garbage Collection'. */) | 5664 | See Info node `(elisp)Garbage Collection'. */) |
| 5879 | (void) | 5665 | (void) |
| 5880 | { | 5666 | { |
| 5881 | #if (GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS \ | ||
| 5882 | || GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS \ | ||
| 5883 | || GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES) | ||
| 5884 | void *end; | 5667 | void *end; |
| 5885 | 5668 | ||
| 5886 | #ifdef HAVE___BUILTIN_UNWIND_INIT | 5669 | #ifdef HAVE___BUILTIN_UNWIND_INIT |
| @@ -5935,12 +5718,6 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5935 | #endif /* not GC_SAVE_REGISTERS_ON_STACK */ | 5718 | #endif /* not GC_SAVE_REGISTERS_ON_STACK */ |
| 5936 | #endif /* not HAVE___BUILTIN_UNWIND_INIT */ | 5719 | #endif /* not HAVE___BUILTIN_UNWIND_INIT */ |
| 5937 | return garbage_collect_1 (end); | 5720 | return garbage_collect_1 (end); |
| 5938 | #elif (GC_MARK_STACK == GC_USE_GCPROS_AS_BEFORE) | ||
| 5939 | /* Old GCPROs-based method without stack marking. */ | ||
| 5940 | return garbage_collect_1 (NULL); | ||
| 5941 | #else | ||
| 5942 | emacs_abort (); | ||
| 5943 | #endif /* GC_MARK_STACK */ | ||
| 5944 | } | 5721 | } |
| 5945 | 5722 | ||
| 5946 | /* Mark Lisp objects in glyph matrix MATRIX. Currently the | 5723 | /* Mark Lisp objects in glyph matrix MATRIX. Currently the |
| @@ -6133,7 +5910,7 @@ mark_save_value (struct Lisp_Save_Value *ptr) | |||
| 6133 | /* If `save_type' is zero, `data[0].pointer' is the address | 5910 | /* If `save_type' is zero, `data[0].pointer' is the address |
| 6134 | of a memory area containing `data[1].integer' potential | 5911 | of a memory area containing `data[1].integer' potential |
| 6135 | Lisp_Objects. */ | 5912 | Lisp_Objects. */ |
| 6136 | if (GC_MARK_STACK && ptr->save_type == SAVE_TYPE_MEMORY) | 5913 | if (ptr->save_type == SAVE_TYPE_MEMORY) |
| 6137 | { | 5914 | { |
| 6138 | Lisp_Object *p = ptr->data[0].pointer; | 5915 | Lisp_Object *p = ptr->data[0].pointer; |
| 6139 | ptrdiff_t nelt; | 5916 | ptrdiff_t nelt; |
| @@ -6208,7 +5985,7 @@ mark_object (Lisp_Object arg) | |||
| 6208 | 5985 | ||
| 6209 | /* Perform some sanity checks on the objects marked here. Abort if | 5986 | /* Perform some sanity checks on the objects marked here. Abort if |
| 6210 | we encounter an object we know is bogus. This increases GC time | 5987 | we encounter an object we know is bogus. This increases GC time |
| 6211 | by ~80%, and requires compilation with GC_MARK_STACK != 0. */ | 5988 | by ~80%. */ |
| 6212 | #ifdef GC_CHECK_MARKED_OBJECTS | 5989 | #ifdef GC_CHECK_MARKED_OBJECTS |
| 6213 | 5990 | ||
| 6214 | /* Check that the object pointed to by PO is known to be a Lisp | 5991 | /* Check that the object pointed to by PO is known to be a Lisp |
| @@ -6634,9 +6411,7 @@ sweep_conses (void) | |||
| 6634 | this_free++; | 6411 | this_free++; |
| 6635 | cblk->conses[pos].u.chain = cons_free_list; | 6412 | cblk->conses[pos].u.chain = cons_free_list; |
| 6636 | cons_free_list = &cblk->conses[pos]; | 6413 | cons_free_list = &cblk->conses[pos]; |
| 6637 | #if GC_MARK_STACK | ||
| 6638 | cons_free_list->car = Vdead; | 6414 | cons_free_list->car = Vdead; |
| 6639 | #endif | ||
| 6640 | } | 6415 | } |
| 6641 | else | 6416 | else |
| 6642 | { | 6417 | { |
| @@ -6795,9 +6570,7 @@ sweep_symbols (void) | |||
| 6795 | xfree (SYMBOL_BLV (&sym->s)); | 6570 | xfree (SYMBOL_BLV (&sym->s)); |
| 6796 | sym->s.next = symbol_free_list; | 6571 | sym->s.next = symbol_free_list; |
| 6797 | symbol_free_list = &sym->s; | 6572 | symbol_free_list = &sym->s; |
| 6798 | #if GC_MARK_STACK | ||
| 6799 | symbol_free_list->function = Vdead; | 6573 | symbol_free_list->function = Vdead; |
| 6800 | #endif | ||
| 6801 | ++this_free; | 6574 | ++this_free; |
| 6802 | } | 6575 | } |
| 6803 | else | 6576 | else |
| @@ -7226,7 +6999,6 @@ init_alloc_once (void) | |||
| 7226 | { | 6999 | { |
| 7227 | /* Even though Qt's contents are not set up, its address is known. */ | 7000 | /* Even though Qt's contents are not set up, its address is known. */ |
| 7228 | Vpurify_flag = Qt; | 7001 | Vpurify_flag = Qt; |
| 7229 | gc_precise = (GC_MARK_STACK == GC_USE_GCPROS_AS_BEFORE); | ||
| 7230 | 7002 | ||
| 7231 | purebeg = PUREBEG; | 7003 | purebeg = PUREBEG; |
| 7232 | pure_size = PURESIZE; | 7004 | pure_size = PURESIZE; |
| @@ -7235,10 +7007,8 @@ init_alloc_once (void) | |||
| 7235 | init_finalizer_list (&finalizers); | 7007 | init_finalizer_list (&finalizers); |
| 7236 | init_finalizer_list (&doomed_finalizers); | 7008 | init_finalizer_list (&doomed_finalizers); |
| 7237 | 7009 | ||
| 7238 | #if GC_MARK_STACK || defined GC_MALLOC_CHECK | ||
| 7239 | mem_init (); | 7010 | mem_init (); |
| 7240 | Vdead = make_pure_string ("DEAD", 4, 4, 0); | 7011 | Vdead = make_pure_string ("DEAD", 4, 4, 0); |
| 7241 | #endif | ||
| 7242 | 7012 | ||
| 7243 | #ifdef DOUG_LEA_MALLOC | 7013 | #ifdef DOUG_LEA_MALLOC |
| 7244 | mallopt (M_TRIM_THRESHOLD, 128 * 1024); /* Trim threshold. */ | 7014 | mallopt (M_TRIM_THRESHOLD, 128 * 1024); /* Trim threshold. */ |
| @@ -7255,11 +7025,9 @@ init_alloc_once (void) | |||
| 7255 | void | 7025 | void |
| 7256 | init_alloc (void) | 7026 | init_alloc (void) |
| 7257 | { | 7027 | { |
| 7258 | #if GC_MARK_STACK | ||
| 7259 | #if !defined GC_SAVE_REGISTERS_ON_STACK && !defined GC_SETJMP_WORKS | 7028 | #if !defined GC_SAVE_REGISTERS_ON_STACK && !defined GC_SETJMP_WORKS |
| 7260 | setjmp_tested_p = longjmps_done = 0; | 7029 | setjmp_tested_p = longjmps_done = 0; |
| 7261 | #endif | 7030 | #endif |
| 7262 | #endif | ||
| 7263 | Vgc_elapsed = make_float (0.0); | 7031 | Vgc_elapsed = make_float (0.0); |
| 7264 | gcs_done = 0; | 7032 | gcs_done = 0; |
| 7265 | 7033 | ||
| @@ -7368,11 +7136,6 @@ The time is in seconds as a floating point value. */); | |||
| 7368 | DEFVAR_INT ("gcs-done", gcs_done, | 7136 | DEFVAR_INT ("gcs-done", gcs_done, |
| 7369 | doc: /* Accumulated number of garbage collections done. */); | 7137 | doc: /* Accumulated number of garbage collections done. */); |
| 7370 | 7138 | ||
| 7371 | DEFVAR_BOOL ("gc-precise", gc_precise, | ||
| 7372 | doc: /* Non-nil means GC stack marking is precise. | ||
| 7373 | Useful mainly for automated GC tests. Build time constant.*/); | ||
| 7374 | XSYMBOL (intern_c_string ("gc-precise"))->constant = 1; | ||
| 7375 | |||
| 7376 | defsubr (&Scons); | 7139 | defsubr (&Scons); |
| 7377 | defsubr (&Slist); | 7140 | defsubr (&Slist); |
| 7378 | defsubr (&Svector); | 7141 | defsubr (&Svector); |
| @@ -7391,10 +7154,6 @@ Useful mainly for automated GC tests. Build time constant.*/); | |||
| 7391 | defsubr (&Smemory_info); | 7154 | defsubr (&Smemory_info); |
| 7392 | defsubr (&Smemory_use_counts); | 7155 | defsubr (&Smemory_use_counts); |
| 7393 | defsubr (&Ssuspicious_object); | 7156 | defsubr (&Ssuspicious_object); |
| 7394 | |||
| 7395 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES | ||
| 7396 | defsubr (&Sgc_status); | ||
| 7397 | #endif | ||
| 7398 | } | 7157 | } |
| 7399 | 7158 | ||
| 7400 | /* When compiled with GCC, GDB might say "No enum type named | 7159 | /* When compiled with GCC, GDB might say "No enum type named |