diff options
| author | Fabián Ezequiel Gallina | 2012-06-14 23:05:43 -0300 |
|---|---|---|
| committer | Fabián Ezequiel Gallina | 2012-06-14 23:05:43 -0300 |
| commit | 315f675857250c2204d024748e9eafa57c68410f (patch) | |
| tree | 101bfee7ff075c2eb02fd4bd80af02ed1da979b5 /src/alloc.c | |
| parent | c6a506fefd22cb1efde1935154e79b471b943c45 (diff) | |
| parent | 4302f5ba6e853d3f42ca21c536afd5a69b9e1774 (diff) | |
| download | emacs-315f675857250c2204d024748e9eafa57c68410f.tar.gz emacs-315f675857250c2204d024748e9eafa57c68410f.zip | |
Merge from trunk
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 655 |
1 files changed, 467 insertions, 188 deletions
diff --git a/src/alloc.c b/src/alloc.c index a120ce9b61f..1478ce9ae4e 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -66,7 +66,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 66 | 66 | ||
| 67 | #include <unistd.h> | 67 | #include <unistd.h> |
| 68 | #ifndef HAVE_UNISTD_H | 68 | #ifndef HAVE_UNISTD_H |
| 69 | extern POINTER_TYPE *sbrk (); | 69 | extern void *sbrk (); |
| 70 | #endif | 70 | #endif |
| 71 | 71 | ||
| 72 | #include <fcntl.h> | 72 | #include <fcntl.h> |
| @@ -234,11 +234,11 @@ static ptrdiff_t pure_bytes_used_before_overflow; | |||
| 234 | 234 | ||
| 235 | /* Index in pure at which next pure Lisp object will be allocated.. */ | 235 | /* Index in pure at which next pure Lisp object will be allocated.. */ |
| 236 | 236 | ||
| 237 | static EMACS_INT pure_bytes_used_lisp; | 237 | static ptrdiff_t pure_bytes_used_lisp; |
| 238 | 238 | ||
| 239 | /* Number of bytes allocated for non-Lisp objects in pure storage. */ | 239 | /* Number of bytes allocated for non-Lisp objects in pure storage. */ |
| 240 | 240 | ||
| 241 | static EMACS_INT pure_bytes_used_non_lisp; | 241 | static ptrdiff_t pure_bytes_used_non_lisp; |
| 242 | 242 | ||
| 243 | /* If nonzero, this is a warning delivered by malloc and not yet | 243 | /* If nonzero, this is a warning delivered by malloc and not yet |
| 244 | displayed. */ | 244 | displayed. */ |
| @@ -273,6 +273,7 @@ static Lisp_Object Qpost_gc_hook; | |||
| 273 | static void mark_buffer (Lisp_Object); | 273 | static void mark_buffer (Lisp_Object); |
| 274 | static void mark_terminals (void); | 274 | static void mark_terminals (void); |
| 275 | static void gc_sweep (void); | 275 | static void gc_sweep (void); |
| 276 | static Lisp_Object make_pure_vector (ptrdiff_t); | ||
| 276 | static void mark_glyph_matrix (struct glyph_matrix *); | 277 | static void mark_glyph_matrix (struct glyph_matrix *); |
| 277 | static void mark_face_cache (struct face_cache *); | 278 | static void mark_face_cache (struct face_cache *); |
| 278 | 279 | ||
| @@ -303,10 +304,12 @@ enum mem_type | |||
| 303 | process, hash_table, frame, terminal, and window, but we never made | 304 | process, hash_table, frame, terminal, and window, but we never made |
| 304 | use of the distinction, so it only caused source-code complexity | 305 | use of the distinction, so it only caused source-code complexity |
| 305 | and runtime slowdown. Minor but pointless. */ | 306 | and runtime slowdown. Minor but pointless. */ |
| 306 | MEM_TYPE_VECTORLIKE | 307 | MEM_TYPE_VECTORLIKE, |
| 308 | /* Special type to denote vector blocks. */ | ||
| 309 | MEM_TYPE_VECTOR_BLOCK | ||
| 307 | }; | 310 | }; |
| 308 | 311 | ||
| 309 | static POINTER_TYPE *lisp_malloc (size_t, enum mem_type); | 312 | static void *lisp_malloc (size_t, enum mem_type); |
| 310 | 313 | ||
| 311 | 314 | ||
| 312 | #if GC_MARK_STACK || defined GC_MALLOC_CHECK | 315 | #if GC_MARK_STACK || defined GC_MALLOC_CHECK |
| @@ -387,8 +390,8 @@ static void *min_heap_address, *max_heap_address; | |||
| 387 | static struct mem_node mem_z; | 390 | static struct mem_node mem_z; |
| 388 | #define MEM_NIL &mem_z | 391 | #define MEM_NIL &mem_z |
| 389 | 392 | ||
| 390 | static struct Lisp_Vector *allocate_vectorlike (EMACS_INT); | 393 | static struct Lisp_Vector *allocate_vectorlike (ptrdiff_t); |
| 391 | static void lisp_free (POINTER_TYPE *); | 394 | static void lisp_free (void *); |
| 392 | static void mark_stack (void); | 395 | static void mark_stack (void); |
| 393 | static int live_vector_p (struct mem_node *, void *); | 396 | static int live_vector_p (struct mem_node *, void *); |
| 394 | static int live_buffer_p (struct mem_node *, void *); | 397 | static int live_buffer_p (struct mem_node *, void *); |
| @@ -435,15 +438,15 @@ static Lisp_Object *staticvec[NSTATICS] = {&Vpurify_flag}; | |||
| 435 | 438 | ||
| 436 | static int staticidx = 0; | 439 | static int staticidx = 0; |
| 437 | 440 | ||
| 438 | static POINTER_TYPE *pure_alloc (size_t, int); | 441 | static void *pure_alloc (size_t, int); |
| 439 | 442 | ||
| 440 | 443 | ||
| 441 | /* Value is SZ rounded up to the next multiple of ALIGNMENT. | 444 | /* Value is SZ rounded up to the next multiple of ALIGNMENT. |
| 442 | ALIGNMENT must be a power of 2. */ | 445 | ALIGNMENT must be a power of 2. */ |
| 443 | 446 | ||
| 444 | #define ALIGN(ptr, ALIGNMENT) \ | 447 | #define ALIGN(ptr, ALIGNMENT) \ |
| 445 | ((POINTER_TYPE *) ((((uintptr_t) (ptr)) + (ALIGNMENT) - 1) \ | 448 | ((void *) (((uintptr_t) (ptr) + (ALIGNMENT) - 1) \ |
| 446 | & ~((ALIGNMENT) - 1))) | 449 | & ~ ((ALIGNMENT) - 1))) |
| 447 | 450 | ||
| 448 | 451 | ||
| 449 | 452 | ||
| @@ -475,7 +478,7 @@ display_malloc_warning (void) | |||
| 475 | /* Called if we can't allocate relocatable space for a buffer. */ | 478 | /* Called if we can't allocate relocatable space for a buffer. */ |
| 476 | 479 | ||
| 477 | void | 480 | void |
| 478 | buffer_memory_full (EMACS_INT nbytes) | 481 | buffer_memory_full (ptrdiff_t nbytes) |
| 479 | { | 482 | { |
| 480 | /* If buffers use the relocating allocator, no need to free | 483 | /* If buffers use the relocating allocator, no need to free |
| 481 | spare_memory, because we may have plenty of malloc space left | 484 | spare_memory, because we may have plenty of malloc space left |
| @@ -493,6 +496,11 @@ buffer_memory_full (EMACS_INT nbytes) | |||
| 493 | xsignal (Qnil, Vmemory_signal_data); | 496 | xsignal (Qnil, Vmemory_signal_data); |
| 494 | } | 497 | } |
| 495 | 498 | ||
| 499 | /* A common multiple of the positive integers A and B. Ideally this | ||
| 500 | would be the least common multiple, but there's no way to do that | ||
| 501 | as a constant expression in C, so do the best that we can easily do. */ | ||
| 502 | #define COMMON_MULTIPLE(a, b) \ | ||
| 503 | ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b)) | ||
| 496 | 504 | ||
| 497 | #ifndef XMALLOC_OVERRUN_CHECK | 505 | #ifndef XMALLOC_OVERRUN_CHECK |
| 498 | #define XMALLOC_OVERRUN_CHECK_OVERHEAD 0 | 506 | #define XMALLOC_OVERRUN_CHECK_OVERHEAD 0 |
| @@ -524,12 +532,8 @@ buffer_memory_full (EMACS_INT nbytes) | |||
| 524 | char c; \ | 532 | char c; \ |
| 525 | }, \ | 533 | }, \ |
| 526 | c) | 534 | c) |
| 527 | #ifdef USE_LSB_TAG | 535 | |
| 528 | /* A common multiple of the positive integers A and B. Ideally this | 536 | #if USE_LSB_TAG |
| 529 | would be the least common multiple, but there's no way to do that | ||
| 530 | as a constant expression in C, so do the best that we can easily do. */ | ||
| 531 | # define COMMON_MULTIPLE(a, b) \ | ||
| 532 | ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b)) | ||
| 533 | # define XMALLOC_HEADER_ALIGNMENT \ | 537 | # define XMALLOC_HEADER_ALIGNMENT \ |
| 534 | COMMON_MULTIPLE (1 << GCTYPEBITS, XMALLOC_BASE_ALIGNMENT) | 538 | COMMON_MULTIPLE (1 << GCTYPEBITS, XMALLOC_BASE_ALIGNMENT) |
| 535 | #else | 539 | #else |
| @@ -604,7 +608,7 @@ static ptrdiff_t check_depth; | |||
| 604 | 608 | ||
| 605 | /* Like malloc, but wraps allocated block with header and trailer. */ | 609 | /* Like malloc, but wraps allocated block with header and trailer. */ |
| 606 | 610 | ||
| 607 | static POINTER_TYPE * | 611 | static void * |
| 608 | overrun_check_malloc (size_t size) | 612 | overrun_check_malloc (size_t size) |
| 609 | { | 613 | { |
| 610 | register unsigned char *val; | 614 | register unsigned char *val; |
| @@ -622,15 +626,15 @@ overrun_check_malloc (size_t size) | |||
| 622 | XMALLOC_OVERRUN_CHECK_SIZE); | 626 | XMALLOC_OVERRUN_CHECK_SIZE); |
| 623 | } | 627 | } |
| 624 | --check_depth; | 628 | --check_depth; |
| 625 | return (POINTER_TYPE *)val; | 629 | return val; |
| 626 | } | 630 | } |
| 627 | 631 | ||
| 628 | 632 | ||
| 629 | /* Like realloc, but checks old block for overrun, and wraps new block | 633 | /* Like realloc, but checks old block for overrun, and wraps new block |
| 630 | with header and trailer. */ | 634 | with header and trailer. */ |
| 631 | 635 | ||
| 632 | static POINTER_TYPE * | 636 | static void * |
| 633 | overrun_check_realloc (POINTER_TYPE *block, size_t size) | 637 | overrun_check_realloc (void *block, size_t size) |
| 634 | { | 638 | { |
| 635 | register unsigned char *val = (unsigned char *) block; | 639 | register unsigned char *val = (unsigned char *) block; |
| 636 | int overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_OVERHEAD : 0; | 640 | int overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_OVERHEAD : 0; |
| @@ -652,7 +656,7 @@ overrun_check_realloc (POINTER_TYPE *block, size_t size) | |||
| 652 | memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE); | 656 | memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE); |
| 653 | } | 657 | } |
| 654 | 658 | ||
| 655 | val = (unsigned char *) realloc ((POINTER_TYPE *)val, size + overhead); | 659 | val = realloc (val, size + overhead); |
| 656 | 660 | ||
| 657 | if (val && check_depth == 1) | 661 | if (val && check_depth == 1) |
| 658 | { | 662 | { |
| @@ -663,13 +667,13 @@ overrun_check_realloc (POINTER_TYPE *block, size_t size) | |||
| 663 | XMALLOC_OVERRUN_CHECK_SIZE); | 667 | XMALLOC_OVERRUN_CHECK_SIZE); |
| 664 | } | 668 | } |
| 665 | --check_depth; | 669 | --check_depth; |
| 666 | return (POINTER_TYPE *)val; | 670 | return val; |
| 667 | } | 671 | } |
| 668 | 672 | ||
| 669 | /* Like free, but checks block for overrun. */ | 673 | /* Like free, but checks block for overrun. */ |
| 670 | 674 | ||
| 671 | static void | 675 | static void |
| 672 | overrun_check_free (POINTER_TYPE *block) | 676 | overrun_check_free (void *block) |
| 673 | { | 677 | { |
| 674 | unsigned char *val = (unsigned char *) block; | 678 | unsigned char *val = (unsigned char *) block; |
| 675 | 679 | ||
| @@ -718,13 +722,13 @@ overrun_check_free (POINTER_TYPE *block) | |||
| 718 | 722 | ||
| 719 | /* Like malloc but check for no memory and block interrupt input.. */ | 723 | /* Like malloc but check for no memory and block interrupt input.. */ |
| 720 | 724 | ||
| 721 | POINTER_TYPE * | 725 | void * |
| 722 | xmalloc (size_t size) | 726 | xmalloc (size_t size) |
| 723 | { | 727 | { |
| 724 | register POINTER_TYPE *val; | 728 | void *val; |
| 725 | 729 | ||
| 726 | MALLOC_BLOCK_INPUT; | 730 | MALLOC_BLOCK_INPUT; |
| 727 | val = (POINTER_TYPE *) malloc (size); | 731 | val = malloc (size); |
| 728 | MALLOC_UNBLOCK_INPUT; | 732 | MALLOC_UNBLOCK_INPUT; |
| 729 | 733 | ||
| 730 | if (!val && size) | 734 | if (!val && size) |
| @@ -735,18 +739,18 @@ xmalloc (size_t size) | |||
| 735 | 739 | ||
| 736 | /* Like realloc but check for no memory and block interrupt input.. */ | 740 | /* Like realloc but check for no memory and block interrupt input.. */ |
| 737 | 741 | ||
| 738 | POINTER_TYPE * | 742 | void * |
| 739 | xrealloc (POINTER_TYPE *block, size_t size) | 743 | xrealloc (void *block, size_t size) |
| 740 | { | 744 | { |
| 741 | register POINTER_TYPE *val; | 745 | void *val; |
| 742 | 746 | ||
| 743 | MALLOC_BLOCK_INPUT; | 747 | MALLOC_BLOCK_INPUT; |
| 744 | /* We must call malloc explicitly when BLOCK is 0, since some | 748 | /* We must call malloc explicitly when BLOCK is 0, since some |
| 745 | reallocs don't do this. */ | 749 | reallocs don't do this. */ |
| 746 | if (! block) | 750 | if (! block) |
| 747 | val = (POINTER_TYPE *) malloc (size); | 751 | val = malloc (size); |
| 748 | else | 752 | else |
| 749 | val = (POINTER_TYPE *) realloc (block, size); | 753 | val = realloc (block, size); |
| 750 | MALLOC_UNBLOCK_INPUT; | 754 | MALLOC_UNBLOCK_INPUT; |
| 751 | 755 | ||
| 752 | if (!val && size) | 756 | if (!val && size) |
| @@ -758,7 +762,7 @@ xrealloc (POINTER_TYPE *block, size_t size) | |||
| 758 | /* Like free but block interrupt input. */ | 762 | /* Like free but block interrupt input. */ |
| 759 | 763 | ||
| 760 | void | 764 | void |
| 761 | xfree (POINTER_TYPE *block) | 765 | xfree (void *block) |
| 762 | { | 766 | { |
| 763 | if (!block) | 767 | if (!block) |
| 764 | return; | 768 | return; |
| @@ -889,11 +893,11 @@ safe_alloca_unwind (Lisp_Object arg) | |||
| 889 | number of bytes to allocate, TYPE describes the intended use of the | 893 | number of bytes to allocate, TYPE describes the intended use of the |
| 890 | allocated memory block (for strings, for conses, ...). */ | 894 | allocated memory block (for strings, for conses, ...). */ |
| 891 | 895 | ||
| 892 | #ifndef USE_LSB_TAG | 896 | #if ! USE_LSB_TAG |
| 893 | static void *lisp_malloc_loser; | 897 | void *lisp_malloc_loser EXTERNALLY_VISIBLE; |
| 894 | #endif | 898 | #endif |
| 895 | 899 | ||
| 896 | static POINTER_TYPE * | 900 | static void * |
| 897 | lisp_malloc (size_t nbytes, enum mem_type type) | 901 | lisp_malloc (size_t nbytes, enum mem_type type) |
| 898 | { | 902 | { |
| 899 | register void *val; | 903 | register void *val; |
| @@ -906,7 +910,7 @@ lisp_malloc (size_t nbytes, enum mem_type type) | |||
| 906 | 910 | ||
| 907 | val = (void *) malloc (nbytes); | 911 | val = (void *) malloc (nbytes); |
| 908 | 912 | ||
| 909 | #ifndef USE_LSB_TAG | 913 | #if ! USE_LSB_TAG |
| 910 | /* If the memory just allocated cannot be addressed thru a Lisp | 914 | /* If the memory just allocated cannot be addressed thru a Lisp |
| 911 | object's pointer, and it needs to be, | 915 | object's pointer, and it needs to be, |
| 912 | that's equivalent to running out of memory. */ | 916 | that's equivalent to running out of memory. */ |
| @@ -938,7 +942,7 @@ lisp_malloc (size_t nbytes, enum mem_type type) | |||
| 938 | call to lisp_malloc. */ | 942 | call to lisp_malloc. */ |
| 939 | 943 | ||
| 940 | static void | 944 | static void |
| 941 | lisp_free (POINTER_TYPE *block) | 945 | lisp_free (void *block) |
| 942 | { | 946 | { |
| 943 | MALLOC_BLOCK_INPUT; | 947 | MALLOC_BLOCK_INPUT; |
| 944 | free (block); | 948 | free (block); |
| @@ -1034,7 +1038,7 @@ static struct ablock *free_ablock; | |||
| 1034 | /* Allocate an aligned block of nbytes. | 1038 | /* Allocate an aligned block of nbytes. |
| 1035 | Alignment is on a multiple of BLOCK_ALIGN and `nbytes' has to be | 1039 | Alignment is on a multiple of BLOCK_ALIGN and `nbytes' has to be |
| 1036 | smaller or equal to BLOCK_BYTES. */ | 1040 | smaller or equal to BLOCK_BYTES. */ |
| 1037 | static POINTER_TYPE * | 1041 | static void * |
| 1038 | lisp_align_malloc (size_t nbytes, enum mem_type type) | 1042 | lisp_align_malloc (size_t nbytes, enum mem_type type) |
| 1039 | { | 1043 | { |
| 1040 | void *base, *val; | 1044 | void *base, *val; |
| @@ -1087,7 +1091,7 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) | |||
| 1087 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); | 1091 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); |
| 1088 | #endif | 1092 | #endif |
| 1089 | 1093 | ||
| 1090 | #ifndef USE_LSB_TAG | 1094 | #if ! USE_LSB_TAG |
| 1091 | /* If the memory just allocated cannot be addressed thru a Lisp | 1095 | /* If the memory just allocated cannot be addressed thru a Lisp |
| 1092 | object's pointer, and it needs to be, that's equivalent to | 1096 | object's pointer, and it needs to be, that's equivalent to |
| 1093 | running out of memory. */ | 1097 | running out of memory. */ |
| @@ -1141,7 +1145,7 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) | |||
| 1141 | } | 1145 | } |
| 1142 | 1146 | ||
| 1143 | static void | 1147 | static void |
| 1144 | lisp_align_free (POINTER_TYPE *block) | 1148 | lisp_align_free (void *block) |
| 1145 | { | 1149 | { |
| 1146 | struct ablock *ablock = block; | 1150 | struct ablock *ablock = block; |
| 1147 | struct ablocks *abase = ABLOCK_ABASE (ablock); | 1151 | struct ablocks *abase = ABLOCK_ABASE (ablock); |
| @@ -1580,35 +1584,6 @@ mark_interval_tree (register INTERVAL tree) | |||
| 1580 | if (! NULL_INTERVAL_P (i)) \ | 1584 | if (! NULL_INTERVAL_P (i)) \ |
| 1581 | (i) = balance_intervals (i); \ | 1585 | (i) = balance_intervals (i); \ |
| 1582 | } while (0) | 1586 | } while (0) |
| 1583 | |||
| 1584 | |||
| 1585 | /* Number support. If USE_LISP_UNION_TYPE is in effect, we | ||
| 1586 | can't create number objects in macros. */ | ||
| 1587 | #ifndef make_number | ||
| 1588 | Lisp_Object | ||
| 1589 | make_number (EMACS_INT n) | ||
| 1590 | { | ||
| 1591 | Lisp_Object obj; | ||
| 1592 | obj.s.val = n; | ||
| 1593 | obj.s.type = Lisp_Int; | ||
| 1594 | return obj; | ||
| 1595 | } | ||
| 1596 | #endif | ||
| 1597 | |||
| 1598 | /* Convert the pointer-sized word P to EMACS_INT while preserving its | ||
| 1599 | type and ptr fields. */ | ||
| 1600 | static Lisp_Object | ||
| 1601 | widen_to_Lisp_Object (void *p) | ||
| 1602 | { | ||
| 1603 | intptr_t i = (intptr_t) p; | ||
| 1604 | #ifdef USE_LISP_UNION_TYPE | ||
| 1605 | Lisp_Object obj; | ||
| 1606 | obj.i = i; | ||
| 1607 | return obj; | ||
| 1608 | #else | ||
| 1609 | return i; | ||
| 1610 | #endif | ||
| 1611 | } | ||
| 1612 | 1587 | ||
| 1613 | /*********************************************************************** | 1588 | /*********************************************************************** |
| 1614 | String Allocation | 1589 | String Allocation |
| @@ -1662,7 +1637,7 @@ struct sdata | |||
| 1662 | 1637 | ||
| 1663 | #ifdef GC_CHECK_STRING_BYTES | 1638 | #ifdef GC_CHECK_STRING_BYTES |
| 1664 | 1639 | ||
| 1665 | EMACS_INT nbytes; | 1640 | ptrdiff_t nbytes; |
| 1666 | unsigned char data[1]; | 1641 | unsigned char data[1]; |
| 1667 | 1642 | ||
| 1668 | #define SDATA_NBYTES(S) (S)->nbytes | 1643 | #define SDATA_NBYTES(S) (S)->nbytes |
| @@ -1677,7 +1652,7 @@ struct sdata | |||
| 1677 | unsigned char data[1]; | 1652 | unsigned char data[1]; |
| 1678 | 1653 | ||
| 1679 | /* When STRING is null. */ | 1654 | /* When STRING is null. */ |
| 1680 | EMACS_INT nbytes; | 1655 | ptrdiff_t nbytes; |
| 1681 | } u; | 1656 | } u; |
| 1682 | 1657 | ||
| 1683 | #define SDATA_NBYTES(S) (S)->u.nbytes | 1658 | #define SDATA_NBYTES(S) (S)->u.nbytes |
| @@ -1787,24 +1762,24 @@ static char const string_overrun_cookie[GC_STRING_OVERRUN_COOKIE_SIZE] = | |||
| 1787 | #define SDATA_SIZE(NBYTES) \ | 1762 | #define SDATA_SIZE(NBYTES) \ |
| 1788 | ((SDATA_DATA_OFFSET \ | 1763 | ((SDATA_DATA_OFFSET \ |
| 1789 | + (NBYTES) + 1 \ | 1764 | + (NBYTES) + 1 \ |
| 1790 | + sizeof (EMACS_INT) - 1) \ | 1765 | + sizeof (ptrdiff_t) - 1) \ |
| 1791 | & ~(sizeof (EMACS_INT) - 1)) | 1766 | & ~(sizeof (ptrdiff_t) - 1)) |
| 1792 | 1767 | ||
| 1793 | #else /* not GC_CHECK_STRING_BYTES */ | 1768 | #else /* not GC_CHECK_STRING_BYTES */ |
| 1794 | 1769 | ||
| 1795 | /* The 'max' reserves space for the nbytes union member even when NBYTES + 1 is | 1770 | /* The 'max' reserves space for the nbytes union member even when NBYTES + 1 is |
| 1796 | less than the size of that member. The 'max' is not needed when | 1771 | less than the size of that member. The 'max' is not needed when |
| 1797 | SDATA_DATA_OFFSET is a multiple of sizeof (EMACS_INT), because then the | 1772 | SDATA_DATA_OFFSET is a multiple of sizeof (ptrdiff_t), because then the |
| 1798 | alignment code reserves enough space. */ | 1773 | alignment code reserves enough space. */ |
| 1799 | 1774 | ||
| 1800 | #define SDATA_SIZE(NBYTES) \ | 1775 | #define SDATA_SIZE(NBYTES) \ |
| 1801 | ((SDATA_DATA_OFFSET \ | 1776 | ((SDATA_DATA_OFFSET \ |
| 1802 | + (SDATA_DATA_OFFSET % sizeof (EMACS_INT) == 0 \ | 1777 | + (SDATA_DATA_OFFSET % sizeof (ptrdiff_t) == 0 \ |
| 1803 | ? NBYTES \ | 1778 | ? NBYTES \ |
| 1804 | : max (NBYTES, sizeof (EMACS_INT) - 1)) \ | 1779 | : max (NBYTES, sizeof (ptrdiff_t) - 1)) \ |
| 1805 | + 1 \ | 1780 | + 1 \ |
| 1806 | + sizeof (EMACS_INT) - 1) \ | 1781 | + sizeof (ptrdiff_t) - 1) \ |
| 1807 | & ~(sizeof (EMACS_INT) - 1)) | 1782 | & ~(sizeof (ptrdiff_t) - 1)) |
| 1808 | 1783 | ||
| 1809 | #endif /* not GC_CHECK_STRING_BYTES */ | 1784 | #endif /* not GC_CHECK_STRING_BYTES */ |
| 1810 | 1785 | ||
| @@ -1848,10 +1823,10 @@ static int check_string_bytes_count; | |||
| 1848 | 1823 | ||
| 1849 | /* Like GC_STRING_BYTES, but with debugging check. */ | 1824 | /* Like GC_STRING_BYTES, but with debugging check. */ |
| 1850 | 1825 | ||
| 1851 | EMACS_INT | 1826 | ptrdiff_t |
| 1852 | string_bytes (struct Lisp_String *s) | 1827 | string_bytes (struct Lisp_String *s) |
| 1853 | { | 1828 | { |
| 1854 | EMACS_INT nbytes = | 1829 | ptrdiff_t nbytes = |
| 1855 | (s->size_byte < 0 ? s->size & ~ARRAY_MARK_FLAG : s->size_byte); | 1830 | (s->size_byte < 0 ? s->size & ~ARRAY_MARK_FLAG : s->size_byte); |
| 1856 | 1831 | ||
| 1857 | if (!PURE_POINTER_P (s) | 1832 | if (!PURE_POINTER_P (s) |
| @@ -1874,7 +1849,7 @@ check_sblock (struct sblock *b) | |||
| 1874 | { | 1849 | { |
| 1875 | /* Compute the next FROM here because copying below may | 1850 | /* Compute the next FROM here because copying below may |
| 1876 | overwrite data we need to compute it. */ | 1851 | overwrite data we need to compute it. */ |
| 1877 | EMACS_INT nbytes; | 1852 | ptrdiff_t nbytes; |
| 1878 | 1853 | ||
| 1879 | /* Check that the string size recorded in the string is the | 1854 | /* Check that the string size recorded in the string is the |
| 1880 | same as the one recorded in the sdata structure. */ | 1855 | same as the one recorded in the sdata structure. */ |
| @@ -2020,7 +1995,7 @@ allocate_string_data (struct Lisp_String *s, | |||
| 2020 | { | 1995 | { |
| 2021 | struct sdata *data, *old_data; | 1996 | struct sdata *data, *old_data; |
| 2022 | struct sblock *b; | 1997 | struct sblock *b; |
| 2023 | EMACS_INT needed, old_nbytes; | 1998 | ptrdiff_t needed, old_nbytes; |
| 2024 | 1999 | ||
| 2025 | if (STRING_BYTES_MAX < nbytes) | 2000 | if (STRING_BYTES_MAX < nbytes) |
| 2026 | string_overflow (); | 2001 | string_overflow (); |
| @@ -2265,7 +2240,7 @@ compact_small_strings (void) | |||
| 2265 | { | 2240 | { |
| 2266 | /* Compute the next FROM here because copying below may | 2241 | /* Compute the next FROM here because copying below may |
| 2267 | overwrite data we need to compute it. */ | 2242 | overwrite data we need to compute it. */ |
| 2268 | EMACS_INT nbytes; | 2243 | ptrdiff_t nbytes; |
| 2269 | 2244 | ||
| 2270 | #ifdef GC_CHECK_STRING_BYTES | 2245 | #ifdef GC_CHECK_STRING_BYTES |
| 2271 | /* Check that the string size recorded in the string is the | 2246 | /* Check that the string size recorded in the string is the |
| @@ -2395,7 +2370,8 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */) | |||
| 2395 | { | 2370 | { |
| 2396 | register Lisp_Object val; | 2371 | register Lisp_Object val; |
| 2397 | struct Lisp_Bool_Vector *p; | 2372 | struct Lisp_Bool_Vector *p; |
| 2398 | EMACS_INT length_in_chars, length_in_elts; | 2373 | ptrdiff_t length_in_chars; |
| 2374 | EMACS_INT length_in_elts; | ||
| 2399 | int bits_per_value; | 2375 | int bits_per_value; |
| 2400 | 2376 | ||
| 2401 | CHECK_NATNUM (length); | 2377 | CHECK_NATNUM (length); |
| @@ -2403,8 +2379,6 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */) | |||
| 2403 | bits_per_value = sizeof (EMACS_INT) * BOOL_VECTOR_BITS_PER_CHAR; | 2379 | bits_per_value = sizeof (EMACS_INT) * BOOL_VECTOR_BITS_PER_CHAR; |
| 2404 | 2380 | ||
| 2405 | length_in_elts = (XFASTINT (length) + bits_per_value - 1) / bits_per_value; | 2381 | length_in_elts = (XFASTINT (length) + bits_per_value - 1) / bits_per_value; |
| 2406 | length_in_chars = ((XFASTINT (length) + BOOL_VECTOR_BITS_PER_CHAR - 1) | ||
| 2407 | / BOOL_VECTOR_BITS_PER_CHAR); | ||
| 2408 | 2382 | ||
| 2409 | /* We must allocate one more elements than LENGTH_IN_ELTS for the | 2383 | /* We must allocate one more elements than LENGTH_IN_ELTS for the |
| 2410 | slot `size' of the struct Lisp_Bool_Vector. */ | 2384 | slot `size' of the struct Lisp_Bool_Vector. */ |
| @@ -2416,6 +2390,8 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */) | |||
| 2416 | p = XBOOL_VECTOR (val); | 2390 | p = XBOOL_VECTOR (val); |
| 2417 | p->size = XFASTINT (length); | 2391 | p->size = XFASTINT (length); |
| 2418 | 2392 | ||
| 2393 | length_in_chars = ((XFASTINT (length) + BOOL_VECTOR_BITS_PER_CHAR - 1) | ||
| 2394 | / BOOL_VECTOR_BITS_PER_CHAR); | ||
| 2419 | if (length_in_chars) | 2395 | if (length_in_chars) |
| 2420 | { | 2396 | { |
| 2421 | memset (p->data, ! NILP (init) ? -1 : 0, length_in_chars); | 2397 | memset (p->data, ! NILP (init) ? -1 : 0, length_in_chars); |
| @@ -2434,10 +2410,10 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */) | |||
| 2434 | multibyte, depending on the contents. */ | 2410 | multibyte, depending on the contents. */ |
| 2435 | 2411 | ||
| 2436 | Lisp_Object | 2412 | Lisp_Object |
| 2437 | make_string (const char *contents, EMACS_INT nbytes) | 2413 | make_string (const char *contents, ptrdiff_t nbytes) |
| 2438 | { | 2414 | { |
| 2439 | register Lisp_Object val; | 2415 | register Lisp_Object val; |
| 2440 | EMACS_INT nchars, multibyte_nbytes; | 2416 | ptrdiff_t nchars, multibyte_nbytes; |
| 2441 | 2417 | ||
| 2442 | parse_str_as_multibyte ((const unsigned char *) contents, nbytes, | 2418 | parse_str_as_multibyte ((const unsigned char *) contents, nbytes, |
| 2443 | &nchars, &multibyte_nbytes); | 2419 | &nchars, &multibyte_nbytes); |
| @@ -2454,7 +2430,7 @@ make_string (const char *contents, EMACS_INT nbytes) | |||
| 2454 | /* Make an unibyte string from LENGTH bytes at CONTENTS. */ | 2430 | /* Make an unibyte string from LENGTH bytes at CONTENTS. */ |
| 2455 | 2431 | ||
| 2456 | Lisp_Object | 2432 | Lisp_Object |
| 2457 | make_unibyte_string (const char *contents, EMACS_INT length) | 2433 | make_unibyte_string (const char *contents, ptrdiff_t length) |
| 2458 | { | 2434 | { |
| 2459 | register Lisp_Object val; | 2435 | register Lisp_Object val; |
| 2460 | val = make_uninit_string (length); | 2436 | val = make_uninit_string (length); |
| @@ -2468,7 +2444,7 @@ make_unibyte_string (const char *contents, EMACS_INT length) | |||
| 2468 | 2444 | ||
| 2469 | Lisp_Object | 2445 | Lisp_Object |
| 2470 | make_multibyte_string (const char *contents, | 2446 | make_multibyte_string (const char *contents, |
| 2471 | EMACS_INT nchars, EMACS_INT nbytes) | 2447 | ptrdiff_t nchars, ptrdiff_t nbytes) |
| 2472 | { | 2448 | { |
| 2473 | register Lisp_Object val; | 2449 | register Lisp_Object val; |
| 2474 | val = make_uninit_multibyte_string (nchars, nbytes); | 2450 | val = make_uninit_multibyte_string (nchars, nbytes); |
| @@ -2482,7 +2458,7 @@ make_multibyte_string (const char *contents, | |||
| 2482 | 2458 | ||
| 2483 | Lisp_Object | 2459 | Lisp_Object |
| 2484 | make_string_from_bytes (const char *contents, | 2460 | make_string_from_bytes (const char *contents, |
| 2485 | EMACS_INT nchars, EMACS_INT nbytes) | 2461 | ptrdiff_t nchars, ptrdiff_t nbytes) |
| 2486 | { | 2462 | { |
| 2487 | register Lisp_Object val; | 2463 | register Lisp_Object val; |
| 2488 | val = make_uninit_multibyte_string (nchars, nbytes); | 2464 | val = make_uninit_multibyte_string (nchars, nbytes); |
| @@ -2500,7 +2476,7 @@ make_string_from_bytes (const char *contents, | |||
| 2500 | 2476 | ||
| 2501 | Lisp_Object | 2477 | Lisp_Object |
| 2502 | make_specified_string (const char *contents, | 2478 | make_specified_string (const char *contents, |
| 2503 | EMACS_INT nchars, EMACS_INT nbytes, int multibyte) | 2479 | ptrdiff_t nchars, ptrdiff_t nbytes, int multibyte) |
| 2504 | { | 2480 | { |
| 2505 | register Lisp_Object val; | 2481 | register Lisp_Object val; |
| 2506 | 2482 | ||
| @@ -2699,8 +2675,10 @@ make_float (double float_value) | |||
| 2699 | GC are put on a free list to be reallocated before allocating | 2675 | GC are put on a free list to be reallocated before allocating |
| 2700 | any new cons cells from the latest cons_block. */ | 2676 | any new cons cells from the latest cons_block. */ |
| 2701 | 2677 | ||
| 2702 | #define CONS_BLOCK_SIZE \ | 2678 | #define CONS_BLOCK_SIZE \ |
| 2703 | (((BLOCK_BYTES - sizeof (struct cons_block *)) * CHAR_BIT) \ | 2679 | (((BLOCK_BYTES - sizeof (struct cons_block *) \ |
| 2680 | /* The compiler might add padding at the end. */ \ | ||
| 2681 | - (sizeof (struct Lisp_Cons) - sizeof (int))) * CHAR_BIT) \ | ||
| 2704 | / (sizeof (struct Lisp_Cons) * CHAR_BIT + 1)) | 2682 | / (sizeof (struct Lisp_Cons) * CHAR_BIT + 1)) |
| 2705 | 2683 | ||
| 2706 | #define CONS_BLOCK(fptr) \ | 2684 | #define CONS_BLOCK(fptr) \ |
| @@ -2924,22 +2902,307 @@ DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0, | |||
| 2924 | Vector Allocation | 2902 | Vector Allocation |
| 2925 | ***********************************************************************/ | 2903 | ***********************************************************************/ |
| 2926 | 2904 | ||
| 2927 | /* Singly-linked list of all vectors. */ | 2905 | /* This value is balanced well enough to avoid too much internal overhead |
| 2906 | for the most common cases; it's not required to be a power of two, but | ||
| 2907 | it's expected to be a mult-of-ROUNDUP_SIZE (see below). */ | ||
| 2928 | 2908 | ||
| 2929 | static struct Lisp_Vector *all_vectors; | 2909 | #define VECTOR_BLOCK_SIZE 4096 |
| 2930 | 2910 | ||
| 2931 | /* Handy constants for vectorlike objects. */ | 2911 | /* Handy constants for vectorlike objects. */ |
| 2932 | enum | 2912 | enum |
| 2933 | { | 2913 | { |
| 2934 | header_size = offsetof (struct Lisp_Vector, contents), | 2914 | header_size = offsetof (struct Lisp_Vector, contents), |
| 2935 | word_size = sizeof (Lisp_Object) | 2915 | word_size = sizeof (Lisp_Object), |
| 2916 | roundup_size = COMMON_MULTIPLE (sizeof (Lisp_Object), | ||
| 2917 | USE_LSB_TAG ? 1 << GCTYPEBITS : 1) | ||
| 2936 | }; | 2918 | }; |
| 2937 | 2919 | ||
| 2920 | /* ROUNDUP_SIZE must be a power of 2. */ | ||
| 2921 | verify ((roundup_size & (roundup_size - 1)) == 0); | ||
| 2922 | |||
| 2923 | /* Round up X to nearest mult-of-ROUNDUP_SIZE. */ | ||
| 2924 | |||
| 2925 | #define vroundup(x) (((x) + (roundup_size - 1)) & ~(roundup_size - 1)) | ||
| 2926 | |||
| 2927 | /* Rounding helps to maintain alignment constraints if USE_LSB_TAG. */ | ||
| 2928 | |||
| 2929 | #define VECTOR_BLOCK_BYTES (VECTOR_BLOCK_SIZE - vroundup (sizeof (void *))) | ||
| 2930 | |||
| 2931 | /* Size of the minimal vector allocated from block. */ | ||
| 2932 | |||
| 2933 | #define VBLOCK_BYTES_MIN vroundup (sizeof (struct Lisp_Vector)) | ||
| 2934 | |||
| 2935 | /* Size of the largest vector allocated from block. */ | ||
| 2936 | |||
| 2937 | #define VBLOCK_BYTES_MAX \ | ||
| 2938 | vroundup ((VECTOR_BLOCK_BYTES / 2) - sizeof (Lisp_Object)) | ||
| 2939 | |||
| 2940 | /* We maintain one free list for each possible block-allocated | ||
| 2941 | vector size, and this is the number of free lists we have. */ | ||
| 2942 | |||
| 2943 | #define VECTOR_MAX_FREE_LIST_INDEX \ | ||
| 2944 | ((VECTOR_BLOCK_BYTES - VBLOCK_BYTES_MIN) / roundup_size + 1) | ||
| 2945 | |||
| 2946 | /* When the vector is on a free list, vectorlike_header.SIZE is set to | ||
| 2947 | this special value ORed with vector's memory footprint size. */ | ||
| 2948 | |||
| 2949 | #define VECTOR_FREE_LIST_FLAG (~(ARRAY_MARK_FLAG | PSEUDOVECTOR_FLAG \ | ||
| 2950 | | (VECTOR_BLOCK_SIZE - 1))) | ||
| 2951 | |||
| 2952 | /* Common shortcut to advance vector pointer over a block data. */ | ||
| 2953 | |||
| 2954 | #define ADVANCE(v, nbytes) ((struct Lisp_Vector *) ((char *) (v) + (nbytes))) | ||
| 2955 | |||
| 2956 | /* Common shortcut to calculate NBYTES-vector index in VECTOR_FREE_LISTS. */ | ||
| 2957 | |||
| 2958 | #define VINDEX(nbytes) (((nbytes) - VBLOCK_BYTES_MIN) / roundup_size) | ||
| 2959 | |||
| 2960 | /* Common shortcut to setup vector on a free list. */ | ||
| 2961 | |||
| 2962 | #define SETUP_ON_FREE_LIST(v, nbytes, index) \ | ||
| 2963 | do { \ | ||
| 2964 | (v)->header.size = VECTOR_FREE_LIST_FLAG | (nbytes); \ | ||
| 2965 | eassert ((nbytes) % roundup_size == 0); \ | ||
| 2966 | (index) = VINDEX (nbytes); \ | ||
| 2967 | eassert ((index) < VECTOR_MAX_FREE_LIST_INDEX); \ | ||
| 2968 | (v)->header.next.vector = vector_free_lists[index]; \ | ||
| 2969 | vector_free_lists[index] = (v); \ | ||
| 2970 | } while (0) | ||
| 2971 | |||
| 2972 | struct vector_block | ||
| 2973 | { | ||
| 2974 | char data[VECTOR_BLOCK_BYTES]; | ||
| 2975 | struct vector_block *next; | ||
| 2976 | }; | ||
| 2977 | |||
| 2978 | /* Chain of vector blocks. */ | ||
| 2979 | |||
| 2980 | static struct vector_block *vector_blocks; | ||
| 2981 | |||
| 2982 | /* Vector free lists, where NTH item points to a chain of free | ||
| 2983 | vectors of the same NBYTES size, so NTH == VINDEX (NBYTES). */ | ||
| 2984 | |||
| 2985 | static struct Lisp_Vector *vector_free_lists[VECTOR_MAX_FREE_LIST_INDEX]; | ||
| 2986 | |||
| 2987 | /* Singly-linked list of large vectors. */ | ||
| 2988 | |||
| 2989 | static struct Lisp_Vector *large_vectors; | ||
| 2990 | |||
| 2991 | /* The only vector with 0 slots, allocated from pure space. */ | ||
| 2992 | |||
| 2993 | static struct Lisp_Vector *zero_vector; | ||
| 2994 | |||
| 2995 | /* Get a new vector block. */ | ||
| 2996 | |||
| 2997 | static struct vector_block * | ||
| 2998 | allocate_vector_block (void) | ||
| 2999 | { | ||
| 3000 | struct vector_block *block; | ||
| 3001 | |||
| 3002 | #ifdef DOUG_LEA_MALLOC | ||
| 3003 | mallopt (M_MMAP_MAX, 0); | ||
| 3004 | #endif | ||
| 3005 | |||
| 3006 | block = xmalloc (sizeof (struct vector_block)); | ||
| 3007 | |||
| 3008 | #ifdef DOUG_LEA_MALLOC | ||
| 3009 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); | ||
| 3010 | #endif | ||
| 3011 | |||
| 3012 | #if GC_MARK_STACK && !defined GC_MALLOC_CHECK | ||
| 3013 | mem_insert (block->data, block->data + VECTOR_BLOCK_BYTES, | ||
| 3014 | MEM_TYPE_VECTOR_BLOCK); | ||
| 3015 | #endif | ||
| 3016 | |||
| 3017 | block->next = vector_blocks; | ||
| 3018 | vector_blocks = block; | ||
| 3019 | return block; | ||
| 3020 | } | ||
| 3021 | |||
| 3022 | /* Called once to initialize vector allocation. */ | ||
| 3023 | |||
| 3024 | static void | ||
| 3025 | init_vectors (void) | ||
| 3026 | { | ||
| 3027 | zero_vector = pure_alloc (header_size, Lisp_Vectorlike); | ||
| 3028 | zero_vector->header.size = 0; | ||
| 3029 | } | ||
| 3030 | |||
| 3031 | /* Allocate vector from a vector block. */ | ||
| 3032 | |||
| 3033 | static struct Lisp_Vector * | ||
| 3034 | allocate_vector_from_block (size_t nbytes) | ||
| 3035 | { | ||
| 3036 | struct Lisp_Vector *vector, *rest; | ||
| 3037 | struct vector_block *block; | ||
| 3038 | size_t index, restbytes; | ||
| 3039 | |||
| 3040 | eassert (VBLOCK_BYTES_MIN <= nbytes && nbytes <= VBLOCK_BYTES_MAX); | ||
| 3041 | eassert (nbytes % roundup_size == 0); | ||
| 3042 | |||
| 3043 | /* First, try to allocate from a free list | ||
| 3044 | containing vectors of the requested size. */ | ||
| 3045 | index = VINDEX (nbytes); | ||
| 3046 | if (vector_free_lists[index]) | ||
| 3047 | { | ||
| 3048 | vector = vector_free_lists[index]; | ||
| 3049 | vector_free_lists[index] = vector->header.next.vector; | ||
| 3050 | vector->header.next.nbytes = nbytes; | ||
| 3051 | return vector; | ||
| 3052 | } | ||
| 3053 | |||
| 3054 | /* Next, check free lists containing larger vectors. Since | ||
| 3055 | we will split the result, we should have remaining space | ||
| 3056 | large enough to use for one-slot vector at least. */ | ||
| 3057 | for (index = VINDEX (nbytes + VBLOCK_BYTES_MIN); | ||
| 3058 | index < VECTOR_MAX_FREE_LIST_INDEX; index++) | ||
| 3059 | if (vector_free_lists[index]) | ||
| 3060 | { | ||
| 3061 | /* This vector is larger than requested. */ | ||
| 3062 | vector = vector_free_lists[index]; | ||
| 3063 | vector_free_lists[index] = vector->header.next.vector; | ||
| 3064 | vector->header.next.nbytes = nbytes; | ||
| 3065 | |||
| 3066 | /* Excess bytes are used for the smaller vector, | ||
| 3067 | which should be set on an appropriate free list. */ | ||
| 3068 | restbytes = index * roundup_size + VBLOCK_BYTES_MIN - nbytes; | ||
| 3069 | eassert (restbytes % roundup_size == 0); | ||
| 3070 | rest = ADVANCE (vector, nbytes); | ||
| 3071 | SETUP_ON_FREE_LIST (rest, restbytes, index); | ||
| 3072 | return vector; | ||
| 3073 | } | ||
| 3074 | |||
| 3075 | /* Finally, need a new vector block. */ | ||
| 3076 | block = allocate_vector_block (); | ||
| 3077 | |||
| 3078 | /* New vector will be at the beginning of this block. */ | ||
| 3079 | vector = (struct Lisp_Vector *) block->data; | ||
| 3080 | vector->header.next.nbytes = nbytes; | ||
| 3081 | |||
| 3082 | /* If the rest of space from this block is large enough | ||
| 3083 | for one-slot vector at least, set up it on a free list. */ | ||
| 3084 | restbytes = VECTOR_BLOCK_BYTES - nbytes; | ||
| 3085 | if (restbytes >= VBLOCK_BYTES_MIN) | ||
| 3086 | { | ||
| 3087 | eassert (restbytes % roundup_size == 0); | ||
| 3088 | rest = ADVANCE (vector, nbytes); | ||
| 3089 | SETUP_ON_FREE_LIST (rest, restbytes, index); | ||
| 3090 | } | ||
| 3091 | return vector; | ||
| 3092 | } | ||
| 3093 | |||
| 3094 | /* Return how many Lisp_Objects can be stored in V. */ | ||
| 3095 | |||
| 3096 | #define VECTOR_SIZE(v) ((v)->header.size & PSEUDOVECTOR_FLAG ? \ | ||
| 3097 | (PSEUDOVECTOR_SIZE_MASK & (v)->header.size) : \ | ||
| 3098 | (v)->header.size) | ||
| 3099 | |||
| 3100 | /* Nonzero if VECTOR pointer is valid pointer inside BLOCK. */ | ||
| 3101 | |||
| 3102 | #define VECTOR_IN_BLOCK(vector, block) \ | ||
| 3103 | ((char *) (vector) <= (block)->data \ | ||
| 3104 | + VECTOR_BLOCK_BYTES - VBLOCK_BYTES_MIN) | ||
| 3105 | |||
| 3106 | /* Reclaim space used by unmarked vectors. */ | ||
| 3107 | |||
| 3108 | static void | ||
| 3109 | sweep_vectors (void) | ||
| 3110 | { | ||
| 3111 | struct vector_block *block = vector_blocks, **bprev = &vector_blocks; | ||
| 3112 | struct Lisp_Vector *vector, *next, **vprev = &large_vectors; | ||
| 3113 | |||
| 3114 | total_vector_size = 0; | ||
| 3115 | memset (vector_free_lists, 0, sizeof (vector_free_lists)); | ||
| 3116 | |||
| 3117 | /* Looking through vector blocks. */ | ||
| 3118 | |||
| 3119 | for (block = vector_blocks; block; block = *bprev) | ||
| 3120 | { | ||
| 3121 | int free_this_block = 0; | ||
| 3122 | |||
| 3123 | for (vector = (struct Lisp_Vector *) block->data; | ||
| 3124 | VECTOR_IN_BLOCK (vector, block); vector = next) | ||
| 3125 | { | ||
| 3126 | if (VECTOR_MARKED_P (vector)) | ||
| 3127 | { | ||
| 3128 | VECTOR_UNMARK (vector); | ||
| 3129 | total_vector_size += VECTOR_SIZE (vector); | ||
| 3130 | next = ADVANCE (vector, vector->header.next.nbytes); | ||
| 3131 | } | ||
| 3132 | else | ||
| 3133 | { | ||
| 3134 | ptrdiff_t nbytes; | ||
| 3135 | |||
| 3136 | if ((vector->header.size & VECTOR_FREE_LIST_FLAG) | ||
| 3137 | == VECTOR_FREE_LIST_FLAG) | ||
| 3138 | vector->header.next.nbytes = | ||
| 3139 | vector->header.size & (VECTOR_BLOCK_SIZE - 1); | ||
| 3140 | |||
| 3141 | next = ADVANCE (vector, vector->header.next.nbytes); | ||
| 3142 | |||
| 3143 | /* While NEXT is not marked, try to coalesce with VECTOR, | ||
| 3144 | thus making VECTOR of the largest possible size. */ | ||
| 3145 | |||
| 3146 | while (VECTOR_IN_BLOCK (next, block)) | ||
| 3147 | { | ||
| 3148 | if (VECTOR_MARKED_P (next)) | ||
| 3149 | break; | ||
| 3150 | if ((next->header.size & VECTOR_FREE_LIST_FLAG) | ||
| 3151 | == VECTOR_FREE_LIST_FLAG) | ||
| 3152 | nbytes = next->header.size & (VECTOR_BLOCK_SIZE - 1); | ||
| 3153 | else | ||
| 3154 | nbytes = next->header.next.nbytes; | ||
| 3155 | vector->header.next.nbytes += nbytes; | ||
| 3156 | next = ADVANCE (next, nbytes); | ||
| 3157 | } | ||
| 3158 | |||
| 3159 | eassert (vector->header.next.nbytes % roundup_size == 0); | ||
| 3160 | |||
| 3161 | if (vector == (struct Lisp_Vector *) block->data | ||
| 3162 | && !VECTOR_IN_BLOCK (next, block)) | ||
| 3163 | /* This block should be freed because all of it's | ||
| 3164 | space was coalesced into the only free vector. */ | ||
| 3165 | free_this_block = 1; | ||
| 3166 | else | ||
| 3167 | SETUP_ON_FREE_LIST (vector, vector->header.next.nbytes, nbytes); | ||
| 3168 | } | ||
| 3169 | } | ||
| 3170 | |||
| 3171 | if (free_this_block) | ||
| 3172 | { | ||
| 3173 | *bprev = block->next; | ||
| 3174 | #if GC_MARK_STACK && !defined GC_MALLOC_CHECK | ||
| 3175 | mem_delete (mem_find (block->data)); | ||
| 3176 | #endif | ||
| 3177 | xfree (block); | ||
| 3178 | } | ||
| 3179 | else | ||
| 3180 | bprev = &block->next; | ||
| 3181 | } | ||
| 3182 | |||
| 3183 | /* Sweep large vectors. */ | ||
| 3184 | |||
| 3185 | for (vector = large_vectors; vector; vector = *vprev) | ||
| 3186 | { | ||
| 3187 | if (VECTOR_MARKED_P (vector)) | ||
| 3188 | { | ||
| 3189 | VECTOR_UNMARK (vector); | ||
| 3190 | total_vector_size += VECTOR_SIZE (vector); | ||
| 3191 | vprev = &vector->header.next.vector; | ||
| 3192 | } | ||
| 3193 | else | ||
| 3194 | { | ||
| 3195 | *vprev = vector->header.next.vector; | ||
| 3196 | lisp_free (vector); | ||
| 3197 | } | ||
| 3198 | } | ||
| 3199 | } | ||
| 3200 | |||
| 2938 | /* Value is a pointer to a newly allocated Lisp_Vector structure | 3201 | /* Value is a pointer to a newly allocated Lisp_Vector structure |
| 2939 | with room for LEN Lisp_Objects. */ | 3202 | with room for LEN Lisp_Objects. */ |
| 2940 | 3203 | ||
| 2941 | static struct Lisp_Vector * | 3204 | static struct Lisp_Vector * |
| 2942 | allocate_vectorlike (EMACS_INT len) | 3205 | allocate_vectorlike (ptrdiff_t len) |
| 2943 | { | 3206 | { |
| 2944 | struct Lisp_Vector *p; | 3207 | struct Lisp_Vector *p; |
| 2945 | size_t nbytes; | 3208 | size_t nbytes; |
| @@ -2956,8 +3219,22 @@ allocate_vectorlike (EMACS_INT len) | |||
| 2956 | /* This gets triggered by code which I haven't bothered to fix. --Stef */ | 3219 | /* This gets triggered by code which I haven't bothered to fix. --Stef */ |
| 2957 | /* eassert (!handling_signal); */ | 3220 | /* eassert (!handling_signal); */ |
| 2958 | 3221 | ||
| 3222 | if (len == 0) | ||
| 3223 | { | ||
| 3224 | MALLOC_UNBLOCK_INPUT; | ||
| 3225 | return zero_vector; | ||
| 3226 | } | ||
| 3227 | |||
| 2959 | nbytes = header_size + len * word_size; | 3228 | nbytes = header_size + len * word_size; |
| 2960 | p = (struct Lisp_Vector *) lisp_malloc (nbytes, MEM_TYPE_VECTORLIKE); | 3229 | |
| 3230 | if (nbytes <= VBLOCK_BYTES_MAX) | ||
| 3231 | p = allocate_vector_from_block (vroundup (nbytes)); | ||
| 3232 | else | ||
| 3233 | { | ||
| 3234 | p = (struct Lisp_Vector *) lisp_malloc (nbytes, MEM_TYPE_VECTORLIKE); | ||
| 3235 | p->header.next.vector = large_vectors; | ||
| 3236 | large_vectors = p; | ||
| 3237 | } | ||
| 2961 | 3238 | ||
| 2962 | #ifdef DOUG_LEA_MALLOC | 3239 | #ifdef DOUG_LEA_MALLOC |
| 2963 | /* Back to a reasonable maximum of mmap'ed areas. */ | 3240 | /* Back to a reasonable maximum of mmap'ed areas. */ |
| @@ -2967,9 +3244,6 @@ allocate_vectorlike (EMACS_INT len) | |||
| 2967 | consing_since_gc += nbytes; | 3244 | consing_since_gc += nbytes; |
| 2968 | vector_cells_consed += len; | 3245 | vector_cells_consed += len; |
| 2969 | 3246 | ||
| 2970 | p->header.next.vector = all_vectors; | ||
| 2971 | all_vectors = p; | ||
| 2972 | |||
| 2973 | MALLOC_UNBLOCK_INPUT; | 3247 | MALLOC_UNBLOCK_INPUT; |
| 2974 | 3248 | ||
| 2975 | return p; | 3249 | return p; |
| @@ -2995,7 +3269,7 @@ allocate_vector (EMACS_INT len) | |||
| 2995 | /* Allocate other vector-like structures. */ | 3269 | /* Allocate other vector-like structures. */ |
| 2996 | 3270 | ||
| 2997 | struct Lisp_Vector * | 3271 | struct Lisp_Vector * |
| 2998 | allocate_pseudovector (int memlen, int lisplen, EMACS_INT tag) | 3272 | allocate_pseudovector (int memlen, int lisplen, int tag) |
| 2999 | { | 3273 | { |
| 3000 | struct Lisp_Vector *v = allocate_vectorlike (memlen); | 3274 | struct Lisp_Vector *v = allocate_vectorlike (memlen); |
| 3001 | int i; | 3275 | int i; |
| @@ -3059,14 +3333,14 @@ See also the function `vector'. */) | |||
| 3059 | (register Lisp_Object length, Lisp_Object init) | 3333 | (register Lisp_Object length, Lisp_Object init) |
| 3060 | { | 3334 | { |
| 3061 | Lisp_Object vector; | 3335 | Lisp_Object vector; |
| 3062 | register EMACS_INT sizei; | 3336 | register ptrdiff_t sizei; |
| 3063 | register EMACS_INT i; | 3337 | register ptrdiff_t i; |
| 3064 | register struct Lisp_Vector *p; | 3338 | register struct Lisp_Vector *p; |
| 3065 | 3339 | ||
| 3066 | CHECK_NATNUM (length); | 3340 | CHECK_NATNUM (length); |
| 3067 | sizei = XFASTINT (length); | ||
| 3068 | 3341 | ||
| 3069 | p = allocate_vector (sizei); | 3342 | p = allocate_vector (XFASTINT (length)); |
| 3343 | sizei = XFASTINT (length); | ||
| 3070 | for (i = 0; i < sizei; i++) | 3344 | for (i = 0; i < sizei; i++) |
| 3071 | p->contents[i] = init; | 3345 | p->contents[i] = init; |
| 3072 | 3346 | ||
| @@ -3093,6 +3367,19 @@ usage: (vector &rest OBJECTS) */) | |||
| 3093 | return val; | 3367 | return val; |
| 3094 | } | 3368 | } |
| 3095 | 3369 | ||
| 3370 | void | ||
| 3371 | make_byte_code (struct Lisp_Vector *v) | ||
| 3372 | { | ||
| 3373 | if (v->header.size > 1 && STRINGP (v->contents[1]) | ||
| 3374 | && STRING_MULTIBYTE (v->contents[1])) | ||
| 3375 | /* BYTECODE-STRING must have been produced by Emacs 20.2 or the | ||
| 3376 | earlier because they produced a raw 8-bit string for byte-code | ||
| 3377 | and now such a byte-code string is loaded as multibyte while | ||
| 3378 | raw 8-bit characters converted to multibyte form. Thus, now we | ||
| 3379 | must convert them back to the original unibyte form. */ | ||
| 3380 | v->contents[1] = Fstring_as_unibyte (v->contents[1]); | ||
| 3381 | XSETPVECTYPE (v, PVEC_COMPILED); | ||
| 3382 | } | ||
| 3096 | 3383 | ||
| 3097 | DEFUN ("make-byte-code", Fmake_byte_code, Smake_byte_code, 4, MANY, 0, | 3384 | DEFUN ("make-byte-code", Fmake_byte_code, Smake_byte_code, 4, MANY, 0, |
| 3098 | doc: /* Create a byte-code object with specified arguments as elements. | 3385 | doc: /* Create a byte-code object with specified arguments as elements. |
| @@ -3116,28 +3403,21 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT | |||
| 3116 | ptrdiff_t i; | 3403 | ptrdiff_t i; |
| 3117 | register struct Lisp_Vector *p; | 3404 | register struct Lisp_Vector *p; |
| 3118 | 3405 | ||
| 3119 | XSETFASTINT (len, nargs); | 3406 | /* We used to purecopy everything here, if purify-flga was set. This worked |
| 3120 | if (!NILP (Vpurify_flag)) | 3407 | OK for Emacs-23, but with Emacs-24's lexical binding code, it can be |
| 3121 | val = make_pure_vector (nargs); | 3408 | dangerous, since make-byte-code is used during execution to build |
| 3122 | else | 3409 | closures, so any closure built during the preload phase would end up |
| 3123 | val = Fmake_vector (len, Qnil); | 3410 | copied into pure space, including its free variables, which is sometimes |
| 3411 | just wasteful and other times plainly wrong (e.g. those free vars may want | ||
| 3412 | to be setcar'd). */ | ||
| 3124 | 3413 | ||
| 3125 | if (nargs > 1 && STRINGP (args[1]) && STRING_MULTIBYTE (args[1])) | 3414 | XSETFASTINT (len, nargs); |
| 3126 | /* BYTECODE-STRING must have been produced by Emacs 20.2 or the | 3415 | val = Fmake_vector (len, Qnil); |
| 3127 | earlier because they produced a raw 8-bit string for byte-code | ||
| 3128 | and now such a byte-code string is loaded as multibyte while | ||
| 3129 | raw 8-bit characters converted to multibyte form. Thus, now we | ||
| 3130 | must convert them back to the original unibyte form. */ | ||
| 3131 | args[1] = Fstring_as_unibyte (args[1]); | ||
| 3132 | 3416 | ||
| 3133 | p = XVECTOR (val); | 3417 | p = XVECTOR (val); |
| 3134 | for (i = 0; i < nargs; i++) | 3418 | for (i = 0; i < nargs; i++) |
| 3135 | { | 3419 | p->contents[i] = args[i]; |
| 3136 | if (!NILP (Vpurify_flag)) | 3420 | make_byte_code (p); |
| 3137 | args[i] = Fpurecopy (args[i]); | ||
| 3138 | p->contents[i] = args[i]; | ||
| 3139 | } | ||
| 3140 | XSETPVECTYPE (p, PVEC_COMPILED); | ||
| 3141 | XSETCOMPILED (val, p); | 3421 | XSETCOMPILED (val, p); |
| 3142 | return val; | 3422 | return val; |
| 3143 | } | 3423 | } |
| @@ -3154,7 +3434,7 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT | |||
| 3154 | union aligned_Lisp_Symbol | 3434 | union aligned_Lisp_Symbol |
| 3155 | { | 3435 | { |
| 3156 | struct Lisp_Symbol s; | 3436 | struct Lisp_Symbol s; |
| 3157 | #ifdef USE_LSB_TAG | 3437 | #if USE_LSB_TAG |
| 3158 | unsigned char c[(sizeof (struct Lisp_Symbol) + (1 << GCTYPEBITS) - 1) | 3438 | unsigned char c[(sizeof (struct Lisp_Symbol) + (1 << GCTYPEBITS) - 1) |
| 3159 | & -(1 << GCTYPEBITS)]; | 3439 | & -(1 << GCTYPEBITS)]; |
| 3160 | #endif | 3440 | #endif |
| @@ -3162,7 +3442,7 @@ union aligned_Lisp_Symbol | |||
| 3162 | 3442 | ||
| 3163 | /* Each symbol_block is just under 1020 bytes long, since malloc | 3443 | /* Each symbol_block is just under 1020 bytes long, since malloc |
| 3164 | really allocates in units of powers of two and uses 4 bytes for its | 3444 | really allocates in units of powers of two and uses 4 bytes for its |
| 3165 | own overhead. */ | 3445 | own overhead. */ |
| 3166 | 3446 | ||
| 3167 | #define SYMBOL_BLOCK_SIZE \ | 3447 | #define SYMBOL_BLOCK_SIZE \ |
| 3168 | ((1020 - sizeof (struct symbol_block *)) / sizeof (union aligned_Lisp_Symbol)) | 3448 | ((1020 - sizeof (struct symbol_block *)) / sizeof (union aligned_Lisp_Symbol)) |
| @@ -3260,7 +3540,7 @@ Its value and function definition are void, and its property list is nil. */) | |||
| 3260 | union aligned_Lisp_Misc | 3540 | union aligned_Lisp_Misc |
| 3261 | { | 3541 | { |
| 3262 | union Lisp_Misc m; | 3542 | union Lisp_Misc m; |
| 3263 | #ifdef USE_LSB_TAG | 3543 | #if USE_LSB_TAG |
| 3264 | unsigned char c[(sizeof (union Lisp_Misc) + (1 << GCTYPEBITS) - 1) | 3544 | unsigned char c[(sizeof (union Lisp_Misc) + (1 << GCTYPEBITS) - 1) |
| 3265 | & -(1 << GCTYPEBITS)]; | 3545 | & -(1 << GCTYPEBITS)]; |
| 3266 | #endif | 3546 | #endif |
| @@ -4068,7 +4348,34 @@ live_misc_p (struct mem_node *m, void *p) | |||
| 4068 | static inline int | 4348 | static inline int |
| 4069 | live_vector_p (struct mem_node *m, void *p) | 4349 | live_vector_p (struct mem_node *m, void *p) |
| 4070 | { | 4350 | { |
| 4071 | return (p == m->start && m->type == MEM_TYPE_VECTORLIKE); | 4351 | if (m->type == MEM_TYPE_VECTOR_BLOCK) |
| 4352 | { | ||
| 4353 | /* This memory node corresponds to a vector block. */ | ||
| 4354 | struct vector_block *block = (struct vector_block *) m->start; | ||
| 4355 | struct Lisp_Vector *vector = (struct Lisp_Vector *) block->data; | ||
| 4356 | |||
| 4357 | /* P is in the block's allocation range. Scan the block | ||
| 4358 | up to P and see whether P points to the start of some | ||
| 4359 | vector which is not on a free list. FIXME: check whether | ||
| 4360 | some allocation patterns (probably a lot of short vectors) | ||
| 4361 | may cause a substantial overhead of this loop. */ | ||
| 4362 | while (VECTOR_IN_BLOCK (vector, block) | ||
| 4363 | && vector <= (struct Lisp_Vector *) p) | ||
| 4364 | { | ||
| 4365 | if ((vector->header.size & VECTOR_FREE_LIST_FLAG) | ||
| 4366 | == VECTOR_FREE_LIST_FLAG) | ||
| 4367 | vector = ADVANCE (vector, (vector->header.size | ||
| 4368 | & (VECTOR_BLOCK_SIZE - 1))); | ||
| 4369 | else if (vector == p) | ||
| 4370 | return 1; | ||
| 4371 | else | ||
| 4372 | vector = ADVANCE (vector, vector->header.next.nbytes); | ||
| 4373 | } | ||
| 4374 | } | ||
| 4375 | else if (m->type == MEM_TYPE_VECTORLIKE && p == m->start) | ||
| 4376 | /* This memory node corresponds to a large vector. */ | ||
| 4377 | return 1; | ||
| 4378 | return 0; | ||
| 4072 | } | 4379 | } |
| 4073 | 4380 | ||
| 4074 | 4381 | ||
| @@ -4215,14 +4522,10 @@ mark_maybe_pointer (void *p) | |||
| 4215 | { | 4522 | { |
| 4216 | struct mem_node *m; | 4523 | struct mem_node *m; |
| 4217 | 4524 | ||
| 4218 | /* Quickly rule out some values which can't point to Lisp data. */ | 4525 | /* Quickly rule out some values which can't point to Lisp data. |
| 4219 | if ((intptr_t) p % | 4526 | USE_LSB_TAG needs Lisp data to be aligned on multiples of 1 << GCTYPEBITS. |
| 4220 | #ifdef USE_LSB_TAG | 4527 | Otherwise, assume that Lisp data is aligned on even addresses. */ |
| 4221 | 8 /* USE_LSB_TAG needs Lisp data to be aligned on multiples of 8. */ | 4528 | if ((intptr_t) p % (USE_LSB_TAG ? 1 << GCTYPEBITS : 2)) |
| 4222 | #else | ||
| 4223 | 2 /* We assume that Lisp data is aligned on even addresses. */ | ||
| 4224 | #endif | ||
| 4225 | ) | ||
| 4226 | return; | 4529 | return; |
| 4227 | 4530 | ||
| 4228 | m = mem_find (p); | 4531 | m = mem_find (p); |
| @@ -4268,6 +4571,7 @@ mark_maybe_pointer (void *p) | |||
| 4268 | break; | 4571 | break; |
| 4269 | 4572 | ||
| 4270 | case MEM_TYPE_VECTORLIKE: | 4573 | case MEM_TYPE_VECTORLIKE: |
| 4574 | case MEM_TYPE_VECTOR_BLOCK: | ||
| 4271 | if (live_vector_p (m, p)) | 4575 | if (live_vector_p (m, p)) |
| 4272 | { | 4576 | { |
| 4273 | Lisp_Object tem; | 4577 | Lisp_Object tem; |
| @@ -4297,8 +4601,8 @@ mark_maybe_pointer (void *p) | |||
| 4297 | wider than a pointer might allocate a Lisp_Object in non-adjacent halves. | 4601 | wider than a pointer might allocate a Lisp_Object in non-adjacent halves. |
| 4298 | If USE_LSB_TAG, the bottom half is not a valid pointer, but it should | 4602 | If USE_LSB_TAG, the bottom half is not a valid pointer, but it should |
| 4299 | suffice to widen it to to a Lisp_Object and check it that way. */ | 4603 | suffice to widen it to to a Lisp_Object and check it that way. */ |
| 4300 | #if defined USE_LSB_TAG || UINTPTR_MAX >> VALBITS != 0 | 4604 | #if USE_LSB_TAG || VAL_MAX < UINTPTR_MAX |
| 4301 | # if !defined USE_LSB_TAG && UINTPTR_MAX >> VALBITS >> GCTYPEBITS != 0 | 4605 | # if !USE_LSB_TAG && VAL_MAX < UINTPTR_MAX >> GCTYPEBITS |
| 4302 | /* If tag bits straddle pointer-word boundaries, neither mark_maybe_pointer | 4606 | /* If tag bits straddle pointer-word boundaries, neither mark_maybe_pointer |
| 4303 | nor mark_maybe_object can follow the pointers. This should not occur on | 4607 | nor mark_maybe_object can follow the pointers. This should not occur on |
| 4304 | any practical porting target. */ | 4608 | any practical porting target. */ |
| @@ -4359,7 +4663,7 @@ mark_memory (void *start, void *end) | |||
| 4359 | void *p = *(void **) ((char *) pp + i); | 4663 | void *p = *(void **) ((char *) pp + i); |
| 4360 | mark_maybe_pointer (p); | 4664 | mark_maybe_pointer (p); |
| 4361 | if (POINTERS_MIGHT_HIDE_IN_OBJECTS) | 4665 | if (POINTERS_MIGHT_HIDE_IN_OBJECTS) |
| 4362 | mark_maybe_object (widen_to_Lisp_Object (p)); | 4666 | mark_maybe_object (XIL ((intptr_t) p)); |
| 4363 | } | 4667 | } |
| 4364 | } | 4668 | } |
| 4365 | 4669 | ||
| @@ -4701,6 +5005,7 @@ valid_lisp_object_p (Lisp_Object obj) | |||
| 4701 | return live_float_p (m, p); | 5005 | return live_float_p (m, p); |
| 4702 | 5006 | ||
| 4703 | case MEM_TYPE_VECTORLIKE: | 5007 | case MEM_TYPE_VECTORLIKE: |
| 5008 | case MEM_TYPE_VECTOR_BLOCK: | ||
| 4704 | return live_vector_p (m, p); | 5009 | return live_vector_p (m, p); |
| 4705 | 5010 | ||
| 4706 | default: | 5011 | default: |
| @@ -4722,11 +5027,11 @@ valid_lisp_object_p (Lisp_Object obj) | |||
| 4722 | pointer to it. TYPE is the Lisp type for which the memory is | 5027 | pointer to it. TYPE is the Lisp type for which the memory is |
| 4723 | allocated. TYPE < 0 means it's not used for a Lisp object. */ | 5028 | allocated. TYPE < 0 means it's not used for a Lisp object. */ |
| 4724 | 5029 | ||
| 4725 | static POINTER_TYPE * | 5030 | static void * |
| 4726 | pure_alloc (size_t size, int type) | 5031 | pure_alloc (size_t size, int type) |
| 4727 | { | 5032 | { |
| 4728 | POINTER_TYPE *result; | 5033 | void *result; |
| 4729 | #ifdef USE_LSB_TAG | 5034 | #if USE_LSB_TAG |
| 4730 | size_t alignment = (1 << GCTYPEBITS); | 5035 | size_t alignment = (1 << GCTYPEBITS); |
| 4731 | #else | 5036 | #else |
| 4732 | size_t alignment = sizeof (EMACS_INT); | 5037 | size_t alignment = sizeof (EMACS_INT); |
| @@ -4791,14 +5096,14 @@ check_pure_size (void) | |||
| 4791 | address. Return NULL if not found. */ | 5096 | address. Return NULL if not found. */ |
| 4792 | 5097 | ||
| 4793 | static char * | 5098 | static char * |
| 4794 | find_string_data_in_pure (const char *data, EMACS_INT nbytes) | 5099 | find_string_data_in_pure (const char *data, ptrdiff_t nbytes) |
| 4795 | { | 5100 | { |
| 4796 | int i; | 5101 | int i; |
| 4797 | EMACS_INT skip, bm_skip[256], last_char_skip, infinity, start, start_max; | 5102 | ptrdiff_t skip, bm_skip[256], last_char_skip, infinity, start, start_max; |
| 4798 | const unsigned char *p; | 5103 | const unsigned char *p; |
| 4799 | char *non_lisp_beg; | 5104 | char *non_lisp_beg; |
| 4800 | 5105 | ||
| 4801 | if (pure_bytes_used_non_lisp < nbytes + 1) | 5106 | if (pure_bytes_used_non_lisp <= nbytes) |
| 4802 | return NULL; | 5107 | return NULL; |
| 4803 | 5108 | ||
| 4804 | /* Set up the Boyer-Moore table. */ | 5109 | /* Set up the Boyer-Moore table. */ |
| @@ -4862,7 +5167,7 @@ find_string_data_in_pure (const char *data, EMACS_INT nbytes) | |||
| 4862 | 5167 | ||
| 4863 | Lisp_Object | 5168 | Lisp_Object |
| 4864 | make_pure_string (const char *data, | 5169 | make_pure_string (const char *data, |
| 4865 | EMACS_INT nchars, EMACS_INT nbytes, int multibyte) | 5170 | ptrdiff_t nchars, ptrdiff_t nbytes, int multibyte) |
| 4866 | { | 5171 | { |
| 4867 | Lisp_Object string; | 5172 | Lisp_Object string; |
| 4868 | struct Lisp_String *s; | 5173 | struct Lisp_String *s; |
| @@ -4890,7 +5195,7 @@ make_pure_c_string (const char *data) | |||
| 4890 | { | 5195 | { |
| 4891 | Lisp_Object string; | 5196 | Lisp_Object string; |
| 4892 | struct Lisp_String *s; | 5197 | struct Lisp_String *s; |
| 4893 | EMACS_INT nchars = strlen (data); | 5198 | ptrdiff_t nchars = strlen (data); |
| 4894 | 5199 | ||
| 4895 | s = (struct Lisp_String *) pure_alloc (sizeof *s, Lisp_String); | 5200 | s = (struct Lisp_String *) pure_alloc (sizeof *s, Lisp_String); |
| 4896 | s->size = nchars; | 5201 | s->size = nchars; |
| @@ -4936,8 +5241,8 @@ make_pure_float (double num) | |||
| 4936 | /* Return a vector with room for LEN Lisp_Objects allocated from | 5241 | /* Return a vector with room for LEN Lisp_Objects allocated from |
| 4937 | pure space. */ | 5242 | pure space. */ |
| 4938 | 5243 | ||
| 4939 | Lisp_Object | 5244 | static Lisp_Object |
| 4940 | make_pure_vector (EMACS_INT len) | 5245 | make_pure_vector (ptrdiff_t len) |
| 4941 | { | 5246 | { |
| 4942 | Lisp_Object new; | 5247 | Lisp_Object new; |
| 4943 | struct Lisp_Vector *p; | 5248 | struct Lisp_Vector *p; |
| @@ -4981,8 +5286,8 @@ Does not copy symbols. Copies strings without text properties. */) | |||
| 4981 | else if (COMPILEDP (obj) || VECTORP (obj)) | 5286 | else if (COMPILEDP (obj) || VECTORP (obj)) |
| 4982 | { | 5287 | { |
| 4983 | register struct Lisp_Vector *vec; | 5288 | register struct Lisp_Vector *vec; |
| 4984 | register EMACS_INT i; | 5289 | register ptrdiff_t i; |
| 4985 | EMACS_INT size; | 5290 | ptrdiff_t size; |
| 4986 | 5291 | ||
| 4987 | size = ASIZE (obj); | 5292 | size = ASIZE (obj); |
| 4988 | if (size & PSEUDOVECTOR_FLAG) | 5293 | if (size & PSEUDOVECTOR_FLAG) |
| @@ -5034,10 +5339,10 @@ staticpro (Lisp_Object *varaddress) | |||
| 5034 | 5339 | ||
| 5035 | /* Temporarily prevent garbage collection. */ | 5340 | /* Temporarily prevent garbage collection. */ |
| 5036 | 5341 | ||
| 5037 | int | 5342 | ptrdiff_t |
| 5038 | inhibit_garbage_collection (void) | 5343 | inhibit_garbage_collection (void) |
| 5039 | { | 5344 | { |
| 5040 | int count = SPECPDL_INDEX (); | 5345 | ptrdiff_t count = SPECPDL_INDEX (); |
| 5041 | 5346 | ||
| 5042 | specbind (Qgc_cons_threshold, make_number (MOST_POSITIVE_FIXNUM)); | 5347 | specbind (Qgc_cons_threshold, make_number (MOST_POSITIVE_FIXNUM)); |
| 5043 | return count; | 5348 | return count; |
| @@ -5063,7 +5368,7 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5063 | ptrdiff_t i; | 5368 | ptrdiff_t i; |
| 5064 | int message_p; | 5369 | int message_p; |
| 5065 | Lisp_Object total[8]; | 5370 | Lisp_Object total[8]; |
| 5066 | int count = SPECPDL_INDEX (); | 5371 | ptrdiff_t count = SPECPDL_INDEX (); |
| 5067 | EMACS_TIME t1, t2, t3; | 5372 | EMACS_TIME t1, t2, t3; |
| 5068 | 5373 | ||
| 5069 | if (abort_on_gc) | 5374 | if (abort_on_gc) |
| @@ -5358,7 +5663,7 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5358 | 5663 | ||
| 5359 | if (!NILP (Vpost_gc_hook)) | 5664 | if (!NILP (Vpost_gc_hook)) |
| 5360 | { | 5665 | { |
| 5361 | int gc_count = inhibit_garbage_collection (); | 5666 | ptrdiff_t gc_count = inhibit_garbage_collection (); |
| 5362 | safe_run_hooks (Qpost_gc_hook); | 5667 | safe_run_hooks (Qpost_gc_hook); |
| 5363 | unbind_to (gc_count, Qnil); | 5668 | unbind_to (gc_count, Qnil); |
| 5364 | } | 5669 | } |
| @@ -5443,8 +5748,8 @@ ptrdiff_t mark_object_loop_halt EXTERNALLY_VISIBLE; | |||
| 5443 | static void | 5748 | static void |
| 5444 | mark_vectorlike (struct Lisp_Vector *ptr) | 5749 | mark_vectorlike (struct Lisp_Vector *ptr) |
| 5445 | { | 5750 | { |
| 5446 | EMACS_INT size = ptr->header.size; | 5751 | ptrdiff_t size = ptr->header.size; |
| 5447 | EMACS_INT i; | 5752 | ptrdiff_t i; |
| 5448 | 5753 | ||
| 5449 | eassert (!VECTOR_MARKED_P (ptr)); | 5754 | eassert (!VECTOR_MARKED_P (ptr)); |
| 5450 | VECTOR_MARK (ptr); /* Else mark it */ | 5755 | VECTOR_MARK (ptr); /* Else mark it */ |
| @@ -6237,33 +6542,7 @@ gc_sweep (void) | |||
| 6237 | } | 6542 | } |
| 6238 | } | 6543 | } |
| 6239 | 6544 | ||
| 6240 | /* Free all unmarked vectors */ | 6545 | sweep_vectors (); |
| 6241 | { | ||
| 6242 | register struct Lisp_Vector *vector = all_vectors, *prev = 0, *next; | ||
| 6243 | total_vector_size = 0; | ||
| 6244 | |||
| 6245 | while (vector) | ||
| 6246 | if (!VECTOR_MARKED_P (vector)) | ||
| 6247 | { | ||
| 6248 | if (prev) | ||
| 6249 | prev->header.next = vector->header.next; | ||
| 6250 | else | ||
| 6251 | all_vectors = vector->header.next.vector; | ||
| 6252 | next = vector->header.next.vector; | ||
| 6253 | lisp_free (vector); | ||
| 6254 | vector = next; | ||
| 6255 | |||
| 6256 | } | ||
| 6257 | else | ||
| 6258 | { | ||
| 6259 | VECTOR_UNMARK (vector); | ||
| 6260 | if (vector->header.size & PSEUDOVECTOR_FLAG) | ||
| 6261 | total_vector_size += PSEUDOVECTOR_SIZE_MASK & vector->header.size; | ||
| 6262 | else | ||
| 6263 | total_vector_size += vector->header.size; | ||
| 6264 | prev = vector, vector = vector->header.next.vector; | ||
| 6265 | } | ||
| 6266 | } | ||
| 6267 | 6546 | ||
| 6268 | #ifdef GC_CHECK_STRING_BYTES | 6547 | #ifdef GC_CHECK_STRING_BYTES |
| 6269 | if (!noninteractive) | 6548 | if (!noninteractive) |
| @@ -6325,7 +6604,7 @@ Lisp_Object | |||
| 6325 | which_symbols (Lisp_Object obj, EMACS_INT find_max) | 6604 | which_symbols (Lisp_Object obj, EMACS_INT find_max) |
| 6326 | { | 6605 | { |
| 6327 | struct symbol_block *sblk; | 6606 | struct symbol_block *sblk; |
| 6328 | int gc_count = inhibit_garbage_collection (); | 6607 | ptrdiff_t gc_count = inhibit_garbage_collection (); |
| 6329 | Lisp_Object found = Qnil; | 6608 | Lisp_Object found = Qnil; |
| 6330 | 6609 | ||
| 6331 | if (! DEADP (obj)) | 6610 | if (! DEADP (obj)) |
| @@ -6400,7 +6679,6 @@ init_alloc_once (void) | |||
| 6400 | Vdead = make_pure_string ("DEAD", 4, 4, 0); | 6679 | Vdead = make_pure_string ("DEAD", 4, 4, 0); |
| 6401 | #endif | 6680 | #endif |
| 6402 | 6681 | ||
| 6403 | all_vectors = 0; | ||
| 6404 | ignore_warnings = 1; | 6682 | ignore_warnings = 1; |
| 6405 | #ifdef DOUG_LEA_MALLOC | 6683 | #ifdef DOUG_LEA_MALLOC |
| 6406 | mallopt (M_TRIM_THRESHOLD, 128*1024); /* trim threshold */ | 6684 | mallopt (M_TRIM_THRESHOLD, 128*1024); /* trim threshold */ |
| @@ -6413,6 +6691,7 @@ init_alloc_once (void) | |||
| 6413 | init_marker (); | 6691 | init_marker (); |
| 6414 | init_float (); | 6692 | init_float (); |
| 6415 | init_intervals (); | 6693 | init_intervals (); |
| 6694 | init_vectors (); | ||
| 6416 | init_weak_hash_tables (); | 6695 | init_weak_hash_tables (); |
| 6417 | 6696 | ||
| 6418 | #ifdef REL_ALLOC | 6697 | #ifdef REL_ALLOC |