comparison src/lrecord.h @ 5120:d1247f3cc363 ben-lisp-object

latest work on lisp-object workspace; more changes eliminating LCRECORD in place of LISP_OBJECT; now compiles and runs.
author Ben Wing <ben@xemacs.org>
date Mon, 28 Dec 2009 01:15:52 -0600
parents e0db3c197671
children 623d57b7fbe8
comparison
equal deleted inserted replaced
5119:d877c14318b3 5120:d1247f3cc363
24 /* This file has been Mule-ized, Ben Wing, 10-13-04. */ 24 /* This file has been Mule-ized, Ben Wing, 10-13-04. */
25 25
26 #ifndef INCLUDED_lrecord_h_ 26 #ifndef INCLUDED_lrecord_h_
27 #define INCLUDED_lrecord_h_ 27 #define INCLUDED_lrecord_h_
28 28
29 #ifdef NEW_GC 29 /* The "lrecord" type of Lisp object is used for all object types other
30 /* The "lrecord" type of Lisp object is used for all object types 30 than a few simple ones (like char and int). This allows many types to be
31 other than a few simple ones (like char and int). This allows many
32 types to be implemented but only a few bits required in a Lisp
33 object for type information. (The tradeoff is that each object has
34 its type marked in it, thereby increasing its size.) All lrecords
35 begin with a `struct lrecord_header', which identifies the lisp
36 object type, by providing an index into a table of `struct
37 lrecord_implementation', which describes the behavior of the lisp
38 object. It also contains some other data bits.
39
40 Creating a new lrecord type is fairly easy; just follow the
41 lead of some existing type (e.g. hash tables). Note that you
42 do not need to supply all the methods (see below); reasonable
43 defaults are provided for many of them. Alternatively, if you're
44 just looking for a way of encapsulating data (which possibly
45 could contain Lisp_Objects in it), you may well be able to use
46 the opaque type.
47 */
48 #else /* not NEW_GC */
49 /* The "lrecord" type of Lisp object is used for all object types
50 other than a few simple ones. This allows many types to be
51 implemented but only a few bits required in a Lisp object for type 31 implemented but only a few bits required in a Lisp object for type
52 information. (The tradeoff is that each object has its type marked 32 information. (The tradeoff is that each object has its type marked in
53 in it, thereby increasing its size.) All lrecords begin with a 33 it, thereby increasing its size.) All lrecords begin with a `struct
54 `struct lrecord_header', which identifies the lisp object type, by 34 lrecord_header', which identifies the lisp object type, by providing an
55 providing an index into a table of `struct lrecord_implementation', 35 index into a table of `struct lrecord_implementation', which describes
56 which describes the behavior of the lisp object. It also contains 36 the behavior of the lisp object. It also contains some other data bits.
57 some other data bits. 37
58 38 #ifndef NEW_GC
59 Lrecords are of two types: straight lrecords, and lcrecords. 39 Lrecords are of two types: straight lrecords, and lcrecords.
60 Straight lrecords are used for those types of objects that have 40 Straight lrecords are used for those types of objects that have
61 their own allocation routines (typically allocated out of 2K chunks 41 their own allocation routines (typically allocated out of 2K chunks
62 of memory called `frob blocks'). These objects have a `struct 42 of memory called `frob blocks'). These objects have a `struct
63 lrecord_header' at the top, containing only the bits needed to find 43 lrecord_header' at the top, containing only the bits needed to find
68 their own allocation. Each such object is malloc()ed individually, 48 their own allocation. Each such object is malloc()ed individually,
69 and the objects are chained together through a `next' pointer. 49 and the objects are chained together through a `next' pointer.
70 Lcrecords have a `struct old_lcrecord_header' at the top, which 50 Lcrecords have a `struct old_lcrecord_header' at the top, which
71 contains a `struct lrecord_header' and a `next' pointer, and are 51 contains a `struct lrecord_header' and a `next' pointer, and are
72 allocated using old_alloc_lcrecord_type() or its variants. 52 allocated using old_alloc_lcrecord_type() or its variants.
73 53 #endif
74 Creating a new lcrecord type is fairly easy; just follow the 54
55 Creating a new Lisp object type is fairly easy; just follow the
75 lead of some existing type (e.g. hash tables). Note that you 56 lead of some existing type (e.g. hash tables). Note that you
76 do not need to supply all the methods (see below); reasonable 57 do not need to supply all the methods (see below); reasonable
77 defaults are provided for many of them. Alternatively, if you're 58 defaults are provided for many of them. Alternatively, if you're
78 just looking for a way of encapsulating data (which possibly 59 just looking for a way of encapsulating data (which possibly
79 could contain Lisp_Objects in it), you may well be able to use 60 could contain Lisp_Objects in it), you may well be able to use
80 the opaque type. --ben 61 the opaque type.
62
63 The "public API's" meant for use by regular Lisp objects are macros
64 in capital letters, involving the word "LISP_OBJECT". Underlyingly,
65 the functions and structures use "lrecord" or "lcrecord", but most
66 code shouldn't have to worry about this.
81 */ 67 */
82 #endif /* not NEW_GC */
83 68
84 #ifdef NEW_GC 69 #ifdef NEW_GC
85 #define ALLOC_LISP_OBJECT(type) alloc_lrecord (&lrecord_##type) 70 #define ALLOC_LISP_OBJECT(type) alloc_lrecord (&lrecord_##type)
86 #define ALLOC_SIZED_LISP_OBJECT(size, type) \ 71 #define ALLOC_SIZED_LISP_OBJECT(size, type) \
87 alloc_sized_lrecord (size, &lrecord_##type) 72 alloc_sized_lrecord (size, &lrecord_##type)
88 #define COPY_SIZED_LCRECORD copy_sized_lrecord 73 #define COPY_SIZED_LISP_OBJECT copy_sized_lrecord
89 #define COPY_LCRECORD copy_lrecord 74 #define COPY_LISP_OBJECT copy_lrecord
90 #define LISPOBJ_STORAGE_SIZE(ptr, size, stats) \ 75 #define LISP_OBJECT_STORAGE_SIZE(ptr, size, stats) \
91 mc_alloced_storage_size (size, stats) 76 mc_alloced_storage_size (size, stats)
92 #define ZERO_LCRECORD zero_lrecord 77 #define ZERO_LISP_OBJECT zero_lrecord
93 #define LCRECORD_HEADER lrecord_header 78 #define LISP_OBJECT_HEADER struct lrecord_header
94 #define FREE_LCRECORD free_lrecord 79 #define FROB_BLOCK_LISP_OBJECT_HEADER struct lrecord_header
80 #define FREE_LISP_OBJECT free_lrecord
95 #else /* not NEW_GC */ 81 #else /* not NEW_GC */
96 #define ALLOC_LISP_OBJECT(type) alloc_automanaged_lcrecord (&lrecord_##type) 82 #define ALLOC_LISP_OBJECT(type) alloc_automanaged_lcrecord (&lrecord_##type)
97 #define ALLOC_SIZED_LISP_OBJECT(size, type) \ 83 #define ALLOC_SIZED_LISP_OBJECT(size, type) \
98 old_alloc_sized_lcrecord (size, &lrecord_##type) 84 old_alloc_sized_lcrecord (size, &lrecord_##type)
99 #define COPY_SIZED_LCRECORD old_copy_sized_lcrecord 85 #define COPY_SIZED_LISP_OBJECT old_copy_sized_lcrecord
100 #define COPY_LCRECORD old_copy_lcrecord 86 #define COPY_LISP_OBJECT old_copy_lcrecord
101 #define LISPOBJ_STORAGE_SIZE malloced_storage_size 87 #define LISP_OBJECT_STORAGE_SIZE malloced_storage_size
102 #define ZERO_LCRECORD old_zero_lcrecord 88 #define ZERO_LISP_OBJECT old_zero_lcrecord
103 #define LCRECORD_HEADER old_lcrecord_header 89 #define LISP_OBJECT_HEADER struct old_lcrecord_header
104 #define FREE_LCRECORD old_free_lcrecord 90 #define FROB_BLOCK_LISP_OBJECT_HEADER struct lrecord_header
91 #define FREE_LISP_OBJECT old_free_lcrecord
105 #endif /* not NEW_GC */ 92 #endif /* not NEW_GC */
106 93
107 BEGIN_C_DECLS 94 BEGIN_C_DECLS
108 95
109 struct lrecord_header 96 struct lrecord_header
728 Lisp_Object value; 715 Lisp_Object value;
729 } htentry; 716 } htentry;
730 717
731 struct Lisp_Hash_Table 718 struct Lisp_Hash_Table
732 { 719 {
733 struct LCRECORD_HEADER header; 720 LISP_OBJECT_HEADER header;
734 Elemcount size; 721 Elemcount size;
735 Elemcount count; 722 Elemcount count;
736 Elemcount rehash_count; 723 Elemcount rehash_count;
737 double rehash_size; 724 double rehash_size;
738 double rehash_threshold; 725 double rehash_threshold;
793 ... 780 ...
794 }; 781 };
795 782
796 struct Lisp_Specifier 783 struct Lisp_Specifier
797 { 784 {
798 struct LCRECORD_HEADER header; 785 LISP_OBJECT_HEADER header;
799 struct specifier_methods *methods; 786 struct specifier_methods *methods;
800 787
801 ... 788 ...
802 // type-specific extra data attached to a specifier 789 // type-specific extra data attached to a specifier
803 max_align_t data[1]; 790 max_align_t data[1];
1153 DEFINE_*_FROB_BLOCK_LISP_OBJECT is for objects that are allocated in 1140 DEFINE_*_FROB_BLOCK_LISP_OBJECT is for objects that are allocated in
1154 large blocks ("frob blocks"), which are parceled up individually. Such 1141 large blocks ("frob blocks"), which are parceled up individually. Such
1155 objects need special handling in alloc.c. This does not apply to 1142 objects need special handling in alloc.c. This does not apply to
1156 NEW_GC, because it does this automatically. 1143 NEW_GC, because it does this automatically.
1157 1144
1145 DEFINE_*_INTERNAL_LISP_OBJECT is for "internal" objects that should
1146 never be visible on the Lisp level. This is a shorthand for the
1147 most common type of internal objects, which have no equal or hash
1148 method (since they generally won't appear in hash tables), no
1149 finalizer and internal_object_printer() as their print method
1150 (which prints that the object is internal and shouldn't be visible
1151 externally). For internal objects needing a finalizer, equal or
1152 hash method, use the normal DEFINE_*_LISP_OBJECT mechanism for
1153 defining these objects.
1154
1158 DEFINE_*_WITH_PROPS is for objects which support the unified property 1155 DEFINE_*_WITH_PROPS is for objects which support the unified property
1159 interface using `get', `put', `remprop' and `object-plist'. 1156 interface using `get', `put', `remprop' and `object-plist'.
1160 1157
1161 DEFINE_MODULE_* is for objects defined in an external module. 1158 DEFINE_MODULE_* is for objects defined in an external module.
1162 1159
1355 /* Steps to create a new object: 1352 /* Steps to create a new object:
1356 1353
1357 1. Declare the struct for your object in a header file somewhere. 1354 1. Declare the struct for your object in a header file somewhere.
1358 Remember that it must begin with 1355 Remember that it must begin with
1359 1356
1360 struct LCRECORD_HEADER header; 1357 LISP_OBJECT_HEADER header;
1361 1358
1362 2. Put the "standard junk" (DECLARE_RECORD()/XFOO/etc.) below the 1359 2. Put the "standard junk" (DECLARE_LISP_OBJECT()/XFOO/etc.) below the
1363 struct definition -- see below. 1360 struct definition -- see below.
1364 1361
1365 3. Add this header file to inline.c. 1362 3. Add this header file to inline.c.
1366 1363
1367 4. Create the methods for your object. Note that technically you don't 1364 4. Create the methods for your object. Note that technically you don't
1370 4. Create the data layout description for your object. See 1367 4. Create the data layout description for your object. See
1371 toolbar_button_description below; the comment above in `struct lrecord', 1368 toolbar_button_description below; the comment above in `struct lrecord',
1372 describing the purpose of the descriptions; and comments elsewhere in 1369 describing the purpose of the descriptions; and comments elsewhere in
1373 this file describing the exact syntax of the description structures. 1370 this file describing the exact syntax of the description structures.
1374 1371
1375 6. Define your object with DEFINE_LISP_OBJECT() or some 1372 6. Define your object with DEFINE_*_LISP_OBJECT() or some
1376 variant. 1373 variant. At the minimum, you need to decide whether your object can
1374 be dumped. Objects that are created as part of the loadup process and
1375 need to be persistent across dumping should be created dumpable.
1376 Nondumpable objects are generally those associated with display,
1377 particularly those containing a pointer to an external library object
1378 (e.g. a window-system window).
1377 1379
1378 7. Include the header file in the .c file where you defined the object. 1380 7. Include the header file in the .c file where you defined the object.
1379 1381
1380 8. Put a call to INIT_LISP_OBJECT() for the object in the 1382 8. Put a call to INIT_LISP_OBJECT() for the object in the
1381 .c file's syms_of_foo() function. 1383 .c file's syms_of_foo() function.
1389 1391
1390 ------------------------------ in toolbar.h ----------------------------- 1392 ------------------------------ in toolbar.h -----------------------------
1391 1393
1392 struct toolbar_button 1394 struct toolbar_button
1393 { 1395 {
1394 struct LCRECORD_HEADER header; 1396 LISP_OBJECT_HEADER header;
1395 1397
1396 Lisp_Object next; 1398 Lisp_Object next;
1397 Lisp_Object frame; 1399 Lisp_Object frame;
1398 1400
1399 Lisp_Object up_glyph; 1401 Lisp_Object up_glyph;
1504 */ 1506 */
1505 1507
1506 /* 1508 /*
1507 1509
1508 Note: Object types defined in external dynamically-loaded modules (not 1510 Note: Object types defined in external dynamically-loaded modules (not
1509 part of the XEmacs main source code) should use DECLARE_MODULE_LRECORD 1511 part of the XEmacs main source code) should use DECLARE_*_MODULE_LISP_OBJECT
1510 and DEFINE_MODULE_LISP_OBJECT rather than DECLARE_LISP_OBJECT 1512 and DEFINE_*_MODULE_LISP_OBJECT rather than DECLARE_*_LISP_OBJECT
1511 and DEFINE_LISP_OBJECT. The MODULE versions declare and 1513 and DEFINE_*_LISP_OBJECT. The MODULE versions declare and
1512 allocate an enumerator for the type being defined. 1514 allocate an enumerator for the type being defined.
1513 1515
1514 */ 1516 */
1515 1517
1516 1518
1517 #ifdef ERROR_CHECK_TYPES 1519 #ifdef ERROR_CHECK_TYPES
1518 1520
1519 # define DECLARE_LISP_OBJECT(c_name, structtype) \ 1521 # define DECLARE_LISP_OBJECT(c_name, structtype) \
1520 extern const struct lrecord_implementation lrecord_##c_name; \ 1522 extern const struct lrecord_implementation lrecord_##c_name; \
1521 DECLARE_INLINE_HEADER ( \ 1523 DECLARE_INLINE_HEADER ( \
1522 structtype * \ 1524 structtype * \
1523 error_check_##c_name (Lisp_Object obj, const Ascbyte *file, int line) \ 1525 error_check_##c_name (Lisp_Object obj, const Ascbyte *file, int line) \
1524 ) \ 1526 ) \
1526 assert_at_line (RECORD_TYPEP (obj, lrecord_type_##c_name), file, line); \ 1528 assert_at_line (RECORD_TYPEP (obj, lrecord_type_##c_name), file, line); \
1527 return (structtype *) XPNTR (obj); \ 1529 return (structtype *) XPNTR (obj); \
1528 } \ 1530 } \
1529 extern Lisp_Object Q##c_name##p 1531 extern Lisp_Object Q##c_name##p
1530 1532
1531 # define DECLARE_MODULE_API_LRECORD(c_name, structtype) \ 1533 # define DECLARE_MODULE_API_LISP_OBJECT(c_name, structtype) \
1532 extern MODULE_API const struct lrecord_implementation lrecord_##c_name; \ 1534 extern MODULE_API const struct lrecord_implementation lrecord_##c_name; \
1533 DECLARE_INLINE_HEADER ( \ 1535 DECLARE_INLINE_HEADER ( \
1534 structtype * \ 1536 structtype * \
1535 error_check_##c_name (Lisp_Object obj, const Ascbyte *file, int line) \ 1537 error_check_##c_name (Lisp_Object obj, const Ascbyte *file, int line) \
1536 ) \ 1538 ) \
1538 assert_at_line (RECORD_TYPEP (obj, lrecord_type_##c_name), file, line); \ 1540 assert_at_line (RECORD_TYPEP (obj, lrecord_type_##c_name), file, line); \
1539 return (structtype *) XPNTR (obj); \ 1541 return (structtype *) XPNTR (obj); \
1540 } \ 1542 } \
1541 extern MODULE_API Lisp_Object Q##c_name##p 1543 extern MODULE_API Lisp_Object Q##c_name##p
1542 1544
1543 # define DECLARE_MODULE_LRECORD(c_name, structtype) \ 1545 # define DECLARE_MODULE_LISP_OBJECT(c_name, structtype) \
1544 extern int lrecord_type_##c_name; \ 1546 extern int lrecord_type_##c_name; \
1545 extern struct lrecord_implementation lrecord_##c_name; \ 1547 extern struct lrecord_implementation lrecord_##c_name; \
1546 DECLARE_INLINE_HEADER ( \ 1548 DECLARE_INLINE_HEADER ( \
1547 structtype * \ 1549 structtype * \
1548 error_check_##c_name (Lisp_Object obj, const Ascbyte *file, int line) \ 1550 error_check_##c_name (Lisp_Object obj, const Ascbyte *file, int line) \
1551 assert_at_line (RECORD_TYPEP (obj, lrecord_type_##c_name), file, line); \ 1553 assert_at_line (RECORD_TYPEP (obj, lrecord_type_##c_name), file, line); \
1552 return (structtype *) XPNTR (obj); \ 1554 return (structtype *) XPNTR (obj); \
1553 } \ 1555 } \
1554 extern Lisp_Object Q##c_name##p 1556 extern Lisp_Object Q##c_name##p
1555 1557
1556 # define DECLARE_NONRECORD(c_name, type_enum, structtype) \
1557 DECLARE_INLINE_HEADER ( \
1558 structtype * \
1559 error_check_##c_name (Lisp_Object obj, const Ascbyte *file, int line) \
1560 ) \
1561 { \
1562 assert_at_line (XTYPE (obj) == type_enum, file, line); \
1563 return (structtype *) XPNTR (obj); \
1564 } \
1565 extern Lisp_Object Q##c_name##p
1566
1567 # define XRECORD(x, c_name, structtype) \ 1558 # define XRECORD(x, c_name, structtype) \
1568 error_check_##c_name (x, __FILE__, __LINE__)
1569 # define XNONRECORD(x, c_name, type_enum, structtype) \
1570 error_check_##c_name (x, __FILE__, __LINE__) 1559 error_check_##c_name (x, __FILE__, __LINE__)
1571 1560
1572 DECLARE_INLINE_HEADER ( 1561 DECLARE_INLINE_HEADER (
1573 Lisp_Object 1562 Lisp_Object
1574 wrap_record_1 (const void *ptr, enum lrecord_type ty, const Ascbyte *file, 1563 wrap_record_1 (const void *ptr, enum lrecord_type ty, const Ascbyte *file,
1584 #define wrap_record(ptr, ty) \ 1573 #define wrap_record(ptr, ty) \
1585 wrap_record_1 (ptr, lrecord_type_##ty, __FILE__, __LINE__) 1574 wrap_record_1 (ptr, lrecord_type_##ty, __FILE__, __LINE__)
1586 1575
1587 #else /* not ERROR_CHECK_TYPES */ 1576 #else /* not ERROR_CHECK_TYPES */
1588 1577
1589 # define DECLARE_LISP_OBJECT(c_name, structtype) \ 1578 # define DECLARE_LISP_OBJECT(c_name, structtype) \
1590 extern Lisp_Object Q##c_name##p; \ 1579 extern Lisp_Object Q##c_name##p; \
1591 extern const struct lrecord_implementation lrecord_##c_name 1580 extern const struct lrecord_implementation lrecord_##c_name
1592 # define DECLARE_MODULE_API_LRECORD(c_name, structtype) \ 1581 # define DECLARE_MODULE_API_LISP_OBJECT(c_name, structtype) \
1593 extern MODULE_API Lisp_Object Q##c_name##p; \ 1582 extern MODULE_API Lisp_Object Q##c_name##p; \
1594 extern MODULE_API const struct lrecord_implementation lrecord_##c_name 1583 extern MODULE_API const struct lrecord_implementation lrecord_##c_name
1595 # define DECLARE_MODULE_LRECORD(c_name, structtype) \ 1584 # define DECLARE_MODULE_LISP_OBJECT(c_name, structtype) \
1596 extern Lisp_Object Q##c_name##p; \ 1585 extern Lisp_Object Q##c_name##p; \
1597 extern int lrecord_type_##c_name; \ 1586 extern int lrecord_type_##c_name; \
1598 extern struct lrecord_implementation lrecord_##c_name 1587 extern struct lrecord_implementation lrecord_##c_name
1599 # define DECLARE_NONRECORD(c_name, type_enum, structtype) \
1600 extern Lisp_Object Q##c_name##p
1601 # define XRECORD(x, c_name, structtype) ((structtype *) XPNTR (x)) 1588 # define XRECORD(x, c_name, structtype) ((structtype *) XPNTR (x))
1602 # define XNONRECORD(x, c_name, type_enum, structtype) \
1603 ((structtype *) XPNTR (x))
1604 /* wrap_pointer_1 is so named as a suggestion not to use it unless you 1589 /* wrap_pointer_1 is so named as a suggestion not to use it unless you
1605 know what you're doing. */ 1590 know what you're doing. */
1606 #define wrap_record(ptr, ty) wrap_pointer_1 (ptr) 1591 #define wrap_record(ptr, ty) wrap_pointer_1 (ptr)
1607 1592
1608 #endif /* not ERROR_CHECK_TYPES */ 1593 #endif /* not ERROR_CHECK_TYPES */
1651 1636
1652 /* How to allocate a Lisp object: 1637 /* How to allocate a Lisp object:
1653 1638
1654 - For most objects, simply call ALLOC_LISP_OBJECT (type), where TYPE is 1639 - For most objects, simply call ALLOC_LISP_OBJECT (type), where TYPE is
1655 the name of the type (e.g. toolbar_button). Such objects can be freed 1640 the name of the type (e.g. toolbar_button). Such objects can be freed
1656 manually using FREE_LCRECORD. 1641 manually using FREE_LISP_OBJECT.
1657 1642
1658 - For objects whose size can vary (and hence which have a 1643 - For objects whose size can vary (and hence which have a
1659 size_in_bytes_method rather than a static_size), call 1644 size_in_bytes_method rather than a static_size), call
1660 ALLOC_SIZED_LISP_OBJECT (size, type), where TYPE is the 1645 ALLOC_SIZED_LISP_OBJECT (size, type), where TYPE is the
1661 name of the type. NOTE: You cannot call FREE_LCRECORD() on such 1646 name of the type. NOTE: You cannot call FREE_LISP_OBJECT() on such
1662 on object! (At least when not NEW_GC) 1647 on object! (At least when not NEW_GC)
1663 1648
1664 - Basic lrecords (of which there are a limited number, which exist only 1649 - Basic lrecords (of which there are a limited number, which exist only
1665 when not NEW_GC, and which have special handling in alloc.c) need 1650 when not NEW_GC, and which have special handling in alloc.c) need
1666 special handling; if you don't understand this, just ignore it. 1651 special handling; if you don't understand this, just ignore it.
1672 #ifndef NEW_GC 1657 #ifndef NEW_GC
1673 /*-------------------------- lcrecord-list -----------------------------*/ 1658 /*-------------------------- lcrecord-list -----------------------------*/
1674 1659
1675 struct lcrecord_list 1660 struct lcrecord_list
1676 { 1661 {
1677 struct LCRECORD_HEADER header; 1662 LISP_OBJECT_HEADER header;
1678 Lisp_Object free; 1663 Lisp_Object free;
1679 Elemcount size; 1664 Elemcount size;
1680 const struct lrecord_implementation *implementation; 1665 const struct lrecord_implementation *implementation;
1681 }; 1666 };
1682 1667
1693 1678
1694 See above for a discussion of the difference between plain lrecords and 1679 See above for a discussion of the difference between plain lrecords and
1695 lrecords. lcrecords themselves are divided into three types: (1) 1680 lrecords. lcrecords themselves are divided into three types: (1)
1696 auto-managed, (2) hand-managed, and (3) unmanaged. "Managed" refers to 1681 auto-managed, (2) hand-managed, and (3) unmanaged. "Managed" refers to
1697 using a special object called an lcrecord-list to keep track of freed 1682 using a special object called an lcrecord-list to keep track of freed
1698 lcrecords, which can freed with FREE_LCRECORD() or the like and later be 1683 lcrecords, which can freed with FREE_LISP_OBJECT() or the like and later be
1699 recycled when a new lcrecord is required, rather than requiring new 1684 recycled when a new lcrecord is required, rather than requiring new
1700 malloc(). Thus, allocation of lcrecords can be very 1685 malloc(). Thus, allocation of lcrecords can be very
1701 cheap. (Technically, the lcrecord-list manager could divide up large 1686 cheap. (Technically, the lcrecord-list manager could divide up large
1702 chunks of memory and allocate out of that, mimicking what happens with 1687 chunks of memory and allocate out of that, mimicking what happens with
1703 lrecords. At that point, however, we'd want to rethink the whole 1688 lrecords. At that point, however, we'd want to rethink the whole
1709 in particular dictate the various types of management: 1694 in particular dictate the various types of management:
1710 1695
1711 -- "Auto-managed" means that you just go ahead and allocate the lcrecord 1696 -- "Auto-managed" means that you just go ahead and allocate the lcrecord
1712 whenever you want, using ALLOC_LISP_OBJECT(), and the appropriate 1697 whenever you want, using ALLOC_LISP_OBJECT(), and the appropriate
1713 lcrecord-list manager is automatically created. To free, you just call 1698 lcrecord-list manager is automatically created. To free, you just call
1714 "FREE_LCRECORD()" and the appropriate lcrecord-list manager is 1699 "FREE_LISP_OBJECT()" and the appropriate lcrecord-list manager is
1715 automatically located and called. The limitation here of course is that 1700 automatically located and called. The limitation here of course is that
1716 all your objects are of the same size. (#### Eventually we should have a 1701 all your objects are of the same size. (#### Eventually we should have a
1717 more sophisticated system that tracks the sizes seen and creates one 1702 more sophisticated system that tracks the sizes seen and creates one
1718 lcrecord list per size, indexed in a hash table. Usually there are only 1703 lcrecord list per size, indexed in a hash table. Usually there are only
1719 a limited number of sizes, so this works well.) 1704 a limited number of sizes, so this works well.)
1807 1792
1808 #define old_zero_lcrecord(lcr) old_zero_sized_lcrecord (lcr, sizeof (*(lcr))) 1793 #define old_zero_lcrecord(lcr) old_zero_sized_lcrecord (lcr, sizeof (*(lcr)))
1809 1794
1810 #else /* NEW_GC */ 1795 #else /* NEW_GC */
1811 1796
1812 Lisp_Object alloc_sized_lrecord (Bytecount size, 1797 MODULE_API Lisp_Object alloc_sized_lrecord (Bytecount size,
1798 const struct lrecord_implementation *imp);
1799 Lisp_Object noseeum_alloc_sized_lrecord (Bytecount size,
1800 const struct lrecord_implementation *imp);
1801 MODULE_API Lisp_Object alloc_lrecord (const struct lrecord_implementation *imp);
1802 Lisp_Object noseeum_alloc_lrecord (const struct lrecord_implementation *imp);
1803
1804 MODULE_API Lisp_Object alloc_lrecord_array (int elemcount,
1813 const struct lrecord_implementation *imp); 1805 const struct lrecord_implementation *imp);
1814 Lisp_Object noseeum_alloc_sized_lrecord (Bytecount size, 1806 MODULE_API Lisp_Object alloc_sized_lrecord_array (Bytecount size,
1815 const struct lrecord_implementation *); 1807 int elemcount,
1816 Lisp_Object alloc_lrecord (const struct lrecord_implementation *imp); 1808 const struct lrecord_implementation *imp);
1817 Lisp_Object noseeum_alloc_lrecord (const struct lrecord_implementation *imp);
1818
1819 Lisp_Object alloc_lrecord_array (int elemcount,
1820 const struct lrecord_implementation *imp);
1821 Lisp_Object alloc_sized_lrecord_array (Bytecount size, int elemcount,
1822 const struct lrecord_implementation *imp);
1823
1824 #define alloc_lrecord_type(type, imp) \
1825 ((type *) XPNTR (alloc_sized_lrecord (sizeof (type), imp)))
1826
1827 #define noseeum_alloc_lrecord_type(type, imp) \
1828 ((type *) XPNTR (noseeum_alloc_sized_lrecord (sizeof (type), imp)))
1829 1809
1830 void free_lrecord (Lisp_Object rec); 1810 void free_lrecord (Lisp_Object rec);
1831 1811
1832 1812
1833 /* Copy the data from one lrecord structure into another, but don't 1813 /* Copy the data from one lrecord structure into another, but don't