diff options
| author | Kenichi Handa | 2012-07-17 07:25:00 +0900 |
|---|---|---|
| committer | Kenichi Handa | 2012-07-17 07:25:00 +0900 |
| commit | 69c41c4070c86baac11a627e9c3d366420aeb7cc (patch) | |
| tree | e07fda92570b5e4f264c9a7869b57960940008f0 /src/alloc.c | |
| parent | 8c536f15bf95916d56bb50495d22b7da7e09fff9 (diff) | |
| parent | 758e556a7ab8f61c007e34310ba399a9aaf15362 (diff) | |
| download | emacs-69c41c4070c86baac11a627e9c3d366420aeb7cc.tar.gz emacs-69c41c4070c86baac11a627e9c3d366420aeb7cc.zip | |
merge trunk
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 1182 |
1 files changed, 709 insertions, 473 deletions
diff --git a/src/alloc.c b/src/alloc.c index 7c461c5a6af..39c360a67e7 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -38,12 +38,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 38 | #include "process.h" | 38 | #include "process.h" |
| 39 | #include "intervals.h" | 39 | #include "intervals.h" |
| 40 | #include "puresize.h" | 40 | #include "puresize.h" |
| 41 | #include "character.h" | ||
| 41 | #include "buffer.h" | 42 | #include "buffer.h" |
| 42 | #include "window.h" | 43 | #include "window.h" |
| 43 | #include "keyboard.h" | 44 | #include "keyboard.h" |
| 44 | #include "frame.h" | 45 | #include "frame.h" |
| 45 | #include "blockinput.h" | 46 | #include "blockinput.h" |
| 46 | #include "character.h" | ||
| 47 | #include "syssignal.h" | 47 | #include "syssignal.h" |
| 48 | #include "termhooks.h" /* For struct terminal. */ | 48 | #include "termhooks.h" /* For struct terminal. */ |
| 49 | #include <setjmp.h> | 49 | #include <setjmp.h> |
| @@ -258,11 +258,6 @@ static char *stack_copy; | |||
| 258 | static ptrdiff_t stack_copy_size; | 258 | static ptrdiff_t stack_copy_size; |
| 259 | #endif | 259 | #endif |
| 260 | 260 | ||
| 261 | /* Non-zero means ignore malloc warnings. Set during initialization. | ||
| 262 | Currently not used. */ | ||
| 263 | |||
| 264 | static int ignore_warnings; | ||
| 265 | |||
| 266 | static Lisp_Object Qgc_cons_threshold; | 261 | static Lisp_Object Qgc_cons_threshold; |
| 267 | Lisp_Object Qchar_table_extra_slots; | 262 | Lisp_Object Qchar_table_extra_slots; |
| 268 | 263 | ||
| @@ -270,7 +265,6 @@ Lisp_Object Qchar_table_extra_slots; | |||
| 270 | 265 | ||
| 271 | static Lisp_Object Qpost_gc_hook; | 266 | static Lisp_Object Qpost_gc_hook; |
| 272 | 267 | ||
| 273 | static void mark_buffer (Lisp_Object); | ||
| 274 | static void mark_terminals (void); | 268 | static void mark_terminals (void); |
| 275 | static void gc_sweep (void); | 269 | static void gc_sweep (void); |
| 276 | static Lisp_Object make_pure_vector (ptrdiff_t); | 270 | static Lisp_Object make_pure_vector (ptrdiff_t); |
| @@ -304,7 +298,9 @@ enum mem_type | |||
| 304 | process, hash_table, frame, terminal, and window, but we never made | 298 | process, hash_table, frame, terminal, and window, but we never made |
| 305 | use of the distinction, so it only caused source-code complexity | 299 | use of the distinction, so it only caused source-code complexity |
| 306 | and runtime slowdown. Minor but pointless. */ | 300 | and runtime slowdown. Minor but pointless. */ |
| 307 | MEM_TYPE_VECTORLIKE | 301 | MEM_TYPE_VECTORLIKE, |
| 302 | /* Special type to denote vector blocks. */ | ||
| 303 | MEM_TYPE_VECTOR_BLOCK | ||
| 308 | }; | 304 | }; |
| 309 | 305 | ||
| 310 | static void *lisp_malloc (size_t, enum mem_type); | 306 | static void *lisp_malloc (size_t, enum mem_type); |
| @@ -429,12 +425,12 @@ struct gcpro *gcprolist; | |||
| 429 | /* Addresses of staticpro'd variables. Initialize it to a nonzero | 425 | /* Addresses of staticpro'd variables. Initialize it to a nonzero |
| 430 | value; otherwise some compilers put it into BSS. */ | 426 | value; otherwise some compilers put it into BSS. */ |
| 431 | 427 | ||
| 432 | #define NSTATICS 0x640 | 428 | #define NSTATICS 0x650 |
| 433 | static Lisp_Object *staticvec[NSTATICS] = {&Vpurify_flag}; | 429 | static Lisp_Object *staticvec[NSTATICS] = {&Vpurify_flag}; |
| 434 | 430 | ||
| 435 | /* Index of next unused slot in staticvec. */ | 431 | /* Index of next unused slot in staticvec. */ |
| 436 | 432 | ||
| 437 | static int staticidx = 0; | 433 | static int staticidx; |
| 438 | 434 | ||
| 439 | static void *pure_alloc (size_t, int); | 435 | static void *pure_alloc (size_t, int); |
| 440 | 436 | ||
| @@ -494,6 +490,11 @@ buffer_memory_full (ptrdiff_t nbytes) | |||
| 494 | xsignal (Qnil, Vmemory_signal_data); | 490 | xsignal (Qnil, Vmemory_signal_data); |
| 495 | } | 491 | } |
| 496 | 492 | ||
| 493 | /* A common multiple of the positive integers A and B. Ideally this | ||
| 494 | would be the least common multiple, but there's no way to do that | ||
| 495 | as a constant expression in C, so do the best that we can easily do. */ | ||
| 496 | #define COMMON_MULTIPLE(a, b) \ | ||
| 497 | ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b)) | ||
| 497 | 498 | ||
| 498 | #ifndef XMALLOC_OVERRUN_CHECK | 499 | #ifndef XMALLOC_OVERRUN_CHECK |
| 499 | #define XMALLOC_OVERRUN_CHECK_OVERHEAD 0 | 500 | #define XMALLOC_OVERRUN_CHECK_OVERHEAD 0 |
| @@ -525,12 +526,8 @@ buffer_memory_full (ptrdiff_t nbytes) | |||
| 525 | char c; \ | 526 | char c; \ |
| 526 | }, \ | 527 | }, \ |
| 527 | c) | 528 | c) |
| 528 | #ifdef USE_LSB_TAG | 529 | |
| 529 | /* A common multiple of the positive integers A and B. Ideally this | 530 | #if USE_LSB_TAG |
| 530 | would be the least common multiple, but there's no way to do that | ||
| 531 | as a constant expression in C, so do the best that we can easily do. */ | ||
| 532 | # define COMMON_MULTIPLE(a, b) \ | ||
| 533 | ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b)) | ||
| 534 | # define XMALLOC_HEADER_ALIGNMENT \ | 531 | # define XMALLOC_HEADER_ALIGNMENT \ |
| 535 | COMMON_MULTIPLE (1 << GCTYPEBITS, XMALLOC_BASE_ALIGNMENT) | 532 | COMMON_MULTIPLE (1 << GCTYPEBITS, XMALLOC_BASE_ALIGNMENT) |
| 536 | #else | 533 | #else |
| @@ -613,7 +610,7 @@ overrun_check_malloc (size_t size) | |||
| 613 | if (SIZE_MAX - overhead < size) | 610 | if (SIZE_MAX - overhead < size) |
| 614 | abort (); | 611 | abort (); |
| 615 | 612 | ||
| 616 | val = (unsigned char *) malloc (size + overhead); | 613 | val = malloc (size + overhead); |
| 617 | if (val && check_depth == 1) | 614 | if (val && check_depth == 1) |
| 618 | { | 615 | { |
| 619 | memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE); | 616 | memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE); |
| @@ -733,6 +730,22 @@ xmalloc (size_t size) | |||
| 733 | return val; | 730 | return val; |
| 734 | } | 731 | } |
| 735 | 732 | ||
| 733 | /* Like the above, but zeroes out the memory just allocated. */ | ||
| 734 | |||
| 735 | void * | ||
| 736 | xzalloc (size_t size) | ||
| 737 | { | ||
| 738 | void *val; | ||
| 739 | |||
| 740 | MALLOC_BLOCK_INPUT; | ||
| 741 | val = malloc (size); | ||
| 742 | MALLOC_UNBLOCK_INPUT; | ||
| 743 | |||
| 744 | if (!val && size) | ||
| 745 | memory_full (size); | ||
| 746 | memset (val, 0, size); | ||
| 747 | return val; | ||
| 748 | } | ||
| 736 | 749 | ||
| 737 | /* Like realloc but check for no memory and block interrupt input.. */ | 750 | /* Like realloc but check for no memory and block interrupt input.. */ |
| 738 | 751 | ||
| @@ -784,7 +797,7 @@ verify (INT_MAX <= PTRDIFF_MAX); | |||
| 784 | void * | 797 | void * |
| 785 | xnmalloc (ptrdiff_t nitems, ptrdiff_t item_size) | 798 | xnmalloc (ptrdiff_t nitems, ptrdiff_t item_size) |
| 786 | { | 799 | { |
| 787 | xassert (0 <= nitems && 0 < item_size); | 800 | eassert (0 <= nitems && 0 < item_size); |
| 788 | if (min (PTRDIFF_MAX, SIZE_MAX) / item_size < nitems) | 801 | if (min (PTRDIFF_MAX, SIZE_MAX) / item_size < nitems) |
| 789 | memory_full (SIZE_MAX); | 802 | memory_full (SIZE_MAX); |
| 790 | return xmalloc (nitems * item_size); | 803 | return xmalloc (nitems * item_size); |
| @@ -797,7 +810,7 @@ xnmalloc (ptrdiff_t nitems, ptrdiff_t item_size) | |||
| 797 | void * | 810 | void * |
| 798 | xnrealloc (void *pa, ptrdiff_t nitems, ptrdiff_t item_size) | 811 | xnrealloc (void *pa, ptrdiff_t nitems, ptrdiff_t item_size) |
| 799 | { | 812 | { |
| 800 | xassert (0 <= nitems && 0 < item_size); | 813 | eassert (0 <= nitems && 0 < item_size); |
| 801 | if (min (PTRDIFF_MAX, SIZE_MAX) / item_size < nitems) | 814 | if (min (PTRDIFF_MAX, SIZE_MAX) / item_size < nitems) |
| 802 | memory_full (SIZE_MAX); | 815 | memory_full (SIZE_MAX); |
| 803 | return xrealloc (pa, nitems * item_size); | 816 | return xrealloc (pa, nitems * item_size); |
| @@ -847,7 +860,7 @@ xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min, | |||
| 847 | ptrdiff_t nitems_incr_max = n_max - n; | 860 | ptrdiff_t nitems_incr_max = n_max - n; |
| 848 | ptrdiff_t incr = max (nitems_incr_min, min (incr_estimate, nitems_incr_max)); | 861 | ptrdiff_t incr = max (nitems_incr_min, min (incr_estimate, nitems_incr_max)); |
| 849 | 862 | ||
| 850 | xassert (0 < item_size && 0 < nitems_incr_min && 0 <= n && -1 <= nitems_max); | 863 | eassert (0 < item_size && 0 < nitems_incr_min && 0 <= n && -1 <= nitems_max); |
| 851 | if (! pa) | 864 | if (! pa) |
| 852 | *nitems = 0; | 865 | *nitems = 0; |
| 853 | if (nitems_incr_max < incr) | 866 | if (nitems_incr_max < incr) |
| @@ -865,7 +878,7 @@ char * | |||
| 865 | xstrdup (const char *s) | 878 | xstrdup (const char *s) |
| 866 | { | 879 | { |
| 867 | size_t len = strlen (s) + 1; | 880 | size_t len = strlen (s) + 1; |
| 868 | char *p = (char *) xmalloc (len); | 881 | char *p = xmalloc (len); |
| 869 | memcpy (p, s, len); | 882 | memcpy (p, s, len); |
| 870 | return p; | 883 | return p; |
| 871 | } | 884 | } |
| @@ -890,8 +903,8 @@ safe_alloca_unwind (Lisp_Object arg) | |||
| 890 | number of bytes to allocate, TYPE describes the intended use of the | 903 | number of bytes to allocate, TYPE describes the intended use of the |
| 891 | allocated memory block (for strings, for conses, ...). */ | 904 | allocated memory block (for strings, for conses, ...). */ |
| 892 | 905 | ||
| 893 | #ifndef USE_LSB_TAG | 906 | #if ! USE_LSB_TAG |
| 894 | static void *lisp_malloc_loser; | 907 | void *lisp_malloc_loser EXTERNALLY_VISIBLE; |
| 895 | #endif | 908 | #endif |
| 896 | 909 | ||
| 897 | static void * | 910 | static void * |
| @@ -905,9 +918,9 @@ lisp_malloc (size_t nbytes, enum mem_type type) | |||
| 905 | allocated_mem_type = type; | 918 | allocated_mem_type = type; |
| 906 | #endif | 919 | #endif |
| 907 | 920 | ||
| 908 | val = (void *) malloc (nbytes); | 921 | val = malloc (nbytes); |
| 909 | 922 | ||
| 910 | #ifndef USE_LSB_TAG | 923 | #if ! USE_LSB_TAG |
| 911 | /* If the memory just allocated cannot be addressed thru a Lisp | 924 | /* If the memory just allocated cannot be addressed thru a Lisp |
| 912 | object's pointer, and it needs to be, | 925 | object's pointer, and it needs to be, |
| 913 | that's equivalent to running out of memory. */ | 926 | that's equivalent to running out of memory. */ |
| @@ -1088,7 +1101,7 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) | |||
| 1088 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); | 1101 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); |
| 1089 | #endif | 1102 | #endif |
| 1090 | 1103 | ||
| 1091 | #ifndef USE_LSB_TAG | 1104 | #if ! USE_LSB_TAG |
| 1092 | /* If the memory just allocated cannot be addressed thru a Lisp | 1105 | /* If the memory just allocated cannot be addressed thru a Lisp |
| 1093 | object's pointer, and it needs to be, that's equivalent to | 1106 | object's pointer, and it needs to be, that's equivalent to |
| 1094 | running out of memory. */ | 1107 | running out of memory. */ |
| @@ -1184,21 +1197,6 @@ lisp_align_free (void *block) | |||
| 1184 | MALLOC_UNBLOCK_INPUT; | 1197 | MALLOC_UNBLOCK_INPUT; |
| 1185 | } | 1198 | } |
| 1186 | 1199 | ||
| 1187 | /* Return a new buffer structure allocated from the heap with | ||
| 1188 | a call to lisp_malloc. */ | ||
| 1189 | |||
| 1190 | struct buffer * | ||
| 1191 | allocate_buffer (void) | ||
| 1192 | { | ||
| 1193 | struct buffer *b | ||
| 1194 | = (struct buffer *) lisp_malloc (sizeof (struct buffer), | ||
| 1195 | MEM_TYPE_BUFFER); | ||
| 1196 | XSETPVECTYPESIZE (b, PVEC_BUFFER, | ||
| 1197 | ((sizeof (struct buffer) + sizeof (EMACS_INT) - 1) | ||
| 1198 | / sizeof (EMACS_INT))); | ||
| 1199 | return b; | ||
| 1200 | } | ||
| 1201 | |||
| 1202 | 1200 | ||
| 1203 | #ifndef SYSTEM_MALLOC | 1201 | #ifndef SYSTEM_MALLOC |
| 1204 | 1202 | ||
| @@ -1306,7 +1304,7 @@ emacs_blocked_malloc (size_t size, const void *ptr) | |||
| 1306 | __malloc_extra_blocks = malloc_hysteresis; | 1304 | __malloc_extra_blocks = malloc_hysteresis; |
| 1307 | #endif | 1305 | #endif |
| 1308 | 1306 | ||
| 1309 | value = (void *) malloc (size); | 1307 | value = malloc (size); |
| 1310 | 1308 | ||
| 1311 | #ifdef GC_MALLOC_CHECK | 1309 | #ifdef GC_MALLOC_CHECK |
| 1312 | { | 1310 | { |
| @@ -1368,7 +1366,7 @@ emacs_blocked_realloc (void *ptr, size_t size, const void *ptr2) | |||
| 1368 | dont_register_blocks = 1; | 1366 | dont_register_blocks = 1; |
| 1369 | #endif /* GC_MALLOC_CHECK */ | 1367 | #endif /* GC_MALLOC_CHECK */ |
| 1370 | 1368 | ||
| 1371 | value = (void *) realloc (ptr, size); | 1369 | value = realloc (ptr, size); |
| 1372 | 1370 | ||
| 1373 | #ifdef GC_MALLOC_CHECK | 1371 | #ifdef GC_MALLOC_CHECK |
| 1374 | dont_register_blocks = 0; | 1372 | dont_register_blocks = 0; |
| @@ -1478,7 +1476,7 @@ static struct interval_block *interval_block; | |||
| 1478 | /* Index in interval_block above of the next unused interval | 1476 | /* Index in interval_block above of the next unused interval |
| 1479 | structure. */ | 1477 | structure. */ |
| 1480 | 1478 | ||
| 1481 | static int interval_block_index; | 1479 | static int interval_block_index = INTERVAL_BLOCK_SIZE; |
| 1482 | 1480 | ||
| 1483 | /* Number of free and live intervals. */ | 1481 | /* Number of free and live intervals. */ |
| 1484 | 1482 | ||
| @@ -1488,18 +1486,6 @@ static EMACS_INT total_free_intervals, total_intervals; | |||
| 1488 | 1486 | ||
| 1489 | static INTERVAL interval_free_list; | 1487 | static INTERVAL interval_free_list; |
| 1490 | 1488 | ||
| 1491 | |||
| 1492 | /* Initialize interval allocation. */ | ||
| 1493 | |||
| 1494 | static void | ||
| 1495 | init_intervals (void) | ||
| 1496 | { | ||
| 1497 | interval_block = NULL; | ||
| 1498 | interval_block_index = INTERVAL_BLOCK_SIZE; | ||
| 1499 | interval_free_list = 0; | ||
| 1500 | } | ||
| 1501 | |||
| 1502 | |||
| 1503 | /* Return a new interval. */ | 1489 | /* Return a new interval. */ |
| 1504 | 1490 | ||
| 1505 | INTERVAL | 1491 | INTERVAL |
| @@ -1520,10 +1506,8 @@ make_interval (void) | |||
| 1520 | { | 1506 | { |
| 1521 | if (interval_block_index == INTERVAL_BLOCK_SIZE) | 1507 | if (interval_block_index == INTERVAL_BLOCK_SIZE) |
| 1522 | { | 1508 | { |
| 1523 | register struct interval_block *newi; | 1509 | struct interval_block *newi |
| 1524 | 1510 | = lisp_malloc (sizeof *newi, MEM_TYPE_NON_LISP); | |
| 1525 | newi = (struct interval_block *) lisp_malloc (sizeof *newi, | ||
| 1526 | MEM_TYPE_NON_LISP); | ||
| 1527 | 1511 | ||
| 1528 | newi->next = interval_block; | 1512 | newi->next = interval_block; |
| 1529 | interval_block = newi; | 1513 | interval_block = newi; |
| @@ -1542,7 +1526,7 @@ make_interval (void) | |||
| 1542 | } | 1526 | } |
| 1543 | 1527 | ||
| 1544 | 1528 | ||
| 1545 | /* Mark Lisp objects in interval I. */ | 1529 | /* Mark Lisp objects in interval I. */ |
| 1546 | 1530 | ||
| 1547 | static void | 1531 | static void |
| 1548 | mark_interval (register INTERVAL i, Lisp_Object dummy) | 1532 | mark_interval (register INTERVAL i, Lisp_Object dummy) |
| @@ -1581,35 +1565,6 @@ mark_interval_tree (register INTERVAL tree) | |||
| 1581 | if (! NULL_INTERVAL_P (i)) \ | 1565 | if (! NULL_INTERVAL_P (i)) \ |
| 1582 | (i) = balance_intervals (i); \ | 1566 | (i) = balance_intervals (i); \ |
| 1583 | } while (0) | 1567 | } while (0) |
| 1584 | |||
| 1585 | |||
| 1586 | /* Number support. If USE_LISP_UNION_TYPE is in effect, we | ||
| 1587 | can't create number objects in macros. */ | ||
| 1588 | #ifndef make_number | ||
| 1589 | Lisp_Object | ||
| 1590 | make_number (EMACS_INT n) | ||
| 1591 | { | ||
| 1592 | Lisp_Object obj; | ||
| 1593 | obj.s.val = n; | ||
| 1594 | obj.s.type = Lisp_Int; | ||
| 1595 | return obj; | ||
| 1596 | } | ||
| 1597 | #endif | ||
| 1598 | |||
| 1599 | /* Convert the pointer-sized word P to EMACS_INT while preserving its | ||
| 1600 | type and ptr fields. */ | ||
| 1601 | static Lisp_Object | ||
| 1602 | widen_to_Lisp_Object (void *p) | ||
| 1603 | { | ||
| 1604 | intptr_t i = (intptr_t) p; | ||
| 1605 | #ifdef USE_LISP_UNION_TYPE | ||
| 1606 | Lisp_Object obj; | ||
| 1607 | obj.i = i; | ||
| 1608 | return obj; | ||
| 1609 | #else | ||
| 1610 | return i; | ||
| 1611 | #endif | ||
| 1612 | } | ||
| 1613 | 1568 | ||
| 1614 | /*********************************************************************** | 1569 | /*********************************************************************** |
| 1615 | String Allocation | 1570 | String Allocation |
| @@ -1831,10 +1786,6 @@ static char const string_overrun_cookie[GC_STRING_OVERRUN_COOKIE_SIZE] = | |||
| 1831 | static void | 1786 | static void |
| 1832 | init_strings (void) | 1787 | init_strings (void) |
| 1833 | { | 1788 | { |
| 1834 | total_strings = total_free_strings = total_string_size = 0; | ||
| 1835 | oldest_sblock = current_sblock = large_sblocks = NULL; | ||
| 1836 | string_blocks = NULL; | ||
| 1837 | string_free_list = NULL; | ||
| 1838 | empty_unibyte_string = make_pure_string ("", 0, 0, 0); | 1789 | empty_unibyte_string = make_pure_string ("", 0, 0, 0); |
| 1839 | empty_multibyte_string = make_pure_string ("", 0, 0, 1); | 1790 | empty_multibyte_string = make_pure_string ("", 0, 0, 1); |
| 1840 | } | 1791 | } |
| @@ -1878,7 +1829,7 @@ check_sblock (struct sblock *b) | |||
| 1878 | ptrdiff_t nbytes; | 1829 | ptrdiff_t nbytes; |
| 1879 | 1830 | ||
| 1880 | /* Check that the string size recorded in the string is the | 1831 | /* Check that the string size recorded in the string is the |
| 1881 | same as the one recorded in the sdata structure. */ | 1832 | same as the one recorded in the sdata structure. */ |
| 1882 | if (from->string) | 1833 | if (from->string) |
| 1883 | CHECK_STRING_BYTES (from->string); | 1834 | CHECK_STRING_BYTES (from->string); |
| 1884 | 1835 | ||
| @@ -1914,7 +1865,7 @@ check_string_bytes (int all_p) | |||
| 1914 | for (b = oldest_sblock; b; b = b->next) | 1865 | for (b = oldest_sblock; b; b = b->next) |
| 1915 | check_sblock (b); | 1866 | check_sblock (b); |
| 1916 | } | 1867 | } |
| 1917 | else | 1868 | else if (current_sblock) |
| 1918 | check_sblock (current_sblock); | 1869 | check_sblock (current_sblock); |
| 1919 | } | 1870 | } |
| 1920 | 1871 | ||
| @@ -1958,17 +1909,17 @@ allocate_string (void) | |||
| 1958 | add all the Lisp_Strings in it to the free-list. */ | 1909 | add all the Lisp_Strings in it to the free-list. */ |
| 1959 | if (string_free_list == NULL) | 1910 | if (string_free_list == NULL) |
| 1960 | { | 1911 | { |
| 1961 | struct string_block *b; | 1912 | struct string_block *b = lisp_malloc (sizeof *b, MEM_TYPE_STRING); |
| 1962 | int i; | 1913 | int i; |
| 1963 | 1914 | ||
| 1964 | b = (struct string_block *) lisp_malloc (sizeof *b, MEM_TYPE_STRING); | ||
| 1965 | memset (b, 0, sizeof *b); | ||
| 1966 | b->next = string_blocks; | 1915 | b->next = string_blocks; |
| 1967 | string_blocks = b; | 1916 | string_blocks = b; |
| 1968 | 1917 | ||
| 1969 | for (i = STRING_BLOCK_SIZE - 1; i >= 0; --i) | 1918 | for (i = STRING_BLOCK_SIZE - 1; i >= 0; --i) |
| 1970 | { | 1919 | { |
| 1971 | s = b->strings + i; | 1920 | s = b->strings + i; |
| 1921 | /* Every string on a free list should have NULL data pointer. */ | ||
| 1922 | s->data = NULL; | ||
| 1972 | NEXT_FREE_LISP_STRING (s) = string_free_list; | 1923 | NEXT_FREE_LISP_STRING (s) = string_free_list; |
| 1973 | string_free_list = s; | 1924 | string_free_list = s; |
| 1974 | } | 1925 | } |
| @@ -1984,9 +1935,6 @@ allocate_string (void) | |||
| 1984 | 1935 | ||
| 1985 | MALLOC_UNBLOCK_INPUT; | 1936 | MALLOC_UNBLOCK_INPUT; |
| 1986 | 1937 | ||
| 1987 | /* Probably not strictly necessary, but play it safe. */ | ||
| 1988 | memset (s, 0, sizeof *s); | ||
| 1989 | |||
| 1990 | --total_free_strings; | 1938 | --total_free_strings; |
| 1991 | ++total_strings; | 1939 | ++total_strings; |
| 1992 | ++strings_consed; | 1940 | ++strings_consed; |
| @@ -2019,9 +1967,9 @@ void | |||
| 2019 | allocate_string_data (struct Lisp_String *s, | 1967 | allocate_string_data (struct Lisp_String *s, |
| 2020 | EMACS_INT nchars, EMACS_INT nbytes) | 1968 | EMACS_INT nchars, EMACS_INT nbytes) |
| 2021 | { | 1969 | { |
| 2022 | struct sdata *data, *old_data; | 1970 | struct sdata *data; |
| 2023 | struct sblock *b; | 1971 | struct sblock *b; |
| 2024 | ptrdiff_t needed, old_nbytes; | 1972 | ptrdiff_t needed; |
| 2025 | 1973 | ||
| 2026 | if (STRING_BYTES_MAX < nbytes) | 1974 | if (STRING_BYTES_MAX < nbytes) |
| 2027 | string_overflow (); | 1975 | string_overflow (); |
| @@ -2029,8 +1977,6 @@ allocate_string_data (struct Lisp_String *s, | |||
| 2029 | /* Determine the number of bytes needed to store NBYTES bytes | 1977 | /* Determine the number of bytes needed to store NBYTES bytes |
| 2030 | of string data. */ | 1978 | of string data. */ |
| 2031 | needed = SDATA_SIZE (nbytes); | 1979 | needed = SDATA_SIZE (nbytes); |
| 2032 | old_data = s->data ? SDATA_OF_STRING (s) : NULL; | ||
| 2033 | old_nbytes = GC_STRING_BYTES (s); | ||
| 2034 | 1980 | ||
| 2035 | MALLOC_BLOCK_INPUT; | 1981 | MALLOC_BLOCK_INPUT; |
| 2036 | 1982 | ||
| @@ -2051,7 +1997,7 @@ allocate_string_data (struct Lisp_String *s, | |||
| 2051 | mallopt (M_MMAP_MAX, 0); | 1997 | mallopt (M_MMAP_MAX, 0); |
| 2052 | #endif | 1998 | #endif |
| 2053 | 1999 | ||
| 2054 | b = (struct sblock *) lisp_malloc (size + GC_STRING_EXTRA, MEM_TYPE_NON_LISP); | 2000 | b = lisp_malloc (size + GC_STRING_EXTRA, MEM_TYPE_NON_LISP); |
| 2055 | 2001 | ||
| 2056 | #ifdef DOUG_LEA_MALLOC | 2002 | #ifdef DOUG_LEA_MALLOC |
| 2057 | /* Back to a reasonable maximum of mmap'ed areas. */ | 2003 | /* Back to a reasonable maximum of mmap'ed areas. */ |
| @@ -2069,7 +2015,7 @@ allocate_string_data (struct Lisp_String *s, | |||
| 2069 | < (needed + GC_STRING_EXTRA))) | 2015 | < (needed + GC_STRING_EXTRA))) |
| 2070 | { | 2016 | { |
| 2071 | /* Not enough room in the current sblock. */ | 2017 | /* Not enough room in the current sblock. */ |
| 2072 | b = (struct sblock *) lisp_malloc (SBLOCK_SIZE, MEM_TYPE_NON_LISP); | 2018 | b = lisp_malloc (SBLOCK_SIZE, MEM_TYPE_NON_LISP); |
| 2073 | b->next_free = &b->first_data; | 2019 | b->next_free = &b->first_data; |
| 2074 | b->first_data.string = NULL; | 2020 | b->first_data.string = NULL; |
| 2075 | b->next = NULL; | 2021 | b->next = NULL; |
| @@ -2100,16 +2046,6 @@ allocate_string_data (struct Lisp_String *s, | |||
| 2100 | memcpy ((char *) data + needed, string_overrun_cookie, | 2046 | memcpy ((char *) data + needed, string_overrun_cookie, |
| 2101 | GC_STRING_OVERRUN_COOKIE_SIZE); | 2047 | GC_STRING_OVERRUN_COOKIE_SIZE); |
| 2102 | #endif | 2048 | #endif |
| 2103 | |||
| 2104 | /* If S had already data assigned, mark that as free by setting its | ||
| 2105 | string back-pointer to null, and recording the size of the data | ||
| 2106 | in it. */ | ||
| 2107 | if (old_data) | ||
| 2108 | { | ||
| 2109 | SDATA_NBYTES (old_data) = old_nbytes; | ||
| 2110 | old_data->string = NULL; | ||
| 2111 | } | ||
| 2112 | |||
| 2113 | consing_since_gc += needed; | 2049 | consing_since_gc += needed; |
| 2114 | } | 2050 | } |
| 2115 | 2051 | ||
| @@ -2260,7 +2196,7 @@ compact_small_strings (void) | |||
| 2260 | for (b = oldest_sblock; b; b = b->next) | 2196 | for (b = oldest_sblock; b; b = b->next) |
| 2261 | { | 2197 | { |
| 2262 | end = b->next_free; | 2198 | end = b->next_free; |
| 2263 | xassert ((char *) end <= (char *) b + SBLOCK_SIZE); | 2199 | eassert ((char *) end <= (char *) b + SBLOCK_SIZE); |
| 2264 | 2200 | ||
| 2265 | for (from = &b->first_data; from < end; from = from_end) | 2201 | for (from = &b->first_data; from < end; from = from_end) |
| 2266 | { | 2202 | { |
| @@ -2311,7 +2247,7 @@ compact_small_strings (void) | |||
| 2311 | /* Copy, and update the string's `data' pointer. */ | 2247 | /* Copy, and update the string's `data' pointer. */ |
| 2312 | if (from != to) | 2248 | if (from != to) |
| 2313 | { | 2249 | { |
| 2314 | xassert (tb != b || to < from); | 2250 | eassert (tb != b || to < from); |
| 2315 | memmove (to, from, nbytes + GC_STRING_EXTRA); | 2251 | memmove (to, from, nbytes + GC_STRING_EXTRA); |
| 2316 | to->string->data = SDATA_DATA (to); | 2252 | to->string->data = SDATA_DATA (to); |
| 2317 | } | 2253 | } |
| @@ -2522,16 +2458,6 @@ make_specified_string (const char *contents, | |||
| 2522 | } | 2458 | } |
| 2523 | 2459 | ||
| 2524 | 2460 | ||
| 2525 | /* Make a string from the data at STR, treating it as multibyte if the | ||
| 2526 | data warrants. */ | ||
| 2527 | |||
| 2528 | Lisp_Object | ||
| 2529 | build_string (const char *str) | ||
| 2530 | { | ||
| 2531 | return make_string (str, strlen (str)); | ||
| 2532 | } | ||
| 2533 | |||
| 2534 | |||
| 2535 | /* Return an unibyte Lisp_String set up to hold LENGTH characters | 2461 | /* Return an unibyte Lisp_String set up to hold LENGTH characters |
| 2536 | occupying LENGTH bytes. */ | 2462 | occupying LENGTH bytes. */ |
| 2537 | 2463 | ||
| @@ -2563,12 +2489,27 @@ make_uninit_multibyte_string (EMACS_INT nchars, EMACS_INT nbytes) | |||
| 2563 | return empty_multibyte_string; | 2489 | return empty_multibyte_string; |
| 2564 | 2490 | ||
| 2565 | s = allocate_string (); | 2491 | s = allocate_string (); |
| 2492 | s->intervals = NULL_INTERVAL; | ||
| 2566 | allocate_string_data (s, nchars, nbytes); | 2493 | allocate_string_data (s, nchars, nbytes); |
| 2567 | XSETSTRING (string, s); | 2494 | XSETSTRING (string, s); |
| 2568 | string_chars_consed += nbytes; | 2495 | string_chars_consed += nbytes; |
| 2569 | return string; | 2496 | return string; |
| 2570 | } | 2497 | } |
| 2571 | 2498 | ||
| 2499 | /* Print arguments to BUF according to a FORMAT, then return | ||
| 2500 | a Lisp_String initialized with the data from BUF. */ | ||
| 2501 | |||
| 2502 | Lisp_Object | ||
| 2503 | make_formatted_string (char *buf, const char *format, ...) | ||
| 2504 | { | ||
| 2505 | va_list ap; | ||
| 2506 | int length; | ||
| 2507 | |||
| 2508 | va_start (ap, format); | ||
| 2509 | length = vsprintf (buf, format, ap); | ||
| 2510 | va_end (ap); | ||
| 2511 | return make_string (buf, length); | ||
| 2512 | } | ||
| 2572 | 2513 | ||
| 2573 | 2514 | ||
| 2574 | /*********************************************************************** | 2515 | /*********************************************************************** |
| @@ -2628,24 +2569,12 @@ static struct float_block *float_block; | |||
| 2628 | 2569 | ||
| 2629 | /* Index of first unused Lisp_Float in the current float_block. */ | 2570 | /* Index of first unused Lisp_Float in the current float_block. */ |
| 2630 | 2571 | ||
| 2631 | static int float_block_index; | 2572 | static int float_block_index = FLOAT_BLOCK_SIZE; |
| 2632 | 2573 | ||
| 2633 | /* Free-list of Lisp_Floats. */ | 2574 | /* Free-list of Lisp_Floats. */ |
| 2634 | 2575 | ||
| 2635 | static struct Lisp_Float *float_free_list; | 2576 | static struct Lisp_Float *float_free_list; |
| 2636 | 2577 | ||
| 2637 | |||
| 2638 | /* Initialize float allocation. */ | ||
| 2639 | |||
| 2640 | static void | ||
| 2641 | init_float (void) | ||
| 2642 | { | ||
| 2643 | float_block = NULL; | ||
| 2644 | float_block_index = FLOAT_BLOCK_SIZE; /* Force alloc of new float_block. */ | ||
| 2645 | float_free_list = 0; | ||
| 2646 | } | ||
| 2647 | |||
| 2648 | |||
| 2649 | /* Return a new float object with value FLOAT_VALUE. */ | 2578 | /* Return a new float object with value FLOAT_VALUE. */ |
| 2650 | 2579 | ||
| 2651 | Lisp_Object | 2580 | Lisp_Object |
| @@ -2668,10 +2597,8 @@ make_float (double float_value) | |||
| 2668 | { | 2597 | { |
| 2669 | if (float_block_index == FLOAT_BLOCK_SIZE) | 2598 | if (float_block_index == FLOAT_BLOCK_SIZE) |
| 2670 | { | 2599 | { |
| 2671 | register struct float_block *new; | 2600 | struct float_block *new |
| 2672 | 2601 | = lisp_align_malloc (sizeof *new, MEM_TYPE_FLOAT); | |
| 2673 | new = (struct float_block *) lisp_align_malloc (sizeof *new, | ||
| 2674 | MEM_TYPE_FLOAT); | ||
| 2675 | new->next = float_block; | 2602 | new->next = float_block; |
| 2676 | memset (new->gcmarkbits, 0, sizeof new->gcmarkbits); | 2603 | memset (new->gcmarkbits, 0, sizeof new->gcmarkbits); |
| 2677 | float_block = new; | 2604 | float_block = new; |
| @@ -2736,24 +2663,12 @@ static struct cons_block *cons_block; | |||
| 2736 | 2663 | ||
| 2737 | /* Index of first unused Lisp_Cons in the current block. */ | 2664 | /* Index of first unused Lisp_Cons in the current block. */ |
| 2738 | 2665 | ||
| 2739 | static int cons_block_index; | 2666 | static int cons_block_index = CONS_BLOCK_SIZE; |
| 2740 | 2667 | ||
| 2741 | /* Free-list of Lisp_Cons structures. */ | 2668 | /* Free-list of Lisp_Cons structures. */ |
| 2742 | 2669 | ||
| 2743 | static struct Lisp_Cons *cons_free_list; | 2670 | static struct Lisp_Cons *cons_free_list; |
| 2744 | 2671 | ||
| 2745 | |||
| 2746 | /* Initialize cons allocation. */ | ||
| 2747 | |||
| 2748 | static void | ||
| 2749 | init_cons (void) | ||
| 2750 | { | ||
| 2751 | cons_block = NULL; | ||
| 2752 | cons_block_index = CONS_BLOCK_SIZE; /* Force alloc of new cons_block. */ | ||
| 2753 | cons_free_list = 0; | ||
| 2754 | } | ||
| 2755 | |||
| 2756 | |||
| 2757 | /* Explicitly free a cons cell by putting it on the free-list. */ | 2672 | /* Explicitly free a cons cell by putting it on the free-list. */ |
| 2758 | 2673 | ||
| 2759 | void | 2674 | void |
| @@ -2787,9 +2702,8 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0, | |||
| 2787 | { | 2702 | { |
| 2788 | if (cons_block_index == CONS_BLOCK_SIZE) | 2703 | if (cons_block_index == CONS_BLOCK_SIZE) |
| 2789 | { | 2704 | { |
| 2790 | register struct cons_block *new; | 2705 | struct cons_block *new |
| 2791 | new = (struct cons_block *) lisp_align_malloc (sizeof *new, | 2706 | = lisp_align_malloc (sizeof *new, MEM_TYPE_CONS); |
| 2792 | MEM_TYPE_CONS); | ||
| 2793 | memset (new->gcmarkbits, 0, sizeof new->gcmarkbits); | 2707 | memset (new->gcmarkbits, 0, sizeof new->gcmarkbits); |
| 2794 | new->next = cons_block; | 2708 | new->next = cons_block; |
| 2795 | cons_block = new; | 2709 | cons_block = new; |
| @@ -2928,17 +2842,294 @@ DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0, | |||
| 2928 | Vector Allocation | 2842 | Vector Allocation |
| 2929 | ***********************************************************************/ | 2843 | ***********************************************************************/ |
| 2930 | 2844 | ||
| 2931 | /* Singly-linked list of all vectors. */ | 2845 | /* This value is balanced well enough to avoid too much internal overhead |
| 2846 | for the most common cases; it's not required to be a power of two, but | ||
| 2847 | it's expected to be a mult-of-ROUNDUP_SIZE (see below). */ | ||
| 2932 | 2848 | ||
| 2933 | static struct Lisp_Vector *all_vectors; | 2849 | #define VECTOR_BLOCK_SIZE 4096 |
| 2934 | 2850 | ||
| 2935 | /* Handy constants for vectorlike objects. */ | 2851 | /* Handy constants for vectorlike objects. */ |
| 2936 | enum | 2852 | enum |
| 2937 | { | 2853 | { |
| 2938 | header_size = offsetof (struct Lisp_Vector, contents), | 2854 | header_size = offsetof (struct Lisp_Vector, contents), |
| 2939 | word_size = sizeof (Lisp_Object) | 2855 | word_size = sizeof (Lisp_Object), |
| 2856 | roundup_size = COMMON_MULTIPLE (sizeof (Lisp_Object), | ||
| 2857 | USE_LSB_TAG ? 1 << GCTYPEBITS : 1) | ||
| 2940 | }; | 2858 | }; |
| 2941 | 2859 | ||
| 2860 | /* ROUNDUP_SIZE must be a power of 2. */ | ||
| 2861 | verify ((roundup_size & (roundup_size - 1)) == 0); | ||
| 2862 | |||
| 2863 | /* Verify assumptions described above. */ | ||
| 2864 | verify ((VECTOR_BLOCK_SIZE % roundup_size) == 0); | ||
| 2865 | verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS)); | ||
| 2866 | |||
| 2867 | /* Round up X to nearest mult-of-ROUNDUP_SIZE. */ | ||
| 2868 | |||
| 2869 | #define vroundup(x) (((x) + (roundup_size - 1)) & ~(roundup_size - 1)) | ||
| 2870 | |||
| 2871 | /* Rounding helps to maintain alignment constraints if USE_LSB_TAG. */ | ||
| 2872 | |||
| 2873 | #define VECTOR_BLOCK_BYTES (VECTOR_BLOCK_SIZE - vroundup (sizeof (void *))) | ||
| 2874 | |||
| 2875 | /* Size of the minimal vector allocated from block. */ | ||
| 2876 | |||
| 2877 | #define VBLOCK_BYTES_MIN vroundup (sizeof (struct Lisp_Vector)) | ||
| 2878 | |||
| 2879 | /* Size of the largest vector allocated from block. */ | ||
| 2880 | |||
| 2881 | #define VBLOCK_BYTES_MAX \ | ||
| 2882 | vroundup ((VECTOR_BLOCK_BYTES / 2) - sizeof (Lisp_Object)) | ||
| 2883 | |||
| 2884 | /* We maintain one free list for each possible block-allocated | ||
| 2885 | vector size, and this is the number of free lists we have. */ | ||
| 2886 | |||
| 2887 | #define VECTOR_MAX_FREE_LIST_INDEX \ | ||
| 2888 | ((VECTOR_BLOCK_BYTES - VBLOCK_BYTES_MIN) / roundup_size + 1) | ||
| 2889 | |||
| 2890 | /* Common shortcut to advance vector pointer over a block data. */ | ||
| 2891 | |||
| 2892 | #define ADVANCE(v, nbytes) ((struct Lisp_Vector *) ((char *) (v) + (nbytes))) | ||
| 2893 | |||
| 2894 | /* Common shortcut to calculate NBYTES-vector index in VECTOR_FREE_LISTS. */ | ||
| 2895 | |||
| 2896 | #define VINDEX(nbytes) (((nbytes) - VBLOCK_BYTES_MIN) / roundup_size) | ||
| 2897 | |||
| 2898 | /* Common shortcut to setup vector on a free list. */ | ||
| 2899 | |||
| 2900 | #define SETUP_ON_FREE_LIST(v, nbytes, index) \ | ||
| 2901 | do { \ | ||
| 2902 | XSETPVECTYPESIZE (v, PVEC_FREE, nbytes); \ | ||
| 2903 | eassert ((nbytes) % roundup_size == 0); \ | ||
| 2904 | (index) = VINDEX (nbytes); \ | ||
| 2905 | eassert ((index) < VECTOR_MAX_FREE_LIST_INDEX); \ | ||
| 2906 | (v)->header.next.vector = vector_free_lists[index]; \ | ||
| 2907 | vector_free_lists[index] = (v); \ | ||
| 2908 | } while (0) | ||
| 2909 | |||
| 2910 | struct vector_block | ||
| 2911 | { | ||
| 2912 | char data[VECTOR_BLOCK_BYTES]; | ||
| 2913 | struct vector_block *next; | ||
| 2914 | }; | ||
| 2915 | |||
| 2916 | /* Chain of vector blocks. */ | ||
| 2917 | |||
| 2918 | static struct vector_block *vector_blocks; | ||
| 2919 | |||
| 2920 | /* Vector free lists, where NTH item points to a chain of free | ||
| 2921 | vectors of the same NBYTES size, so NTH == VINDEX (NBYTES). */ | ||
| 2922 | |||
| 2923 | static struct Lisp_Vector *vector_free_lists[VECTOR_MAX_FREE_LIST_INDEX]; | ||
| 2924 | |||
| 2925 | /* Singly-linked list of large vectors. */ | ||
| 2926 | |||
| 2927 | static struct Lisp_Vector *large_vectors; | ||
| 2928 | |||
| 2929 | /* The only vector with 0 slots, allocated from pure space. */ | ||
| 2930 | |||
| 2931 | Lisp_Object zero_vector; | ||
| 2932 | |||
| 2933 | /* Get a new vector block. */ | ||
| 2934 | |||
| 2935 | static struct vector_block * | ||
| 2936 | allocate_vector_block (void) | ||
| 2937 | { | ||
| 2938 | struct vector_block *block = xmalloc (sizeof *block); | ||
| 2939 | |||
| 2940 | #if GC_MARK_STACK && !defined GC_MALLOC_CHECK | ||
| 2941 | mem_insert (block->data, block->data + VECTOR_BLOCK_BYTES, | ||
| 2942 | MEM_TYPE_VECTOR_BLOCK); | ||
| 2943 | #endif | ||
| 2944 | |||
| 2945 | block->next = vector_blocks; | ||
| 2946 | vector_blocks = block; | ||
| 2947 | return block; | ||
| 2948 | } | ||
| 2949 | |||
| 2950 | /* Called once to initialize vector allocation. */ | ||
| 2951 | |||
| 2952 | static void | ||
| 2953 | init_vectors (void) | ||
| 2954 | { | ||
| 2955 | zero_vector = make_pure_vector (0); | ||
| 2956 | } | ||
| 2957 | |||
| 2958 | /* Allocate vector from a vector block. */ | ||
| 2959 | |||
| 2960 | static struct Lisp_Vector * | ||
| 2961 | allocate_vector_from_block (size_t nbytes) | ||
| 2962 | { | ||
| 2963 | struct Lisp_Vector *vector, *rest; | ||
| 2964 | struct vector_block *block; | ||
| 2965 | size_t index, restbytes; | ||
| 2966 | |||
| 2967 | eassert (VBLOCK_BYTES_MIN <= nbytes && nbytes <= VBLOCK_BYTES_MAX); | ||
| 2968 | eassert (nbytes % roundup_size == 0); | ||
| 2969 | |||
| 2970 | /* First, try to allocate from a free list | ||
| 2971 | containing vectors of the requested size. */ | ||
| 2972 | index = VINDEX (nbytes); | ||
| 2973 | if (vector_free_lists[index]) | ||
| 2974 | { | ||
| 2975 | vector = vector_free_lists[index]; | ||
| 2976 | vector_free_lists[index] = vector->header.next.vector; | ||
| 2977 | vector->header.next.nbytes = nbytes; | ||
| 2978 | return vector; | ||
| 2979 | } | ||
| 2980 | |||
| 2981 | /* Next, check free lists containing larger vectors. Since | ||
| 2982 | we will split the result, we should have remaining space | ||
| 2983 | large enough to use for one-slot vector at least. */ | ||
| 2984 | for (index = VINDEX (nbytes + VBLOCK_BYTES_MIN); | ||
| 2985 | index < VECTOR_MAX_FREE_LIST_INDEX; index++) | ||
| 2986 | if (vector_free_lists[index]) | ||
| 2987 | { | ||
| 2988 | /* This vector is larger than requested. */ | ||
| 2989 | vector = vector_free_lists[index]; | ||
| 2990 | vector_free_lists[index] = vector->header.next.vector; | ||
| 2991 | vector->header.next.nbytes = nbytes; | ||
| 2992 | |||
| 2993 | /* Excess bytes are used for the smaller vector, | ||
| 2994 | which should be set on an appropriate free list. */ | ||
| 2995 | restbytes = index * roundup_size + VBLOCK_BYTES_MIN - nbytes; | ||
| 2996 | eassert (restbytes % roundup_size == 0); | ||
| 2997 | rest = ADVANCE (vector, nbytes); | ||
| 2998 | SETUP_ON_FREE_LIST (rest, restbytes, index); | ||
| 2999 | return vector; | ||
| 3000 | } | ||
| 3001 | |||
| 3002 | /* Finally, need a new vector block. */ | ||
| 3003 | block = allocate_vector_block (); | ||
| 3004 | |||
| 3005 | /* New vector will be at the beginning of this block. */ | ||
| 3006 | vector = (struct Lisp_Vector *) block->data; | ||
| 3007 | vector->header.next.nbytes = nbytes; | ||
| 3008 | |||
| 3009 | /* If the rest of space from this block is large enough | ||
| 3010 | for one-slot vector at least, set up it on a free list. */ | ||
| 3011 | restbytes = VECTOR_BLOCK_BYTES - nbytes; | ||
| 3012 | if (restbytes >= VBLOCK_BYTES_MIN) | ||
| 3013 | { | ||
| 3014 | eassert (restbytes % roundup_size == 0); | ||
| 3015 | rest = ADVANCE (vector, nbytes); | ||
| 3016 | SETUP_ON_FREE_LIST (rest, restbytes, index); | ||
| 3017 | } | ||
| 3018 | return vector; | ||
| 3019 | } | ||
| 3020 | |||
| 3021 | /* Return how many Lisp_Objects can be stored in V. */ | ||
| 3022 | |||
| 3023 | #define VECTOR_SIZE(v) ((v)->header.size & PSEUDOVECTOR_FLAG ? \ | ||
| 3024 | (PSEUDOVECTOR_SIZE_MASK & (v)->header.size) : \ | ||
| 3025 | (v)->header.size) | ||
| 3026 | |||
| 3027 | /* Nonzero if VECTOR pointer is valid pointer inside BLOCK. */ | ||
| 3028 | |||
| 3029 | #define VECTOR_IN_BLOCK(vector, block) \ | ||
| 3030 | ((char *) (vector) <= (block)->data \ | ||
| 3031 | + VECTOR_BLOCK_BYTES - VBLOCK_BYTES_MIN) | ||
| 3032 | |||
| 3033 | /* Number of bytes used by vector-block-allocated object. This is the only | ||
| 3034 | place where we actually use the `nbytes' field of the vector-header. | ||
| 3035 | I.e. we could get rid of the `nbytes' field by computing it based on the | ||
| 3036 | vector-type. */ | ||
| 3037 | |||
| 3038 | #define PSEUDOVECTOR_NBYTES(vector) \ | ||
| 3039 | (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE) \ | ||
| 3040 | ? vector->header.size & PSEUDOVECTOR_SIZE_MASK \ | ||
| 3041 | : vector->header.next.nbytes) | ||
| 3042 | |||
| 3043 | /* Reclaim space used by unmarked vectors. */ | ||
| 3044 | |||
| 3045 | static void | ||
| 3046 | sweep_vectors (void) | ||
| 3047 | { | ||
| 3048 | struct vector_block *block = vector_blocks, **bprev = &vector_blocks; | ||
| 3049 | struct Lisp_Vector *vector, *next, **vprev = &large_vectors; | ||
| 3050 | |||
| 3051 | total_vector_size = 0; | ||
| 3052 | memset (vector_free_lists, 0, sizeof (vector_free_lists)); | ||
| 3053 | |||
| 3054 | /* Looking through vector blocks. */ | ||
| 3055 | |||
| 3056 | for (block = vector_blocks; block; block = *bprev) | ||
| 3057 | { | ||
| 3058 | int free_this_block = 0; | ||
| 3059 | |||
| 3060 | for (vector = (struct Lisp_Vector *) block->data; | ||
| 3061 | VECTOR_IN_BLOCK (vector, block); vector = next) | ||
| 3062 | { | ||
| 3063 | if (VECTOR_MARKED_P (vector)) | ||
| 3064 | { | ||
| 3065 | VECTOR_UNMARK (vector); | ||
| 3066 | total_vector_size += VECTOR_SIZE (vector); | ||
| 3067 | next = ADVANCE (vector, vector->header.next.nbytes); | ||
| 3068 | } | ||
| 3069 | else | ||
| 3070 | { | ||
| 3071 | ptrdiff_t nbytes = PSEUDOVECTOR_NBYTES (vector); | ||
| 3072 | ptrdiff_t total_bytes = nbytes; | ||
| 3073 | |||
| 3074 | next = ADVANCE (vector, nbytes); | ||
| 3075 | |||
| 3076 | /* While NEXT is not marked, try to coalesce with VECTOR, | ||
| 3077 | thus making VECTOR of the largest possible size. */ | ||
| 3078 | |||
| 3079 | while (VECTOR_IN_BLOCK (next, block)) | ||
| 3080 | { | ||
| 3081 | if (VECTOR_MARKED_P (next)) | ||
| 3082 | break; | ||
| 3083 | nbytes = PSEUDOVECTOR_NBYTES (next); | ||
| 3084 | total_bytes += nbytes; | ||
| 3085 | next = ADVANCE (next, nbytes); | ||
| 3086 | } | ||
| 3087 | |||
| 3088 | eassert (total_bytes % roundup_size == 0); | ||
| 3089 | |||
| 3090 | if (vector == (struct Lisp_Vector *) block->data | ||
| 3091 | && !VECTOR_IN_BLOCK (next, block)) | ||
| 3092 | /* This block should be freed because all of it's | ||
| 3093 | space was coalesced into the only free vector. */ | ||
| 3094 | free_this_block = 1; | ||
| 3095 | else | ||
| 3096 | { | ||
| 3097 | int tmp; | ||
| 3098 | SETUP_ON_FREE_LIST (vector, total_bytes, tmp); | ||
| 3099 | } | ||
| 3100 | } | ||
| 3101 | } | ||
| 3102 | |||
| 3103 | if (free_this_block) | ||
| 3104 | { | ||
| 3105 | *bprev = block->next; | ||
| 3106 | #if GC_MARK_STACK && !defined GC_MALLOC_CHECK | ||
| 3107 | mem_delete (mem_find (block->data)); | ||
| 3108 | #endif | ||
| 3109 | xfree (block); | ||
| 3110 | } | ||
| 3111 | else | ||
| 3112 | bprev = &block->next; | ||
| 3113 | } | ||
| 3114 | |||
| 3115 | /* Sweep large vectors. */ | ||
| 3116 | |||
| 3117 | for (vector = large_vectors; vector; vector = *vprev) | ||
| 3118 | { | ||
| 3119 | if (VECTOR_MARKED_P (vector)) | ||
| 3120 | { | ||
| 3121 | VECTOR_UNMARK (vector); | ||
| 3122 | total_vector_size += VECTOR_SIZE (vector); | ||
| 3123 | vprev = &vector->header.next.vector; | ||
| 3124 | } | ||
| 3125 | else | ||
| 3126 | { | ||
| 3127 | *vprev = vector->header.next.vector; | ||
| 3128 | lisp_free (vector); | ||
| 3129 | } | ||
| 3130 | } | ||
| 3131 | } | ||
| 3132 | |||
| 2942 | /* Value is a pointer to a newly allocated Lisp_Vector structure | 3133 | /* Value is a pointer to a newly allocated Lisp_Vector structure |
| 2943 | with room for LEN Lisp_Objects. */ | 3134 | with room for LEN Lisp_Objects. */ |
| 2944 | 3135 | ||
| @@ -2946,33 +3137,42 @@ static struct Lisp_Vector * | |||
| 2946 | allocate_vectorlike (ptrdiff_t len) | 3137 | allocate_vectorlike (ptrdiff_t len) |
| 2947 | { | 3138 | { |
| 2948 | struct Lisp_Vector *p; | 3139 | struct Lisp_Vector *p; |
| 2949 | size_t nbytes; | ||
| 2950 | 3140 | ||
| 2951 | MALLOC_BLOCK_INPUT; | 3141 | MALLOC_BLOCK_INPUT; |
| 2952 | 3142 | ||
| 2953 | #ifdef DOUG_LEA_MALLOC | ||
| 2954 | /* Prevent mmap'ing the chunk. Lisp data may not be mmap'ed | ||
| 2955 | because mapped region contents are not preserved in | ||
| 2956 | a dumped Emacs. */ | ||
| 2957 | mallopt (M_MMAP_MAX, 0); | ||
| 2958 | #endif | ||
| 2959 | |||
| 2960 | /* This gets triggered by code which I haven't bothered to fix. --Stef */ | 3143 | /* This gets triggered by code which I haven't bothered to fix. --Stef */ |
| 2961 | /* eassert (!handling_signal); */ | 3144 | /* eassert (!handling_signal); */ |
| 2962 | 3145 | ||
| 2963 | nbytes = header_size + len * word_size; | 3146 | if (len == 0) |
| 2964 | p = (struct Lisp_Vector *) lisp_malloc (nbytes, MEM_TYPE_VECTORLIKE); | 3147 | p = XVECTOR (zero_vector); |
| 3148 | else | ||
| 3149 | { | ||
| 3150 | size_t nbytes = header_size + len * word_size; | ||
| 2965 | 3151 | ||
| 2966 | #ifdef DOUG_LEA_MALLOC | 3152 | #ifdef DOUG_LEA_MALLOC |
| 2967 | /* Back to a reasonable maximum of mmap'ed areas. */ | 3153 | /* Prevent mmap'ing the chunk. Lisp data may not be mmap'ed |
| 2968 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); | 3154 | because mapped region contents are not preserved in |
| 3155 | a dumped Emacs. */ | ||
| 3156 | mallopt (M_MMAP_MAX, 0); | ||
| 2969 | #endif | 3157 | #endif |
| 2970 | 3158 | ||
| 2971 | consing_since_gc += nbytes; | 3159 | if (nbytes <= VBLOCK_BYTES_MAX) |
| 2972 | vector_cells_consed += len; | 3160 | p = allocate_vector_from_block (vroundup (nbytes)); |
| 3161 | else | ||
| 3162 | { | ||
| 3163 | p = lisp_malloc (nbytes, MEM_TYPE_VECTORLIKE); | ||
| 3164 | p->header.next.vector = large_vectors; | ||
| 3165 | large_vectors = p; | ||
| 3166 | } | ||
| 3167 | |||
| 3168 | #ifdef DOUG_LEA_MALLOC | ||
| 3169 | /* Back to a reasonable maximum of mmap'ed areas. */ | ||
| 3170 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); | ||
| 3171 | #endif | ||
| 2973 | 3172 | ||
| 2974 | p->header.next.vector = all_vectors; | 3173 | consing_since_gc += nbytes; |
| 2975 | all_vectors = p; | 3174 | vector_cells_consed += len; |
| 3175 | } | ||
| 2976 | 3176 | ||
| 2977 | MALLOC_UNBLOCK_INPUT; | 3177 | MALLOC_UNBLOCK_INPUT; |
| 2978 | 3178 | ||
| @@ -3012,50 +3212,70 @@ allocate_pseudovector (int memlen, int lisplen, int tag) | |||
| 3012 | return v; | 3212 | return v; |
| 3013 | } | 3213 | } |
| 3014 | 3214 | ||
| 3215 | struct buffer * | ||
| 3216 | allocate_buffer (void) | ||
| 3217 | { | ||
| 3218 | struct buffer *b = lisp_malloc (sizeof *b, MEM_TYPE_BUFFER); | ||
| 3219 | |||
| 3220 | XSETPVECTYPESIZE (b, PVEC_BUFFER, (offsetof (struct buffer, own_text) | ||
| 3221 | - header_size) / word_size); | ||
| 3222 | /* Note that the fields of B are not initialized. */ | ||
| 3223 | return b; | ||
| 3224 | } | ||
| 3225 | |||
| 3015 | struct Lisp_Hash_Table * | 3226 | struct Lisp_Hash_Table * |
| 3016 | allocate_hash_table (void) | 3227 | allocate_hash_table (void) |
| 3017 | { | 3228 | { |
| 3018 | return ALLOCATE_PSEUDOVECTOR (struct Lisp_Hash_Table, count, PVEC_HASH_TABLE); | 3229 | return ALLOCATE_PSEUDOVECTOR (struct Lisp_Hash_Table, count, PVEC_HASH_TABLE); |
| 3019 | } | 3230 | } |
| 3020 | 3231 | ||
| 3021 | |||
| 3022 | struct window * | 3232 | struct window * |
| 3023 | allocate_window (void) | 3233 | allocate_window (void) |
| 3024 | { | 3234 | { |
| 3025 | return ALLOCATE_PSEUDOVECTOR (struct window, current_matrix, PVEC_WINDOW); | 3235 | struct window *w; |
| 3026 | } | ||
| 3027 | 3236 | ||
| 3237 | w = ALLOCATE_PSEUDOVECTOR (struct window, current_matrix, PVEC_WINDOW); | ||
| 3238 | /* Users assumes that non-Lisp data is zeroed. */ | ||
| 3239 | memset (&w->current_matrix, 0, | ||
| 3240 | sizeof (*w) - offsetof (struct window, current_matrix)); | ||
| 3241 | return w; | ||
| 3242 | } | ||
| 3028 | 3243 | ||
| 3029 | struct terminal * | 3244 | struct terminal * |
| 3030 | allocate_terminal (void) | 3245 | allocate_terminal (void) |
| 3031 | { | 3246 | { |
| 3032 | struct terminal *t = ALLOCATE_PSEUDOVECTOR (struct terminal, | 3247 | struct terminal *t; |
| 3033 | next_terminal, PVEC_TERMINAL); | ||
| 3034 | /* Zero out the non-GC'd fields. FIXME: This should be made unnecessary. */ | ||
| 3035 | memset (&t->next_terminal, 0, | ||
| 3036 | (char*) (t + 1) - (char*) &t->next_terminal); | ||
| 3037 | 3248 | ||
| 3249 | t = ALLOCATE_PSEUDOVECTOR (struct terminal, next_terminal, PVEC_TERMINAL); | ||
| 3250 | /* Users assumes that non-Lisp data is zeroed. */ | ||
| 3251 | memset (&t->next_terminal, 0, | ||
| 3252 | sizeof (*t) - offsetof (struct terminal, next_terminal)); | ||
| 3038 | return t; | 3253 | return t; |
| 3039 | } | 3254 | } |
| 3040 | 3255 | ||
| 3041 | struct frame * | 3256 | struct frame * |
| 3042 | allocate_frame (void) | 3257 | allocate_frame (void) |
| 3043 | { | 3258 | { |
| 3044 | struct frame *f = ALLOCATE_PSEUDOVECTOR (struct frame, | 3259 | struct frame *f; |
| 3045 | face_cache, PVEC_FRAME); | 3260 | |
| 3046 | /* Zero out the non-GC'd fields. FIXME: This should be made unnecessary. */ | 3261 | f = ALLOCATE_PSEUDOVECTOR (struct frame, face_cache, PVEC_FRAME); |
| 3262 | /* Users assumes that non-Lisp data is zeroed. */ | ||
| 3047 | memset (&f->face_cache, 0, | 3263 | memset (&f->face_cache, 0, |
| 3048 | (char *) (f + 1) - (char *) &f->face_cache); | 3264 | sizeof (*f) - offsetof (struct frame, face_cache)); |
| 3049 | return f; | 3265 | return f; |
| 3050 | } | 3266 | } |
| 3051 | 3267 | ||
| 3052 | |||
| 3053 | struct Lisp_Process * | 3268 | struct Lisp_Process * |
| 3054 | allocate_process (void) | 3269 | allocate_process (void) |
| 3055 | { | 3270 | { |
| 3056 | return ALLOCATE_PSEUDOVECTOR (struct Lisp_Process, pid, PVEC_PROCESS); | 3271 | struct Lisp_Process *p; |
| 3057 | } | ||
| 3058 | 3272 | ||
| 3273 | p = ALLOCATE_PSEUDOVECTOR (struct Lisp_Process, pid, PVEC_PROCESS); | ||
| 3274 | /* Users assumes that non-Lisp data is zeroed. */ | ||
| 3275 | memset (&p->pid, 0, | ||
| 3276 | sizeof (*p) - offsetof (struct Lisp_Process, pid)); | ||
| 3277 | return p; | ||
| 3278 | } | ||
| 3059 | 3279 | ||
| 3060 | DEFUN ("make-vector", Fmake_vector, Smake_vector, 2, 2, 0, | 3280 | DEFUN ("make-vector", Fmake_vector, Smake_vector, 2, 2, 0, |
| 3061 | doc: /* Return a newly created vector of length LENGTH, with each element being INIT. | 3281 | doc: /* Return a newly created vector of length LENGTH, with each element being INIT. |
| @@ -3097,6 +3317,19 @@ usage: (vector &rest OBJECTS) */) | |||
| 3097 | return val; | 3317 | return val; |
| 3098 | } | 3318 | } |
| 3099 | 3319 | ||
| 3320 | void | ||
| 3321 | make_byte_code (struct Lisp_Vector *v) | ||
| 3322 | { | ||
| 3323 | if (v->header.size > 1 && STRINGP (v->contents[1]) | ||
| 3324 | && STRING_MULTIBYTE (v->contents[1])) | ||
| 3325 | /* BYTECODE-STRING must have been produced by Emacs 20.2 or the | ||
| 3326 | earlier because they produced a raw 8-bit string for byte-code | ||
| 3327 | and now such a byte-code string is loaded as multibyte while | ||
| 3328 | raw 8-bit characters converted to multibyte form. Thus, now we | ||
| 3329 | must convert them back to the original unibyte form. */ | ||
| 3330 | v->contents[1] = Fstring_as_unibyte (v->contents[1]); | ||
| 3331 | XSETPVECTYPE (v, PVEC_COMPILED); | ||
| 3332 | } | ||
| 3100 | 3333 | ||
| 3101 | DEFUN ("make-byte-code", Fmake_byte_code, Smake_byte_code, 4, MANY, 0, | 3334 | DEFUN ("make-byte-code", Fmake_byte_code, Smake_byte_code, 4, MANY, 0, |
| 3102 | doc: /* Create a byte-code object with specified arguments as elements. | 3335 | doc: /* Create a byte-code object with specified arguments as elements. |
| @@ -3120,28 +3353,21 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT | |||
| 3120 | ptrdiff_t i; | 3353 | ptrdiff_t i; |
| 3121 | register struct Lisp_Vector *p; | 3354 | register struct Lisp_Vector *p; |
| 3122 | 3355 | ||
| 3123 | XSETFASTINT (len, nargs); | 3356 | /* We used to purecopy everything here, if purify-flga was set. This worked |
| 3124 | if (!NILP (Vpurify_flag)) | 3357 | OK for Emacs-23, but with Emacs-24's lexical binding code, it can be |
| 3125 | val = make_pure_vector (nargs); | 3358 | dangerous, since make-byte-code is used during execution to build |
| 3126 | else | 3359 | closures, so any closure built during the preload phase would end up |
| 3127 | val = Fmake_vector (len, Qnil); | 3360 | copied into pure space, including its free variables, which is sometimes |
| 3361 | just wasteful and other times plainly wrong (e.g. those free vars may want | ||
| 3362 | to be setcar'd). */ | ||
| 3128 | 3363 | ||
| 3129 | if (nargs > 1 && STRINGP (args[1]) && STRING_MULTIBYTE (args[1])) | 3364 | XSETFASTINT (len, nargs); |
| 3130 | /* BYTECODE-STRING must have been produced by Emacs 20.2 or the | 3365 | val = Fmake_vector (len, Qnil); |
| 3131 | earlier because they produced a raw 8-bit string for byte-code | ||
| 3132 | and now such a byte-code string is loaded as multibyte while | ||
| 3133 | raw 8-bit characters converted to multibyte form. Thus, now we | ||
| 3134 | must convert them back to the original unibyte form. */ | ||
| 3135 | args[1] = Fstring_as_unibyte (args[1]); | ||
| 3136 | 3366 | ||
| 3137 | p = XVECTOR (val); | 3367 | p = XVECTOR (val); |
| 3138 | for (i = 0; i < nargs; i++) | 3368 | for (i = 0; i < nargs; i++) |
| 3139 | { | 3369 | p->contents[i] = args[i]; |
| 3140 | if (!NILP (Vpurify_flag)) | 3370 | make_byte_code (p); |
| 3141 | args[i] = Fpurecopy (args[i]); | ||
| 3142 | p->contents[i] = args[i]; | ||
| 3143 | } | ||
| 3144 | XSETPVECTYPE (p, PVEC_COMPILED); | ||
| 3145 | XSETCOMPILED (val, p); | 3371 | XSETCOMPILED (val, p); |
| 3146 | return val; | 3372 | return val; |
| 3147 | } | 3373 | } |
| @@ -3158,7 +3384,7 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT | |||
| 3158 | union aligned_Lisp_Symbol | 3384 | union aligned_Lisp_Symbol |
| 3159 | { | 3385 | { |
| 3160 | struct Lisp_Symbol s; | 3386 | struct Lisp_Symbol s; |
| 3161 | #ifdef USE_LSB_TAG | 3387 | #if USE_LSB_TAG |
| 3162 | unsigned char c[(sizeof (struct Lisp_Symbol) + (1 << GCTYPEBITS) - 1) | 3388 | unsigned char c[(sizeof (struct Lisp_Symbol) + (1 << GCTYPEBITS) - 1) |
| 3163 | & -(1 << GCTYPEBITS)]; | 3389 | & -(1 << GCTYPEBITS)]; |
| 3164 | #endif | 3390 | #endif |
| @@ -3166,7 +3392,7 @@ union aligned_Lisp_Symbol | |||
| 3166 | 3392 | ||
| 3167 | /* Each symbol_block is just under 1020 bytes long, since malloc | 3393 | /* Each symbol_block is just under 1020 bytes long, since malloc |
| 3168 | really allocates in units of powers of two and uses 4 bytes for its | 3394 | really allocates in units of powers of two and uses 4 bytes for its |
| 3169 | own overhead. */ | 3395 | own overhead. */ |
| 3170 | 3396 | ||
| 3171 | #define SYMBOL_BLOCK_SIZE \ | 3397 | #define SYMBOL_BLOCK_SIZE \ |
| 3172 | ((1020 - sizeof (struct symbol_block *)) / sizeof (union aligned_Lisp_Symbol)) | 3398 | ((1020 - sizeof (struct symbol_block *)) / sizeof (union aligned_Lisp_Symbol)) |
| @@ -3182,24 +3408,12 @@ struct symbol_block | |||
| 3182 | structure in it. */ | 3408 | structure in it. */ |
| 3183 | 3409 | ||
| 3184 | static struct symbol_block *symbol_block; | 3410 | static struct symbol_block *symbol_block; |
| 3185 | static int symbol_block_index; | 3411 | static int symbol_block_index = SYMBOL_BLOCK_SIZE; |
| 3186 | 3412 | ||
| 3187 | /* List of free symbols. */ | 3413 | /* List of free symbols. */ |
| 3188 | 3414 | ||
| 3189 | static struct Lisp_Symbol *symbol_free_list; | 3415 | static struct Lisp_Symbol *symbol_free_list; |
| 3190 | 3416 | ||
| 3191 | |||
| 3192 | /* Initialize symbol allocation. */ | ||
| 3193 | |||
| 3194 | static void | ||
| 3195 | init_symbol (void) | ||
| 3196 | { | ||
| 3197 | symbol_block = NULL; | ||
| 3198 | symbol_block_index = SYMBOL_BLOCK_SIZE; | ||
| 3199 | symbol_free_list = 0; | ||
| 3200 | } | ||
| 3201 | |||
| 3202 | |||
| 3203 | DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0, | 3417 | DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0, |
| 3204 | doc: /* Return a newly allocated uninterned symbol whose name is NAME. | 3418 | doc: /* Return a newly allocated uninterned symbol whose name is NAME. |
| 3205 | Its value and function definition are void, and its property list is nil. */) | 3419 | Its value and function definition are void, and its property list is nil. */) |
| @@ -3223,9 +3437,8 @@ Its value and function definition are void, and its property list is nil. */) | |||
| 3223 | { | 3437 | { |
| 3224 | if (symbol_block_index == SYMBOL_BLOCK_SIZE) | 3438 | if (symbol_block_index == SYMBOL_BLOCK_SIZE) |
| 3225 | { | 3439 | { |
| 3226 | struct symbol_block *new; | 3440 | struct symbol_block *new |
| 3227 | new = (struct symbol_block *) lisp_malloc (sizeof *new, | 3441 | = lisp_malloc (sizeof *new, MEM_TYPE_SYMBOL); |
| 3228 | MEM_TYPE_SYMBOL); | ||
| 3229 | new->next = symbol_block; | 3442 | new->next = symbol_block; |
| 3230 | symbol_block = new; | 3443 | symbol_block = new; |
| 3231 | symbol_block_index = 0; | 3444 | symbol_block_index = 0; |
| @@ -3264,7 +3477,7 @@ Its value and function definition are void, and its property list is nil. */) | |||
| 3264 | union aligned_Lisp_Misc | 3477 | union aligned_Lisp_Misc |
| 3265 | { | 3478 | { |
| 3266 | union Lisp_Misc m; | 3479 | union Lisp_Misc m; |
| 3267 | #ifdef USE_LSB_TAG | 3480 | #if USE_LSB_TAG |
| 3268 | unsigned char c[(sizeof (union Lisp_Misc) + (1 << GCTYPEBITS) - 1) | 3481 | unsigned char c[(sizeof (union Lisp_Misc) + (1 << GCTYPEBITS) - 1) |
| 3269 | & -(1 << GCTYPEBITS)]; | 3482 | & -(1 << GCTYPEBITS)]; |
| 3270 | #endif | 3483 | #endif |
| @@ -3284,18 +3497,10 @@ struct marker_block | |||
| 3284 | }; | 3497 | }; |
| 3285 | 3498 | ||
| 3286 | static struct marker_block *marker_block; | 3499 | static struct marker_block *marker_block; |
| 3287 | static int marker_block_index; | 3500 | static int marker_block_index = MARKER_BLOCK_SIZE; |
| 3288 | 3501 | ||
| 3289 | static union Lisp_Misc *marker_free_list; | 3502 | static union Lisp_Misc *marker_free_list; |
| 3290 | 3503 | ||
| 3291 | static void | ||
| 3292 | init_marker (void) | ||
| 3293 | { | ||
| 3294 | marker_block = NULL; | ||
| 3295 | marker_block_index = MARKER_BLOCK_SIZE; | ||
| 3296 | marker_free_list = 0; | ||
| 3297 | } | ||
| 3298 | |||
| 3299 | /* Return a newly allocated Lisp_Misc object, with no substructure. */ | 3504 | /* Return a newly allocated Lisp_Misc object, with no substructure. */ |
| 3300 | 3505 | ||
| 3301 | Lisp_Object | 3506 | Lisp_Object |
| @@ -3316,9 +3521,7 @@ allocate_misc (void) | |||
| 3316 | { | 3521 | { |
| 3317 | if (marker_block_index == MARKER_BLOCK_SIZE) | 3522 | if (marker_block_index == MARKER_BLOCK_SIZE) |
| 3318 | { | 3523 | { |
| 3319 | struct marker_block *new; | 3524 | struct marker_block *new = lisp_malloc (sizeof *new, MEM_TYPE_MISC); |
| 3320 | new = (struct marker_block *) lisp_malloc (sizeof *new, | ||
| 3321 | MEM_TYPE_MISC); | ||
| 3322 | new->next = marker_block; | 3525 | new->next = marker_block; |
| 3323 | marker_block = new; | 3526 | marker_block = new; |
| 3324 | marker_block_index = 0; | 3527 | marker_block_index = 0; |
| @@ -3386,6 +3589,33 @@ DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0, | |||
| 3386 | return val; | 3589 | return val; |
| 3387 | } | 3590 | } |
| 3388 | 3591 | ||
| 3592 | /* Return a newly allocated marker which points into BUF | ||
| 3593 | at character position CHARPOS and byte position BYTEPOS. */ | ||
| 3594 | |||
| 3595 | Lisp_Object | ||
| 3596 | build_marker (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t bytepos) | ||
| 3597 | { | ||
| 3598 | Lisp_Object obj; | ||
| 3599 | struct Lisp_Marker *m; | ||
| 3600 | |||
| 3601 | /* No dead buffers here. */ | ||
| 3602 | eassert (!NILP (BVAR (buf, name))); | ||
| 3603 | |||
| 3604 | /* Every character is at least one byte. */ | ||
| 3605 | eassert (charpos <= bytepos); | ||
| 3606 | |||
| 3607 | obj = allocate_misc (); | ||
| 3608 | XMISCTYPE (obj) = Lisp_Misc_Marker; | ||
| 3609 | m = XMARKER (obj); | ||
| 3610 | m->buffer = buf; | ||
| 3611 | m->charpos = charpos; | ||
| 3612 | m->bytepos = bytepos; | ||
| 3613 | m->insertion_type = 0; | ||
| 3614 | m->next = BUF_MARKERS (buf); | ||
| 3615 | BUF_MARKERS (buf) = m; | ||
| 3616 | return obj; | ||
| 3617 | } | ||
| 3618 | |||
| 3389 | /* Put MARKER back on the free list after using it temporarily. */ | 3619 | /* Put MARKER back on the free list after using it temporarily. */ |
| 3390 | 3620 | ||
| 3391 | void | 3621 | void |
| @@ -3511,25 +3741,25 @@ refill_memory_reserve (void) | |||
| 3511 | { | 3741 | { |
| 3512 | #ifndef SYSTEM_MALLOC | 3742 | #ifndef SYSTEM_MALLOC |
| 3513 | if (spare_memory[0] == 0) | 3743 | if (spare_memory[0] == 0) |
| 3514 | spare_memory[0] = (char *) malloc (SPARE_MEMORY); | 3744 | spare_memory[0] = malloc (SPARE_MEMORY); |
| 3515 | if (spare_memory[1] == 0) | 3745 | if (spare_memory[1] == 0) |
| 3516 | spare_memory[1] = (char *) lisp_align_malloc (sizeof (struct cons_block), | 3746 | spare_memory[1] = lisp_align_malloc (sizeof (struct cons_block), |
| 3517 | MEM_TYPE_CONS); | 3747 | MEM_TYPE_CONS); |
| 3518 | if (spare_memory[2] == 0) | 3748 | if (spare_memory[2] == 0) |
| 3519 | spare_memory[2] = (char *) lisp_align_malloc (sizeof (struct cons_block), | 3749 | spare_memory[2] = lisp_align_malloc (sizeof (struct cons_block), |
| 3520 | MEM_TYPE_CONS); | 3750 | MEM_TYPE_CONS); |
| 3521 | if (spare_memory[3] == 0) | 3751 | if (spare_memory[3] == 0) |
| 3522 | spare_memory[3] = (char *) lisp_align_malloc (sizeof (struct cons_block), | 3752 | spare_memory[3] = lisp_align_malloc (sizeof (struct cons_block), |
| 3523 | MEM_TYPE_CONS); | 3753 | MEM_TYPE_CONS); |
| 3524 | if (spare_memory[4] == 0) | 3754 | if (spare_memory[4] == 0) |
| 3525 | spare_memory[4] = (char *) lisp_align_malloc (sizeof (struct cons_block), | 3755 | spare_memory[4] = lisp_align_malloc (sizeof (struct cons_block), |
| 3526 | MEM_TYPE_CONS); | 3756 | MEM_TYPE_CONS); |
| 3527 | if (spare_memory[5] == 0) | 3757 | if (spare_memory[5] == 0) |
| 3528 | spare_memory[5] = (char *) lisp_malloc (sizeof (struct string_block), | 3758 | spare_memory[5] = lisp_malloc (sizeof (struct string_block), |
| 3529 | MEM_TYPE_STRING); | 3759 | MEM_TYPE_STRING); |
| 3530 | if (spare_memory[6] == 0) | 3760 | if (spare_memory[6] == 0) |
| 3531 | spare_memory[6] = (char *) lisp_malloc (sizeof (struct string_block), | 3761 | spare_memory[6] = lisp_malloc (sizeof (struct string_block), |
| 3532 | MEM_TYPE_STRING); | 3762 | MEM_TYPE_STRING); |
| 3533 | if (spare_memory[0] && spare_memory[1] && spare_memory[5]) | 3763 | if (spare_memory[0] && spare_memory[1] && spare_memory[5]) |
| 3534 | Vmemory_full = Qnil; | 3764 | Vmemory_full = Qnil; |
| 3535 | #endif | 3765 | #endif |
| @@ -3629,11 +3859,11 @@ mem_insert (void *start, void *end, enum mem_type type) | |||
| 3629 | 3859 | ||
| 3630 | /* Create a new node. */ | 3860 | /* Create a new node. */ |
| 3631 | #ifdef GC_MALLOC_CHECK | 3861 | #ifdef GC_MALLOC_CHECK |
| 3632 | x = (struct mem_node *) _malloc_internal (sizeof *x); | 3862 | x = _malloc_internal (sizeof *x); |
| 3633 | if (x == NULL) | 3863 | if (x == NULL) |
| 3634 | abort (); | 3864 | abort (); |
| 3635 | #else | 3865 | #else |
| 3636 | x = (struct mem_node *) xmalloc (sizeof *x); | 3866 | x = xmalloc (sizeof *x); |
| 3637 | #endif | 3867 | #endif |
| 3638 | x->start = start; | 3868 | x->start = start; |
| 3639 | x->end = end; | 3869 | x->end = end; |
| @@ -4072,7 +4302,33 @@ live_misc_p (struct mem_node *m, void *p) | |||
| 4072 | static inline int | 4302 | static inline int |
| 4073 | live_vector_p (struct mem_node *m, void *p) | 4303 | live_vector_p (struct mem_node *m, void *p) |
| 4074 | { | 4304 | { |
| 4075 | return (p == m->start && m->type == MEM_TYPE_VECTORLIKE); | 4305 | if (m->type == MEM_TYPE_VECTOR_BLOCK) |
| 4306 | { | ||
| 4307 | /* This memory node corresponds to a vector block. */ | ||
| 4308 | struct vector_block *block = (struct vector_block *) m->start; | ||
| 4309 | struct Lisp_Vector *vector = (struct Lisp_Vector *) block->data; | ||
| 4310 | |||
| 4311 | /* P is in the block's allocation range. Scan the block | ||
| 4312 | up to P and see whether P points to the start of some | ||
| 4313 | vector which is not on a free list. FIXME: check whether | ||
| 4314 | some allocation patterns (probably a lot of short vectors) | ||
| 4315 | may cause a substantial overhead of this loop. */ | ||
| 4316 | while (VECTOR_IN_BLOCK (vector, block) | ||
| 4317 | && vector <= (struct Lisp_Vector *) p) | ||
| 4318 | { | ||
| 4319 | if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE)) | ||
| 4320 | vector = ADVANCE (vector, (vector->header.size | ||
| 4321 | & PSEUDOVECTOR_SIZE_MASK)); | ||
| 4322 | else if (vector == p) | ||
| 4323 | return 1; | ||
| 4324 | else | ||
| 4325 | vector = ADVANCE (vector, vector->header.next.nbytes); | ||
| 4326 | } | ||
| 4327 | } | ||
| 4328 | else if (m->type == MEM_TYPE_VECTORLIKE && p == m->start) | ||
| 4329 | /* This memory node corresponds to a large vector. */ | ||
| 4330 | return 1; | ||
| 4331 | return 0; | ||
| 4076 | } | 4332 | } |
| 4077 | 4333 | ||
| 4078 | 4334 | ||
| @@ -4219,14 +4475,10 @@ mark_maybe_pointer (void *p) | |||
| 4219 | { | 4475 | { |
| 4220 | struct mem_node *m; | 4476 | struct mem_node *m; |
| 4221 | 4477 | ||
| 4222 | /* Quickly rule out some values which can't point to Lisp data. */ | 4478 | /* Quickly rule out some values which can't point to Lisp data. |
| 4223 | if ((intptr_t) p % | 4479 | USE_LSB_TAG needs Lisp data to be aligned on multiples of 1 << GCTYPEBITS. |
| 4224 | #ifdef USE_LSB_TAG | 4480 | Otherwise, assume that Lisp data is aligned on even addresses. */ |
| 4225 | 8 /* USE_LSB_TAG needs Lisp data to be aligned on multiples of 8. */ | 4481 | if ((intptr_t) p % (USE_LSB_TAG ? 1 << GCTYPEBITS : 2)) |
| 4226 | #else | ||
| 4227 | 2 /* We assume that Lisp data is aligned on even addresses. */ | ||
| 4228 | #endif | ||
| 4229 | ) | ||
| 4230 | return; | 4482 | return; |
| 4231 | 4483 | ||
| 4232 | m = mem_find (p); | 4484 | m = mem_find (p); |
| @@ -4272,6 +4524,7 @@ mark_maybe_pointer (void *p) | |||
| 4272 | break; | 4524 | break; |
| 4273 | 4525 | ||
| 4274 | case MEM_TYPE_VECTORLIKE: | 4526 | case MEM_TYPE_VECTORLIKE: |
| 4527 | case MEM_TYPE_VECTOR_BLOCK: | ||
| 4275 | if (live_vector_p (m, p)) | 4528 | if (live_vector_p (m, p)) |
| 4276 | { | 4529 | { |
| 4277 | Lisp_Object tem; | 4530 | Lisp_Object tem; |
| @@ -4301,8 +4554,8 @@ mark_maybe_pointer (void *p) | |||
| 4301 | wider than a pointer might allocate a Lisp_Object in non-adjacent halves. | 4554 | wider than a pointer might allocate a Lisp_Object in non-adjacent halves. |
| 4302 | If USE_LSB_TAG, the bottom half is not a valid pointer, but it should | 4555 | If USE_LSB_TAG, the bottom half is not a valid pointer, but it should |
| 4303 | suffice to widen it to to a Lisp_Object and check it that way. */ | 4556 | suffice to widen it to to a Lisp_Object and check it that way. */ |
| 4304 | #if defined USE_LSB_TAG || VAL_MAX < UINTPTR_MAX | 4557 | #if USE_LSB_TAG || VAL_MAX < UINTPTR_MAX |
| 4305 | # if !defined USE_LSB_TAG && VAL_MAX < UINTPTR_MAX >> GCTYPEBITS | 4558 | # if !USE_LSB_TAG && VAL_MAX < UINTPTR_MAX >> GCTYPEBITS |
| 4306 | /* If tag bits straddle pointer-word boundaries, neither mark_maybe_pointer | 4559 | /* If tag bits straddle pointer-word boundaries, neither mark_maybe_pointer |
| 4307 | nor mark_maybe_object can follow the pointers. This should not occur on | 4560 | nor mark_maybe_object can follow the pointers. This should not occur on |
| 4308 | any practical porting target. */ | 4561 | any practical porting target. */ |
| @@ -4322,6 +4575,14 @@ mark_maybe_pointer (void *p) | |||
| 4322 | 4575 | ||
| 4323 | static void | 4576 | static void |
| 4324 | mark_memory (void *start, void *end) | 4577 | mark_memory (void *start, void *end) |
| 4578 | #if defined (__clang__) && defined (__has_feature) | ||
| 4579 | #if __has_feature(address_sanitizer) | ||
| 4580 | /* Do not allow -faddress-sanitizer to check this function, since it | ||
| 4581 | crosses the function stack boundary, and thus would yield many | ||
| 4582 | false positives. */ | ||
| 4583 | __attribute__((no_address_safety_analysis)) | ||
| 4584 | #endif | ||
| 4585 | #endif | ||
| 4325 | { | 4586 | { |
| 4326 | void **pp; | 4587 | void **pp; |
| 4327 | int i; | 4588 | int i; |
| @@ -4363,7 +4624,7 @@ mark_memory (void *start, void *end) | |||
| 4363 | void *p = *(void **) ((char *) pp + i); | 4624 | void *p = *(void **) ((char *) pp + i); |
| 4364 | mark_maybe_pointer (p); | 4625 | mark_maybe_pointer (p); |
| 4365 | if (POINTERS_MIGHT_HIDE_IN_OBJECTS) | 4626 | if (POINTERS_MIGHT_HIDE_IN_OBJECTS) |
| 4366 | mark_maybe_object (widen_to_Lisp_Object (p)); | 4627 | mark_maybe_object (XIL ((intptr_t) p)); |
| 4367 | } | 4628 | } |
| 4368 | } | 4629 | } |
| 4369 | 4630 | ||
| @@ -4705,6 +4966,7 @@ valid_lisp_object_p (Lisp_Object obj) | |||
| 4705 | return live_float_p (m, p); | 4966 | return live_float_p (m, p); |
| 4706 | 4967 | ||
| 4707 | case MEM_TYPE_VECTORLIKE: | 4968 | case MEM_TYPE_VECTORLIKE: |
| 4969 | case MEM_TYPE_VECTOR_BLOCK: | ||
| 4708 | return live_vector_p (m, p); | 4970 | return live_vector_p (m, p); |
| 4709 | 4971 | ||
| 4710 | default: | 4972 | default: |
| @@ -4730,7 +4992,7 @@ static void * | |||
| 4730 | pure_alloc (size_t size, int type) | 4992 | pure_alloc (size_t size, int type) |
| 4731 | { | 4993 | { |
| 4732 | void *result; | 4994 | void *result; |
| 4733 | #ifdef USE_LSB_TAG | 4995 | #if USE_LSB_TAG |
| 4734 | size_t alignment = (1 << GCTYPEBITS); | 4996 | size_t alignment = (1 << GCTYPEBITS); |
| 4735 | #else | 4997 | #else |
| 4736 | size_t alignment = sizeof (EMACS_INT); | 4998 | size_t alignment = sizeof (EMACS_INT); |
| @@ -4769,7 +5031,7 @@ pure_alloc (size_t size, int type) | |||
| 4769 | /* Don't allocate a large amount here, | 5031 | /* Don't allocate a large amount here, |
| 4770 | because it might get mmap'd and then its address | 5032 | because it might get mmap'd and then its address |
| 4771 | might not be usable. */ | 5033 | might not be usable. */ |
| 4772 | purebeg = (char *) xmalloc (10000); | 5034 | purebeg = xmalloc (10000); |
| 4773 | pure_size = 10000; | 5035 | pure_size = 10000; |
| 4774 | pure_bytes_used_before_overflow += pure_bytes_used - size; | 5036 | pure_bytes_used_before_overflow += pure_bytes_used - size; |
| 4775 | pure_bytes_used = 0; | 5037 | pure_bytes_used = 0; |
| @@ -4886,15 +5148,14 @@ make_pure_string (const char *data, | |||
| 4886 | return string; | 5148 | return string; |
| 4887 | } | 5149 | } |
| 4888 | 5150 | ||
| 4889 | /* Return a string a string allocated in pure space. Do not allocate | 5151 | /* Return a string allocated in pure space. Do not |
| 4890 | the string data, just point to DATA. */ | 5152 | allocate the string data, just point to DATA. */ |
| 4891 | 5153 | ||
| 4892 | Lisp_Object | 5154 | Lisp_Object |
| 4893 | make_pure_c_string (const char *data) | 5155 | make_pure_c_string (const char *data, ptrdiff_t nchars) |
| 4894 | { | 5156 | { |
| 4895 | Lisp_Object string; | 5157 | Lisp_Object string; |
| 4896 | struct Lisp_String *s; | 5158 | struct Lisp_String *s; |
| 4897 | ptrdiff_t nchars = strlen (data); | ||
| 4898 | 5159 | ||
| 4899 | s = (struct Lisp_String *) pure_alloc (sizeof *s, Lisp_String); | 5160 | s = (struct Lisp_String *) pure_alloc (sizeof *s, Lisp_String); |
| 4900 | s->size = nchars; | 5161 | s->size = nchars; |
| @@ -4993,7 +5254,7 @@ Does not copy symbols. Copies strings without text properties. */) | |||
| 4993 | size &= PSEUDOVECTOR_SIZE_MASK; | 5254 | size &= PSEUDOVECTOR_SIZE_MASK; |
| 4994 | vec = XVECTOR (make_pure_vector (size)); | 5255 | vec = XVECTOR (make_pure_vector (size)); |
| 4995 | for (i = 0; i < size; i++) | 5256 | for (i = 0; i < size; i++) |
| 4996 | vec->contents[i] = Fpurecopy (XVECTOR (obj)->contents[i]); | 5257 | vec->contents[i] = Fpurecopy (AREF (obj, i)); |
| 4997 | if (COMPILEDP (obj)) | 5258 | if (COMPILEDP (obj)) |
| 4998 | { | 5259 | { |
| 4999 | XSETPVECTYPE (vec, PVEC_COMPILED); | 5260 | XSETPVECTYPE (vec, PVEC_COMPILED); |
| @@ -5068,7 +5329,7 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5068 | int message_p; | 5329 | int message_p; |
| 5069 | Lisp_Object total[8]; | 5330 | Lisp_Object total[8]; |
| 5070 | ptrdiff_t count = SPECPDL_INDEX (); | 5331 | ptrdiff_t count = SPECPDL_INDEX (); |
| 5071 | EMACS_TIME t1, t2, t3; | 5332 | EMACS_TIME t1; |
| 5072 | 5333 | ||
| 5073 | if (abort_on_gc) | 5334 | if (abort_on_gc) |
| 5074 | abort (); | 5335 | abort (); |
| @@ -5091,7 +5352,8 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5091 | turned off in that buffer. Calling truncate_undo_list on | 5352 | turned off in that buffer. Calling truncate_undo_list on |
| 5092 | Qt tends to return NULL, which effectively turns undo back on. | 5353 | Qt tends to return NULL, which effectively turns undo back on. |
| 5093 | So don't call truncate_undo_list if undo_list is Qt. */ | 5354 | So don't call truncate_undo_list if undo_list is Qt. */ |
| 5094 | if (! NILP (nextb->BUFFER_INTERNAL_FIELD (name)) && ! EQ (nextb->BUFFER_INTERNAL_FIELD (undo_list), Qt)) | 5355 | if (! NILP (nextb->BUFFER_INTERNAL_FIELD (name)) |
| 5356 | && ! EQ (nextb->BUFFER_INTERNAL_FIELD (undo_list), Qt)) | ||
| 5095 | truncate_undo_list (nextb); | 5357 | truncate_undo_list (nextb); |
| 5096 | 5358 | ||
| 5097 | /* Shrink buffer gaps, but skip indirect and dead buffers. */ | 5359 | /* Shrink buffer gaps, but skip indirect and dead buffers. */ |
| @@ -5116,7 +5378,7 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5116 | } | 5378 | } |
| 5117 | } | 5379 | } |
| 5118 | 5380 | ||
| 5119 | EMACS_GET_TIME (t1); | 5381 | t1 = current_emacs_time (); |
| 5120 | 5382 | ||
| 5121 | /* In case user calls debug_print during GC, | 5383 | /* In case user calls debug_print during GC, |
| 5122 | don't let that cause a recursive GC. */ | 5384 | don't let that cause a recursive GC. */ |
| @@ -5146,7 +5408,7 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5146 | { | 5408 | { |
| 5147 | if (stack_copy_size < stack_size) | 5409 | if (stack_copy_size < stack_size) |
| 5148 | { | 5410 | { |
| 5149 | stack_copy = (char *) xrealloc (stack_copy, stack_size); | 5411 | stack_copy = xrealloc (stack_copy, stack_size); |
| 5150 | stack_copy_size = stack_size; | 5412 | stack_copy_size = stack_size; |
| 5151 | } | 5413 | } |
| 5152 | memcpy (stack_copy, stack, stack_size); | 5414 | memcpy (stack_copy, stack, stack_size); |
| @@ -5368,12 +5630,14 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5368 | } | 5630 | } |
| 5369 | 5631 | ||
| 5370 | /* Accumulate statistics. */ | 5632 | /* Accumulate statistics. */ |
| 5371 | EMACS_GET_TIME (t2); | ||
| 5372 | EMACS_SUB_TIME (t3, t2, t1); | ||
| 5373 | if (FLOATP (Vgc_elapsed)) | 5633 | if (FLOATP (Vgc_elapsed)) |
| 5374 | Vgc_elapsed = make_float (XFLOAT_DATA (Vgc_elapsed) + | 5634 | { |
| 5375 | EMACS_SECS (t3) + | 5635 | EMACS_TIME t2 = current_emacs_time (); |
| 5376 | EMACS_USECS (t3) * 1.0e-6); | 5636 | EMACS_TIME t3 = sub_emacs_time (t2, t1); |
| 5637 | Vgc_elapsed = make_float (XFLOAT_DATA (Vgc_elapsed) | ||
| 5638 | + EMACS_TIME_TO_DOUBLE (t3)); | ||
| 5639 | } | ||
| 5640 | |||
| 5377 | gcs_done++; | 5641 | gcs_done++; |
| 5378 | 5642 | ||
| 5379 | return Flist (sizeof total / sizeof *total, total); | 5643 | return Flist (sizeof total / sizeof *total, total); |
| @@ -5451,15 +5715,15 @@ mark_vectorlike (struct Lisp_Vector *ptr) | |||
| 5451 | ptrdiff_t i; | 5715 | ptrdiff_t i; |
| 5452 | 5716 | ||
| 5453 | eassert (!VECTOR_MARKED_P (ptr)); | 5717 | eassert (!VECTOR_MARKED_P (ptr)); |
| 5454 | VECTOR_MARK (ptr); /* Else mark it */ | 5718 | VECTOR_MARK (ptr); /* Else mark it. */ |
| 5455 | if (size & PSEUDOVECTOR_FLAG) | 5719 | if (size & PSEUDOVECTOR_FLAG) |
| 5456 | size &= PSEUDOVECTOR_SIZE_MASK; | 5720 | size &= PSEUDOVECTOR_SIZE_MASK; |
| 5457 | 5721 | ||
| 5458 | /* Note that this size is not the memory-footprint size, but only | 5722 | /* Note that this size is not the memory-footprint size, but only |
| 5459 | the number of Lisp_Object fields that we should trace. | 5723 | the number of Lisp_Object fields that we should trace. |
| 5460 | The distinction is used e.g. by Lisp_Process which places extra | 5724 | The distinction is used e.g. by Lisp_Process which places extra |
| 5461 | non-Lisp_Object fields at the end of the structure. */ | 5725 | non-Lisp_Object fields at the end of the structure... */ |
| 5462 | for (i = 0; i < size; i++) /* and then mark its elements */ | 5726 | for (i = 0; i < size; i++) /* ...and then mark its elements. */ |
| 5463 | mark_object (ptr->contents[i]); | 5727 | mark_object (ptr->contents[i]); |
| 5464 | } | 5728 | } |
| 5465 | 5729 | ||
| @@ -5491,6 +5755,46 @@ mark_char_table (struct Lisp_Vector *ptr) | |||
| 5491 | } | 5755 | } |
| 5492 | } | 5756 | } |
| 5493 | 5757 | ||
| 5758 | /* Mark the chain of overlays starting at PTR. */ | ||
| 5759 | |||
| 5760 | static void | ||
| 5761 | mark_overlay (struct Lisp_Overlay *ptr) | ||
| 5762 | { | ||
| 5763 | for (; ptr && !ptr->gcmarkbit; ptr = ptr->next) | ||
| 5764 | { | ||
| 5765 | ptr->gcmarkbit = 1; | ||
| 5766 | mark_object (ptr->start); | ||
| 5767 | mark_object (ptr->end); | ||
| 5768 | mark_object (ptr->plist); | ||
| 5769 | } | ||
| 5770 | } | ||
| 5771 | |||
| 5772 | /* Mark Lisp_Objects and special pointers in BUFFER. */ | ||
| 5773 | |||
| 5774 | static void | ||
| 5775 | mark_buffer (struct buffer *buffer) | ||
| 5776 | { | ||
| 5777 | /* This is handled much like other pseudovectors... */ | ||
| 5778 | mark_vectorlike ((struct Lisp_Vector *) buffer); | ||
| 5779 | |||
| 5780 | /* ...but there are some buffer-specific things. */ | ||
| 5781 | |||
| 5782 | MARK_INTERVAL_TREE (BUF_INTERVALS (buffer)); | ||
| 5783 | |||
| 5784 | /* For now, we just don't mark the undo_list. It's done later in | ||
| 5785 | a special way just before the sweep phase, and after stripping | ||
| 5786 | some of its elements that are not needed any more. */ | ||
| 5787 | |||
| 5788 | mark_overlay (buffer->overlays_before); | ||
| 5789 | mark_overlay (buffer->overlays_after); | ||
| 5790 | |||
| 5791 | /* If this is an indirect buffer, mark its base buffer. */ | ||
| 5792 | if (buffer->base_buffer && !VECTOR_MARKED_P (buffer->base_buffer)) | ||
| 5793 | mark_buffer (buffer->base_buffer); | ||
| 5794 | } | ||
| 5795 | |||
| 5796 | /* Determine type of generic Lisp_Object and mark it accordingly. */ | ||
| 5797 | |||
| 5494 | void | 5798 | void |
| 5495 | mark_object (Lisp_Object arg) | 5799 | mark_object (Lisp_Object arg) |
| 5496 | { | 5800 | { |
| @@ -5556,99 +5860,132 @@ mark_object (Lisp_Object arg) | |||
| 5556 | if (STRING_MARKED_P (ptr)) | 5860 | if (STRING_MARKED_P (ptr)) |
| 5557 | break; | 5861 | break; |
| 5558 | CHECK_ALLOCATED_AND_LIVE (live_string_p); | 5862 | CHECK_ALLOCATED_AND_LIVE (live_string_p); |
| 5559 | MARK_INTERVAL_TREE (ptr->intervals); | ||
| 5560 | MARK_STRING (ptr); | 5863 | MARK_STRING (ptr); |
| 5864 | MARK_INTERVAL_TREE (ptr->intervals); | ||
| 5561 | #ifdef GC_CHECK_STRING_BYTES | 5865 | #ifdef GC_CHECK_STRING_BYTES |
| 5562 | /* Check that the string size recorded in the string is the | 5866 | /* Check that the string size recorded in the string is the |
| 5563 | same as the one recorded in the sdata structure. */ | 5867 | same as the one recorded in the sdata structure. */ |
| 5564 | CHECK_STRING_BYTES (ptr); | 5868 | CHECK_STRING_BYTES (ptr); |
| 5565 | #endif /* GC_CHECK_STRING_BYTES */ | 5869 | #endif /* GC_CHECK_STRING_BYTES */ |
| 5566 | } | 5870 | } |
| 5567 | break; | 5871 | break; |
| 5568 | 5872 | ||
| 5569 | case Lisp_Vectorlike: | 5873 | case Lisp_Vectorlike: |
| 5570 | if (VECTOR_MARKED_P (XVECTOR (obj))) | 5874 | { |
| 5571 | break; | 5875 | register struct Lisp_Vector *ptr = XVECTOR (obj); |
| 5876 | register ptrdiff_t pvectype; | ||
| 5877 | |||
| 5878 | if (VECTOR_MARKED_P (ptr)) | ||
| 5879 | break; | ||
| 5880 | |||
| 5572 | #ifdef GC_CHECK_MARKED_OBJECTS | 5881 | #ifdef GC_CHECK_MARKED_OBJECTS |
| 5573 | m = mem_find (po); | 5882 | m = mem_find (po); |
| 5574 | if (m == MEM_NIL && !SUBRP (obj) | 5883 | if (m == MEM_NIL && !SUBRP (obj) |
| 5575 | && po != &buffer_defaults | 5884 | && po != &buffer_defaults |
| 5576 | && po != &buffer_local_symbols) | 5885 | && po != &buffer_local_symbols) |
| 5577 | abort (); | 5886 | abort (); |
| 5578 | #endif /* GC_CHECK_MARKED_OBJECTS */ | 5887 | #endif /* GC_CHECK_MARKED_OBJECTS */ |
| 5579 | 5888 | ||
| 5580 | if (BUFFERP (obj)) | 5889 | if (ptr->header.size & PSEUDOVECTOR_FLAG) |
| 5581 | { | 5890 | pvectype = ((ptr->header.size & PVEC_TYPE_MASK) |
| 5891 | >> PSEUDOVECTOR_SIZE_BITS); | ||
| 5892 | else | ||
| 5893 | pvectype = 0; | ||
| 5894 | |||
| 5895 | if (pvectype != PVEC_SUBR && pvectype != PVEC_BUFFER) | ||
| 5896 | CHECK_LIVE (live_vector_p); | ||
| 5897 | |||
| 5898 | switch (pvectype) | ||
| 5899 | { | ||
| 5900 | case PVEC_BUFFER: | ||
| 5582 | #ifdef GC_CHECK_MARKED_OBJECTS | 5901 | #ifdef GC_CHECK_MARKED_OBJECTS |
| 5583 | if (po != &buffer_defaults && po != &buffer_local_symbols) | 5902 | if (po != &buffer_defaults && po != &buffer_local_symbols) |
| 5903 | { | ||
| 5904 | struct buffer *b = all_buffers; | ||
| 5905 | for (; b && b != po; b = b->header.next.buffer) | ||
| 5906 | ; | ||
| 5907 | if (b == NULL) | ||
| 5908 | abort (); | ||
| 5909 | } | ||
| 5910 | #endif /* GC_CHECK_MARKED_OBJECTS */ | ||
| 5911 | mark_buffer ((struct buffer *) ptr); | ||
| 5912 | break; | ||
| 5913 | |||
| 5914 | case PVEC_COMPILED: | ||
| 5915 | { /* We could treat this just like a vector, but it is better | ||
| 5916 | to save the COMPILED_CONSTANTS element for last and avoid | ||
| 5917 | recursion there. */ | ||
| 5918 | int size = ptr->header.size & PSEUDOVECTOR_SIZE_MASK; | ||
| 5919 | int i; | ||
| 5920 | |||
| 5921 | VECTOR_MARK (ptr); | ||
| 5922 | for (i = 0; i < size; i++) | ||
| 5923 | if (i != COMPILED_CONSTANTS) | ||
| 5924 | mark_object (ptr->contents[i]); | ||
| 5925 | if (size > COMPILED_CONSTANTS) | ||
| 5926 | { | ||
| 5927 | obj = ptr->contents[COMPILED_CONSTANTS]; | ||
| 5928 | goto loop; | ||
| 5929 | } | ||
| 5930 | } | ||
| 5931 | break; | ||
| 5932 | |||
| 5933 | case PVEC_FRAME: | ||
| 5584 | { | 5934 | { |
| 5585 | struct buffer *b; | 5935 | mark_vectorlike (ptr); |
| 5586 | for (b = all_buffers; b && b != po; b = b->header.next.buffer) | 5936 | mark_face_cache (((struct frame *) ptr)->face_cache); |
| 5587 | ; | ||
| 5588 | if (b == NULL) | ||
| 5589 | abort (); | ||
| 5590 | } | 5937 | } |
| 5591 | #endif /* GC_CHECK_MARKED_OBJECTS */ | 5938 | break; |
| 5592 | mark_buffer (obj); | ||
| 5593 | } | ||
| 5594 | else if (SUBRP (obj)) | ||
| 5595 | break; | ||
| 5596 | else if (COMPILEDP (obj)) | ||
| 5597 | /* We could treat this just like a vector, but it is better to | ||
| 5598 | save the COMPILED_CONSTANTS element for last and avoid | ||
| 5599 | recursion there. */ | ||
| 5600 | { | ||
| 5601 | register struct Lisp_Vector *ptr = XVECTOR (obj); | ||
| 5602 | int size = ptr->header.size & PSEUDOVECTOR_SIZE_MASK; | ||
| 5603 | int i; | ||
| 5604 | 5939 | ||
| 5605 | CHECK_LIVE (live_vector_p); | 5940 | case PVEC_WINDOW: |
| 5606 | VECTOR_MARK (ptr); /* Else mark it */ | ||
| 5607 | for (i = 0; i < size; i++) /* and then mark its elements */ | ||
| 5608 | { | 5941 | { |
| 5609 | if (i != COMPILED_CONSTANTS) | 5942 | struct window *w = (struct window *) ptr; |
| 5610 | mark_object (ptr->contents[i]); | 5943 | |
| 5944 | mark_vectorlike (ptr); | ||
| 5945 | /* Mark glyphs for leaf windows. Marking window | ||
| 5946 | matrices is sufficient because frame matrices | ||
| 5947 | use the same glyph memory. */ | ||
| 5948 | if (NILP (w->hchild) && NILP (w->vchild) && w->current_matrix) | ||
| 5949 | { | ||
| 5950 | mark_glyph_matrix (w->current_matrix); | ||
| 5951 | mark_glyph_matrix (w->desired_matrix); | ||
| 5952 | } | ||
| 5611 | } | 5953 | } |
| 5612 | obj = ptr->contents[COMPILED_CONSTANTS]; | 5954 | break; |
| 5613 | goto loop; | 5955 | |
| 5614 | } | 5956 | case PVEC_HASH_TABLE: |
| 5615 | else if (FRAMEP (obj)) | ||
| 5616 | { | ||
| 5617 | register struct frame *ptr = XFRAME (obj); | ||
| 5618 | mark_vectorlike (XVECTOR (obj)); | ||
| 5619 | mark_face_cache (ptr->face_cache); | ||
| 5620 | } | ||
| 5621 | else if (WINDOWP (obj)) | ||
| 5622 | { | ||
| 5623 | register struct Lisp_Vector *ptr = XVECTOR (obj); | ||
| 5624 | struct window *w = XWINDOW (obj); | ||
| 5625 | mark_vectorlike (ptr); | ||
| 5626 | /* Mark glyphs for leaf windows. Marking window matrices is | ||
| 5627 | sufficient because frame matrices use the same glyph | ||
| 5628 | memory. */ | ||
| 5629 | if (NILP (w->hchild) | ||
| 5630 | && NILP (w->vchild) | ||
| 5631 | && w->current_matrix) | ||
| 5632 | { | 5957 | { |
| 5633 | mark_glyph_matrix (w->current_matrix); | 5958 | struct Lisp_Hash_Table *h = (struct Lisp_Hash_Table *) ptr; |
| 5634 | mark_glyph_matrix (w->desired_matrix); | 5959 | |
| 5960 | mark_vectorlike (ptr); | ||
| 5961 | /* If hash table is not weak, mark all keys and values. | ||
| 5962 | For weak tables, mark only the vector. */ | ||
| 5963 | if (NILP (h->weak)) | ||
| 5964 | mark_object (h->key_and_value); | ||
| 5965 | else | ||
| 5966 | VECTOR_MARK (XVECTOR (h->key_and_value)); | ||
| 5635 | } | 5967 | } |
| 5636 | } | 5968 | break; |
| 5637 | else if (HASH_TABLE_P (obj)) | 5969 | |
| 5638 | { | 5970 | case PVEC_CHAR_TABLE: |
| 5639 | struct Lisp_Hash_Table *h = XHASH_TABLE (obj); | 5971 | mark_char_table (ptr); |
| 5640 | mark_vectorlike ((struct Lisp_Vector *)h); | 5972 | break; |
| 5641 | /* If hash table is not weak, mark all keys and values. | 5973 | |
| 5642 | For weak tables, mark only the vector. */ | 5974 | case PVEC_BOOL_VECTOR: |
| 5643 | if (NILP (h->weak)) | 5975 | /* No Lisp_Objects to mark in a bool vector. */ |
| 5644 | mark_object (h->key_and_value); | 5976 | VECTOR_MARK (ptr); |
| 5645 | else | 5977 | break; |
| 5646 | VECTOR_MARK (XVECTOR (h->key_and_value)); | 5978 | |
| 5647 | } | 5979 | case PVEC_SUBR: |
| 5648 | else if (CHAR_TABLE_P (obj)) | 5980 | break; |
| 5649 | mark_char_table (XVECTOR (obj)); | 5981 | |
| 5650 | else | 5982 | case PVEC_FREE: |
| 5651 | mark_vectorlike (XVECTOR (obj)); | 5983 | abort (); |
| 5984 | |||
| 5985 | default: | ||
| 5986 | mark_vectorlike (ptr); | ||
| 5987 | } | ||
| 5988 | } | ||
| 5652 | break; | 5989 | break; |
| 5653 | 5990 | ||
| 5654 | case Lisp_Symbol: | 5991 | case Lisp_Symbol: |
| @@ -5699,7 +6036,7 @@ mark_object (Lisp_Object arg) | |||
| 5699 | ptr = ptr->next; | 6036 | ptr = ptr->next; |
| 5700 | if (ptr) | 6037 | if (ptr) |
| 5701 | { | 6038 | { |
| 5702 | ptrx = ptr; /* Use of ptrx avoids compiler bug on Sun */ | 6039 | ptrx = ptr; /* Use of ptrx avoids compiler bug on Sun. */ |
| 5703 | XSETSYMBOL (obj, ptrx); | 6040 | XSETSYMBOL (obj, ptrx); |
| 5704 | goto loop; | 6041 | goto loop; |
| 5705 | } | 6042 | } |
| @@ -5708,20 +6045,21 @@ mark_object (Lisp_Object arg) | |||
| 5708 | 6045 | ||
| 5709 | case Lisp_Misc: | 6046 | case Lisp_Misc: |
| 5710 | CHECK_ALLOCATED_AND_LIVE (live_misc_p); | 6047 | CHECK_ALLOCATED_AND_LIVE (live_misc_p); |
| 6048 | |||
| 5711 | if (XMISCANY (obj)->gcmarkbit) | 6049 | if (XMISCANY (obj)->gcmarkbit) |
| 5712 | break; | 6050 | break; |
| 5713 | XMISCANY (obj)->gcmarkbit = 1; | ||
| 5714 | 6051 | ||
| 5715 | switch (XMISCTYPE (obj)) | 6052 | switch (XMISCTYPE (obj)) |
| 5716 | { | 6053 | { |
| 5717 | |||
| 5718 | case Lisp_Misc_Marker: | 6054 | case Lisp_Misc_Marker: |
| 5719 | /* DO NOT mark thru the marker's chain. | 6055 | /* DO NOT mark thru the marker's chain. |
| 5720 | The buffer's markers chain does not preserve markers from gc; | 6056 | The buffer's markers chain does not preserve markers from gc; |
| 5721 | instead, markers are removed from the chain when freed by gc. */ | 6057 | instead, markers are removed from the chain when freed by gc. */ |
| 6058 | XMISCANY (obj)->gcmarkbit = 1; | ||
| 5722 | break; | 6059 | break; |
| 5723 | 6060 | ||
| 5724 | case Lisp_Misc_Save_Value: | 6061 | case Lisp_Misc_Save_Value: |
| 6062 | XMISCANY (obj)->gcmarkbit = 1; | ||
| 5725 | #if GC_MARK_STACK | 6063 | #if GC_MARK_STACK |
| 5726 | { | 6064 | { |
| 5727 | register struct Lisp_Save_Value *ptr = XSAVE_VALUE (obj); | 6065 | register struct Lisp_Save_Value *ptr = XSAVE_VALUE (obj); |
| @@ -5739,17 +6077,7 @@ mark_object (Lisp_Object arg) | |||
| 5739 | break; | 6077 | break; |
| 5740 | 6078 | ||
| 5741 | case Lisp_Misc_Overlay: | 6079 | case Lisp_Misc_Overlay: |
| 5742 | { | 6080 | mark_overlay (XOVERLAY (obj)); |
| 5743 | struct Lisp_Overlay *ptr = XOVERLAY (obj); | ||
| 5744 | mark_object (ptr->start); | ||
| 5745 | mark_object (ptr->end); | ||
| 5746 | mark_object (ptr->plist); | ||
| 5747 | if (ptr->next) | ||
| 5748 | { | ||
| 5749 | XSETMISC (obj, ptr->next); | ||
| 5750 | goto loop; | ||
| 5751 | } | ||
| 5752 | } | ||
| 5753 | break; | 6081 | break; |
| 5754 | 6082 | ||
| 5755 | default: | 6083 | default: |
| @@ -5795,52 +6123,6 @@ mark_object (Lisp_Object arg) | |||
| 5795 | #undef CHECK_ALLOCATED | 6123 | #undef CHECK_ALLOCATED |
| 5796 | #undef CHECK_ALLOCATED_AND_LIVE | 6124 | #undef CHECK_ALLOCATED_AND_LIVE |
| 5797 | } | 6125 | } |
| 5798 | |||
| 5799 | /* Mark the pointers in a buffer structure. */ | ||
| 5800 | |||
| 5801 | static void | ||
| 5802 | mark_buffer (Lisp_Object buf) | ||
| 5803 | { | ||
| 5804 | register struct buffer *buffer = XBUFFER (buf); | ||
| 5805 | register Lisp_Object *ptr, tmp; | ||
| 5806 | Lisp_Object base_buffer; | ||
| 5807 | |||
| 5808 | eassert (!VECTOR_MARKED_P (buffer)); | ||
| 5809 | VECTOR_MARK (buffer); | ||
| 5810 | |||
| 5811 | MARK_INTERVAL_TREE (BUF_INTERVALS (buffer)); | ||
| 5812 | |||
| 5813 | /* For now, we just don't mark the undo_list. It's done later in | ||
| 5814 | a special way just before the sweep phase, and after stripping | ||
| 5815 | some of its elements that are not needed any more. */ | ||
| 5816 | |||
| 5817 | if (buffer->overlays_before) | ||
| 5818 | { | ||
| 5819 | XSETMISC (tmp, buffer->overlays_before); | ||
| 5820 | mark_object (tmp); | ||
| 5821 | } | ||
| 5822 | if (buffer->overlays_after) | ||
| 5823 | { | ||
| 5824 | XSETMISC (tmp, buffer->overlays_after); | ||
| 5825 | mark_object (tmp); | ||
| 5826 | } | ||
| 5827 | |||
| 5828 | /* buffer-local Lisp variables start at `undo_list', | ||
| 5829 | tho only the ones from `name' on are GC'd normally. */ | ||
| 5830 | for (ptr = &buffer->BUFFER_INTERNAL_FIELD (name); | ||
| 5831 | ptr <= &PER_BUFFER_VALUE (buffer, | ||
| 5832 | PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER)); | ||
| 5833 | ptr++) | ||
| 5834 | mark_object (*ptr); | ||
| 5835 | |||
| 5836 | /* If this is an indirect buffer, mark its base buffer. */ | ||
| 5837 | if (buffer->base_buffer && !VECTOR_MARKED_P (buffer->base_buffer)) | ||
| 5838 | { | ||
| 5839 | XSETBUFFER (base_buffer, buffer->base_buffer); | ||
| 5840 | mark_buffer (base_buffer); | ||
| 5841 | } | ||
| 5842 | } | ||
| 5843 | |||
| 5844 | /* Mark the Lisp pointers in the terminal objects. | 6126 | /* Mark the Lisp pointers in the terminal objects. |
| 5845 | Called by Fgarbage_collect. */ | 6127 | Called by Fgarbage_collect. */ |
| 5846 | 6128 | ||
| @@ -6241,33 +6523,7 @@ gc_sweep (void) | |||
| 6241 | } | 6523 | } |
| 6242 | } | 6524 | } |
| 6243 | 6525 | ||
| 6244 | /* Free all unmarked vectors */ | 6526 | sweep_vectors (); |
| 6245 | { | ||
| 6246 | register struct Lisp_Vector *vector = all_vectors, *prev = 0, *next; | ||
| 6247 | total_vector_size = 0; | ||
| 6248 | |||
| 6249 | while (vector) | ||
| 6250 | if (!VECTOR_MARKED_P (vector)) | ||
| 6251 | { | ||
| 6252 | if (prev) | ||
| 6253 | prev->header.next = vector->header.next; | ||
| 6254 | else | ||
| 6255 | all_vectors = vector->header.next.vector; | ||
| 6256 | next = vector->header.next.vector; | ||
| 6257 | lisp_free (vector); | ||
| 6258 | vector = next; | ||
| 6259 | |||
| 6260 | } | ||
| 6261 | else | ||
| 6262 | { | ||
| 6263 | VECTOR_UNMARK (vector); | ||
| 6264 | if (vector->header.size & PSEUDOVECTOR_FLAG) | ||
| 6265 | total_vector_size += PSEUDOVECTOR_SIZE_MASK & vector->header.size; | ||
| 6266 | else | ||
| 6267 | total_vector_size += vector->header.size; | ||
| 6268 | prev = vector, vector = vector->header.next.vector; | ||
| 6269 | } | ||
| 6270 | } | ||
| 6271 | 6527 | ||
| 6272 | #ifdef GC_CHECK_STRING_BYTES | 6528 | #ifdef GC_CHECK_STRING_BYTES |
| 6273 | if (!noninteractive) | 6529 | if (!noninteractive) |
| @@ -6392,32 +6648,19 @@ init_alloc_once (void) | |||
| 6392 | /* Used to do Vpurify_flag = Qt here, but Qt isn't set up yet! */ | 6648 | /* Used to do Vpurify_flag = Qt here, but Qt isn't set up yet! */ |
| 6393 | purebeg = PUREBEG; | 6649 | purebeg = PUREBEG; |
| 6394 | pure_size = PURESIZE; | 6650 | pure_size = PURESIZE; |
| 6395 | pure_bytes_used = 0; | ||
| 6396 | pure_bytes_used_lisp = pure_bytes_used_non_lisp = 0; | ||
| 6397 | pure_bytes_used_before_overflow = 0; | ||
| 6398 | |||
| 6399 | /* Initialize the list of free aligned blocks. */ | ||
| 6400 | free_ablock = NULL; | ||
| 6401 | 6651 | ||
| 6402 | #if GC_MARK_STACK || defined GC_MALLOC_CHECK | 6652 | #if GC_MARK_STACK || defined GC_MALLOC_CHECK |
| 6403 | mem_init (); | 6653 | mem_init (); |
| 6404 | Vdead = make_pure_string ("DEAD", 4, 4, 0); | 6654 | Vdead = make_pure_string ("DEAD", 4, 4, 0); |
| 6405 | #endif | 6655 | #endif |
| 6406 | 6656 | ||
| 6407 | all_vectors = 0; | ||
| 6408 | ignore_warnings = 1; | ||
| 6409 | #ifdef DOUG_LEA_MALLOC | 6657 | #ifdef DOUG_LEA_MALLOC |
| 6410 | mallopt (M_TRIM_THRESHOLD, 128*1024); /* trim threshold */ | 6658 | mallopt (M_TRIM_THRESHOLD, 128*1024); /* trim threshold */ |
| 6411 | mallopt (M_MMAP_THRESHOLD, 64*1024); /* mmap threshold */ | 6659 | mallopt (M_MMAP_THRESHOLD, 64*1024); /* mmap threshold */ |
| 6412 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); /* max. number of mmap'ed areas */ | 6660 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); /* max. number of mmap'ed areas */ |
| 6413 | #endif | 6661 | #endif |
| 6414 | init_strings (); | 6662 | init_strings (); |
| 6415 | init_cons (); | 6663 | init_vectors (); |
| 6416 | init_symbol (); | ||
| 6417 | init_marker (); | ||
| 6418 | init_float (); | ||
| 6419 | init_intervals (); | ||
| 6420 | init_weak_hash_tables (); | ||
| 6421 | 6664 | ||
| 6422 | #ifdef REL_ALLOC | 6665 | #ifdef REL_ALLOC |
| 6423 | malloc_hysteresis = 32; | 6666 | malloc_hysteresis = 32; |
| @@ -6426,14 +6669,7 @@ init_alloc_once (void) | |||
| 6426 | #endif | 6669 | #endif |
| 6427 | 6670 | ||
| 6428 | refill_memory_reserve (); | 6671 | refill_memory_reserve (); |
| 6429 | |||
| 6430 | ignore_warnings = 0; | ||
| 6431 | gcprolist = 0; | ||
| 6432 | byte_stack_list = 0; | ||
| 6433 | staticidx = 0; | ||
| 6434 | consing_since_gc = 0; | ||
| 6435 | gc_cons_threshold = 100000 * sizeof (Lisp_Object); | 6672 | gc_cons_threshold = 100000 * sizeof (Lisp_Object); |
| 6436 | gc_relative_threshold = 0; | ||
| 6437 | } | 6673 | } |
| 6438 | 6674 | ||
| 6439 | void | 6675 | void |
| @@ -6521,7 +6757,7 @@ do hash-consing of the objects allocated to pure space. */); | |||
| 6521 | not be able to allocate the memory to hold it. */ | 6757 | not be able to allocate the memory to hold it. */ |
| 6522 | Vmemory_signal_data | 6758 | Vmemory_signal_data |
| 6523 | = pure_cons (Qerror, | 6759 | = pure_cons (Qerror, |
| 6524 | pure_cons (make_pure_c_string ("Memory exhausted--use M-x save-some-buffers then exit and restart Emacs"), Qnil)); | 6760 | pure_cons (build_pure_c_string ("Memory exhausted--use M-x save-some-buffers then exit and restart Emacs"), Qnil)); |
| 6525 | 6761 | ||
| 6526 | DEFVAR_LISP ("memory-full", Vmemory_full, | 6762 | DEFVAR_LISP ("memory-full", Vmemory_full, |
| 6527 | doc: /* Non-nil means Emacs cannot get much more Lisp memory. */); | 6763 | doc: /* Non-nil means Emacs cannot get much more Lisp memory. */); |