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 |
