Mercurial > emacs
comparison src/alloc.c @ 1300:b13b79e28eb5
* alloc.c: #include "intervals.h".
(init_intervals, make_interval,
mark_interval, mark_interval_tree): New functions conditionally
defined.
(make_uninit_string): Call INITIALIZE_INTERVAL.
(INIT_INTERVALS, UNMARK_BALANCE_INTERVALS, MARK_INTERVAL_TREE):
New macros, conditionally defined.
(mark_object): Call MARK_INTERVAL_TREE in case Lisp_String.
(gc_sweep): If text properties are in use, place all unmarked
intervals on the free list. Call UNMARK_BALANCE_INTERVALS on
`buffer->intervals' when unmarking `buffer'.
(compact_strings): Include INTERVAL_PTR_SIZE in calculation for
target of bcopy when relocating strings.
(init_alloc_once): Call INIT_INTERVALS.
(make_pure_string): Include INTERVAL_PTR_SIZE in calculation of
`size'.
| author | Joseph Arceneaux <jla@gnu.org> |
|---|---|
| date | Fri, 02 Oct 1992 19:59:42 +0000 |
| parents | a9241dc503ab |
| children | 0edeba6fc9fc |
comparison
equal
deleted
inserted
replaced
| 1299:b8337cdf2e8b | 1300:b13b79e28eb5 |
|---|---|
| 18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | 18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ |
| 19 | 19 |
| 20 | 20 |
| 21 #include "config.h" | 21 #include "config.h" |
| 22 #include "lisp.h" | 22 #include "lisp.h" |
| 23 #include "intervals.h" | |
| 23 #include "puresize.h" | 24 #include "puresize.h" |
| 24 #ifndef standalone | 25 #ifndef standalone |
| 25 #include "buffer.h" | 26 #include "buffer.h" |
| 26 #include "window.h" | 27 #include "window.h" |
| 27 #ifdef MULTI_FRAME | 28 #ifdef MULTI_FRAME |
| 174 | 175 |
| 175 if (!val && size) memory_full (); | 176 if (!val && size) memory_full (); |
| 176 return val; | 177 return val; |
| 177 } | 178 } |
| 178 | 179 |
| 180 #ifdef USE_TEXT_PROPERTIES | |
| 181 #define INTERVAL_BLOCK_SIZE \ | |
| 182 ((1020 - sizeof (struct interval_block *)) / sizeof (struct interval)) | |
| 183 | |
| 184 struct interval_block | |
| 185 { | |
| 186 struct interval_block *next; | |
| 187 struct interval intervals[INTERVAL_BLOCK_SIZE]; | |
| 188 }; | |
| 189 | |
| 190 struct interval_block *interval_block; | |
| 191 static int interval_block_index; | |
| 192 | |
| 193 INTERVAL interval_free_list; | |
| 194 | |
| 195 static void | |
| 196 init_intervals () | |
| 197 { | |
| 198 interval_block | |
| 199 = (struct interval_block *) malloc (sizeof (struct interval_block)); | |
| 200 interval_block->next = 0; | |
| 201 bzero (interval_block->intervals, sizeof interval_block->intervals); | |
| 202 interval_block_index = 0; | |
| 203 interval_free_list = 0; | |
| 204 } | |
| 205 | |
| 206 #define INIT_INTERVALS init_intervals () | |
| 207 | |
| 208 INTERVAL | |
| 209 make_interval () | |
| 210 { | |
| 211 INTERVAL val; | |
| 212 | |
| 213 if (interval_free_list) | |
| 214 { | |
| 215 val = interval_free_list; | |
| 216 interval_free_list = interval_free_list->parent; | |
| 217 } | |
| 218 else | |
| 219 { | |
| 220 if (interval_block_index == INTERVAL_BLOCK_SIZE) | |
| 221 { | |
| 222 register struct interval_block *newi | |
| 223 = (struct interval_block *) malloc (sizeof (struct interval_block)); | |
| 224 | |
| 225 if (!newi) | |
| 226 memory_full (); | |
| 227 | |
| 228 VALIDATE_LISP_STORAGE (newi, sizeof *newi); | |
| 229 newi->next = interval_block; | |
| 230 interval_block = newi; | |
| 231 interval_block_index = 0; | |
| 232 } | |
| 233 val = &interval_block->intervals[interval_block_index++]; | |
| 234 } | |
| 235 consing_since_gc += sizeof (struct interval); | |
| 236 RESET_INTERVAL (val); | |
| 237 return val; | |
| 238 } | |
| 239 | |
| 240 static int total_free_intervals, total_intervals; | |
| 241 | |
| 242 /* Mark the pointers of one interval. */ | |
| 243 | |
| 244 static void | |
| 245 mark_interval (i) | |
| 246 register INTERVAL i; | |
| 247 { | |
| 248 if (XMARKBIT (i->plist)) | |
| 249 abort (); | |
| 250 mark_object (&i->plist); | |
| 251 XMARK (i->plist); | |
| 252 } | |
| 253 | |
| 254 static void | |
| 255 mark_interval_tree (tree) | |
| 256 register INTERVAL tree; | |
| 257 { | |
| 258 if (XMARKBIT (tree->plist)) | |
| 259 return; | |
| 260 | |
| 261 traverse_intervals (tree, 1, &mark_interval); | |
| 262 } | |
| 263 | |
| 264 #define MARK_INTERVAL_TREE(i) \ | |
| 265 { if (!NULL_INTERVAL_P (i)) mark_interval_tree (i); } | |
| 266 | |
| 267 #define UNMARK_BALANCE_INTERVALS(i) \ | |
| 268 { \ | |
| 269 if (! NULL_INTERVAL_P (i)) \ | |
| 270 { \ | |
| 271 XUNMARK ((Lisp_Object) (i->parent)); \ | |
| 272 i = balance_intervals (i); \ | |
| 273 } \ | |
| 274 } | |
| 275 | |
| 276 #else /* no interval use */ | |
| 277 | |
| 278 #define INIT_INTERVALS | |
| 279 | |
| 280 #define UNMARK_BALANCE_INTERVALS(i) | |
| 281 #define MARK_INTERVAL_TREE(i) | |
| 282 | |
| 283 #endif /* no interval use */ | |
| 284 | |
| 179 #ifdef LISP_FLOAT_TYPE | 285 #ifdef LISP_FLOAT_TYPE |
| 180 /* Allocation of float cells, just like conses */ | 286 /* Allocation of float cells, just like conses */ |
| 181 /* We store float cells inside of float_blocks, allocating a new | 287 /* We store float cells inside of float_blocks, allocating a new |
| 182 float_block with malloc whenever necessary. Float cells reclaimed by | 288 float_block with malloc whenever necessary. Float cells reclaimed by |
| 183 GC are put on a free list to be reallocated before allocating | 289 GC are put on a free list to be reallocated before allocating |
| 739 (struct Lisp_String *) current_string_block->chars); | 845 (struct Lisp_String *) current_string_block->chars); |
| 740 } | 846 } |
| 741 | 847 |
| 742 XSTRING (val)->size = length; | 848 XSTRING (val)->size = length; |
| 743 XSTRING (val)->data[length] = 0; | 849 XSTRING (val)->data[length] = 0; |
| 850 INITIALIZE_INTERVAL (XSTRING (val), NULL_INTERVAL); | |
| 744 | 851 |
| 745 return val; | 852 return val; |
| 746 } | 853 } |
| 747 | 854 |
| 748 /* Return a newly created vector or string with specified arguments as | 855 /* Return a newly created vector or string with specified arguments as |
| 831 make_pure_string (data, length) | 938 make_pure_string (data, length) |
| 832 char *data; | 939 char *data; |
| 833 int length; | 940 int length; |
| 834 { | 941 { |
| 835 register Lisp_Object new; | 942 register Lisp_Object new; |
| 836 register int size = sizeof (int) + length + 1; | 943 register int size = sizeof (int) + INTERVAL_PTR_SIZE + length + 1; |
| 837 | 944 |
| 838 if (pureptr + size > PURESIZE) | 945 if (pureptr + size > PURESIZE) |
| 839 error ("Pure Lisp storage exhausted"); | 946 error ("Pure Lisp storage exhausted"); |
| 840 XSET (new, Lisp_String, PUREBEG + pureptr); | 947 XSET (new, Lisp_String, PUREBEG + pureptr); |
| 841 XSTRING (new)->size = length; | 948 XSTRING (new)->size = length; |
| 1300 { | 1407 { |
| 1301 case Lisp_String: | 1408 case Lisp_String: |
| 1302 { | 1409 { |
| 1303 register struct Lisp_String *ptr = XSTRING (obj); | 1410 register struct Lisp_String *ptr = XSTRING (obj); |
| 1304 | 1411 |
| 1412 MARK_INTERVAL_TREE (ptr->intervals); | |
| 1305 if (ptr->size & MARKBIT) | 1413 if (ptr->size & MARKBIT) |
| 1306 /* A large string. Just set ARRAY_MARK_FLAG. */ | 1414 /* A large string. Just set ARRAY_MARK_FLAG. */ |
| 1307 ptr->size |= ARRAY_MARK_FLAG; | 1415 ptr->size |= ARRAY_MARK_FLAG; |
| 1308 else | 1416 else |
| 1309 { | 1417 { |
| 1485 register Lisp_Object *ptr; | 1593 register Lisp_Object *ptr; |
| 1486 | 1594 |
| 1487 /* This is the buffer's markbit */ | 1595 /* This is the buffer's markbit */ |
| 1488 mark_object (&buffer->name); | 1596 mark_object (&buffer->name); |
| 1489 XMARK (buffer->name); | 1597 XMARK (buffer->name); |
| 1598 | |
| 1599 MARK_INTERVAL_TREE (buffer->intervals); | |
| 1490 | 1600 |
| 1491 #if 0 | 1601 #if 0 |
| 1492 mark_object (buffer->syntax_table); | 1602 mark_object (buffer->syntax_table); |
| 1493 | 1603 |
| 1494 /* Mark the various string-pointers in the buffer object. | 1604 /* Mark the various string-pointers in the buffer object. |
| 1581 } | 1691 } |
| 1582 total_floats = num_used; | 1692 total_floats = num_used; |
| 1583 total_free_floats = num_free; | 1693 total_free_floats = num_free; |
| 1584 } | 1694 } |
| 1585 #endif /* LISP_FLOAT_TYPE */ | 1695 #endif /* LISP_FLOAT_TYPE */ |
| 1696 | |
| 1697 #ifdef USE_TEXT_PROPERTIES | |
| 1698 /* Put all unmarked intervals on free list */ | |
| 1699 { | |
| 1700 register struct interval_block *iblk; | |
| 1701 register int lim = interval_block_index; | |
| 1702 register int num_free = 0, num_used = 0; | |
| 1703 | |
| 1704 interval_free_list = 0; | |
| 1705 | |
| 1706 for (iblk = interval_block; iblk; iblk = iblk->next) | |
| 1707 { | |
| 1708 register int i; | |
| 1709 | |
| 1710 for (i = 0; i < lim; i++) | |
| 1711 { | |
| 1712 if (! XMARKBIT (iblk->intervals[i].plist)) | |
| 1713 { | |
| 1714 iblk->intervals[i].parent = interval_free_list; | |
| 1715 interval_free_list = &iblk->intervals[i]; | |
| 1716 num_free++; | |
| 1717 } | |
| 1718 else | |
| 1719 { | |
| 1720 num_used++; | |
| 1721 XUNMARK (iblk->intervals[i].plist); | |
| 1722 } | |
| 1723 } | |
| 1724 lim = INTERVAL_BLOCK_SIZE; | |
| 1725 } | |
| 1726 total_intervals = num_used; | |
| 1727 total_free_intervals = num_free; | |
| 1728 } | |
| 1729 #endif /* USE_TEXT_PROPERTIES */ | |
| 1586 | 1730 |
| 1587 /* Put all unmarked symbols on free list */ | 1731 /* Put all unmarked symbols on free list */ |
| 1588 { | 1732 { |
| 1589 register struct symbol_block *sblk; | 1733 register struct symbol_block *sblk; |
| 1590 register int lim = symbol_block_index; | 1734 register int lim = symbol_block_index; |
| 1668 buffer = next; | 1812 buffer = next; |
| 1669 } | 1813 } |
| 1670 else | 1814 else |
| 1671 { | 1815 { |
| 1672 XUNMARK (buffer->name); | 1816 XUNMARK (buffer->name); |
| 1817 UNMARK_BALANCE_INTERVALS (buffer->intervals); | |
| 1673 | 1818 |
| 1674 #if 0 | 1819 #if 0 |
| 1675 /* Each `struct Lisp_String *' was turned into a Lisp_Object | 1820 /* Each `struct Lisp_String *' was turned into a Lisp_Object |
| 1676 for purposes of marking and relocation. | 1821 for purposes of marking and relocation. |
| 1677 Turn them back into C pointers now. */ | 1822 Turn them back into C pointers now. */ |
| 1803 newaddr = (struct Lisp_String *) &to_sb->chars[to_pos]; | 1948 newaddr = (struct Lisp_String *) &to_sb->chars[to_pos]; |
| 1804 to_pos += STRING_FULLSIZE (size); | 1949 to_pos += STRING_FULLSIZE (size); |
| 1805 | 1950 |
| 1806 /* Copy the string itself to the new place. */ | 1951 /* Copy the string itself to the new place. */ |
| 1807 if (nextstr != newaddr) | 1952 if (nextstr != newaddr) |
| 1808 bcopy (nextstr, newaddr, size + 1 + sizeof (int)); | 1953 bcopy (nextstr, newaddr, size + 1 + sizeof (int) |
| 1954 + INTERVAL_PTR_SIZE); | |
| 1809 | 1955 |
| 1810 /* Go through NEXTSTR's chain of references | 1956 /* Go through NEXTSTR's chain of references |
| 1811 and make each slot in the chain point to | 1957 and make each slot in the chain point to |
| 1812 the new address of this string. */ | 1958 the new address of this string. */ |
| 1813 size = newaddr->size; | 1959 size = newaddr->size; |
| 1880 init_symbol (); | 2026 init_symbol (); |
| 1881 init_marker (); | 2027 init_marker (); |
| 1882 #ifdef LISP_FLOAT_TYPE | 2028 #ifdef LISP_FLOAT_TYPE |
| 1883 init_float (); | 2029 init_float (); |
| 1884 #endif /* LISP_FLOAT_TYPE */ | 2030 #endif /* LISP_FLOAT_TYPE */ |
| 2031 INIT_INTERVALS; | |
| 2032 | |
| 1885 ignore_warnings = 0; | 2033 ignore_warnings = 0; |
| 1886 gcprolist = 0; | 2034 gcprolist = 0; |
| 1887 staticidx = 0; | 2035 staticidx = 0; |
| 1888 consing_since_gc = 0; | 2036 consing_since_gc = 0; |
| 1889 gc_cons_threshold = 100000; | 2037 gc_cons_threshold = 100000; |
