Mercurial > hg > xemacs-beta
comparison src/alloc.c @ 5140:e5380fdaf8f1
merge
| author | Ben Wing <ben@xemacs.org> |
|---|---|
| date | Sat, 13 Mar 2010 05:38:34 -0600 |
| parents | a9c41067dd88 |
| children | f965e31a35f0 |
comparison
equal
deleted
inserted
replaced
| 5139:a48ef26d87ee | 5140:e5380fdaf8f1 |
|---|---|
| 146 #define NOSEEUM_INCREMENT_CONS_COUNTER(size, type) \ | 146 #define NOSEEUM_INCREMENT_CONS_COUNTER(size, type) \ |
| 147 INCREMENT_CONS_COUNTER_1 (size) | 147 INCREMENT_CONS_COUNTER_1 (size) |
| 148 #endif | 148 #endif |
| 149 | 149 |
| 150 #ifdef NEW_GC | 150 #ifdef NEW_GC |
| 151 /* The call to recompute_need_to_garbage_collect is moved to | 151 /* [[ The call to recompute_need_to_garbage_collect is moved to |
| 152 free_lrecord, since DECREMENT_CONS_COUNTER is extensively called | 152 free_normal_lisp_object, since DECREMENT_CONS_COUNTER is extensively called |
| 153 during sweep and recomputing need_to_garbage_collect all the time | 153 during sweep and recomputing need_to_garbage_collect all the time |
| 154 is not needed. */ | 154 is not needed. ]] -- not accurate! */ |
| 155 #define DECREMENT_CONS_COUNTER(size) do { \ | 155 #define DECREMENT_CONS_COUNTER(size) do { \ |
| 156 consing_since_gc -= (size); \ | 156 consing_since_gc -= (size); \ |
| 157 total_consing -= (size); \ | 157 total_consing -= (size); \ |
| 158 if (profiling_active) \ | 158 if (profiling_active) \ |
| 159 profile_record_unconsing (size); \ | 159 profile_record_unconsing (size); \ |
| 560 size += lrecord_stats[i].bytes_in_use; | 560 size += lrecord_stats[i].bytes_in_use; |
| 561 return size; | 561 return size; |
| 562 } | 562 } |
| 563 #endif /* NEW_GC && ALLOC_TYPE_STATS */ | 563 #endif /* NEW_GC && ALLOC_TYPE_STATS */ |
| 564 | 564 |
| 565 #define assert_proper_sizing(size) \ | |
| 566 type_checking_assert \ | |
| 567 (implementation->static_size == 0 ? \ | |
| 568 implementation->size_in_bytes_method != NULL : \ | |
| 569 implementation->size_in_bytes_method == NULL && \ | |
| 570 implementation->static_size == size) | |
| 571 | |
| 565 #ifndef NEW_GC | 572 #ifndef NEW_GC |
| 566 /* lcrecords are chained together through their "next" field. | 573 /* lcrecords are chained together through their "next" field. |
| 567 After doing the mark phase, GC will walk this linked list | 574 After doing the mark phase, GC will walk this linked list |
| 568 and free any lcrecord which hasn't been marked. */ | 575 and free any lcrecord which hasn't been marked. */ |
| 569 static struct old_lcrecord_header *all_lcrecords; | 576 static struct old_lcrecord_header *all_lcrecords; |
| 570 #endif /* not NEW_GC */ | 577 #endif /* not NEW_GC */ |
| 571 | 578 |
| 572 #ifdef NEW_GC | 579 #ifdef NEW_GC |
| 573 /* The basic lrecord allocation functions. See lrecord.h for details. */ | 580 /* The basic lrecord allocation functions. See lrecord.h for details. */ |
| 574 void * | 581 static Lisp_Object |
| 575 alloc_lrecord (Bytecount size, | 582 alloc_sized_lrecord_1 (Bytecount size, |
| 576 const struct lrecord_implementation *implementation) | 583 const struct lrecord_implementation *implementation, |
| 584 int noseeum) | |
| 577 { | 585 { |
| 578 struct lrecord_header *lheader; | 586 struct lrecord_header *lheader; |
| 579 | 587 |
| 580 type_checking_assert | 588 assert_proper_sizing (size); |
| 581 ((implementation->static_size == 0 ? | |
| 582 implementation->size_in_bytes_method != NULL : | |
| 583 implementation->static_size == size)); | |
| 584 | 589 |
| 585 lheader = (struct lrecord_header *) mc_alloc (size); | 590 lheader = (struct lrecord_header *) mc_alloc (size); |
| 586 gc_checking_assert (LRECORD_FREE_P (lheader)); | 591 gc_checking_assert (LRECORD_FREE_P (lheader)); |
| 587 set_lheader_implementation (lheader, implementation); | 592 set_lheader_implementation (lheader, implementation); |
| 593 lheader->uid = lrecord_uid_counter++; | |
| 588 #ifdef ALLOC_TYPE_STATS | 594 #ifdef ALLOC_TYPE_STATS |
| 589 inc_lrecord_stats (size, lheader); | 595 inc_lrecord_stats (size, lheader); |
| 590 #endif /* ALLOC_TYPE_STATS */ | 596 #endif /* ALLOC_TYPE_STATS */ |
| 591 if (implementation->finalizer) | 597 if (implementation->finalizer) |
| 592 add_finalizable_obj (wrap_pointer_1 (lheader)); | 598 add_finalizable_obj (wrap_pointer_1 (lheader)); |
| 593 INCREMENT_CONS_COUNTER (size, implementation->name); | 599 if (noseeum) |
| 594 return lheader; | 600 NOSEEUM_INCREMENT_CONS_COUNTER (size, implementation->name); |
| 595 } | 601 else |
| 596 | 602 INCREMENT_CONS_COUNTER (size, implementation->name); |
| 597 | 603 return wrap_pointer_1 (lheader); |
| 598 void * | 604 } |
| 599 noseeum_alloc_lrecord (Bytecount size, | 605 |
| 600 const struct lrecord_implementation *implementation) | 606 Lisp_Object |
| 601 { | 607 alloc_sized_lrecord (Bytecount size, |
| 602 struct lrecord_header *lheader; | |
| 603 | |
| 604 type_checking_assert | |
| 605 ((implementation->static_size == 0 ? | |
| 606 implementation->size_in_bytes_method != NULL : | |
| 607 implementation->static_size == size)); | |
| 608 | |
| 609 lheader = (struct lrecord_header *) mc_alloc (size); | |
| 610 gc_checking_assert (LRECORD_FREE_P (lheader)); | |
| 611 set_lheader_implementation (lheader, implementation); | |
| 612 #ifdef ALLOC_TYPE_STATS | |
| 613 inc_lrecord_stats (size, lheader); | |
| 614 #endif /* ALLOC_TYPE_STATS */ | |
| 615 if (implementation->finalizer) | |
| 616 add_finalizable_obj (wrap_pointer_1 (lheader)); | |
| 617 NOSEEUM_INCREMENT_CONS_COUNTER (size, implementation->name); | |
| 618 return lheader; | |
| 619 } | |
| 620 | |
| 621 void * | |
| 622 alloc_lrecord_array (Bytecount size, int elemcount, | |
| 623 const struct lrecord_implementation *implementation) | 608 const struct lrecord_implementation *implementation) |
| 609 { | |
| 610 return alloc_sized_lrecord_1 (size, implementation, 0); | |
| 611 } | |
| 612 | |
| 613 Lisp_Object | |
| 614 noseeum_alloc_sized_lrecord (Bytecount size, | |
| 615 const struct lrecord_implementation * | |
| 616 implementation) | |
| 617 { | |
| 618 return alloc_sized_lrecord_1 (size, implementation, 1); | |
| 619 } | |
| 620 | |
| 621 Lisp_Object | |
| 622 alloc_lrecord (const struct lrecord_implementation *implementation) | |
| 623 { | |
| 624 type_checking_assert (implementation->static_size > 0); | |
| 625 return alloc_sized_lrecord (implementation->static_size, implementation); | |
| 626 } | |
| 627 | |
| 628 Lisp_Object | |
| 629 noseeum_alloc_lrecord (const struct lrecord_implementation *implementation) | |
| 630 { | |
| 631 type_checking_assert (implementation->static_size > 0); | |
| 632 return noseeum_alloc_sized_lrecord (implementation->static_size, implementation); | |
| 633 } | |
| 634 | |
| 635 Lisp_Object | |
| 636 alloc_sized_lrecord_array (Bytecount size, int elemcount, | |
| 637 const struct lrecord_implementation *implementation) | |
| 624 { | 638 { |
| 625 struct lrecord_header *lheader; | 639 struct lrecord_header *lheader; |
| 626 Rawbyte *start, *stop; | 640 Rawbyte *start, *stop; |
| 627 | 641 |
| 628 type_checking_assert | 642 assert_proper_sizing (size); |
| 629 ((implementation->static_size == 0 ? | |
| 630 implementation->size_in_bytes_method != NULL : | |
| 631 implementation->static_size == size)); | |
| 632 | 643 |
| 633 lheader = (struct lrecord_header *) mc_alloc_array (size, elemcount); | 644 lheader = (struct lrecord_header *) mc_alloc_array (size, elemcount); |
| 634 gc_checking_assert (LRECORD_FREE_P (lheader)); | 645 gc_checking_assert (LRECORD_FREE_P (lheader)); |
| 635 | 646 |
| 636 for (start = (Rawbyte *) lheader, | 647 for (start = (Rawbyte *) lheader, |
| 637 stop = ((Rawbyte *) lheader) + (size * elemcount -1); | 648 /* #### FIXME: why is this -1 present? */ |
| 649 stop = ((Rawbyte *) lheader) + (size * elemcount -1); | |
| 638 start < stop; start += size) | 650 start < stop; start += size) |
| 639 { | 651 { |
| 640 struct lrecord_header *lh = (struct lrecord_header *) start; | 652 struct lrecord_header *lh = (struct lrecord_header *) start; |
| 641 set_lheader_implementation (lh, implementation); | 653 set_lheader_implementation (lh, implementation); |
| 642 lh->uid = lrecord_uid_counter++; | 654 lh->uid = lrecord_uid_counter++; |
| 644 inc_lrecord_stats (size, lh); | 656 inc_lrecord_stats (size, lh); |
| 645 #endif /* not ALLOC_TYPE_STATS */ | 657 #endif /* not ALLOC_TYPE_STATS */ |
| 646 if (implementation->finalizer) | 658 if (implementation->finalizer) |
| 647 add_finalizable_obj (wrap_pointer_1 (lh)); | 659 add_finalizable_obj (wrap_pointer_1 (lh)); |
| 648 } | 660 } |
| 661 | |
| 649 INCREMENT_CONS_COUNTER (size * elemcount, implementation->name); | 662 INCREMENT_CONS_COUNTER (size * elemcount, implementation->name); |
| 650 return lheader; | 663 return wrap_pointer_1 (lheader); |
| 651 } | 664 } |
| 652 | 665 |
| 653 void | 666 Lisp_Object |
| 654 free_lrecord (Lisp_Object UNUSED (lrecord)) | 667 alloc_lrecord_array (int elemcount, |
| 655 { | 668 const struct lrecord_implementation *implementation) |
| 656 /* Manual frees are not allowed with asynchronous finalization */ | 669 { |
| 657 return; | 670 type_checking_assert (implementation->static_size > 0); |
| 658 } | 671 return alloc_sized_lrecord_array (implementation->static_size, elemcount, |
| 672 implementation); | |
| 673 } | |
| 674 | |
| 659 #else /* not NEW_GC */ | 675 #else /* not NEW_GC */ |
| 660 | 676 |
| 661 /* The most basic of the lcrecord allocation functions. Not usually called | 677 /* The most basic of the lcrecord allocation functions. Not usually called |
| 662 directly. Allocates an lrecord not managed by any lcrecord-list, of a | 678 directly. Allocates an lrecord not managed by any lcrecord-list, of a |
| 663 specified size. See lrecord.h. */ | 679 specified size. See lrecord.h. */ |
| 664 | 680 |
| 665 void * | 681 Lisp_Object |
| 666 old_basic_alloc_lcrecord (Bytecount size, | 682 old_alloc_sized_lcrecord (Bytecount size, |
| 667 const struct lrecord_implementation *implementation) | 683 const struct lrecord_implementation *implementation) |
| 668 { | 684 { |
| 669 struct old_lcrecord_header *lcheader; | 685 struct old_lcrecord_header *lcheader; |
| 670 | 686 |
| 687 assert_proper_sizing (size); | |
| 671 type_checking_assert | 688 type_checking_assert |
| 672 ((implementation->static_size == 0 ? | 689 (!implementation->frob_block_p |
| 673 implementation->size_in_bytes_method != NULL : | |
| 674 implementation->static_size == size) | |
| 675 && | 690 && |
| 676 (! implementation->basic_p) | 691 !(implementation->hash == NULL && implementation->equal != NULL)); |
| 677 && | |
| 678 (! (implementation->hash == NULL && implementation->equal != NULL))); | |
| 679 | 692 |
| 680 lcheader = (struct old_lcrecord_header *) allocate_lisp_storage (size); | 693 lcheader = (struct old_lcrecord_header *) allocate_lisp_storage (size); |
| 681 set_lheader_implementation (&lcheader->lheader, implementation); | 694 set_lheader_implementation (&lcheader->lheader, implementation); |
| 682 lcheader->next = all_lcrecords; | 695 lcheader->next = all_lcrecords; |
| 683 #if 1 /* mly prefers to see small ID numbers */ | 696 #if 1 /* mly prefers to see small ID numbers */ |
| 686 lcheader->uid = (int) &lcheader; | 699 lcheader->uid = (int) &lcheader; |
| 687 #endif | 700 #endif |
| 688 lcheader->free = 0; | 701 lcheader->free = 0; |
| 689 all_lcrecords = lcheader; | 702 all_lcrecords = lcheader; |
| 690 INCREMENT_CONS_COUNTER (size, implementation->name); | 703 INCREMENT_CONS_COUNTER (size, implementation->name); |
| 691 return lcheader; | 704 return wrap_pointer_1 (lcheader); |
| 705 } | |
| 706 | |
| 707 Lisp_Object | |
| 708 old_alloc_lcrecord (const struct lrecord_implementation *implementation) | |
| 709 { | |
| 710 type_checking_assert (implementation->static_size > 0); | |
| 711 return old_alloc_sized_lcrecord (implementation->static_size, | |
| 712 implementation); | |
| 692 } | 713 } |
| 693 | 714 |
| 694 #if 0 /* Presently unused */ | 715 #if 0 /* Presently unused */ |
| 695 /* Very, very poor man's EGC? | 716 /* Very, very poor man's EGC? |
| 696 * This may be slow and thrash pages all over the place. | 717 * This may be slow and thrash pages all over the place. |
| 721 else | 742 else |
| 722 header = next; | 743 header = next; |
| 723 } | 744 } |
| 724 } | 745 } |
| 725 if (lrecord->implementation->finalizer) | 746 if (lrecord->implementation->finalizer) |
| 726 lrecord->implementation->finalizer (lrecord, 0); | 747 lrecord->implementation->finalizer (wrap_pointer_1 (lrecord)); |
| 727 xfree (lrecord); | 748 xfree (lrecord); |
| 728 return; | 749 return; |
| 729 } | 750 } |
| 730 #endif /* Unused */ | 751 #endif /* Unused */ |
| 731 #endif /* not NEW_GC */ | 752 #endif /* not NEW_GC */ |
| 739 #else /* not NEW_GC */ | 760 #else /* not NEW_GC */ |
| 740 struct old_lcrecord_header *header; | 761 struct old_lcrecord_header *header; |
| 741 | 762 |
| 742 for (header = all_lcrecords; header; header = header->next) | 763 for (header = all_lcrecords; header; header = header->next) |
| 743 { | 764 { |
| 744 if (LHEADER_IMPLEMENTATION (&header->lheader)->finalizer && | 765 struct lrecord_header *objh = &header->lheader; |
| 745 !header->free) | 766 const struct lrecord_implementation *imp = LHEADER_IMPLEMENTATION (objh); |
| 746 LHEADER_IMPLEMENTATION (&header->lheader)->finalizer (header, 1); | 767 #if 0 /* possibly useful for debugging */ |
| 768 if (!RECORD_DUMPABLE (objh) && !header->free) | |
| 769 { | |
| 770 stderr_out ("Disksaving a non-dumpable object: "); | |
| 771 debug_print (wrap_pointer_1 (header)); | |
| 772 } | |
| 773 #endif | |
| 774 if (imp->disksaver && !header->free) | |
| 775 (imp->disksaver) (wrap_pointer_1 (header)); | |
| 747 } | 776 } |
| 748 #endif /* not NEW_GC */ | 777 #endif /* not NEW_GC */ |
| 749 } | 778 } |
| 750 | 779 |
| 751 /* Bitwise copy all parts of a Lisp object other than the header */ | 780 /* Bitwise copy all parts of a Lisp object other than the header */ |
| 763 #ifdef NEW_GC | 792 #ifdef NEW_GC |
| 764 memcpy ((char *) XRECORD_LHEADER (dst) + sizeof (struct lrecord_header), | 793 memcpy ((char *) XRECORD_LHEADER (dst) + sizeof (struct lrecord_header), |
| 765 (char *) XRECORD_LHEADER (src) + sizeof (struct lrecord_header), | 794 (char *) XRECORD_LHEADER (src) + sizeof (struct lrecord_header), |
| 766 size - sizeof (struct lrecord_header)); | 795 size - sizeof (struct lrecord_header)); |
| 767 #else /* not NEW_GC */ | 796 #else /* not NEW_GC */ |
| 768 if (imp->basic_p) | 797 if (imp->frob_block_p) |
| 769 memcpy ((char *) XRECORD_LHEADER (dst) + sizeof (struct lrecord_header), | 798 memcpy ((char *) XRECORD_LHEADER (dst) + sizeof (struct lrecord_header), |
| 770 (char *) XRECORD_LHEADER (src) + sizeof (struct lrecord_header), | 799 (char *) XRECORD_LHEADER (src) + sizeof (struct lrecord_header), |
| 771 size - sizeof (struct lrecord_header)); | 800 size - sizeof (struct lrecord_header)); |
| 772 else | 801 else |
| 773 memcpy ((char *) XRECORD_LHEADER (dst) + | 802 memcpy ((char *) XRECORD_LHEADER (dst) + |
| 774 sizeof (struct old_lcrecord_header), | 803 sizeof (struct old_lcrecord_header), |
| 775 (char *) XRECORD_LHEADER (src) + | 804 (char *) XRECORD_LHEADER (src) + |
| 776 sizeof (struct old_lcrecord_header), | 805 sizeof (struct old_lcrecord_header), |
| 777 size - sizeof (struct old_lcrecord_header)); | 806 size - sizeof (struct old_lcrecord_header)); |
| 778 #endif /* not NEW_GC */ | 807 #endif /* not NEW_GC */ |
| 808 } | |
| 809 | |
| 810 /* Zero out all parts of a Lisp object other than the header, for a | |
| 811 variable-sized object. The size needs to be given explicitly because | |
| 812 at the time this is called, the contents of the object may not be | |
| 813 defined, or may not be set up in such a way that we can reliably | |
| 814 retrieve the size, since it may depend on settings inside of the object. */ | |
| 815 | |
| 816 void | |
| 817 zero_sized_lisp_object (Lisp_Object obj, Bytecount size) | |
| 818 { | |
| 819 #ifndef NEW_GC | |
| 820 const struct lrecord_implementation *imp = | |
| 821 XRECORD_LHEADER_IMPLEMENTATION (obj); | |
| 822 #endif /* not NEW_GC */ | |
| 823 | |
| 824 #ifdef NEW_GC | |
| 825 memset ((char *) XRECORD_LHEADER (obj) + sizeof (struct lrecord_header), 0, | |
| 826 size - sizeof (struct lrecord_header)); | |
| 827 #else /* not NEW_GC */ | |
| 828 if (imp->frob_block_p) | |
| 829 memset ((char *) XRECORD_LHEADER (obj) + sizeof (struct lrecord_header), 0, | |
| 830 size - sizeof (struct lrecord_header)); | |
| 831 else | |
| 832 memset ((char *) XRECORD_LHEADER (obj) + | |
| 833 sizeof (struct old_lcrecord_header), 0, | |
| 834 size - sizeof (struct old_lcrecord_header)); | |
| 835 #endif /* not NEW_GC */ | |
| 836 } | |
| 837 | |
| 838 /* Zero out all parts of a Lisp object other than the header, for an object | |
| 839 that isn't variable-size. Objects that are variable-size need to use | |
| 840 zero_sized_lisp_object(). | |
| 841 */ | |
| 842 | |
| 843 void | |
| 844 zero_nonsized_lisp_object (Lisp_Object obj) | |
| 845 { | |
| 846 const struct lrecord_implementation *imp = | |
| 847 XRECORD_LHEADER_IMPLEMENTATION (obj); | |
| 848 assert (!imp->size_in_bytes_method); | |
| 849 | |
| 850 zero_sized_lisp_object (obj, lisp_object_size (obj)); | |
| 851 } | |
| 852 | |
| 853 #ifdef MEMORY_USAGE_STATS | |
| 854 | |
| 855 Bytecount | |
| 856 lisp_object_storage_size (Lisp_Object obj, struct overhead_stats *ovstats) | |
| 857 { | |
| 858 #ifndef NEW_GC | |
| 859 const struct lrecord_implementation *imp = | |
| 860 XRECORD_LHEADER_IMPLEMENTATION (obj); | |
| 861 #endif /* not NEW_GC */ | |
| 862 Bytecount size = lisp_object_size (obj); | |
| 863 | |
| 864 #ifdef NEW_GC | |
| 865 return mc_alloced_storage_size (size, ovstats); | |
| 866 #else | |
| 867 if (imp->frob_block_p) | |
| 868 { | |
| 869 Bytecount overhead = fixed_type_block_overhead (size); | |
| 870 if (ovstats) | |
| 871 { | |
| 872 ovstats->was_requested += size; | |
| 873 ovstats->malloc_overhead += overhead; | |
| 874 } | |
| 875 return size + overhead; | |
| 876 } | |
| 877 else | |
| 878 return malloced_storage_size (XPNTR (obj), size, ovstats); | |
| 879 #endif | |
| 880 } | |
| 881 | |
| 882 #endif /* MEMORY_USAGE_STATS */ | |
| 883 | |
| 884 void | |
| 885 free_normal_lisp_object (Lisp_Object obj) | |
| 886 { | |
| 887 #ifndef NEW_GC | |
| 888 const struct lrecord_implementation *imp = | |
| 889 XRECORD_LHEADER_IMPLEMENTATION (obj); | |
| 890 #endif /* not NEW_GC */ | |
| 891 | |
| 892 #ifdef NEW_GC | |
| 893 /* Manual frees are not allowed with asynchronous finalization */ | |
| 894 return; | |
| 895 #else | |
| 896 assert (!imp->frob_block_p); | |
| 897 assert (!imp->size_in_bytes_method); | |
| 898 old_free_lcrecord (obj); | |
| 899 #endif | |
| 779 } | 900 } |
| 780 | 901 |
| 781 | 902 |
| 782 /************************************************************************/ | 903 /************************************************************************/ |
| 783 /* Debugger support */ | 904 /* Debugger support */ |
| 1152 } while (0) | 1273 } while (0) |
| 1153 #endif /* NEW_GC */ | 1274 #endif /* NEW_GC */ |
| 1154 | 1275 |
| 1155 #ifdef NEW_GC | 1276 #ifdef NEW_GC |
| 1156 #define FREE_FIXED_TYPE_WHEN_NOT_IN_GC(lo, type, structtype, ptr) \ | 1277 #define FREE_FIXED_TYPE_WHEN_NOT_IN_GC(lo, type, structtype, ptr) \ |
| 1157 free_lrecord (lo) | 1278 free_normal_lisp_object (lo) |
| 1158 #else /* not NEW_GC */ | 1279 #else /* not NEW_GC */ |
| 1159 /* Like FREE_FIXED_TYPE() but used when we are explicitly | 1280 /* Like FREE_FIXED_TYPE() but used when we are explicitly |
| 1160 freeing a structure through free_cons(), free_marker(), etc. | 1281 freeing a structure through free_cons(), free_marker(), etc. |
| 1161 rather than through the normal process of sweeping. | 1282 rather than through the normal process of sweeping. |
| 1162 We attempt to undo the changes made to the allocation counters | 1283 We attempt to undo the changes made to the allocation counters |
| 1179 #define FREE_FIXED_TYPE_WHEN_NOT_IN_GC(lo, type, structtype, ptr) | 1300 #define FREE_FIXED_TYPE_WHEN_NOT_IN_GC(lo, type, structtype, ptr) |
| 1180 #endif | 1301 #endif |
| 1181 #endif /* (not) NEW_GC */ | 1302 #endif /* (not) NEW_GC */ |
| 1182 | 1303 |
| 1183 #ifdef NEW_GC | 1304 #ifdef NEW_GC |
| 1184 #define ALLOCATE_FIXED_TYPE_AND_SET_IMPL(type, lisp_type, var, lrec_ptr) \ | 1305 #define ALLOC_FROB_BLOCK_LISP_OBJECT(type, lisp_type, var, lrec_ptr)\ |
| 1185 do { \ | 1306 do { \ |
| 1186 (var) = alloc_lrecord_type (lisp_type, lrec_ptr); \ | 1307 (var) = (lisp_type *) XPNTR (ALLOC_NORMAL_LISP_OBJECT (type)); \ |
| 1187 } while (0) | 1308 } while (0) |
| 1188 #define NOSEEUM_ALLOCATE_FIXED_TYPE_AND_SET_IMPL(type, lisp_type, var, \ | 1309 #define NOSEEUM_ALLOC_FROB_BLOCK_LISP_OBJECT(type, lisp_type, var, \ |
| 1189 lrec_ptr) \ | 1310 lrec_ptr) \ |
| 1190 do { \ | 1311 do { \ |
| 1191 (var) = noseeum_alloc_lrecord_type (lisp_type, lrec_ptr); \ | 1312 (var) = (lisp_type *) XPNTR (noseeum_alloc_lrecord (lrec_ptr)); \ |
| 1192 } while (0) | 1313 } while (0) |
| 1193 #else /* not NEW_GC */ | 1314 #else /* not NEW_GC */ |
| 1194 #define ALLOCATE_FIXED_TYPE_AND_SET_IMPL(type, lisp_type, var, lrec_ptr) \ | 1315 #define ALLOC_FROB_BLOCK_LISP_OBJECT(type, lisp_type, var, lrec_ptr) \ |
| 1195 do \ | 1316 do \ |
| 1196 { \ | 1317 { \ |
| 1197 ALLOCATE_FIXED_TYPE (type, lisp_type, var); \ | 1318 ALLOCATE_FIXED_TYPE (type, lisp_type, var); \ |
| 1198 set_lheader_implementation (&(var)->lheader, lrec_ptr); \ | 1319 set_lheader_implementation (&(var)->lheader, lrec_ptr); \ |
| 1199 } while (0) | 1320 } while (0) |
| 1200 #define NOSEEUM_ALLOCATE_FIXED_TYPE_AND_SET_IMPL(type, lisp_type, var, \ | 1321 #define NOSEEUM_ALLOC_FROB_BLOCK_LISP_OBJECT(type, lisp_type, var, \ |
| 1201 lrec_ptr) \ | 1322 lrec_ptr) \ |
| 1202 do \ | 1323 do \ |
| 1203 { \ | 1324 { \ |
| 1204 NOSEEUM_ALLOCATE_FIXED_TYPE (type, lisp_type, var); \ | 1325 NOSEEUM_ALLOCATE_FIXED_TYPE (type, lisp_type, var); \ |
| 1205 set_lheader_implementation (&(var)->lheader, lrec_ptr); \ | 1326 set_lheader_implementation (&(var)->lheader, lrec_ptr); \ |
| 1245 { XD_LISP_OBJECT, offsetof (Lisp_Cons, car_) }, | 1366 { XD_LISP_OBJECT, offsetof (Lisp_Cons, car_) }, |
| 1246 { XD_LISP_OBJECT, offsetof (Lisp_Cons, cdr_) }, | 1367 { XD_LISP_OBJECT, offsetof (Lisp_Cons, cdr_) }, |
| 1247 { XD_END } | 1368 { XD_END } |
| 1248 }; | 1369 }; |
| 1249 | 1370 |
| 1250 DEFINE_BASIC_LRECORD_IMPLEMENTATION ("cons", cons, | 1371 DEFINE_DUMPABLE_FROB_BLOCK_LISP_OBJECT ("cons", cons, |
| 1251 1, /*dumpable-flag*/ | 1372 mark_cons, print_cons, 0, cons_equal, |
| 1252 mark_cons, print_cons, 0, | 1373 /* |
| 1253 cons_equal, | 1374 * No `hash' method needed. |
| 1254 /* | 1375 * internal_hash knows how to |
| 1255 * No `hash' method needed. | 1376 * handle conses. |
| 1256 * internal_hash knows how to | 1377 */ |
| 1257 * handle conses. | 1378 0, cons_description, Lisp_Cons); |
| 1258 */ | |
| 1259 0, | |
| 1260 cons_description, | |
| 1261 Lisp_Cons); | |
| 1262 | 1379 |
| 1263 DEFUN ("cons", Fcons, 2, 2, 0, /* | 1380 DEFUN ("cons", Fcons, 2, 2, 0, /* |
| 1264 Create a new cons cell, give it CAR and CDR as components, and return it. | 1381 Create a new cons cell, give it CAR and CDR as components, and return it. |
| 1265 | 1382 |
| 1266 A cons cell is a Lisp object (an area in memory) made up of two pointers | 1383 A cons cell is a Lisp object (an area in memory) made up of two pointers |
| 1276 { | 1393 { |
| 1277 /* This cannot GC. */ | 1394 /* This cannot GC. */ |
| 1278 Lisp_Object val; | 1395 Lisp_Object val; |
| 1279 Lisp_Cons *c; | 1396 Lisp_Cons *c; |
| 1280 | 1397 |
| 1281 ALLOCATE_FIXED_TYPE_AND_SET_IMPL (cons, Lisp_Cons, c, &lrecord_cons); | 1398 ALLOC_FROB_BLOCK_LISP_OBJECT (cons, Lisp_Cons, c, &lrecord_cons); |
| 1282 val = wrap_cons (c); | 1399 val = wrap_cons (c); |
| 1283 XSETCAR (val, car); | 1400 XSETCAR (val, car); |
| 1284 XSETCDR (val, cdr); | 1401 XSETCDR (val, cdr); |
| 1285 return val; | 1402 return val; |
| 1286 } | 1403 } |
| 1292 noseeum_cons (Lisp_Object car, Lisp_Object cdr) | 1409 noseeum_cons (Lisp_Object car, Lisp_Object cdr) |
| 1293 { | 1410 { |
| 1294 Lisp_Object val; | 1411 Lisp_Object val; |
| 1295 Lisp_Cons *c; | 1412 Lisp_Cons *c; |
| 1296 | 1413 |
| 1297 NOSEEUM_ALLOCATE_FIXED_TYPE_AND_SET_IMPL (cons, Lisp_Cons, c, &lrecord_cons); | 1414 NOSEEUM_ALLOC_FROB_BLOCK_LISP_OBJECT (cons, Lisp_Cons, c, &lrecord_cons); |
| 1298 val = wrap_cons (c); | 1415 val = wrap_cons (c); |
| 1299 XCAR (val) = car; | 1416 XCAR (val) = car; |
| 1300 XCDR (val) = cdr; | 1417 XCDR (val) = cdr; |
| 1301 return val; | 1418 return val; |
| 1302 } | 1419 } |
| 1404 Lisp_Object | 1521 Lisp_Object |
| 1405 make_float (double float_value) | 1522 make_float (double float_value) |
| 1406 { | 1523 { |
| 1407 Lisp_Float *f; | 1524 Lisp_Float *f; |
| 1408 | 1525 |
| 1409 ALLOCATE_FIXED_TYPE_AND_SET_IMPL (float, Lisp_Float, f, &lrecord_float); | 1526 ALLOC_FROB_BLOCK_LISP_OBJECT (float, Lisp_Float, f, &lrecord_float); |
| 1410 | 1527 |
| 1411 /* Avoid dump-time `uninitialized memory read' purify warnings. */ | 1528 /* Avoid dump-time `uninitialized memory read' purify warnings. */ |
| 1412 if (sizeof (struct lrecord_header) + sizeof (double) != sizeof (*f)) | 1529 if (sizeof (struct lrecord_header) + sizeof (double) != sizeof (*f)) |
| 1413 zero_lrecord (f); | 1530 zero_nonsized_lisp_object (wrap_float (f)); |
| 1414 | 1531 |
| 1415 float_data (f) = float_value; | 1532 float_data (f) = float_value; |
| 1416 return wrap_float (f); | 1533 return wrap_float (f); |
| 1417 } | 1534 } |
| 1418 | 1535 |
| 1431 Lisp_Object | 1548 Lisp_Object |
| 1432 make_bignum (long bignum_value) | 1549 make_bignum (long bignum_value) |
| 1433 { | 1550 { |
| 1434 Lisp_Bignum *b; | 1551 Lisp_Bignum *b; |
| 1435 | 1552 |
| 1436 ALLOCATE_FIXED_TYPE_AND_SET_IMPL (bignum, Lisp_Bignum, b, &lrecord_bignum); | 1553 ALLOC_FROB_BLOCK_LISP_OBJECT (bignum, Lisp_Bignum, b, &lrecord_bignum); |
| 1437 bignum_init (bignum_data (b)); | 1554 bignum_init (bignum_data (b)); |
| 1438 bignum_set_long (bignum_data (b), bignum_value); | 1555 bignum_set_long (bignum_data (b), bignum_value); |
| 1439 return wrap_bignum (b); | 1556 return wrap_bignum (b); |
| 1440 } | 1557 } |
| 1441 | 1558 |
| 1444 Lisp_Object | 1561 Lisp_Object |
| 1445 make_bignum_bg (bignum bg) | 1562 make_bignum_bg (bignum bg) |
| 1446 { | 1563 { |
| 1447 Lisp_Bignum *b; | 1564 Lisp_Bignum *b; |
| 1448 | 1565 |
| 1449 ALLOCATE_FIXED_TYPE_AND_SET_IMPL (bignum, Lisp_Bignum, b, &lrecord_bignum); | 1566 ALLOC_FROB_BLOCK_LISP_OBJECT (bignum, Lisp_Bignum, b, &lrecord_bignum); |
| 1450 bignum_init (bignum_data (b)); | 1567 bignum_init (bignum_data (b)); |
| 1451 bignum_set (bignum_data (b), bg); | 1568 bignum_set (bignum_data (b), bg); |
| 1452 return wrap_bignum (b); | 1569 return wrap_bignum (b); |
| 1453 } | 1570 } |
| 1454 #endif /* HAVE_BIGNUM */ | 1571 #endif /* HAVE_BIGNUM */ |
| 1461 Lisp_Object | 1578 Lisp_Object |
| 1462 make_ratio (long numerator, unsigned long denominator) | 1579 make_ratio (long numerator, unsigned long denominator) |
| 1463 { | 1580 { |
| 1464 Lisp_Ratio *r; | 1581 Lisp_Ratio *r; |
| 1465 | 1582 |
| 1466 ALLOCATE_FIXED_TYPE_AND_SET_IMPL (ratio, Lisp_Ratio, r, &lrecord_ratio); | 1583 ALLOC_FROB_BLOCK_LISP_OBJECT (ratio, Lisp_Ratio, r, &lrecord_ratio); |
| 1467 ratio_init (ratio_data (r)); | 1584 ratio_init (ratio_data (r)); |
| 1468 ratio_set_long_ulong (ratio_data (r), numerator, denominator); | 1585 ratio_set_long_ulong (ratio_data (r), numerator, denominator); |
| 1469 ratio_canonicalize (ratio_data (r)); | 1586 ratio_canonicalize (ratio_data (r)); |
| 1470 return wrap_ratio (r); | 1587 return wrap_ratio (r); |
| 1471 } | 1588 } |
| 1473 Lisp_Object | 1590 Lisp_Object |
| 1474 make_ratio_bg (bignum numerator, bignum denominator) | 1591 make_ratio_bg (bignum numerator, bignum denominator) |
| 1475 { | 1592 { |
| 1476 Lisp_Ratio *r; | 1593 Lisp_Ratio *r; |
| 1477 | 1594 |
| 1478 ALLOCATE_FIXED_TYPE_AND_SET_IMPL (ratio, Lisp_Ratio, r, &lrecord_ratio); | 1595 ALLOC_FROB_BLOCK_LISP_OBJECT (ratio, Lisp_Ratio, r, &lrecord_ratio); |
| 1479 ratio_init (ratio_data (r)); | 1596 ratio_init (ratio_data (r)); |
| 1480 ratio_set_bignum_bignum (ratio_data (r), numerator, denominator); | 1597 ratio_set_bignum_bignum (ratio_data (r), numerator, denominator); |
| 1481 ratio_canonicalize (ratio_data (r)); | 1598 ratio_canonicalize (ratio_data (r)); |
| 1482 return wrap_ratio (r); | 1599 return wrap_ratio (r); |
| 1483 } | 1600 } |
| 1485 Lisp_Object | 1602 Lisp_Object |
| 1486 make_ratio_rt (ratio rat) | 1603 make_ratio_rt (ratio rat) |
| 1487 { | 1604 { |
| 1488 Lisp_Ratio *r; | 1605 Lisp_Ratio *r; |
| 1489 | 1606 |
| 1490 ALLOCATE_FIXED_TYPE_AND_SET_IMPL (ratio, Lisp_Ratio, r, &lrecord_ratio); | 1607 ALLOC_FROB_BLOCK_LISP_OBJECT (ratio, Lisp_Ratio, r, &lrecord_ratio); |
| 1491 ratio_init (ratio_data (r)); | 1608 ratio_init (ratio_data (r)); |
| 1492 ratio_set (ratio_data (r), rat); | 1609 ratio_set (ratio_data (r), rat); |
| 1493 return wrap_ratio (r); | 1610 return wrap_ratio (r); |
| 1494 } | 1611 } |
| 1495 #endif /* HAVE_RATIO */ | 1612 #endif /* HAVE_RATIO */ |
| 1504 Lisp_Object | 1621 Lisp_Object |
| 1505 make_bigfloat (double float_value, unsigned long precision) | 1622 make_bigfloat (double float_value, unsigned long precision) |
| 1506 { | 1623 { |
| 1507 Lisp_Bigfloat *f; | 1624 Lisp_Bigfloat *f; |
| 1508 | 1625 |
| 1509 ALLOCATE_FIXED_TYPE_AND_SET_IMPL (bigfloat, Lisp_Bigfloat, f, &lrecord_bigfloat); | 1626 ALLOC_FROB_BLOCK_LISP_OBJECT (bigfloat, Lisp_Bigfloat, f, &lrecord_bigfloat); |
| 1510 if (precision == 0UL) | 1627 if (precision == 0UL) |
| 1511 bigfloat_init (bigfloat_data (f)); | 1628 bigfloat_init (bigfloat_data (f)); |
| 1512 else | 1629 else |
| 1513 bigfloat_init_prec (bigfloat_data (f), precision); | 1630 bigfloat_init_prec (bigfloat_data (f), precision); |
| 1514 bigfloat_set_double (bigfloat_data (f), float_value); | 1631 bigfloat_set_double (bigfloat_data (f), float_value); |
| 1519 Lisp_Object | 1636 Lisp_Object |
| 1520 make_bigfloat_bf (bigfloat float_value) | 1637 make_bigfloat_bf (bigfloat float_value) |
| 1521 { | 1638 { |
| 1522 Lisp_Bigfloat *f; | 1639 Lisp_Bigfloat *f; |
| 1523 | 1640 |
| 1524 ALLOCATE_FIXED_TYPE_AND_SET_IMPL (bigfloat, Lisp_Bigfloat, f, &lrecord_bigfloat); | 1641 ALLOC_FROB_BLOCK_LISP_OBJECT (bigfloat, Lisp_Bigfloat, f, &lrecord_bigfloat); |
| 1525 bigfloat_init_prec (bigfloat_data (f), bigfloat_get_prec (float_value)); | 1642 bigfloat_init_prec (bigfloat_data (f), bigfloat_get_prec (float_value)); |
| 1526 bigfloat_set (bigfloat_data (f), float_value); | 1643 bigfloat_set (bigfloat_data (f), float_value); |
| 1527 return wrap_bigfloat (f); | 1644 return wrap_bigfloat (f); |
| 1528 } | 1645 } |
| 1529 #endif /* HAVE_BIGFLOAT */ | 1646 #endif /* HAVE_BIGFLOAT */ |
| 1543 mark_object (ptr->contents[i]); | 1660 mark_object (ptr->contents[i]); |
| 1544 return (len > 0) ? ptr->contents[len - 1] : Qnil; | 1661 return (len > 0) ? ptr->contents[len - 1] : Qnil; |
| 1545 } | 1662 } |
| 1546 | 1663 |
| 1547 static Bytecount | 1664 static Bytecount |
| 1548 size_vector (const void *lheader) | 1665 size_vector (Lisp_Object obj) |
| 1549 { | 1666 { |
| 1667 | |
| 1550 return FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Vector, Lisp_Object, contents, | 1668 return FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Vector, Lisp_Object, contents, |
| 1551 ((Lisp_Vector *) lheader)->size); | 1669 XVECTOR (obj)->size); |
| 1552 } | 1670 } |
| 1553 | 1671 |
| 1554 static int | 1672 static int |
| 1555 vector_equal (Lisp_Object obj1, Lisp_Object obj2, int depth, int foldcase) | 1673 vector_equal (Lisp_Object obj1, Lisp_Object obj2, int depth, int foldcase) |
| 1556 { | 1674 { |
| 1581 { XD_LONG, offsetof (Lisp_Vector, size) }, | 1699 { XD_LONG, offsetof (Lisp_Vector, size) }, |
| 1582 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Vector, contents), XD_INDIRECT(0, 0) }, | 1700 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Vector, contents), XD_INDIRECT(0, 0) }, |
| 1583 { XD_END } | 1701 { XD_END } |
| 1584 }; | 1702 }; |
| 1585 | 1703 |
| 1586 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("vector", vector, | 1704 DEFINE_DUMPABLE_SIZABLE_LISP_OBJECT ("vector", vector, |
| 1587 1, /*dumpable-flag*/ | 1705 mark_vector, print_vector, 0, |
| 1588 mark_vector, print_vector, 0, | 1706 vector_equal, |
| 1589 vector_equal, | 1707 vector_hash, |
| 1590 vector_hash, | 1708 vector_description, |
| 1591 vector_description, | 1709 size_vector, Lisp_Vector); |
| 1592 size_vector, Lisp_Vector); | |
| 1593 /* #### should allocate `small' vectors from a frob-block */ | 1710 /* #### should allocate `small' vectors from a frob-block */ |
| 1594 static Lisp_Vector * | 1711 static Lisp_Vector * |
| 1595 make_vector_internal (Elemcount sizei) | 1712 make_vector_internal (Elemcount sizei) |
| 1596 { | 1713 { |
| 1597 /* no `next' field; we use lcrecords */ | 1714 /* no `next' field; we use lcrecords */ |
| 1598 Bytecount sizem = FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Vector, Lisp_Object, | 1715 Bytecount sizem = FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Vector, Lisp_Object, |
| 1599 contents, sizei); | 1716 contents, sizei); |
| 1600 Lisp_Vector *p = | 1717 Lisp_Object obj = ALLOC_SIZED_LISP_OBJECT (sizem, vector); |
| 1601 (Lisp_Vector *) BASIC_ALLOC_LCRECORD (sizem, &lrecord_vector); | 1718 Lisp_Vector *p = XVECTOR (obj); |
| 1602 | 1719 |
| 1603 p->size = sizei; | 1720 p->size = sizei; |
| 1604 return p; | 1721 return p; |
| 1605 } | 1722 } |
| 1606 | 1723 |
| 1754 /* no `next' field; we use lcrecords */ | 1871 /* no `next' field; we use lcrecords */ |
| 1755 Elemcount num_longs = BIT_VECTOR_LONG_STORAGE (sizei); | 1872 Elemcount num_longs = BIT_VECTOR_LONG_STORAGE (sizei); |
| 1756 Bytecount sizem = FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Bit_Vector, | 1873 Bytecount sizem = FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Bit_Vector, |
| 1757 unsigned long, | 1874 unsigned long, |
| 1758 bits, num_longs); | 1875 bits, num_longs); |
| 1759 Lisp_Bit_Vector *p = (Lisp_Bit_Vector *) | 1876 Lisp_Object obj = ALLOC_SIZED_LISP_OBJECT (sizem, bit_vector); |
| 1760 BASIC_ALLOC_LCRECORD (sizem, &lrecord_bit_vector); | 1877 Lisp_Bit_Vector *p = XBIT_VECTOR (obj); |
| 1761 | 1878 |
| 1762 bit_vector_length (p) = sizei; | 1879 bit_vector_length (p) = sizei; |
| 1763 return p; | 1880 return p; |
| 1764 } | 1881 } |
| 1765 | 1882 |
| 1841 static Lisp_Object | 1958 static Lisp_Object |
| 1842 make_compiled_function (void) | 1959 make_compiled_function (void) |
| 1843 { | 1960 { |
| 1844 Lisp_Compiled_Function *f; | 1961 Lisp_Compiled_Function *f; |
| 1845 | 1962 |
| 1846 ALLOCATE_FIXED_TYPE_AND_SET_IMPL (compiled_function, Lisp_Compiled_Function, | 1963 ALLOC_FROB_BLOCK_LISP_OBJECT (compiled_function, Lisp_Compiled_Function, |
| 1847 f, &lrecord_compiled_function); | 1964 f, &lrecord_compiled_function); |
| 1848 | 1965 |
| 1849 f->stack_depth = 0; | 1966 f->stack_depth = 0; |
| 1850 f->specpdl_depth = 0; | 1967 f->specpdl_depth = 0; |
| 1851 f->flags.documentationp = 0; | 1968 f->flags.documentationp = 0; |
| 1979 { | 2096 { |
| 1980 Lisp_Symbol *p; | 2097 Lisp_Symbol *p; |
| 1981 | 2098 |
| 1982 CHECK_STRING (name); | 2099 CHECK_STRING (name); |
| 1983 | 2100 |
| 1984 ALLOCATE_FIXED_TYPE_AND_SET_IMPL (symbol, Lisp_Symbol, p, &lrecord_symbol); | 2101 ALLOC_FROB_BLOCK_LISP_OBJECT (symbol, Lisp_Symbol, p, &lrecord_symbol); |
| 1985 p->name = name; | 2102 p->name = name; |
| 1986 p->plist = Qnil; | 2103 p->plist = Qnil; |
| 1987 p->value = Qunbound; | 2104 p->value = Qunbound; |
| 1988 p->function = Qunbound; | 2105 p->function = Qunbound; |
| 1989 symbol_next (p) = 0; | 2106 symbol_next (p) = 0; |
| 2001 struct extent * | 2118 struct extent * |
| 2002 allocate_extent (void) | 2119 allocate_extent (void) |
| 2003 { | 2120 { |
| 2004 struct extent *e; | 2121 struct extent *e; |
| 2005 | 2122 |
| 2006 ALLOCATE_FIXED_TYPE_AND_SET_IMPL (extent, struct extent, e, &lrecord_extent); | 2123 ALLOC_FROB_BLOCK_LISP_OBJECT (extent, struct extent, e, &lrecord_extent); |
| 2007 extent_object (e) = Qnil; | 2124 extent_object (e) = Qnil; |
| 2008 set_extent_start (e, -1); | 2125 set_extent_start (e, -1); |
| 2009 set_extent_end (e, -1); | 2126 set_extent_end (e, -1); |
| 2010 e->plist = Qnil; | 2127 e->plist = Qnil; |
| 2011 | 2128 |
| 2029 Lisp_Object | 2146 Lisp_Object |
| 2030 allocate_event (void) | 2147 allocate_event (void) |
| 2031 { | 2148 { |
| 2032 Lisp_Event *e; | 2149 Lisp_Event *e; |
| 2033 | 2150 |
| 2034 ALLOCATE_FIXED_TYPE_AND_SET_IMPL (event, Lisp_Event, e, &lrecord_event); | 2151 ALLOC_FROB_BLOCK_LISP_OBJECT (event, Lisp_Event, e, &lrecord_event); |
| 2035 | 2152 |
| 2036 return wrap_event (e); | 2153 return wrap_event (e); |
| 2037 } | 2154 } |
| 2038 | 2155 |
| 2039 #ifdef EVENT_DATA_AS_OBJECTS | 2156 #ifdef EVENT_DATA_AS_OBJECTS |
| 2043 Lisp_Object | 2160 Lisp_Object |
| 2044 make_key_data (void) | 2161 make_key_data (void) |
| 2045 { | 2162 { |
| 2046 Lisp_Key_Data *d; | 2163 Lisp_Key_Data *d; |
| 2047 | 2164 |
| 2048 ALLOCATE_FIXED_TYPE_AND_SET_IMPL (key_data, Lisp_Key_Data, d, | 2165 ALLOC_FROB_BLOCK_LISP_OBJECT (key_data, Lisp_Key_Data, d, |
| 2049 &lrecord_key_data); | 2166 &lrecord_key_data); |
| 2050 zero_lrecord (d); | 2167 zero_nonsized_lisp_object (wrap_key_data (d)); |
| 2051 d->keysym = Qnil; | 2168 d->keysym = Qnil; |
| 2052 | 2169 |
| 2053 return wrap_key_data (d); | 2170 return wrap_key_data (d); |
| 2054 } | 2171 } |
| 2055 | 2172 |
| 2059 Lisp_Object | 2176 Lisp_Object |
| 2060 make_button_data (void) | 2177 make_button_data (void) |
| 2061 { | 2178 { |
| 2062 Lisp_Button_Data *d; | 2179 Lisp_Button_Data *d; |
| 2063 | 2180 |
| 2064 ALLOCATE_FIXED_TYPE_AND_SET_IMPL (button_data, Lisp_Button_Data, d, &lrecord_button_data); | 2181 ALLOC_FROB_BLOCK_LISP_OBJECT (button_data, Lisp_Button_Data, d, &lrecord_button_data); |
| 2065 zero_lrecord (d); | 2182 zero_nonsized_lisp_object (wrap_button_data (d)); |
| 2066 return wrap_button_data (d); | 2183 return wrap_button_data (d); |
| 2067 } | 2184 } |
| 2068 | 2185 |
| 2069 DECLARE_FIXED_TYPE_ALLOC (motion_data, Lisp_Motion_Data); | 2186 DECLARE_FIXED_TYPE_ALLOC (motion_data, Lisp_Motion_Data); |
| 2070 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_motion_data 1000 | 2187 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_motion_data 1000 |
| 2072 Lisp_Object | 2189 Lisp_Object |
| 2073 make_motion_data (void) | 2190 make_motion_data (void) |
| 2074 { | 2191 { |
| 2075 Lisp_Motion_Data *d; | 2192 Lisp_Motion_Data *d; |
| 2076 | 2193 |
| 2077 ALLOCATE_FIXED_TYPE_AND_SET_IMPL (motion_data, Lisp_Motion_Data, d, &lrecord_motion_data); | 2194 ALLOC_FROB_BLOCK_LISP_OBJECT (motion_data, Lisp_Motion_Data, d, &lrecord_motion_data); |
| 2078 zero_lrecord (d); | 2195 zero_nonsized_lisp_object (wrap_motion_data (d)); |
| 2079 | 2196 |
| 2080 return wrap_motion_data (d); | 2197 return wrap_motion_data (d); |
| 2081 } | 2198 } |
| 2082 | 2199 |
| 2083 DECLARE_FIXED_TYPE_ALLOC (process_data, Lisp_Process_Data); | 2200 DECLARE_FIXED_TYPE_ALLOC (process_data, Lisp_Process_Data); |
| 2086 Lisp_Object | 2203 Lisp_Object |
| 2087 make_process_data (void) | 2204 make_process_data (void) |
| 2088 { | 2205 { |
| 2089 Lisp_Process_Data *d; | 2206 Lisp_Process_Data *d; |
| 2090 | 2207 |
| 2091 ALLOCATE_FIXED_TYPE_AND_SET_IMPL (process_data, Lisp_Process_Data, d, &lrecord_process_data); | 2208 ALLOC_FROB_BLOCK_LISP_OBJECT (process_data, Lisp_Process_Data, d, &lrecord_process_data); |
| 2092 zero_lrecord (d); | 2209 zero_nonsized_lisp_object (wrap_process_data (d)); |
| 2093 d->process = Qnil; | 2210 d->process = Qnil; |
| 2094 | 2211 |
| 2095 return wrap_process_data (d); | 2212 return wrap_process_data (d); |
| 2096 } | 2213 } |
| 2097 | 2214 |
| 2101 Lisp_Object | 2218 Lisp_Object |
| 2102 make_timeout_data (void) | 2219 make_timeout_data (void) |
| 2103 { | 2220 { |
| 2104 Lisp_Timeout_Data *d; | 2221 Lisp_Timeout_Data *d; |
| 2105 | 2222 |
| 2106 ALLOCATE_FIXED_TYPE_AND_SET_IMPL (timeout_data, Lisp_Timeout_Data, d, &lrecord_timeout_data); | 2223 ALLOC_FROB_BLOCK_LISP_OBJECT (timeout_data, Lisp_Timeout_Data, d, &lrecord_timeout_data); |
| 2107 zero_lrecord (d); | 2224 zero_nonsized_lisp_object (wrap_timeout_data (d)); |
| 2108 d->function = Qnil; | 2225 d->function = Qnil; |
| 2109 d->object = Qnil; | 2226 d->object = Qnil; |
| 2110 | 2227 |
| 2111 return wrap_timeout_data (d); | 2228 return wrap_timeout_data (d); |
| 2112 } | 2229 } |
| 2117 Lisp_Object | 2234 Lisp_Object |
| 2118 make_magic_data (void) | 2235 make_magic_data (void) |
| 2119 { | 2236 { |
| 2120 Lisp_Magic_Data *d; | 2237 Lisp_Magic_Data *d; |
| 2121 | 2238 |
| 2122 ALLOCATE_FIXED_TYPE_AND_SET_IMPL (magic_data, Lisp_Magic_Data, d, &lrecord_magic_data); | 2239 ALLOC_FROB_BLOCK_LISP_OBJECT (magic_data, Lisp_Magic_Data, d, &lrecord_magic_data); |
| 2123 zero_lrecord (d); | 2240 zero_nonsized_lisp_object (wrap_magic_data (d)); |
| 2124 | 2241 |
| 2125 return wrap_magic_data (d); | 2242 return wrap_magic_data (d); |
| 2126 } | 2243 } |
| 2127 | 2244 |
| 2128 DECLARE_FIXED_TYPE_ALLOC (magic_eval_data, Lisp_Magic_Eval_Data); | 2245 DECLARE_FIXED_TYPE_ALLOC (magic_eval_data, Lisp_Magic_Eval_Data); |
| 2131 Lisp_Object | 2248 Lisp_Object |
| 2132 make_magic_eval_data (void) | 2249 make_magic_eval_data (void) |
| 2133 { | 2250 { |
| 2134 Lisp_Magic_Eval_Data *d; | 2251 Lisp_Magic_Eval_Data *d; |
| 2135 | 2252 |
| 2136 ALLOCATE_FIXED_TYPE_AND_SET_IMPL (magic_eval_data, Lisp_Magic_Eval_Data, d, &lrecord_magic_eval_data); | 2253 ALLOC_FROB_BLOCK_LISP_OBJECT (magic_eval_data, Lisp_Magic_Eval_Data, d, &lrecord_magic_eval_data); |
| 2137 zero_lrecord (d); | 2254 zero_nonsized_lisp_object (wrap_magic_eval_data (d)); |
| 2138 d->object = Qnil; | 2255 d->object = Qnil; |
| 2139 | 2256 |
| 2140 return wrap_magic_eval_data (d); | 2257 return wrap_magic_eval_data (d); |
| 2141 } | 2258 } |
| 2142 | 2259 |
| 2146 Lisp_Object | 2263 Lisp_Object |
| 2147 make_eval_data (void) | 2264 make_eval_data (void) |
| 2148 { | 2265 { |
| 2149 Lisp_Eval_Data *d; | 2266 Lisp_Eval_Data *d; |
| 2150 | 2267 |
| 2151 ALLOCATE_FIXED_TYPE_AND_SET_IMPL (eval_data, Lisp_Eval_Data, d, &lrecord_eval_data); | 2268 ALLOC_FROB_BLOCK_LISP_OBJECT (eval_data, Lisp_Eval_Data, d, &lrecord_eval_data); |
| 2152 zero_lrecord (d); | 2269 zero_nonsized_lisp_object (wrap_eval_data (d)); |
| 2153 d->function = Qnil; | 2270 d->function = Qnil; |
| 2154 d->object = Qnil; | 2271 d->object = Qnil; |
| 2155 | 2272 |
| 2156 return wrap_eval_data (d); | 2273 return wrap_eval_data (d); |
| 2157 } | 2274 } |
| 2162 Lisp_Object | 2279 Lisp_Object |
| 2163 make_misc_user_data (void) | 2280 make_misc_user_data (void) |
| 2164 { | 2281 { |
| 2165 Lisp_Misc_User_Data *d; | 2282 Lisp_Misc_User_Data *d; |
| 2166 | 2283 |
| 2167 ALLOCATE_FIXED_TYPE_AND_SET_IMPL (misc_user_data, Lisp_Misc_User_Data, d, &lrecord_misc_user_data); | 2284 ALLOC_FROB_BLOCK_LISP_OBJECT (misc_user_data, Lisp_Misc_User_Data, d, &lrecord_misc_user_data); |
| 2168 zero_lrecord (d); | 2285 zero_nonsized_lisp_object (wrap_misc_user_data (d)); |
| 2169 d->function = Qnil; | 2286 d->function = Qnil; |
| 2170 d->object = Qnil; | 2287 d->object = Qnil; |
| 2171 | 2288 |
| 2172 return wrap_misc_user_data (d); | 2289 return wrap_misc_user_data (d); |
| 2173 } | 2290 } |
| 2186 */ | 2303 */ |
| 2187 ()) | 2304 ()) |
| 2188 { | 2305 { |
| 2189 Lisp_Marker *p; | 2306 Lisp_Marker *p; |
| 2190 | 2307 |
| 2191 ALLOCATE_FIXED_TYPE_AND_SET_IMPL (marker, Lisp_Marker, p, &lrecord_marker); | 2308 ALLOC_FROB_BLOCK_LISP_OBJECT (marker, Lisp_Marker, p, &lrecord_marker); |
| 2192 p->buffer = 0; | 2309 p->buffer = 0; |
| 2193 p->membpos = 0; | 2310 p->membpos = 0; |
| 2194 marker_next (p) = 0; | 2311 marker_next (p) = 0; |
| 2195 marker_prev (p) = 0; | 2312 marker_prev (p) = 0; |
| 2196 p->insertion_type = 0; | 2313 p->insertion_type = 0; |
| 2200 Lisp_Object | 2317 Lisp_Object |
| 2201 noseeum_make_marker (void) | 2318 noseeum_make_marker (void) |
| 2202 { | 2319 { |
| 2203 Lisp_Marker *p; | 2320 Lisp_Marker *p; |
| 2204 | 2321 |
| 2205 NOSEEUM_ALLOCATE_FIXED_TYPE_AND_SET_IMPL (marker, Lisp_Marker, p, | 2322 NOSEEUM_ALLOC_FROB_BLOCK_LISP_OBJECT (marker, Lisp_Marker, p, |
| 2206 &lrecord_marker); | 2323 &lrecord_marker); |
| 2207 p->buffer = 0; | 2324 p->buffer = 0; |
| 2208 p->membpos = 0; | 2325 p->membpos = 0; |
| 2209 marker_next (p) = 0; | 2326 marker_next (p) = 0; |
| 2210 marker_prev (p) = 0; | 2327 marker_prev (p) = 0; |
| 2217 /* String allocation */ | 2334 /* String allocation */ |
| 2218 /************************************************************************/ | 2335 /************************************************************************/ |
| 2219 | 2336 |
| 2220 /* The data for "short" strings generally resides inside of structs of type | 2337 /* The data for "short" strings generally resides inside of structs of type |
| 2221 string_chars_block. The Lisp_String structure is allocated just like any | 2338 string_chars_block. The Lisp_String structure is allocated just like any |
| 2222 other basic lrecord, and these are freelisted when they get garbage | 2339 other frob-block lrecord, and these are freelisted when they get garbage |
| 2223 collected. The data for short strings get compacted, but the data for | 2340 collected. The data for short strings get compacted, but the data for |
| 2224 large strings do not. | 2341 large strings do not. |
| 2225 | 2342 |
| 2226 Previously Lisp_String structures were relocated, but this caused a lot | 2343 Previously Lisp_String structures were relocated, but this caused a lot |
| 2227 of bus-errors because the C code didn't include enough GCPRO's for | 2344 of bus-errors because the C code didn't include enough GCPRO's for |
| 2318 internal_hash() already knows how to hash strings and finalization | 2435 internal_hash() already knows how to hash strings and finalization |
| 2319 is done with the ADDITIONAL_FREE_string macro, which is the | 2436 is done with the ADDITIONAL_FREE_string macro, which is the |
| 2320 standard way to do finalization when using | 2437 standard way to do finalization when using |
| 2321 SWEEP_FIXED_TYPE_BLOCK(). */ | 2438 SWEEP_FIXED_TYPE_BLOCK(). */ |
| 2322 | 2439 |
| 2323 DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS ("string", string, | 2440 DEFINE_DUMPABLE_FROB_BLOCK_GENERAL_LISP_OBJECT ("string", string, |
| 2324 1, /*dumpable-flag*/ | |
| 2325 mark_string, print_string, | 2441 mark_string, print_string, |
| 2326 0, string_equal, 0, | 2442 0, string_equal, 0, |
| 2327 string_description, | 2443 string_description, |
| 2328 string_getprop, | 2444 string_getprop, |
| 2329 string_putprop, | 2445 string_putprop, |
| 2330 string_remprop, | 2446 string_remprop, |
| 2331 string_plist, | 2447 string_plist, |
| 2448 0 /* no disksaver */, | |
| 2332 Lisp_String); | 2449 Lisp_String); |
| 2333 #endif /* not NEW_GC */ | 2450 #endif /* not NEW_GC */ |
| 2334 | 2451 |
| 2335 #ifdef NEW_GC | 2452 #ifdef NEW_GC |
| 2336 #define STRING_FULLSIZE(size) \ | 2453 #define STRING_FULLSIZE(size) \ |
| 2368 #define STRING_CHARS_FREE_P(ptr) ((ptr)->string == NULL) | 2485 #define STRING_CHARS_FREE_P(ptr) ((ptr)->string == NULL) |
| 2369 #define MARK_STRING_CHARS_AS_FREE(ptr) ((void) ((ptr)->string = NULL)) | 2486 #define MARK_STRING_CHARS_AS_FREE(ptr) ((void) ((ptr)->string = NULL)) |
| 2370 #endif /* not NEW_GC */ | 2487 #endif /* not NEW_GC */ |
| 2371 | 2488 |
| 2372 #ifdef NEW_GC | 2489 #ifdef NEW_GC |
| 2373 DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS ("string", string, | 2490 DEFINE_DUMPABLE_GENERAL_LISP_OBJECT ("string", string, |
| 2374 1, /*dumpable-flag*/ | 2491 mark_string, print_string, |
| 2375 mark_string, print_string, | 2492 0, |
| 2376 0, | 2493 string_equal, 0, |
| 2377 string_equal, 0, | 2494 string_description, |
| 2378 string_description, | 2495 string_getprop, |
| 2379 string_getprop, | 2496 string_putprop, |
| 2380 string_putprop, | 2497 string_remprop, |
| 2381 string_remprop, | 2498 string_plist, |
| 2382 string_plist, | 2499 0 /* no disksaver */, |
| 2383 Lisp_String); | 2500 Lisp_String); |
| 2384 | 2501 |
| 2385 | 2502 |
| 2386 static const struct memory_description string_direct_data_description[] = { | 2503 static const struct memory_description string_direct_data_description[] = { |
| 2387 { XD_BYTECOUNT, offsetof (Lisp_String_Direct_Data, size) }, | 2504 { XD_BYTECOUNT, offsetof (Lisp_String_Direct_Data, size) }, |
| 2388 { XD_END } | 2505 { XD_END } |
| 2389 }; | 2506 }; |
| 2390 | 2507 |
| 2391 static Bytecount | 2508 static Bytecount |
| 2392 size_string_direct_data (const void *lheader) | 2509 size_string_direct_data (Lisp_Object obj) |
| 2393 { | 2510 { |
| 2394 return STRING_FULLSIZE (((Lisp_String_Direct_Data *) lheader)->size); | 2511 return STRING_FULLSIZE (XSTRING_DIRECT_DATA (obj)->size); |
| 2395 } | 2512 } |
| 2396 | 2513 |
| 2397 | 2514 |
| 2398 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("string-direct-data", | 2515 DEFINE_DUMPABLE_SIZABLE_INTERNAL_LISP_OBJECT ("string-direct-data", |
| 2399 string_direct_data, | 2516 string_direct_data, |
| 2400 1, /*dumpable-flag*/ | 2517 0, |
| 2401 0, 0, 0, 0, 0, | 2518 string_direct_data_description, |
| 2402 string_direct_data_description, | 2519 size_string_direct_data, |
| 2403 size_string_direct_data, | 2520 Lisp_String_Direct_Data); |
| 2404 Lisp_String_Direct_Data); | |
| 2405 | 2521 |
| 2406 | 2522 |
| 2407 static const struct memory_description string_indirect_data_description[] = { | 2523 static const struct memory_description string_indirect_data_description[] = { |
| 2408 { XD_BYTECOUNT, offsetof (Lisp_String_Indirect_Data, size) }, | 2524 { XD_BYTECOUNT, offsetof (Lisp_String_Indirect_Data, size) }, |
| 2409 { XD_OPAQUE_DATA_PTR, offsetof (Lisp_String_Indirect_Data, data), | 2525 { XD_OPAQUE_DATA_PTR, offsetof (Lisp_String_Indirect_Data, data), |
| 2410 XD_INDIRECT(0, 1) }, | 2526 XD_INDIRECT(0, 1) }, |
| 2411 { XD_END } | 2527 { XD_END } |
| 2412 }; | 2528 }; |
| 2413 | 2529 |
| 2414 DEFINE_LRECORD_IMPLEMENTATION ("string-indirect-data", | 2530 DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT ("string-indirect-data", |
| 2415 string_indirect_data, | 2531 string_indirect_data, |
| 2416 1, /*dumpable-flag*/ | 2532 0, |
| 2417 0, 0, 0, 0, 0, | 2533 string_indirect_data_description, |
| 2418 string_indirect_data_description, | 2534 Lisp_String_Indirect_Data); |
| 2419 Lisp_String_Indirect_Data); | |
| 2420 #endif /* NEW_GC */ | 2535 #endif /* NEW_GC */ |
| 2421 | 2536 |
| 2422 #ifndef NEW_GC | 2537 #ifndef NEW_GC |
| 2423 struct string_chars | 2538 struct string_chars |
| 2424 { | 2539 { |
| 2518 Bytecount fullsize = STRING_FULLSIZE (length); | 2633 Bytecount fullsize = STRING_FULLSIZE (length); |
| 2519 | 2634 |
| 2520 assert (length >= 0 && fullsize > 0); | 2635 assert (length >= 0 && fullsize > 0); |
| 2521 | 2636 |
| 2522 #ifdef NEW_GC | 2637 #ifdef NEW_GC |
| 2523 s = alloc_lrecord_type (Lisp_String, &lrecord_string); | 2638 s = XSTRING (ALLOC_NORMAL_LISP_OBJECT (string)); |
| 2524 #else /* not NEW_GC */ | 2639 #else /* not NEW_GC */ |
| 2525 /* Allocate the string header */ | 2640 /* Allocate the string header */ |
| 2526 ALLOCATE_FIXED_TYPE (string, Lisp_String, s); | 2641 ALLOCATE_FIXED_TYPE (string, Lisp_String, s); |
| 2527 xzero (*s); | 2642 xzero (*s); |
| 2528 set_lheader_implementation (&s->u.lheader, &lrecord_string); | 2643 set_lheader_implementation (&s->u.lheader, &lrecord_string); |
| 2533 XSET_STRING_ASCII_BEGIN (wrap_string (s), 0); | 2648 XSET_STRING_ASCII_BEGIN (wrap_string (s), 0); |
| 2534 | 2649 |
| 2535 #ifdef NEW_GC | 2650 #ifdef NEW_GC |
| 2536 set_lispstringp_direct (s); | 2651 set_lispstringp_direct (s); |
| 2537 STRING_DATA_OBJECT (s) = | 2652 STRING_DATA_OBJECT (s) = |
| 2538 wrap_string_direct_data (alloc_lrecord (fullsize, | 2653 alloc_sized_lrecord (fullsize, &lrecord_string_direct_data); |
| 2539 &lrecord_string_direct_data)); | |
| 2540 #else /* not NEW_GC */ | 2654 #else /* not NEW_GC */ |
| 2541 set_lispstringp_data (s, BIG_STRING_FULLSIZE_P (fullsize) | 2655 set_lispstringp_data (s, BIG_STRING_FULLSIZE_P (fullsize) |
| 2542 ? allocate_big_string_chars (length + 1) | 2656 ? allocate_big_string_chars (length + 1) |
| 2543 : allocate_string_chars_struct (wrap_string (s), | 2657 : allocate_string_chars_struct (wrap_string (s), |
| 2544 fullsize)->chars); | 2658 fullsize)->chars); |
| 2981 #if defined (ERROR_CHECK_TEXT) && defined (MULE) | 3095 #if defined (ERROR_CHECK_TEXT) && defined (MULE) |
| 2982 bytecount_to_charcount (contents, length); /* Just for the assertions */ | 3096 bytecount_to_charcount (contents, length); /* Just for the assertions */ |
| 2983 #endif | 3097 #endif |
| 2984 | 3098 |
| 2985 #ifdef NEW_GC | 3099 #ifdef NEW_GC |
| 2986 s = alloc_lrecord_type (Lisp_String, &lrecord_string); | 3100 s = XSTRING (ALLOC_NORMAL_LISP_OBJECT (string)); |
| 2987 mcpro (wrap_pointer_1 (s)); /* otherwise nocopy_strings get | 3101 mcpro (wrap_pointer_1 (s)); /* otherwise nocopy_strings get |
| 2988 collected and static data is tried to | 3102 collected and static data is tried to |
| 2989 be freed. */ | 3103 be freed. */ |
| 2990 #else /* not NEW_GC */ | 3104 #else /* not NEW_GC */ |
| 2991 /* Allocate the string header */ | 3105 /* Allocate the string header */ |
| 2996 /* Don't need to XSET_STRING_ASCII_BEGIN() here because it happens in | 3110 /* Don't need to XSET_STRING_ASCII_BEGIN() here because it happens in |
| 2997 init_string_ascii_begin(). */ | 3111 init_string_ascii_begin(). */ |
| 2998 s->plist = Qnil; | 3112 s->plist = Qnil; |
| 2999 #ifdef NEW_GC | 3113 #ifdef NEW_GC |
| 3000 set_lispstringp_indirect (s); | 3114 set_lispstringp_indirect (s); |
| 3001 STRING_DATA_OBJECT (s) = | 3115 STRING_DATA_OBJECT (s) = ALLOC_NORMAL_LISP_OBJECT (string_indirect_data); |
| 3002 wrap_string_indirect_data | |
| 3003 (alloc_lrecord_type (Lisp_String_Indirect_Data, | |
| 3004 &lrecord_string_indirect_data)); | |
| 3005 XSTRING_INDIRECT_DATA_DATA (STRING_DATA_OBJECT (s)) = (Ibyte *) contents; | 3116 XSTRING_INDIRECT_DATA_DATA (STRING_DATA_OBJECT (s)) = (Ibyte *) contents; |
| 3006 XSTRING_INDIRECT_DATA_SIZE (STRING_DATA_OBJECT (s)) = length; | 3117 XSTRING_INDIRECT_DATA_SIZE (STRING_DATA_OBJECT (s)) = length; |
| 3007 #else /* not NEW_GC */ | 3118 #else /* not NEW_GC */ |
| 3008 set_lispstringp_data (s, (Ibyte *) contents); | 3119 set_lispstringp_data (s, (Ibyte *) contents); |
| 3009 set_lispstringp_length (s, length); | 3120 set_lispstringp_length (s, length); |
| 3020 /************************************************************************/ | 3131 /************************************************************************/ |
| 3021 /* lcrecord lists */ | 3132 /* lcrecord lists */ |
| 3022 /************************************************************************/ | 3133 /************************************************************************/ |
| 3023 | 3134 |
| 3024 /* Lcrecord lists are used to manage the allocation of particular | 3135 /* Lcrecord lists are used to manage the allocation of particular |
| 3025 sorts of lcrecords, to avoid calling BASIC_ALLOC_LCRECORD() (and thus | 3136 sorts of lcrecords, to avoid calling ALLOC_NORMAL_LISP_OBJECT() (and thus |
| 3026 malloc() and garbage-collection junk) as much as possible. | 3137 malloc() and garbage-collection junk) as much as possible. |
| 3027 It is similar to the Blocktype class. | 3138 It is similar to the Blocktype class. |
| 3028 | 3139 |
| 3029 See detailed comment in lcrecord.h. | 3140 See detailed comment in lcrecord.h. |
| 3030 */ | 3141 */ |
| 3033 { XD_LISP_OBJECT, offsetof (struct free_lcrecord_header, chain), 0, { 0 }, | 3144 { XD_LISP_OBJECT, offsetof (struct free_lcrecord_header, chain), 0, { 0 }, |
| 3034 XD_FLAG_FREE_LISP_OBJECT }, | 3145 XD_FLAG_FREE_LISP_OBJECT }, |
| 3035 { XD_END } | 3146 { XD_END } |
| 3036 }; | 3147 }; |
| 3037 | 3148 |
| 3038 DEFINE_LRECORD_IMPLEMENTATION ("free", free, | 3149 DEFINE_NODUMP_INTERNAL_LISP_OBJECT ("free", free, 0, free_description, |
| 3039 0, /*dumpable-flag*/ | 3150 struct free_lcrecord_header); |
| 3040 0, internal_object_printer, | |
| 3041 0, 0, 0, free_description, | |
| 3042 struct free_lcrecord_header); | |
| 3043 | 3151 |
| 3044 const struct memory_description lcrecord_list_description[] = { | 3152 const struct memory_description lcrecord_list_description[] = { |
| 3045 { XD_LISP_OBJECT, offsetof (struct lcrecord_list, free), 0, { 0 }, | 3153 { XD_LISP_OBJECT, offsetof (struct lcrecord_list, free), 0, { 0 }, |
| 3046 XD_FLAG_FREE_LISP_OBJECT }, | 3154 XD_FLAG_FREE_LISP_OBJECT }, |
| 3047 { XD_END } | 3155 { XD_END } |
| 3062 gc_checking_assert | 3170 gc_checking_assert |
| 3063 (/* There should be no other pointers to the free list. */ | 3171 (/* There should be no other pointers to the free list. */ |
| 3064 ! MARKED_RECORD_HEADER_P (lheader) | 3172 ! MARKED_RECORD_HEADER_P (lheader) |
| 3065 && | 3173 && |
| 3066 /* Only lcrecords should be here. */ | 3174 /* Only lcrecords should be here. */ |
| 3067 ! list->implementation->basic_p | 3175 ! list->implementation->frob_block_p |
| 3068 && | 3176 && |
| 3069 /* Only free lcrecords should be here. */ | 3177 /* Only free lcrecords should be here. */ |
| 3070 free_header->lcheader.free | 3178 free_header->lcheader.free |
| 3071 && | 3179 && |
| 3072 /* The type of the lcrecord must be right. */ | 3180 /* The type of the lcrecord must be right. */ |
| 3082 } | 3190 } |
| 3083 | 3191 |
| 3084 return Qnil; | 3192 return Qnil; |
| 3085 } | 3193 } |
| 3086 | 3194 |
| 3087 DEFINE_LRECORD_IMPLEMENTATION ("lcrecord-list", lcrecord_list, | 3195 DEFINE_NODUMP_INTERNAL_LISP_OBJECT ("lcrecord-list", lcrecord_list, |
| 3088 0, /*dumpable-flag*/ | 3196 mark_lcrecord_list, |
| 3089 mark_lcrecord_list, internal_object_printer, | 3197 lcrecord_list_description, |
| 3090 0, 0, 0, lcrecord_list_description, | 3198 struct lcrecord_list); |
| 3091 struct lcrecord_list); | |
| 3092 | 3199 |
| 3093 Lisp_Object | 3200 Lisp_Object |
| 3094 make_lcrecord_list (Elemcount size, | 3201 make_lcrecord_list (Elemcount size, |
| 3095 const struct lrecord_implementation *implementation) | 3202 const struct lrecord_implementation *implementation) |
| 3096 { | 3203 { |
| 3097 /* Don't use old_alloc_lcrecord_type() avoid infinite recursion | 3204 /* Don't use alloc_automanaged_lcrecord() avoid infinite recursion |
| 3098 allocating this, */ | 3205 allocating this. */ |
| 3099 struct lcrecord_list *p = (struct lcrecord_list *) | 3206 struct lcrecord_list *p = (struct lcrecord_list *) |
| 3100 old_basic_alloc_lcrecord (sizeof (struct lcrecord_list), | 3207 old_alloc_lcrecord (&lrecord_lcrecord_list); |
| 3101 &lrecord_lcrecord_list); | |
| 3102 | 3208 |
| 3103 p->implementation = implementation; | 3209 p->implementation = implementation; |
| 3104 p->size = size; | 3210 p->size = size; |
| 3105 p->free = Qnil; | 3211 p->free = Qnil; |
| 3106 return wrap_lcrecord_list (p); | 3212 return wrap_lcrecord_list (p); |
| 3123 assert (! MARKED_RECORD_HEADER_P (lheader)); | 3229 assert (! MARKED_RECORD_HEADER_P (lheader)); |
| 3124 /* Only free lcrecords should be here. */ | 3230 /* Only free lcrecords should be here. */ |
| 3125 assert (free_header->lcheader.free); | 3231 assert (free_header->lcheader.free); |
| 3126 assert (lheader->type == lrecord_type_free); | 3232 assert (lheader->type == lrecord_type_free); |
| 3127 /* Only lcrecords should be here. */ | 3233 /* Only lcrecords should be here. */ |
| 3128 assert (! (list->implementation->basic_p)); | 3234 assert (! (list->implementation->frob_block_p)); |
| 3129 #if 0 /* Not used anymore, now that we set the type of the header to | 3235 #if 0 /* Not used anymore, now that we set the type of the header to |
| 3130 lrecord_type_free. */ | 3236 lrecord_type_free. */ |
| 3131 /* The type of the lcrecord must be right. */ | 3237 /* The type of the lcrecord must be right. */ |
| 3132 assert (LHEADER_IMPLEMENTATION (lheader) == list->implementation); | 3238 assert (LHEADER_IMPLEMENTATION (lheader) == list->implementation); |
| 3133 #endif /* 0 */ | 3239 #endif /* 0 */ |
| 3138 | 3244 |
| 3139 list->free = free_header->chain; | 3245 list->free = free_header->chain; |
| 3140 free_header->lcheader.free = 0; | 3246 free_header->lcheader.free = 0; |
| 3141 /* Put back the correct type, as we set it to lrecord_type_free. */ | 3247 /* Put back the correct type, as we set it to lrecord_type_free. */ |
| 3142 lheader->type = list->implementation->lrecord_type_index; | 3248 lheader->type = list->implementation->lrecord_type_index; |
| 3143 old_zero_sized_lcrecord (free_header, list->size); | 3249 zero_sized_lisp_object (val, list->size); |
| 3144 return val; | 3250 return val; |
| 3145 } | 3251 } |
| 3146 else | 3252 else |
| 3147 return wrap_pointer_1 (old_basic_alloc_lcrecord (list->size, | 3253 return wrap_pointer_1 (old_alloc_sized_lcrecord (list->size, |
| 3148 list->implementation)); | 3254 list->implementation)); |
| 3149 } | 3255 } |
| 3150 | 3256 |
| 3151 /* "Free" a Lisp object LCRECORD by placing it on its associated free list | 3257 /* "Free" a Lisp object LCRECORD by placing it on its associated free list |
| 3152 LCRECORD_LIST; next time alloc_managed_lcrecord() is called with the | 3258 LCRECORD_LIST; next time alloc_managed_lcrecord() is called with the |
| 3187 problems. */ | 3293 problems. */ |
| 3188 gc_checking_assert (!gc_in_progress); | 3294 gc_checking_assert (!gc_in_progress); |
| 3189 | 3295 |
| 3190 /* Make sure the size is correct. This will catch, for example, | 3296 /* Make sure the size is correct. This will catch, for example, |
| 3191 putting a window configuration on the wrong free list. */ | 3297 putting a window configuration on the wrong free list. */ |
| 3192 gc_checking_assert (detagged_lisp_object_size (lheader) == list->size); | 3298 gc_checking_assert (lisp_object_size (lcrecord) == list->size); |
| 3193 /* Make sure the object isn't already freed. */ | 3299 /* Make sure the object isn't already freed. */ |
| 3194 gc_checking_assert (!free_header->lcheader.free); | 3300 gc_checking_assert (!free_header->lcheader.free); |
| 3195 /* Freeing stuff in dumped memory is bad. If you trip this, you | 3301 /* Freeing stuff in dumped memory is bad. If you trip this, you |
| 3196 may need to check for this before freeing. */ | 3302 may need to check for this before freeing. */ |
| 3197 gc_checking_assert (!OBJECT_DUMPED_P (lcrecord)); | 3303 gc_checking_assert (!OBJECT_DUMPED_P (lcrecord)); |
| 3198 | 3304 |
| 3199 if (implementation->finalizer) | 3305 if (implementation->finalizer) |
| 3200 implementation->finalizer (lheader, 0); | 3306 implementation->finalizer (lcrecord); |
| 3201 /* Yes, there are two ways to indicate freeness -- the type is | 3307 /* Yes, there are two ways to indicate freeness -- the type is |
| 3202 lrecord_type_free or the ->free flag is set. We used to do only the | 3308 lrecord_type_free or the ->free flag is set. We used to do only the |
| 3203 latter; now we do the former as well for KKCC purposes. Probably | 3309 latter; now we do the former as well for KKCC purposes. Probably |
| 3204 safer in any case, as we will lose quicker this way than keeping | 3310 safer in any case, as we will lose quicker this way than keeping |
| 3205 around an lrecord of apparently correct type but bogus junk in it. */ | 3311 around an lrecord of apparently correct type but bogus junk in it. */ |
| 3209 list->free = lcrecord; | 3315 list->free = lcrecord; |
| 3210 } | 3316 } |
| 3211 | 3317 |
| 3212 static Lisp_Object all_lcrecord_lists[countof (lrecord_implementations_table)]; | 3318 static Lisp_Object all_lcrecord_lists[countof (lrecord_implementations_table)]; |
| 3213 | 3319 |
| 3214 void * | 3320 Lisp_Object |
| 3215 alloc_automanaged_lcrecord (Bytecount size, | 3321 alloc_automanaged_sized_lcrecord (Bytecount size, |
| 3216 const struct lrecord_implementation *imp) | 3322 const struct lrecord_implementation *imp) |
| 3217 { | 3323 { |
| 3218 if (EQ (all_lcrecord_lists[imp->lrecord_type_index], Qzero)) | 3324 if (EQ (all_lcrecord_lists[imp->lrecord_type_index], Qzero)) |
| 3219 all_lcrecord_lists[imp->lrecord_type_index] = | 3325 all_lcrecord_lists[imp->lrecord_type_index] = |
| 3220 make_lcrecord_list (size, imp); | 3326 make_lcrecord_list (size, imp); |
| 3221 | 3327 |
| 3222 return XPNTR (alloc_managed_lcrecord | 3328 return alloc_managed_lcrecord (all_lcrecord_lists[imp->lrecord_type_index]); |
| 3223 (all_lcrecord_lists[imp->lrecord_type_index])); | 3329 } |
| 3330 | |
| 3331 Lisp_Object | |
| 3332 alloc_automanaged_lcrecord (const struct lrecord_implementation *imp) | |
| 3333 { | |
| 3334 type_checking_assert (imp->static_size > 0); | |
| 3335 return alloc_automanaged_sized_lcrecord (imp->static_size, imp); | |
| 3224 } | 3336 } |
| 3225 | 3337 |
| 3226 void | 3338 void |
| 3227 old_free_lcrecord (Lisp_Object rec) | 3339 old_free_lcrecord (Lisp_Object rec) |
| 3228 { | 3340 { |
| 3555 GC_CHECK_LHEADER_INVARIANTS (h); | 3667 GC_CHECK_LHEADER_INVARIANTS (h); |
| 3556 | 3668 |
| 3557 if (! MARKED_RECORD_HEADER_P (h) && ! header->free) | 3669 if (! MARKED_RECORD_HEADER_P (h) && ! header->free) |
| 3558 { | 3670 { |
| 3559 if (LHEADER_IMPLEMENTATION (h)->finalizer) | 3671 if (LHEADER_IMPLEMENTATION (h)->finalizer) |
| 3560 LHEADER_IMPLEMENTATION (h)->finalizer (h, 0); | 3672 LHEADER_IMPLEMENTATION (h)->finalizer (wrap_pointer_1 (h)); |
| 3561 } | 3673 } |
| 3562 } | 3674 } |
| 3563 | 3675 |
| 3564 for (header = *prev; header; ) | 3676 for (header = *prev; header; ) |
| 3565 { | 3677 { |
| 4843 2 * sizeof (void *), is required as overhead and that | 4955 2 * sizeof (void *), is required as overhead and that |
| 4844 blocks are allocated in the minimum required size except | 4956 blocks are allocated in the minimum required size except |
| 4845 that some minimum block size is imposed (e.g. 16 bytes). */ | 4957 that some minimum block size is imposed (e.g. 16 bytes). */ |
| 4846 | 4958 |
| 4847 Bytecount | 4959 Bytecount |
| 4848 malloced_storage_size (void *UNUSED (ptr), Bytecount claimed_size, | 4960 malloced_storage_size (void * UNUSED (ptr), Bytecount claimed_size, |
| 4849 struct overhead_stats *stats) | 4961 struct overhead_stats *stats) |
| 4850 { | 4962 { |
| 4851 Bytecount orig_claimed_size = claimed_size; | 4963 Bytecount orig_claimed_size = claimed_size; |
| 4852 | 4964 |
| 4853 #ifndef SYSTEM_MALLOC | 4965 #ifndef SYSTEM_MALLOC |
| 5079 int i; | 5191 int i; |
| 5080 for (i = 0; i < countof (lrecord_implementations_table); i++) | 5192 for (i = 0; i < countof (lrecord_implementations_table); i++) |
| 5081 lrecord_implementations_table[i] = 0; | 5193 lrecord_implementations_table[i] = 0; |
| 5082 } | 5194 } |
| 5083 | 5195 |
| 5084 INIT_LRECORD_IMPLEMENTATION (cons); | 5196 INIT_LISP_OBJECT (cons); |
| 5085 INIT_LRECORD_IMPLEMENTATION (vector); | 5197 INIT_LISP_OBJECT (vector); |
| 5086 INIT_LRECORD_IMPLEMENTATION (string); | 5198 INIT_LISP_OBJECT (string); |
| 5087 #ifdef NEW_GC | 5199 #ifdef NEW_GC |
| 5088 INIT_LRECORD_IMPLEMENTATION (string_indirect_data); | 5200 INIT_LISP_OBJECT (string_indirect_data); |
| 5089 INIT_LRECORD_IMPLEMENTATION (string_direct_data); | 5201 INIT_LISP_OBJECT (string_direct_data); |
| 5090 #endif /* NEW_GC */ | 5202 #endif /* NEW_GC */ |
| 5091 #ifndef NEW_GC | 5203 #ifndef NEW_GC |
| 5092 INIT_LRECORD_IMPLEMENTATION (lcrecord_list); | 5204 INIT_LISP_OBJECT (lcrecord_list); |
| 5093 INIT_LRECORD_IMPLEMENTATION (free); | 5205 INIT_LISP_OBJECT (free); |
| 5094 #endif /* not NEW_GC */ | 5206 #endif /* not NEW_GC */ |
| 5095 | 5207 |
| 5096 staticpros = Dynarr_new2 (Lisp_Object_ptr_dynarr, Lisp_Object *); | 5208 staticpros = Dynarr_new2 (Lisp_Object_ptr_dynarr, Lisp_Object *); |
| 5097 Dynarr_resize (staticpros, 1410); /* merely a small optimization */ | 5209 Dynarr_resize (staticpros, 1410); /* merely a small optimization */ |
| 5098 dump_add_root_block_ptr (&staticpros, &staticpros_description); | 5210 dump_add_root_block_ptr (&staticpros, &staticpros_description); |
