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));