Mercurial > hg > xemacs-beta
comparison src/alloc.c @ 5117:3742ea8250b5 ben-lisp-object ben-lisp-object-final-ws-year-2005
Checking in final CVS version of workspace 'ben-lisp-object'
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Sat, 26 Dec 2009 00:20:27 -0600 |
parents | d30cd499e445 |
children | e0db3c197671 |
comparison
equal
deleted
inserted
replaced
5116:e56f73345619 | 5117:3742ea8250b5 |
---|---|
581 | 581 |
582 DECREMENT_CONS_COUNTER (size); | 582 DECREMENT_CONS_COUNTER (size); |
583 } | 583 } |
584 #endif /* not (MC_ALLOC && ALLOC_TYPE_STATS) */ | 584 #endif /* not (MC_ALLOC && ALLOC_TYPE_STATS) */ |
585 | 585 |
586 #define assert_proper_sizing(size) \ | |
587 type_checking_assert \ | |
588 (implementation->static_size == 0 ? \ | |
589 implementation->size_in_bytes_method != NULL : \ | |
590 implementation->size_in_bytes_method == NULL && \ | |
591 implementation->static_size == size) | |
592 | |
586 #ifndef MC_ALLOC | 593 #ifndef MC_ALLOC |
587 /* lcrecords are chained together through their "next" field. | 594 /* lcrecords are chained together through their "next" field. |
588 After doing the mark phase, GC will walk this linked list | 595 After doing the mark phase, GC will walk this linked list |
589 and free any lcrecord which hasn't been marked. */ | 596 and free any lcrecord which hasn't been marked. */ |
590 static struct old_lcrecord_header *all_lcrecords; | 597 static struct old_lcrecord_header *all_lcrecords; |
591 #endif /* not MC_ALLOC */ | 598 #endif /* not MC_ALLOC */ |
592 | 599 |
593 #ifdef MC_ALLOC | 600 #ifdef MC_ALLOC |
601 | |
594 /* The basic lrecord allocation functions. See lrecord.h for details. */ | 602 /* The basic lrecord allocation functions. See lrecord.h for details. */ |
595 void * | 603 static Lisp_Object |
596 alloc_lrecord (Bytecount size, | 604 alloc_sized_lrecord_1 (Bytecount size, |
597 const struct lrecord_implementation *implementation) | 605 const struct lrecord_implementation *implementation, |
606 int noseeum) | |
598 { | 607 { |
599 struct lrecord_header *lheader; | 608 struct lrecord_header *lheader; |
600 | 609 |
601 type_checking_assert | 610 assert_proper_sizing (size); |
602 ((implementation->static_size == 0 ? | |
603 implementation->size_in_bytes_method != NULL : | |
604 implementation->static_size == size)); | |
605 | 611 |
606 lheader = (struct lrecord_header *) mc_alloc (size); | 612 lheader = (struct lrecord_header *) mc_alloc (size); |
607 gc_checking_assert (LRECORD_FREE_P (lheader)); | 613 gc_checking_assert (LRECORD_FREE_P (lheader)); |
608 set_lheader_implementation (lheader, implementation); | 614 set_lheader_implementation (lheader, implementation); |
609 #ifdef ALLOC_TYPE_STATS | 615 #ifdef ALLOC_TYPE_STATS |
610 inc_lrecord_stats (size, lheader); | 616 inc_lrecord_stats (size, lheader); |
611 #endif /* ALLOC_TYPE_STATS */ | 617 #endif /* ALLOC_TYPE_STATS */ |
612 INCREMENT_CONS_COUNTER (size, implementation->name); | 618 if (noseeum) |
613 return lheader; | 619 NOSEEUM_INCREMENT_CONS_COUNTER (size, implementation->name); |
614 } | 620 else |
615 | 621 INCREMENT_CONS_COUNTER (size, implementation->name); |
616 void * | 622 return wrap_pointer_1 (lheader); |
617 noseeum_alloc_lrecord (Bytecount size, | 623 } |
618 const struct lrecord_implementation *implementation) | 624 |
619 { | 625 Lisp_Object |
620 struct lrecord_header *lheader; | 626 alloc_sized_lrecord (Bytecount size, |
621 | 627 const struct lrecord_implementation *implementation) |
622 type_checking_assert | 628 { |
623 ((implementation->static_size == 0 ? | 629 return alloc_sized_lrecord_1 (size, implementation, 0); |
624 implementation->size_in_bytes_method != NULL : | 630 } |
625 implementation->static_size == size)); | 631 |
626 | 632 Lisp_Object |
627 lheader = (struct lrecord_header *) mc_alloc (size); | 633 noseeum_alloc_sized_lrecord (Bytecount size, |
628 gc_checking_assert (LRECORD_FREE_P (lheader)); | 634 const struct lrecord_implementation * |
629 set_lheader_implementation (lheader, implementation); | 635 implementation) |
630 #ifdef ALLOC_TYPE_STATS | 636 { |
631 inc_lrecord_stats (size, lheader); | 637 return alloc_sized_lrecord_1 (size, implementation, 1); |
632 #endif /* ALLOC_TYPE_STATS */ | 638 } |
633 NOSEEUM_INCREMENT_CONS_COUNTER (size, implementation->name); | 639 |
634 return lheader; | 640 Lisp_Object |
641 alloc_lrecord (const struct lrecord_implementation *implementation) | |
642 { | |
643 type_checking_assert (implementation->static_size > 0); | |
644 return alloc_sized_lrecord (implementation->static_size, implementation); | |
635 } | 645 } |
636 | 646 |
637 void | 647 void |
638 free_lrecord (Lisp_Object lrecord) | 648 free_lrecord (Lisp_Object lrecord) |
639 { | 649 { |
648 | 658 |
649 /* The most basic of the lcrecord allocation functions. Not usually called | 659 /* The most basic of the lcrecord allocation functions. Not usually called |
650 directly. Allocates an lrecord not managed by any lcrecord-list, of a | 660 directly. Allocates an lrecord not managed by any lcrecord-list, of a |
651 specified size. See lrecord.h. */ | 661 specified size. See lrecord.h. */ |
652 | 662 |
653 void * | 663 Lisp_Object |
654 old_basic_alloc_lcrecord (Bytecount size, | 664 old_alloc_sized_lcrecord (Bytecount size, |
655 const struct lrecord_implementation *implementation) | 665 const struct lrecord_implementation *implementation) |
656 { | 666 { |
657 struct old_lcrecord_header *lcheader; | 667 struct old_lcrecord_header *lcheader; |
658 | 668 |
669 assert_proper_sizing (size); | |
659 type_checking_assert | 670 type_checking_assert |
660 ((implementation->static_size == 0 ? | 671 (!implementation->basic_p |
661 implementation->size_in_bytes_method != NULL : | |
662 implementation->static_size == size) | |
663 && | 672 && |
664 (! implementation->basic_p) | 673 !(implementation->hash == NULL && implementation->equal != NULL)); |
665 && | |
666 (! (implementation->hash == NULL && implementation->equal != NULL))); | |
667 | 674 |
668 lcheader = (struct old_lcrecord_header *) allocate_lisp_storage (size); | 675 lcheader = (struct old_lcrecord_header *) allocate_lisp_storage (size); |
669 set_lheader_implementation (&lcheader->lheader, implementation); | 676 set_lheader_implementation (&lcheader->lheader, implementation); |
670 lcheader->next = all_lcrecords; | 677 lcheader->next = all_lcrecords; |
671 #if 1 /* mly prefers to see small ID numbers */ | 678 #if 1 /* mly prefers to see small ID numbers */ |
674 lcheader->uid = (int) &lcheader; | 681 lcheader->uid = (int) &lcheader; |
675 #endif | 682 #endif |
676 lcheader->free = 0; | 683 lcheader->free = 0; |
677 all_lcrecords = lcheader; | 684 all_lcrecords = lcheader; |
678 INCREMENT_CONS_COUNTER (size, implementation->name); | 685 INCREMENT_CONS_COUNTER (size, implementation->name); |
679 return lcheader; | 686 return wrap_pointer_1 (lcheader); |
687 } | |
688 | |
689 Lisp_Object | |
690 old_alloc_lcrecord (const struct lrecord_implementation *implementation) | |
691 { | |
692 type_checking_assert (implementation->static_size > 0); | |
693 return old_alloc_sized_lcrecord (implementation->static_size, | |
694 implementation); | |
680 } | 695 } |
681 | 696 |
682 #if 0 /* Presently unused */ | 697 #if 0 /* Presently unused */ |
683 /* Very, very poor man's EGC? | 698 /* Very, very poor man's EGC? |
684 * This may be slow and thrash pages all over the place. | 699 * This may be slow and thrash pages all over the place. |
1238 { XD_LISP_OBJECT, offsetof (Lisp_Cons, car_) }, | 1253 { XD_LISP_OBJECT, offsetof (Lisp_Cons, car_) }, |
1239 { XD_LISP_OBJECT, offsetof (Lisp_Cons, cdr_) }, | 1254 { XD_LISP_OBJECT, offsetof (Lisp_Cons, cdr_) }, |
1240 { XD_END } | 1255 { XD_END } |
1241 }; | 1256 }; |
1242 | 1257 |
1243 DEFINE_BASIC_LRECORD_IMPLEMENTATION ("cons", cons, | 1258 DEFINE_FROB_BLOCK_LISP_OBJECT ("cons", cons, Lisp_Cons, cons_description, |
1244 1, /*dumpable-flag*/ | 1259 1, /*dumpable-flag*/ |
1245 mark_cons, print_cons, 0, | 1260 mark_cons, print_cons, cons_equal, |
1246 cons_equal, | 1261 /* |
1247 /* | 1262 * No `hash' method needed. |
1248 * No `hash' method needed. | 1263 * internal_hash knows how to |
1249 * internal_hash knows how to | 1264 * handle conses. |
1250 * handle conses. | 1265 */ |
1251 */ | 1266 0, 0); |
1252 0, | |
1253 cons_description, | |
1254 Lisp_Cons); | |
1255 | 1267 |
1256 DEFUN ("cons", Fcons, 2, 2, 0, /* | 1268 DEFUN ("cons", Fcons, 2, 2, 0, /* |
1257 Create a new cons, give it CAR and CDR as components, and return it. | 1269 Create a new cons, give it CAR and CDR as components, and return it. |
1258 */ | 1270 */ |
1259 (car, cdr)) | 1271 (car, cdr)) |
1563 { XD_LONG, offsetof (Lisp_Vector, size) }, | 1575 { XD_LONG, offsetof (Lisp_Vector, size) }, |
1564 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Vector, contents), XD_INDIRECT(0, 0) }, | 1576 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Vector, contents), XD_INDIRECT(0, 0) }, |
1565 { XD_END } | 1577 { XD_END } |
1566 }; | 1578 }; |
1567 | 1579 |
1568 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("vector", vector, | 1580 DEFINE_SIZABLE_LISP_OBJECT ("vector", vector, |
1569 1, /*dumpable-flag*/ | 1581 1, /*dumpable-flag*/ |
1570 mark_vector, print_vector, 0, | 1582 mark_vector, print_vector, 0, |
1571 vector_equal, | 1583 vector_equal, |
1572 vector_hash, | 1584 vector_hash, |
1573 vector_description, | 1585 vector_description, |
1577 make_vector_internal (Elemcount sizei) | 1589 make_vector_internal (Elemcount sizei) |
1578 { | 1590 { |
1579 /* no `next' field; we use lcrecords */ | 1591 /* no `next' field; we use lcrecords */ |
1580 Bytecount sizem = FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Vector, Lisp_Object, | 1592 Bytecount sizem = FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Vector, Lisp_Object, |
1581 contents, sizei); | 1593 contents, sizei); |
1582 Lisp_Vector *p = | 1594 Lisp_Object obj = ALLOC_SIZED_LISP_OBJECT (sizem, vector); |
1583 (Lisp_Vector *) BASIC_ALLOC_LCRECORD (sizem, &lrecord_vector); | 1595 Lisp_Vector *p = XVECTOR (obj); |
1584 | 1596 |
1585 p->size = sizei; | 1597 p->size = sizei; |
1586 return p; | 1598 return p; |
1587 } | 1599 } |
1588 | 1600 |
1734 /* no `next' field; we use lcrecords */ | 1746 /* no `next' field; we use lcrecords */ |
1735 Elemcount num_longs = BIT_VECTOR_LONG_STORAGE (sizei); | 1747 Elemcount num_longs = BIT_VECTOR_LONG_STORAGE (sizei); |
1736 Bytecount sizem = FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Bit_Vector, | 1748 Bytecount sizem = FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Bit_Vector, |
1737 unsigned long, | 1749 unsigned long, |
1738 bits, num_longs); | 1750 bits, num_longs); |
1739 Lisp_Bit_Vector *p = (Lisp_Bit_Vector *) | 1751 Lisp_Object obj = ALLOC_SIZED_LISP_OBJECT (sizem, bit_vector); |
1740 BASIC_ALLOC_LCRECORD (sizem, &lrecord_bit_vector); | 1752 Lisp_Bit_Vector *p = XBIT_VECTOR (obj); |
1741 | 1753 |
1742 bit_vector_length (p) = sizei; | 1754 bit_vector_length (p) = sizei; |
1743 return p; | 1755 return p; |
1744 } | 1756 } |
1745 | 1757 |
2296 internal_hash() already knows how to hash strings and finalization | 2308 internal_hash() already knows how to hash strings and finalization |
2297 is done with the ADDITIONAL_FREE_string macro, which is the | 2309 is done with the ADDITIONAL_FREE_string macro, which is the |
2298 standard way to do finalization when using | 2310 standard way to do finalization when using |
2299 SWEEP_FIXED_TYPE_BLOCK(). */ | 2311 SWEEP_FIXED_TYPE_BLOCK(). */ |
2300 | 2312 |
2301 DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS ("string", string, | 2313 DEFINE_BASIC_LISP_OBJECT_WITH_PROPS ("string", string, |
2302 1, /*dumpable-flag*/ | |
2303 mark_string, print_string, | 2314 mark_string, print_string, |
2304 0, string_equal, 0, | 2315 0, string_equal, 0, |
2305 string_description, | 2316 string_description, |
2306 string_getprop, | 2317 string_getprop, |
2307 string_putprop, | 2318 string_putprop, |
2356 if (BIG_STRING_SIZE_P (size)) | 2367 if (BIG_STRING_SIZE_P (size)) |
2357 xfree (s->data_, Ibyte *); | 2368 xfree (s->data_, Ibyte *); |
2358 } | 2369 } |
2359 } | 2370 } |
2360 | 2371 |
2361 DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS ("string", string, | 2372 DEFINE_LISP_OBJECT_WITH_PROPS ("string", string, |
2362 1, /*dumpable-flag*/ | |
2363 mark_string, print_string, | 2373 mark_string, print_string, |
2364 finalize_string, | 2374 finalize_string, |
2365 string_equal, 0, | 2375 string_equal, 0, |
2366 string_description, | 2376 string_description, |
2367 string_getprop, | 2377 string_getprop, |
2881 /************************************************************************/ | 2891 /************************************************************************/ |
2882 /* lcrecord lists */ | 2892 /* lcrecord lists */ |
2883 /************************************************************************/ | 2893 /************************************************************************/ |
2884 | 2894 |
2885 /* Lcrecord lists are used to manage the allocation of particular | 2895 /* Lcrecord lists are used to manage the allocation of particular |
2886 sorts of lcrecords, to avoid calling BASIC_ALLOC_LCRECORD() (and thus | 2896 sorts of lcrecords, to avoid calling ALLOC_LISP_OBJECT() (and thus |
2887 malloc() and garbage-collection junk) as much as possible. | 2897 malloc() and garbage-collection junk) as much as possible. |
2888 It is similar to the Blocktype class. | 2898 It is similar to the Blocktype class. |
2889 | 2899 |
2890 See detailed comment in lcrecord.h. | 2900 See detailed comment in lcrecord.h. |
2891 */ | 2901 */ |
2894 { XD_LISP_OBJECT, offsetof (struct free_lcrecord_header, chain), 0, { 0 }, | 2904 { XD_LISP_OBJECT, offsetof (struct free_lcrecord_header, chain), 0, { 0 }, |
2895 XD_FLAG_FREE_LISP_OBJECT }, | 2905 XD_FLAG_FREE_LISP_OBJECT }, |
2896 { XD_END } | 2906 { XD_END } |
2897 }; | 2907 }; |
2898 | 2908 |
2899 DEFINE_LRECORD_IMPLEMENTATION ("free", free, | 2909 DEFINE_NONDUMPABLE_LISP_OBJECT ("free", free, 0, 0, |
2900 0, /*dumpable-flag*/ | 2910 0, 0, 0, free_description, |
2901 0, internal_object_printer, | 2911 struct free_lcrecord_header); |
2902 0, 0, 0, free_description, | |
2903 struct free_lcrecord_header); | |
2904 | 2912 |
2905 const struct memory_description lcrecord_list_description[] = { | 2913 const struct memory_description lcrecord_list_description[] = { |
2906 { XD_LISP_OBJECT, offsetof (struct lcrecord_list, free), 0, { 0 }, | 2914 { XD_LISP_OBJECT, offsetof (struct lcrecord_list, free), 0, { 0 }, |
2907 XD_FLAG_FREE_LISP_OBJECT }, | 2915 XD_FLAG_FREE_LISP_OBJECT }, |
2908 { XD_END } | 2916 { XD_END } |
2943 } | 2951 } |
2944 | 2952 |
2945 return Qnil; | 2953 return Qnil; |
2946 } | 2954 } |
2947 | 2955 |
2948 DEFINE_LRECORD_IMPLEMENTATION ("lcrecord-list", lcrecord_list, | 2956 DEFINE_NONDUMPABLE_LISP_OBJECT ("lcrecord-list", lcrecord_list, |
2949 0, /*dumpable-flag*/ | 2957 mark_lcrecord_list, |
2950 mark_lcrecord_list, internal_object_printer, | 2958 0, |
2951 0, 0, 0, lcrecord_list_description, | 2959 0, 0, 0, lcrecord_list_description, |
2952 struct lcrecord_list); | 2960 struct lcrecord_list); |
2953 | 2961 |
2954 Lisp_Object | 2962 Lisp_Object |
2955 make_lcrecord_list (Elemcount size, | 2963 make_lcrecord_list (Elemcount size, |
2956 const struct lrecord_implementation *implementation) | 2964 const struct lrecord_implementation *implementation) |
2957 { | 2965 { |
3062 list->free = lcrecord; | 3070 list->free = lcrecord; |
3063 } | 3071 } |
3064 | 3072 |
3065 static Lisp_Object all_lcrecord_lists[countof (lrecord_implementations_table)]; | 3073 static Lisp_Object all_lcrecord_lists[countof (lrecord_implementations_table)]; |
3066 | 3074 |
3067 void * | 3075 Lisp_Object |
3068 alloc_automanaged_lcrecord (Bytecount size, | 3076 alloc_automanaged_sized_lcrecord (Bytecount size, |
3069 const struct lrecord_implementation *imp) | 3077 const struct lrecord_implementation *imp) |
3070 { | 3078 { |
3071 if (EQ (all_lcrecord_lists[imp->lrecord_type_index], Qzero)) | 3079 if (EQ (all_lcrecord_lists[imp->lrecord_type_index], Qzero)) |
3072 all_lcrecord_lists[imp->lrecord_type_index] = | 3080 all_lcrecord_lists[imp->lrecord_type_index] = |
3073 make_lcrecord_list (size, imp); | 3081 make_lcrecord_list (size, imp); |
3074 | 3082 |
3075 return XPNTR (alloc_managed_lcrecord | 3083 return alloc_managed_lcrecord (all_lcrecord_lists[imp->lrecord_type_index]); |
3076 (all_lcrecord_lists[imp->lrecord_type_index])); | 3084 } |
3085 | |
3086 Lisp_Object | |
3087 alloc_automanaged_lcrecord (const struct lrecord_implementation *imp) | |
3088 { | |
3089 type_checking_assert (imp->static_size > 0); | |
3090 return alloc_automanaged_sized_lcrecord (imp->static_size, imp); | |
3077 } | 3091 } |
3078 | 3092 |
3079 void | 3093 void |
3080 old_free_lcrecord (Lisp_Object rec) | 3094 old_free_lcrecord (Lisp_Object rec) |
3081 { | 3095 { |
6162 int i; | 6176 int i; |
6163 for (i = 0; i < countof (lrecord_implementations_table); i++) | 6177 for (i = 0; i < countof (lrecord_implementations_table); i++) |
6164 lrecord_implementations_table[i] = 0; | 6178 lrecord_implementations_table[i] = 0; |
6165 } | 6179 } |
6166 | 6180 |
6167 INIT_LRECORD_IMPLEMENTATION (cons); | 6181 INIT_LISP_OBJECT (cons); |
6168 INIT_LRECORD_IMPLEMENTATION (vector); | 6182 INIT_LISP_OBJECT (vector); |
6169 INIT_LRECORD_IMPLEMENTATION (string); | 6183 INIT_LISP_OBJECT (string); |
6170 #ifndef MC_ALLOC | 6184 #ifndef MC_ALLOC |
6171 INIT_LRECORD_IMPLEMENTATION (lcrecord_list); | 6185 INIT_LISP_OBJECT (lcrecord_list); |
6172 INIT_LRECORD_IMPLEMENTATION (free); | 6186 INIT_LISP_OBJECT (free); |
6173 #endif /* not MC_ALLOC */ | 6187 #endif /* not MC_ALLOC */ |
6174 | 6188 |
6175 staticpros = Dynarr_new2 (Lisp_Object_ptr_dynarr, Lisp_Object *); | 6189 staticpros = Dynarr_new2 (Lisp_Object_ptr_dynarr, Lisp_Object *); |
6176 Dynarr_resize (staticpros, 1410); /* merely a small optimization */ | 6190 Dynarr_resize (staticpros, 1410); /* merely a small optimization */ |
6177 dump_add_root_block_ptr (&staticpros, &staticpros_description); | 6191 dump_add_root_block_ptr (&staticpros, &staticpros_description); |