Mercurial > emacs
comparison src/alloc.c @ 51658:00b3e009b3f5
(make_interval, Fmake_symbol, allocate_misc):
Initialize the new field `gcmarkbit'.
(mark_interval, MARK_INTERVAL_TREE): Use the new `gcmarkbit' field.
(mark_interval_tree): Don't mark the tree separately from the nodes.
(UNMARK_BALANCE_INTERVALS): Don't unmark the tree.
(mark_maybe_object, mark_maybe_pointer, Fgarbage_collect, mark_object)
(survives_gc_p, gc_sweep): Use new `gcmarkbit' fields.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Wed, 25 Jun 2003 23:27:32 +0000 |
parents | 42f25a716cb8 |
children | 0f333fd92a1d |
comparison
equal
deleted
inserted
replaced
51657:7fb427e8d984 | 51658:00b3e009b3f5 |
---|---|
945 val = &interval_block->intervals[interval_block_index++]; | 945 val = &interval_block->intervals[interval_block_index++]; |
946 } | 946 } |
947 consing_since_gc += sizeof (struct interval); | 947 consing_since_gc += sizeof (struct interval); |
948 intervals_consed++; | 948 intervals_consed++; |
949 RESET_INTERVAL (val); | 949 RESET_INTERVAL (val); |
950 val->gcmarkbit = 0; | |
950 return val; | 951 return val; |
951 } | 952 } |
952 | 953 |
953 | 954 |
954 /* Mark Lisp objects in interval I. */ | 955 /* Mark Lisp objects in interval I. */ |
956 static void | 957 static void |
957 mark_interval (i, dummy) | 958 mark_interval (i, dummy) |
958 register INTERVAL i; | 959 register INTERVAL i; |
959 Lisp_Object dummy; | 960 Lisp_Object dummy; |
960 { | 961 { |
961 if (XMARKBIT (i->plist)) | 962 eassert (!i->gcmarkbit); /* Intervals are never shared. */ |
962 abort (); | 963 i->gcmarkbit = 1; |
963 mark_object (&i->plist); | 964 mark_object (&i->plist); |
964 XMARK (i->plist); | |
965 } | 965 } |
966 | 966 |
967 | 967 |
968 /* Mark the interval tree rooted in TREE. Don't call this directly; | 968 /* Mark the interval tree rooted in TREE. Don't call this directly; |
969 use the macro MARK_INTERVAL_TREE instead. */ | 969 use the macro MARK_INTERVAL_TREE instead. */ |
974 { | 974 { |
975 /* No need to test if this tree has been marked already; this | 975 /* No need to test if this tree has been marked already; this |
976 function is always called through the MARK_INTERVAL_TREE macro, | 976 function is always called through the MARK_INTERVAL_TREE macro, |
977 which takes care of that. */ | 977 which takes care of that. */ |
978 | 978 |
979 /* XMARK expands to an assignment; the LHS of an assignment can't be | |
980 a cast. */ | |
981 XMARK (tree->up.obj); | |
982 | |
983 traverse_intervals_noorder (tree, mark_interval, Qnil); | 979 traverse_intervals_noorder (tree, mark_interval, Qnil); |
984 } | 980 } |
985 | 981 |
986 | 982 |
987 /* Mark the interval tree rooted in I. */ | 983 /* Mark the interval tree rooted in I. */ |
988 | 984 |
989 #define MARK_INTERVAL_TREE(i) \ | 985 #define MARK_INTERVAL_TREE(i) \ |
990 do { \ | 986 do { \ |
991 if (!NULL_INTERVAL_P (i) \ | 987 if (!NULL_INTERVAL_P (i) && !i->gcmarkbit) \ |
992 && ! XMARKBIT (i->up.obj)) \ | |
993 mark_interval_tree (i); \ | 988 mark_interval_tree (i); \ |
994 } while (0) | 989 } while (0) |
995 | 990 |
996 | |
997 /* The oddity in the call to XUNMARK is necessary because XUNMARK | |
998 expands to an assignment to its argument, and most C compilers | |
999 don't support casts on the left operand of `='. */ | |
1000 | 991 |
1001 #define UNMARK_BALANCE_INTERVALS(i) \ | 992 #define UNMARK_BALANCE_INTERVALS(i) \ |
1002 do { \ | 993 do { \ |
1003 if (! NULL_INTERVAL_P (i)) \ | 994 if (! NULL_INTERVAL_P (i)) \ |
1004 { \ | 995 (i) = balance_intervals (i); \ |
1005 XUNMARK ((i)->up.obj); \ | |
1006 (i) = balance_intervals (i); \ | |
1007 } \ | |
1008 } while (0) | 996 } while (0) |
1009 | 997 |
1010 | 998 |
1011 /* Number support. If NO_UNION_TYPE isn't in effect, we | 999 /* Number support. If NO_UNION_TYPE isn't in effect, we |
1012 can't create number objects in macros. */ | 1000 can't create number objects in macros. */ |
2566 p->xname = name; | 2554 p->xname = name; |
2567 p->plist = Qnil; | 2555 p->plist = Qnil; |
2568 p->value = Qunbound; | 2556 p->value = Qunbound; |
2569 p->function = Qunbound; | 2557 p->function = Qunbound; |
2570 p->next = NULL; | 2558 p->next = NULL; |
2559 p->gcmarkbit = 0; | |
2571 p->interned = SYMBOL_UNINTERNED; | 2560 p->interned = SYMBOL_UNINTERNED; |
2572 p->constant = 0; | 2561 p->constant = 0; |
2573 p->indirect_variable = 0; | 2562 p->indirect_variable = 0; |
2574 consing_since_gc += sizeof (struct Lisp_Symbol); | 2563 consing_since_gc += sizeof (struct Lisp_Symbol); |
2575 symbols_consed++; | 2564 symbols_consed++; |
2642 XSETMISC (val, &marker_block->markers[marker_block_index++]); | 2631 XSETMISC (val, &marker_block->markers[marker_block_index++]); |
2643 } | 2632 } |
2644 | 2633 |
2645 consing_since_gc += sizeof (union Lisp_Misc); | 2634 consing_since_gc += sizeof (union Lisp_Misc); |
2646 misc_objects_consed++; | 2635 misc_objects_consed++; |
2636 XMARKER (val)->gcmarkbit = 0; | |
2647 return val; | 2637 return val; |
2648 } | 2638 } |
2649 | 2639 |
2650 /* Return a Lisp_Misc_Save_Value object containing POINTER and | 2640 /* Return a Lisp_Misc_Save_Value object containing POINTER and |
2651 INTEGER. This is used to package C values to call record_unwind_protect. | 2641 INTEGER. This is used to package C values to call record_unwind_protect. |
3300 && m->type >= MEM_TYPE_VECTOR | 3290 && m->type >= MEM_TYPE_VECTOR |
3301 && m->type <= MEM_TYPE_WINDOW); | 3291 && m->type <= MEM_TYPE_WINDOW); |
3302 } | 3292 } |
3303 | 3293 |
3304 | 3294 |
3305 /* Value is non-zero of P is a pointer to a live buffer. M is a | 3295 /* Value is non-zero if P is a pointer to a live buffer. M is a |
3306 pointer to the mem_block for P. */ | 3296 pointer to the mem_block for P. */ |
3307 | 3297 |
3308 static INLINE int | 3298 static INLINE int |
3309 live_buffer_p (m, p) | 3299 live_buffer_p (m, p) |
3310 struct mem_node *m; | 3300 struct mem_node *m; |
3395 mark_p = (live_cons_p (m, po) | 3385 mark_p = (live_cons_p (m, po) |
3396 && !XMARKBIT (XCONS (obj)->car)); | 3386 && !XMARKBIT (XCONS (obj)->car)); |
3397 break; | 3387 break; |
3398 | 3388 |
3399 case Lisp_Symbol: | 3389 case Lisp_Symbol: |
3400 mark_p = (live_symbol_p (m, po) | 3390 mark_p = (live_symbol_p (m, po) && !XSYMBOL (obj)->gcmarkbit); |
3401 && !XMARKBIT (XSYMBOL (obj)->plist)); | |
3402 break; | 3391 break; |
3403 | 3392 |
3404 case Lisp_Float: | 3393 case Lisp_Float: |
3405 mark_p = (live_float_p (m, po) | 3394 mark_p = (live_float_p (m, po) |
3406 && !XMARKBIT (XFLOAT (obj)->type)); | 3395 && !XMARKBIT (XFLOAT (obj)->type)); |
3416 else if (live_buffer_p (m, po)) | 3405 else if (live_buffer_p (m, po)) |
3417 mark_p = GC_BUFFERP (obj) && !XMARKBIT (XBUFFER (obj)->name); | 3406 mark_p = GC_BUFFERP (obj) && !XMARKBIT (XBUFFER (obj)->name); |
3418 break; | 3407 break; |
3419 | 3408 |
3420 case Lisp_Misc: | 3409 case Lisp_Misc: |
3421 if (live_misc_p (m, po)) | 3410 mark_p = (live_misc_p (m, po) && !XMARKER (obj)->gcmarkbit); |
3422 { | |
3423 switch (XMISCTYPE (obj)) | |
3424 { | |
3425 case Lisp_Misc_Marker: | |
3426 mark_p = !XMARKBIT (XMARKER (obj)->chain); | |
3427 break; | |
3428 | |
3429 case Lisp_Misc_Buffer_Local_Value: | |
3430 case Lisp_Misc_Some_Buffer_Local_Value: | |
3431 mark_p = !XMARKBIT (XBUFFER_LOCAL_VALUE (obj)->realvalue); | |
3432 break; | |
3433 | |
3434 case Lisp_Misc_Overlay: | |
3435 mark_p = !XMARKBIT (XOVERLAY (obj)->plist); | |
3436 break; | |
3437 } | |
3438 } | |
3439 break; | 3411 break; |
3440 | 3412 |
3441 case Lisp_Int: | 3413 case Lisp_Int: |
3442 case Lisp_Type_Limit: | 3414 case Lisp_Type_Limit: |
3443 break; | 3415 break; |
3498 && !STRING_MARKED_P ((struct Lisp_String *) p)) | 3470 && !STRING_MARKED_P ((struct Lisp_String *) p)) |
3499 XSETSTRING (obj, p); | 3471 XSETSTRING (obj, p); |
3500 break; | 3472 break; |
3501 | 3473 |
3502 case MEM_TYPE_MISC: | 3474 case MEM_TYPE_MISC: |
3503 if (live_misc_p (m, p)) | 3475 if (live_misc_p (m, p) && !((struct Lisp_Free *) p)->gcmarkbit) |
3504 { | 3476 XSETMISC (obj, p); |
3505 Lisp_Object tem; | |
3506 XSETMISC (tem, p); | |
3507 | |
3508 switch (XMISCTYPE (tem)) | |
3509 { | |
3510 case Lisp_Misc_Marker: | |
3511 if (!XMARKBIT (XMARKER (tem)->chain)) | |
3512 obj = tem; | |
3513 break; | |
3514 | |
3515 case Lisp_Misc_Buffer_Local_Value: | |
3516 case Lisp_Misc_Some_Buffer_Local_Value: | |
3517 if (!XMARKBIT (XBUFFER_LOCAL_VALUE (tem)->realvalue)) | |
3518 obj = tem; | |
3519 break; | |
3520 | |
3521 case Lisp_Misc_Overlay: | |
3522 if (!XMARKBIT (XOVERLAY (tem)->plist)) | |
3523 obj = tem; | |
3524 break; | |
3525 } | |
3526 } | |
3527 break; | 3477 break; |
3528 | 3478 |
3529 case MEM_TYPE_SYMBOL: | 3479 case MEM_TYPE_SYMBOL: |
3530 if (live_symbol_p (m, p) | 3480 if (live_symbol_p (m, p) && !((struct Lisp_Symbol *) p)->gcmarkbit) |
3531 && !XMARKBIT (((struct Lisp_Symbol *) p)->plist)) | |
3532 XSETSYMBOL (obj, p); | 3481 XSETSYMBOL (obj, p); |
3533 break; | 3482 break; |
3534 | 3483 |
3535 case MEM_TYPE_FLOAT: | 3484 case MEM_TYPE_FLOAT: |
3536 if (live_float_p (m, p) | 3485 if (live_float_p (m, p) |
4276 prev = Qnil; | 4225 prev = Qnil; |
4277 while (CONSP (tail)) | 4226 while (CONSP (tail)) |
4278 { | 4227 { |
4279 if (GC_CONSP (XCAR (tail)) | 4228 if (GC_CONSP (XCAR (tail)) |
4280 && GC_MARKERP (XCAR (XCAR (tail))) | 4229 && GC_MARKERP (XCAR (XCAR (tail))) |
4281 && ! XMARKBIT (XMARKER (XCAR (XCAR (tail)))->chain)) | 4230 && !XMARKER (XCAR (XCAR (tail)))->gcmarkbit) |
4282 { | 4231 { |
4283 if (NILP (prev)) | 4232 if (NILP (prev)) |
4284 nextb->undo_list = tail = XCDR (tail); | 4233 nextb->undo_list = tail = XCDR (tail); |
4285 else | 4234 else |
4286 { | 4235 { |
4772 case Lisp_Symbol: | 4721 case Lisp_Symbol: |
4773 { | 4722 { |
4774 register struct Lisp_Symbol *ptr = XSYMBOL (obj); | 4723 register struct Lisp_Symbol *ptr = XSYMBOL (obj); |
4775 struct Lisp_Symbol *ptrx; | 4724 struct Lisp_Symbol *ptrx; |
4776 | 4725 |
4777 if (XMARKBIT (ptr->plist)) break; | 4726 if (ptr->gcmarkbit) break; |
4778 CHECK_ALLOCATED_AND_LIVE (live_symbol_p); | 4727 CHECK_ALLOCATED_AND_LIVE (live_symbol_p); |
4779 XMARK (ptr->plist); | 4728 ptr->gcmarkbit = 1; |
4780 mark_object ((Lisp_Object *) &ptr->value); | 4729 mark_object ((Lisp_Object *) &ptr->value); |
4781 mark_object (&ptr->function); | 4730 mark_object (&ptr->function); |
4782 mark_object (&ptr->plist); | 4731 mark_object (&ptr->plist); |
4783 | 4732 |
4784 if (!PURE_POINTER_P (XSTRING (ptr->xname))) | 4733 if (!PURE_POINTER_P (XSTRING (ptr->xname))) |
4802 } | 4751 } |
4803 break; | 4752 break; |
4804 | 4753 |
4805 case Lisp_Misc: | 4754 case Lisp_Misc: |
4806 CHECK_ALLOCATED_AND_LIVE (live_misc_p); | 4755 CHECK_ALLOCATED_AND_LIVE (live_misc_p); |
4756 if (XMARKER (obj)->gcmarkbit) | |
4757 break; | |
4758 XMARKER (obj)->gcmarkbit = 1; | |
4807 switch (XMISCTYPE (obj)) | 4759 switch (XMISCTYPE (obj)) |
4808 { | 4760 { |
4809 case Lisp_Misc_Marker: | |
4810 XMARK (XMARKER (obj)->chain); | |
4811 /* DO NOT mark thru the marker's chain. | |
4812 The buffer's markers chain does not preserve markers from gc; | |
4813 instead, markers are removed from the chain when freed by gc. */ | |
4814 break; | |
4815 | |
4816 case Lisp_Misc_Buffer_Local_Value: | 4761 case Lisp_Misc_Buffer_Local_Value: |
4817 case Lisp_Misc_Some_Buffer_Local_Value: | 4762 case Lisp_Misc_Some_Buffer_Local_Value: |
4818 { | 4763 { |
4819 register struct Lisp_Buffer_Local_Value *ptr | 4764 register struct Lisp_Buffer_Local_Value *ptr |
4820 = XBUFFER_LOCAL_VALUE (obj); | 4765 = XBUFFER_LOCAL_VALUE (obj); |
4821 if (XMARKBIT (ptr->realvalue)) break; | |
4822 XMARK (ptr->realvalue); | |
4823 /* If the cdr is nil, avoid recursion for the car. */ | 4766 /* If the cdr is nil, avoid recursion for the car. */ |
4824 if (EQ (ptr->cdr, Qnil)) | 4767 if (EQ (ptr->cdr, Qnil)) |
4825 { | 4768 { |
4826 objptr = &ptr->realvalue; | 4769 objptr = &ptr->realvalue; |
4827 goto loop; | 4770 goto loop; |
4831 mark_object (&ptr->frame); | 4774 mark_object (&ptr->frame); |
4832 objptr = &ptr->cdr; | 4775 objptr = &ptr->cdr; |
4833 goto loop; | 4776 goto loop; |
4834 } | 4777 } |
4835 | 4778 |
4779 case Lisp_Misc_Marker: | |
4780 /* DO NOT mark thru the marker's chain. | |
4781 The buffer's markers chain does not preserve markers from gc; | |
4782 instead, markers are removed from the chain when freed by gc. */ | |
4836 case Lisp_Misc_Intfwd: | 4783 case Lisp_Misc_Intfwd: |
4837 case Lisp_Misc_Boolfwd: | 4784 case Lisp_Misc_Boolfwd: |
4838 case Lisp_Misc_Objfwd: | 4785 case Lisp_Misc_Objfwd: |
4839 case Lisp_Misc_Buffer_Objfwd: | 4786 case Lisp_Misc_Buffer_Objfwd: |
4840 case Lisp_Misc_Kboard_Objfwd: | 4787 case Lisp_Misc_Kboard_Objfwd: |
4845 break; | 4792 break; |
4846 | 4793 |
4847 case Lisp_Misc_Overlay: | 4794 case Lisp_Misc_Overlay: |
4848 { | 4795 { |
4849 struct Lisp_Overlay *ptr = XOVERLAY (obj); | 4796 struct Lisp_Overlay *ptr = XOVERLAY (obj); |
4850 if (!XMARKBIT (ptr->plist)) | 4797 mark_object (&ptr->start); |
4851 { | 4798 mark_object (&ptr->end); |
4852 XMARK (ptr->plist); | 4799 objptr = &ptr->plist; |
4853 mark_object (&ptr->start); | 4800 goto loop; |
4854 mark_object (&ptr->end); | |
4855 objptr = &ptr->plist; | |
4856 goto loop; | |
4857 } | |
4858 } | 4801 } |
4859 break; | 4802 break; |
4860 | 4803 |
4861 default: | 4804 default: |
4862 abort (); | 4805 abort (); |
4920 if (CONSP (buffer->undo_list)) | 4863 if (CONSP (buffer->undo_list)) |
4921 { | 4864 { |
4922 Lisp_Object tail; | 4865 Lisp_Object tail; |
4923 tail = buffer->undo_list; | 4866 tail = buffer->undo_list; |
4924 | 4867 |
4868 /* We mark the undo list specially because | |
4869 its pointers to markers should be weak. */ | |
4870 | |
4925 while (CONSP (tail)) | 4871 while (CONSP (tail)) |
4926 { | 4872 { |
4927 register struct Lisp_Cons *ptr = XCONS (tail); | 4873 register struct Lisp_Cons *ptr = XCONS (tail); |
4928 | 4874 |
4929 if (XMARKBIT (ptr->car)) | 4875 if (XMARKBIT (ptr->car)) |
4978 case Lisp_Int: | 4924 case Lisp_Int: |
4979 survives_p = 1; | 4925 survives_p = 1; |
4980 break; | 4926 break; |
4981 | 4927 |
4982 case Lisp_Symbol: | 4928 case Lisp_Symbol: |
4983 survives_p = XMARKBIT (XSYMBOL (obj)->plist); | 4929 survives_p = XSYMBOL (obj)->gcmarkbit; |
4984 break; | 4930 break; |
4985 | 4931 |
4986 case Lisp_Misc: | 4932 case Lisp_Misc: |
4933 /* FIXME: Maybe we should just use obj->mark for all? */ | |
4987 switch (XMISCTYPE (obj)) | 4934 switch (XMISCTYPE (obj)) |
4988 { | 4935 { |
4989 case Lisp_Misc_Marker: | 4936 case Lisp_Misc_Marker: |
4990 survives_p = XMARKBIT (obj); | 4937 survives_p = XMARKER (obj)->gcmarkbit; |
4991 break; | 4938 break; |
4992 | 4939 |
4993 case Lisp_Misc_Buffer_Local_Value: | 4940 case Lisp_Misc_Buffer_Local_Value: |
4994 case Lisp_Misc_Some_Buffer_Local_Value: | 4941 case Lisp_Misc_Some_Buffer_Local_Value: |
4995 survives_p = XMARKBIT (XBUFFER_LOCAL_VALUE (obj)->realvalue); | 4942 survives_p = XBUFFER_LOCAL_VALUE (obj)->gcmarkbit; |
4996 break; | 4943 break; |
4997 | 4944 |
4998 case Lisp_Misc_Intfwd: | 4945 case Lisp_Misc_Intfwd: |
4999 case Lisp_Misc_Boolfwd: | 4946 case Lisp_Misc_Boolfwd: |
5000 case Lisp_Misc_Objfwd: | 4947 case Lisp_Misc_Objfwd: |
5002 case Lisp_Misc_Kboard_Objfwd: | 4949 case Lisp_Misc_Kboard_Objfwd: |
5003 survives_p = 1; | 4950 survives_p = 1; |
5004 break; | 4951 break; |
5005 | 4952 |
5006 case Lisp_Misc_Overlay: | 4953 case Lisp_Misc_Overlay: |
5007 survives_p = XMARKBIT (XOVERLAY (obj)->plist); | 4954 survives_p = XOVERLAY (obj)->gcmarkbit; |
5008 break; | 4955 break; |
5009 | 4956 |
5010 default: | 4957 default: |
5011 abort (); | 4958 abort (); |
5012 } | 4959 } |
5174 register int i; | 5121 register int i; |
5175 int this_free = 0; | 5122 int this_free = 0; |
5176 | 5123 |
5177 for (i = 0; i < lim; i++) | 5124 for (i = 0; i < lim; i++) |
5178 { | 5125 { |
5179 if (! XMARKBIT (iblk->intervals[i].plist)) | 5126 if (!iblk->intervals[i].gcmarkbit) |
5180 { | 5127 { |
5181 SET_INTERVAL_PARENT (&iblk->intervals[i], interval_free_list); | 5128 SET_INTERVAL_PARENT (&iblk->intervals[i], interval_free_list); |
5182 interval_free_list = &iblk->intervals[i]; | 5129 interval_free_list = &iblk->intervals[i]; |
5183 this_free++; | 5130 this_free++; |
5184 } | 5131 } |
5185 else | 5132 else |
5186 { | 5133 { |
5187 num_used++; | 5134 num_used++; |
5188 XUNMARK (iblk->intervals[i].plist); | 5135 iblk->intervals[i].gcmarkbit = 0; |
5189 } | 5136 } |
5190 } | 5137 } |
5191 lim = INTERVAL_BLOCK_SIZE; | 5138 lim = INTERVAL_BLOCK_SIZE; |
5192 /* If this block contains only free intervals and we have already | 5139 /* If this block contains only free intervals and we have already |
5193 seen more than two blocks worth of free intervals then | 5140 seen more than two blocks worth of free intervals then |
5230 /* Check if the symbol was created during loadup. In such a case | 5177 /* Check if the symbol was created during loadup. In such a case |
5231 it might be pointed to by pure bytecode which we don't trace, | 5178 it might be pointed to by pure bytecode which we don't trace, |
5232 so we conservatively assume that it is live. */ | 5179 so we conservatively assume that it is live. */ |
5233 int pure_p = PURE_POINTER_P (XSTRING (sym->xname)); | 5180 int pure_p = PURE_POINTER_P (XSTRING (sym->xname)); |
5234 | 5181 |
5235 if (!XMARKBIT (sym->plist) && !pure_p) | 5182 if (!sym->gcmarkbit && !pure_p) |
5236 { | 5183 { |
5237 *(struct Lisp_Symbol **) &sym->value = symbol_free_list; | 5184 *(struct Lisp_Symbol **) &sym->value = symbol_free_list; |
5238 symbol_free_list = sym; | 5185 symbol_free_list = sym; |
5239 #if GC_MARK_STACK | 5186 #if GC_MARK_STACK |
5240 symbol_free_list->function = Vdead; | 5187 symbol_free_list->function = Vdead; |
5244 else | 5191 else |
5245 { | 5192 { |
5246 ++num_used; | 5193 ++num_used; |
5247 if (!pure_p) | 5194 if (!pure_p) |
5248 UNMARK_STRING (XSTRING (sym->xname)); | 5195 UNMARK_STRING (XSTRING (sym->xname)); |
5249 XUNMARK (sym->plist); | 5196 sym->gcmarkbit = 0; |
5250 } | 5197 } |
5251 } | 5198 } |
5252 | 5199 |
5253 lim = SYMBOL_BLOCK_SIZE; | 5200 lim = SYMBOL_BLOCK_SIZE; |
5254 /* If this block contains only free symbols and we have already | 5201 /* If this block contains only free symbols and we have already |
5284 | 5231 |
5285 for (mblk = marker_block; mblk; mblk = *mprev) | 5232 for (mblk = marker_block; mblk; mblk = *mprev) |
5286 { | 5233 { |
5287 register int i; | 5234 register int i; |
5288 int this_free = 0; | 5235 int this_free = 0; |
5289 EMACS_INT already_free = -1; | |
5290 | 5236 |
5291 for (i = 0; i < lim; i++) | 5237 for (i = 0; i < lim; i++) |
5292 { | 5238 { |
5293 Lisp_Object *markword; | 5239 if (!mblk->markers[i].u_marker.gcmarkbit) |
5294 switch (mblk->markers[i].u_marker.type) | |
5295 { | |
5296 case Lisp_Misc_Marker: | |
5297 markword = &mblk->markers[i].u_marker.chain; | |
5298 break; | |
5299 case Lisp_Misc_Buffer_Local_Value: | |
5300 case Lisp_Misc_Some_Buffer_Local_Value: | |
5301 markword = &mblk->markers[i].u_buffer_local_value.realvalue; | |
5302 break; | |
5303 case Lisp_Misc_Overlay: | |
5304 markword = &mblk->markers[i].u_overlay.plist; | |
5305 break; | |
5306 case Lisp_Misc_Free: | |
5307 /* If the object was already free, keep it | |
5308 on the free list. */ | |
5309 markword = (Lisp_Object *) &already_free; | |
5310 break; | |
5311 default: | |
5312 markword = 0; | |
5313 break; | |
5314 } | |
5315 if (markword && !XMARKBIT (*markword)) | |
5316 { | 5240 { |
5317 Lisp_Object tem; | 5241 Lisp_Object tem; |
5318 if (mblk->markers[i].u_marker.type == Lisp_Misc_Marker) | 5242 if (mblk->markers[i].u_marker.type == Lisp_Misc_Marker) |
5319 { | 5243 { |
5320 /* tem1 avoids Sun compiler bug */ | 5244 /* tem1 avoids Sun compiler bug */ |
5331 this_free++; | 5255 this_free++; |
5332 } | 5256 } |
5333 else | 5257 else |
5334 { | 5258 { |
5335 num_used++; | 5259 num_used++; |
5336 if (markword) | 5260 mblk->markers[i].u_marker.gcmarkbit = 0; |
5337 XUNMARK (*markword); | |
5338 } | 5261 } |
5339 } | 5262 } |
5340 lim = MARKER_BLOCK_SIZE; | 5263 lim = MARKER_BLOCK_SIZE; |
5341 /* If this block contains only free markers and we have already | 5264 /* If this block contains only free markers and we have already |
5342 seen more than two blocks worth of free markers then deallocate | 5265 seen more than two blocks worth of free markers then deallocate |