Mercurial > hg > xemacs-beta
comparison src/alloc.c @ 454:d7a9135ec789 r21-2-42
Import from CVS: tag r21-2-42
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:40:54 +0200 |
parents | 3d3049ae1304 |
children | e7ef97881643 |
comparison
equal
deleted
inserted
replaced
453:270b05afd845 | 454:d7a9135ec789 |
---|---|
542 (e.g. the obarray, where are all symbols are stored; the | 542 (e.g. the obarray, where are all symbols are stored; the |
543 current catches and condition-cases; the backtrace list of | 543 current catches and condition-cases; the backtrace list of |
544 currently executing functions; the gcpro list; etc.) and | 544 currently executing functions; the gcpro list; etc.) and |
545 recursively marking all objects that are accessible. | 545 recursively marking all objects that are accessible. |
546 | 546 |
547 At the beginning of the sweep stage, the conses in the cons | 547 At the beginning of the sweep stage, the conses in the cons blocks |
548 blocks are in one of three states: in use and marked, in use | 548 are in one of three states: in use and marked, in use but not |
549 but not marked, and not in use (already freed). Any conses | 549 marked, and not in use (already freed). Any conses that are marked |
550 that are marked have been marked in the mark stage just | 550 have been marked in the mark stage just executed, because as part |
551 executed, because as part of the sweep stage we unmark any | 551 of the sweep stage we unmark any marked objects. The way we tell |
552 marked objects. The way we tell whether or not a cons cell | 552 whether or not a cons cell is in use is through the LRECORD_FREE_P |
553 is in use is through the FREE_STRUCT_P macro. This basically | 553 macro. This uses a special lrecord type `lrecord_type_free', |
554 looks at the first 4 bytes (or however many bytes a pointer | 554 which is never associated with any valid object. |
555 fits in) to see if all the bits in those bytes are 1. The | 555 |
556 resulting value (0xFFFFFFFF) is not a valid pointer and is | 556 Conses on the free_cons_list are threaded through a pointer stored |
557 not a valid Lisp_Object. All current fixed-size types have | 557 in the conses themselves. Because the cons is still in a |
558 a pointer or Lisp_Object as their first element with the | 558 cons_block and needs to remain marked as not in use for the next |
559 exception of strings; they have a size value, which can | 559 time that GC happens, we need room to store both the "free" |
560 never be less than zero, and so 0xFFFFFFFF is invalid for | 560 indicator and the chaining pointer. So this pointer is stored |
561 strings as well. Now assuming that a cons cell is in use, | 561 after the lrecord header (actually where C places a pointer after |
562 the way we tell whether or not it is marked is to look at | 562 the lrecord header; they are not necessarily contiguous). This |
563 the mark bit of its car (each Lisp_Object has one bit | 563 implies that all fixed-size types must be big enough to contain at |
564 reserved as a mark bit, in case it's needed). Note that | 564 least one pointer. This is true for all current fixed-size types, |
565 different types of objects use different fields to indicate | 565 with the possible exception of Lisp_Floats, for which we define the |
566 whether the object is marked, but the principle is the same. | 566 meat of the struct using a union of a pointer and a double to |
567 | 567 ensure adequate space for the free list chain pointer. |
568 Conses on the free_cons_list are threaded through a pointer | |
569 stored in the bytes directly after the bytes that are set | |
570 to 0xFFFFFFFF (we cannot overwrite these because the cons | |
571 is still in a cons_block and needs to remain marked as | |
572 not in use for the next time that GC happens). This | |
573 implies that all fixed-size types must be at least big | |
574 enough to store two pointers, which is indeed the case | |
575 for all current fixed-size types. | |
576 | 568 |
577 Some types of objects need additional "finalization" done | 569 Some types of objects need additional "finalization" done |
578 when an object is converted from in use to not in use; | 570 when an object is converted from in use to not in use; |
579 this is the purpose of the ADDITIONAL_FREE_type macro. | 571 this is the purpose of the ADDITIONAL_FREE_type macro. |
580 For example, markers need to be removed from the chain | 572 For example, markers need to be removed from the chain |
584 apply to extents, however). | 576 apply to extents, however). |
585 | 577 |
586 WARNING: Things are in an extremely bizarre state when | 578 WARNING: Things are in an extremely bizarre state when |
587 the ADDITIONAL_FREE_type macros are called, so beware! | 579 the ADDITIONAL_FREE_type macros are called, so beware! |
588 | 580 |
589 When ERROR_CHECK_GC is defined, we do things differently | 581 When ERROR_CHECK_GC is defined, we do things differently so as to |
590 so as to maximize our chances of catching places where | 582 maximize our chances of catching places where there is insufficient |
591 there is insufficient GCPROing. The thing we want to | 583 GCPROing. The thing we want to avoid is having an object that |
592 avoid is having an object that we're using but didn't | 584 we're using but didn't GCPRO get freed by GC and then reallocated |
593 GCPRO get freed by GC and then reallocated while we're | 585 while we're in the process of using it -- this will result in |
594 in the process of using it -- this will result in something | 586 something seemingly unrelated getting trashed, and is extremely |
595 seemingly unrelated getting trashed, and is extremely | 587 difficult to track down. If the object gets freed but not |
596 difficult to track down. If the object gets freed but | 588 reallocated, we can usually catch this because we set most of the |
597 not reallocated, we can usually catch this because we | 589 bytes of a freed object to 0xDEADBEEF. (The lisp object type is set |
598 set all bytes of a freed object to 0xDEADBEEF. (The | 590 to the invalid type `lrecord_type_free', however, and a pointer |
599 first four bytes, however, are 0xFFFFFFFF, and the next | 591 used to chain freed objects together is stored after the lrecord |
600 four are a pointer used to chain freed objects together; | 592 header; we play some tricks with this pointer to make it more |
601 we play some tricks with this pointer to make it more | |
602 bogus, so crashes are more likely to occur right away.) | 593 bogus, so crashes are more likely to occur right away.) |
603 | 594 |
604 We want freed objects to stay free as long as possible, | 595 We want freed objects to stay free as long as possible, |
605 so instead of doing what we do above, we maintain the | 596 so instead of doing what we do above, we maintain the |
606 free objects in a first-in first-out queue. We also | 597 free objects in a first-in first-out queue. We also |
661 }; \ | 652 }; \ |
662 \ | 653 \ |
663 static struct type##_block *current_##type##_block; \ | 654 static struct type##_block *current_##type##_block; \ |
664 static int current_##type##_block_index; \ | 655 static int current_##type##_block_index; \ |
665 \ | 656 \ |
666 static structtype *type##_free_list; \ | 657 static Lisp_Free *type##_free_list; \ |
667 static structtype *type##_free_list_tail; \ | 658 static Lisp_Free *type##_free_list_tail; \ |
668 \ | 659 \ |
669 static void \ | 660 static void \ |
670 init_##type##_alloc (void) \ | 661 init_##type##_alloc (void) \ |
671 { \ | 662 { \ |
672 current_##type##_block = 0; \ | 663 current_##type##_block = 0; \ |
702 /* Note: if you get crashes in this function, suspect incorrect calls | 693 /* Note: if you get crashes in this function, suspect incorrect calls |
703 to free_cons() and friends. This happened once because the cons | 694 to free_cons() and friends. This happened once because the cons |
704 cell was not GC-protected and was getting collected before | 695 cell was not GC-protected and was getting collected before |
705 free_cons() was called. */ | 696 free_cons() was called. */ |
706 | 697 |
707 #define ALLOCATE_FIXED_TYPE_1(type, structtype, result) \ | 698 #define ALLOCATE_FIXED_TYPE_1(type, structtype, result) do { \ |
708 do \ | 699 if (gc_count_num_##type##_freelist > \ |
709 { \ | 700 MINIMUM_ALLOWED_FIXED_TYPE_CELLS_##type) \ |
710 if (gc_count_num_##type##_freelist > \ | |
711 MINIMUM_ALLOWED_FIXED_TYPE_CELLS_##type) \ | |
712 { \ | |
713 result = type##_free_list; \ | |
714 /* Before actually using the chain pointer, we complement all its \ | |
715 bits; see FREE_FIXED_TYPE(). */ \ | |
716 type##_free_list = \ | |
717 (structtype *) ~(unsigned long) \ | |
718 (* (structtype **) ((char *) result + sizeof (void *))); \ | |
719 gc_count_num_##type##_freelist--; \ | |
720 } \ | |
721 else \ | |
722 ALLOCATE_FIXED_TYPE_FROM_BLOCK (type, result); \ | |
723 MARK_STRUCT_AS_NOT_FREE (result); \ | |
724 } while (0) | |
725 | |
726 #else /* !ERROR_CHECK_GC */ | |
727 | |
728 #define ALLOCATE_FIXED_TYPE_1(type, structtype, result) \ | |
729 do \ | |
730 { \ | |
731 if (type##_free_list) \ | |
732 { \ | 701 { \ |
733 result = type##_free_list; \ | 702 result = (structtype *) type##_free_list; \ |
734 type##_free_list = \ | 703 /* Before actually using the chain pointer, \ |
735 * (structtype **) ((char *) result + sizeof (void *)); \ | 704 we complement all its bits; see FREE_FIXED_TYPE(). */ \ |
705 type##_free_list = (Lisp_Free *) \ | |
706 (~ (EMACS_UINT) (type##_free_list->chain)); \ | |
707 gc_count_num_##type##_freelist--; \ | |
736 } \ | 708 } \ |
737 else \ | 709 else \ |
738 ALLOCATE_FIXED_TYPE_FROM_BLOCK (type, result); \ | 710 ALLOCATE_FIXED_TYPE_FROM_BLOCK (type, result); \ |
739 MARK_STRUCT_AS_NOT_FREE (result); \ | 711 MARK_LRECORD_AS_NOT_FREE (result); \ |
740 } while (0) | 712 } while (0) |
741 | 713 |
714 #else /* !ERROR_CHECK_GC */ | |
715 | |
716 #define ALLOCATE_FIXED_TYPE_1(type, structtype, result) do { \ | |
717 if (type##_free_list) \ | |
718 { \ | |
719 result = (structtype *) type##_free_list; \ | |
720 type##_free_list = type##_free_list->chain; \ | |
721 } \ | |
722 else \ | |
723 ALLOCATE_FIXED_TYPE_FROM_BLOCK (type, result); \ | |
724 MARK_LRECORD_AS_NOT_FREE (result); \ | |
725 } while (0) | |
726 | |
742 #endif /* !ERROR_CHECK_GC */ | 727 #endif /* !ERROR_CHECK_GC */ |
728 | |
743 | 729 |
744 #define ALLOCATE_FIXED_TYPE(type, structtype, result) \ | 730 #define ALLOCATE_FIXED_TYPE(type, structtype, result) \ |
745 do \ | 731 do \ |
746 { \ | 732 { \ |
747 ALLOCATE_FIXED_TYPE_1 (type, structtype, result); \ | 733 ALLOCATE_FIXED_TYPE_1 (type, structtype, result); \ |
753 { \ | 739 { \ |
754 ALLOCATE_FIXED_TYPE_1 (type, structtype, result); \ | 740 ALLOCATE_FIXED_TYPE_1 (type, structtype, result); \ |
755 NOSEEUM_INCREMENT_CONS_COUNTER (sizeof (structtype), #type); \ | 741 NOSEEUM_INCREMENT_CONS_COUNTER (sizeof (structtype), #type); \ |
756 } while (0) | 742 } while (0) |
757 | 743 |
758 /* INVALID_POINTER_VALUE should be a value that is invalid as a pointer | 744 |
759 to a Lisp object and invalid as an actual Lisp_Object value. We have | 745 /* Lisp_Free is the type to represent a free list member inside a frob |
760 to make sure that this value cannot be an integer in Lisp_Object form. | 746 block of any lisp object type. */ |
761 0xFFFFFFFF could be so on a 64-bit system, so we extend it to 64 bits. | 747 typedef struct Lisp_Free |
762 On a 32-bit system, the type bits will be non-zero, making the value | 748 { |
763 be a pointer, and the pointer will be misaligned. | 749 struct lrecord_header lheader; |
764 | 750 struct Lisp_Free *chain; |
765 Even if Emacs is run on some weirdo system that allows and allocates | 751 } Lisp_Free; |
766 byte-aligned pointers, this pointer is at the very top of the address | 752 |
767 space and so it's almost inconceivable that it could ever be valid. */ | 753 #define LRECORD_FREE_P(ptr) \ |
768 | 754 ((ptr)->lheader.type == lrecord_type_free) |
769 #if INTBITS == 32 | 755 |
770 # define INVALID_POINTER_VALUE 0xFFFFFFFF | 756 #define MARK_LRECORD_AS_FREE(ptr) \ |
771 #elif INTBITS == 48 | 757 ((void) ((ptr)->lheader.type = lrecord_type_free)) |
772 # define INVALID_POINTER_VALUE 0xFFFFFFFFFFFF | 758 |
773 #elif INTBITS == 64 | 759 #ifdef ERROR_CHECK_GC |
774 # define INVALID_POINTER_VALUE 0xFFFFFFFFFFFFFFFF | 760 #define MARK_LRECORD_AS_NOT_FREE(ptr) \ |
761 ((void) ((ptr)->lheader.type = lrecord_type_undefined)) | |
775 #else | 762 #else |
776 You have some weird system and need to supply a reasonable value here. | 763 #define MARK_LRECORD_AS_NOT_FREE(ptr) DO_NOTHING |
777 #endif | 764 #endif |
778 | 765 |
779 /* The construct (* (void **) (ptr)) would cause aliasing problems | |
780 with modern optimizing compilers like `gcc -O3 -fstrict-aliasing'. | |
781 But `char *' can legally alias any pointer. Hence this union trick... | |
782 | |
783 It turned out that the union trick was not good enough for xlC -O3; | |
784 and it is questionable whether it really complies with the C standard. | |
785 so we use memset instead, which should be safe from optimizations. */ | |
786 typedef union { char c; void *p; } *aliasing_voidpp; | |
787 #define ALIASING_VOIDPP_DEREFERENCE(ptr) \ | |
788 (((aliasing_voidpp) (ptr))->p) | |
789 #define FREE_STRUCT_P(ptr) \ | |
790 (ALIASING_VOIDPP_DEREFERENCE (ptr) == (void *) INVALID_POINTER_VALUE) | |
791 #define MARK_STRUCT_AS_FREE(ptr) memset (ptr, 0xff, sizeof (void *)) | |
792 #define MARK_STRUCT_AS_NOT_FREE(ptr) memset (ptr, 0x00, sizeof (void *)) | |
793 | |
794 #ifdef ERROR_CHECK_GC | 766 #ifdef ERROR_CHECK_GC |
795 | 767 |
796 #define PUT_FIXED_TYPE_ON_FREE_LIST(type, structtype, ptr) \ | 768 #define PUT_FIXED_TYPE_ON_FREE_LIST(type, structtype, ptr) do { \ |
797 do { if (type##_free_list_tail) \ | 769 if (type##_free_list_tail) \ |
798 { \ | 770 { \ |
799 /* When we store the chain pointer, we complement all \ | 771 /* When we store the chain pointer, we complement all \ |
800 its bits; this should significantly increase its \ | 772 its bits; this should significantly increase its \ |
801 bogosity in case someone tries to use the value, and \ | 773 bogosity in case someone tries to use the value, and \ |
802 should make us dump faster if someone stores something \ | 774 should make us crash faster if someone overwrites the \ |
803 over the pointer because when it gets un-complemented in \ | 775 pointer because when it gets un-complemented in \ |
804 ALLOCATED_FIXED_TYPE(), the resulting pointer will be \ | 776 ALLOCATED_FIXED_TYPE(), the resulting pointer will be \ |
805 extremely bogus. */ \ | 777 extremely bogus. */ \ |
806 * (structtype **) \ | 778 type##_free_list_tail->chain = \ |
807 ((char *) type##_free_list_tail + sizeof (void *)) = \ | 779 (Lisp_Free *) ~ (EMACS_UINT) (ptr); \ |
808 (structtype *) ~(unsigned long) ptr; \ | 780 } \ |
809 } \ | 781 else \ |
810 else \ | 782 type##_free_list = (Lisp_Free *) (ptr); \ |
811 type##_free_list = ptr; \ | 783 type##_free_list_tail = (Lisp_Free *) (ptr); \ |
812 type##_free_list_tail = ptr; \ | 784 } while (0) |
813 } while (0) | |
814 | 785 |
815 #else /* !ERROR_CHECK_GC */ | 786 #else /* !ERROR_CHECK_GC */ |
816 | 787 |
817 #define PUT_FIXED_TYPE_ON_FREE_LIST(type, structtype, ptr) \ | 788 #define PUT_FIXED_TYPE_ON_FREE_LIST(type, structtype, ptr) do { \ |
818 do { * (structtype **) ((char *) (ptr) + sizeof (void *)) = \ | 789 ((Lisp_Free *) (ptr))->chain = type##_free_list; \ |
819 type##_free_list; \ | 790 type##_free_list = (Lisp_Free *) (ptr); \ |
820 type##_free_list = (ptr); \ | 791 } while (0) \ |
821 } while (0) | |
822 | 792 |
823 #endif /* !ERROR_CHECK_GC */ | 793 #endif /* !ERROR_CHECK_GC */ |
824 | 794 |
825 /* TYPE and STRUCTTYPE are the same as in ALLOCATE_FIXED_TYPE(). */ | 795 /* TYPE and STRUCTTYPE are the same as in ALLOCATE_FIXED_TYPE(). */ |
826 | 796 |
827 #define FREE_FIXED_TYPE(type, structtype, ptr) do { \ | 797 #define FREE_FIXED_TYPE(type, structtype, ptr) do { \ |
828 structtype *FFT_ptr = (ptr); \ | 798 structtype *FFT_ptr = (ptr); \ |
829 ADDITIONAL_FREE_##type (FFT_ptr); \ | 799 ADDITIONAL_FREE_##type (FFT_ptr); \ |
830 deadbeef_memory (FFT_ptr, sizeof (structtype)); \ | 800 deadbeef_memory (FFT_ptr, sizeof (structtype)); \ |
831 PUT_FIXED_TYPE_ON_FREE_LIST (type, structtype, FFT_ptr); \ | 801 PUT_FIXED_TYPE_ON_FREE_LIST (type, structtype, FFT_ptr); \ |
832 MARK_STRUCT_AS_FREE (FFT_ptr); \ | 802 MARK_LRECORD_AS_FREE (FFT_ptr); \ |
833 } while (0) | 803 } while (0) |
834 | 804 |
835 /* Like FREE_FIXED_TYPE() but used when we are explicitly | 805 /* Like FREE_FIXED_TYPE() but used when we are explicitly |
836 freeing a structure through free_cons(), free_marker(), etc. | 806 freeing a structure through free_cons(), free_marker(), etc. |
837 rather than through the normal process of sweeping. | 807 rather than through the normal process of sweeping. |
1779 ALIGNOF (Lisp_String *)) | 1749 ALIGNOF (Lisp_String *)) |
1780 | 1750 |
1781 #define BIG_STRING_FULLSIZE_P(fullsize) ((fullsize) >= STRING_CHARS_BLOCK_SIZE) | 1751 #define BIG_STRING_FULLSIZE_P(fullsize) ((fullsize) >= STRING_CHARS_BLOCK_SIZE) |
1782 #define BIG_STRING_SIZE_P(size) (BIG_STRING_FULLSIZE_P (STRING_FULLSIZE(size))) | 1752 #define BIG_STRING_SIZE_P(size) (BIG_STRING_FULLSIZE_P (STRING_FULLSIZE(size))) |
1783 | 1753 |
1754 #define STRING_CHARS_FREE_P(ptr) ((ptr)->string == NULL) | |
1755 #define MARK_STRING_CHARS_AS_FREE(ptr) ((void) ((ptr)->string = NULL)) | |
1756 | |
1784 struct string_chars | 1757 struct string_chars |
1785 { | 1758 { |
1786 Lisp_String *string; | 1759 Lisp_String *string; |
1787 unsigned char chars[1]; | 1760 unsigned char chars[1]; |
1788 }; | 1761 }; |
1986 struct string_chars *old_s_chars = (struct string_chars *) | 1959 struct string_chars *old_s_chars = (struct string_chars *) |
1987 ((char *) old_data - offsetof (struct string_chars, chars)); | 1960 ((char *) old_data - offsetof (struct string_chars, chars)); |
1988 /* Sanity check to make sure we aren't hosed by strange | 1961 /* Sanity check to make sure we aren't hosed by strange |
1989 alignment/padding. */ | 1962 alignment/padding. */ |
1990 assert (old_s_chars->string == s); | 1963 assert (old_s_chars->string == s); |
1991 MARK_STRUCT_AS_FREE (old_s_chars); | 1964 MARK_STRING_CHARS_AS_FREE (old_s_chars); |
1992 ((struct unused_string_chars *) old_s_chars)->fullsize = | 1965 ((struct unused_string_chars *) old_s_chars)->fullsize = |
1993 oldfullsize; | 1966 oldfullsize; |
1994 } | 1967 } |
1995 } | 1968 } |
1996 } | 1969 } |
2642 \ | 2615 \ |
2643 for (SFTB_iii = 0; SFTB_iii < SFTB_limit; SFTB_iii++) \ | 2616 for (SFTB_iii = 0; SFTB_iii < SFTB_limit; SFTB_iii++) \ |
2644 { \ | 2617 { \ |
2645 obj_type *SFTB_victim = &(SFTB_current->block[SFTB_iii]); \ | 2618 obj_type *SFTB_victim = &(SFTB_current->block[SFTB_iii]); \ |
2646 \ | 2619 \ |
2647 if (FREE_STRUCT_P (SFTB_victim)) \ | 2620 if (LRECORD_FREE_P (SFTB_victim)) \ |
2648 { \ | 2621 { \ |
2649 num_free++; \ | 2622 num_free++; \ |
2650 } \ | 2623 } \ |
2651 else if (C_READONLY_RECORD_HEADER_P (&SFTB_victim->lheader)) \ | 2624 else if (C_READONLY_RECORD_HEADER_P (&SFTB_victim->lheader)) \ |
2652 { \ | 2625 { \ |
2688 SFTB_current; \ | 2661 SFTB_current; \ |
2689 ) \ | 2662 ) \ |
2690 { \ | 2663 { \ |
2691 int SFTB_iii; \ | 2664 int SFTB_iii; \ |
2692 int SFTB_empty = 1; \ | 2665 int SFTB_empty = 1; \ |
2693 obj_type *SFTB_old_free_list = typename##_free_list; \ | 2666 Lisp_Free *SFTB_old_free_list = typename##_free_list; \ |
2694 \ | 2667 \ |
2695 for (SFTB_iii = 0; SFTB_iii < SFTB_limit; SFTB_iii++) \ | 2668 for (SFTB_iii = 0; SFTB_iii < SFTB_limit; SFTB_iii++) \ |
2696 { \ | 2669 { \ |
2697 obj_type *SFTB_victim = &(SFTB_current->block[SFTB_iii]); \ | 2670 obj_type *SFTB_victim = &(SFTB_current->block[SFTB_iii]); \ |
2698 \ | 2671 \ |
2699 if (FREE_STRUCT_P (SFTB_victim)) \ | 2672 if (LRECORD_FREE_P (SFTB_victim)) \ |
2700 { \ | 2673 { \ |
2701 num_free++; \ | 2674 num_free++; \ |
2702 PUT_FIXED_TYPE_ON_FREE_LIST (typename, obj_type, SFTB_victim); \ | 2675 PUT_FIXED_TYPE_ON_FREE_LIST (typename, obj_type, SFTB_victim); \ |
2703 } \ | 2676 } \ |
2704 else if (C_READONLY_RECORD_HEADER_P (&SFTB_victim->lheader)) \ | 2677 else if (C_READONLY_RECORD_HEADER_P (&SFTB_victim->lheader)) \ |
2912 (struct string_chars *) &(sb->string_chars[pos]); | 2885 (struct string_chars *) &(sb->string_chars[pos]); |
2913 Lisp_String *string; | 2886 Lisp_String *string; |
2914 int size; | 2887 int size; |
2915 int fullsize; | 2888 int fullsize; |
2916 | 2889 |
2917 /* If the string_chars struct is marked as free (i.e. the STRING | 2890 /* If the string_chars struct is marked as free (i.e. the |
2918 pointer is 0xFFFFFFFF) then this is an unused chunk of string | 2891 STRING pointer is NULL) then this is an unused chunk of |
2919 storage. (See below.) */ | 2892 string storage. (See below.) */ |
2920 | 2893 |
2921 if (FREE_STRUCT_P (s_chars)) | 2894 if (STRING_CHARS_FREE_P (s_chars)) |
2922 { | 2895 { |
2923 fullsize = ((struct unused_string_chars *) s_chars)->fullsize; | 2896 fullsize = ((struct unused_string_chars *) s_chars)->fullsize; |
2924 pos += fullsize; | 2897 pos += fullsize; |
2925 continue; | 2898 continue; |
2926 } | 2899 } |
2963 struct string_chars *to_s_chars; | 2936 struct string_chars *to_s_chars; |
2964 Lisp_String *string; | 2937 Lisp_String *string; |
2965 int size; | 2938 int size; |
2966 int fullsize; | 2939 int fullsize; |
2967 | 2940 |
2968 /* If the string_chars struct is marked as free (i.e. the STRING | 2941 /* If the string_chars struct is marked as free (i.e. the |
2969 pointer is 0xFFFFFFFF) then this is an unused chunk of string | 2942 STRING pointer is NULL) then this is an unused chunk of |
2970 storage. This happens under Mule when a string's size changes | 2943 string storage. This happens under Mule when a string's |
2971 in such a way that its fullsize changes. (Strings can change | 2944 size changes in such a way that its fullsize changes. |
2972 size because a different-length character can be substituted | 2945 (Strings can change size because a different-length |
2973 for another character.) In this case, after the bogus string | 2946 character can be substituted for another character.) |
2974 pointer is the "fullsize" of this entry, i.e. how many bytes | 2947 In this case, after the bogus string pointer is the |
2975 to skip. */ | 2948 "fullsize" of this entry, i.e. how many bytes to skip. */ |
2976 | 2949 |
2977 if (FREE_STRUCT_P (from_s_chars)) | 2950 if (STRING_CHARS_FREE_P (from_s_chars)) |
2978 { | 2951 { |
2979 fullsize = ((struct unused_string_chars *) from_s_chars)->fullsize; | 2952 fullsize = ((struct unused_string_chars *) from_s_chars)->fullsize; |
2980 from_pos += fullsize; | 2953 from_pos += fullsize; |
2981 continue; | 2954 continue; |
2982 } | 2955 } |
2983 | 2956 |
2984 string = from_s_chars->string; | 2957 string = from_s_chars->string; |
2985 assert (!(FREE_STRUCT_P (string))); | 2958 assert (!(LRECORD_FREE_P (string))); |
2986 | 2959 |
2987 size = string_length (string); | 2960 size = string_length (string); |
2988 fullsize = STRING_FULLSIZE (size); | 2961 fullsize = STRING_FULLSIZE (size); |
2989 | 2962 |
2990 gc_checking_assert (! BIG_STRING_FULLSIZE_P (fullsize)); | 2963 gc_checking_assert (! BIG_STRING_FULLSIZE_P (fullsize)); |