diff options
| author | Paul Eggert | 2011-06-15 12:57:25 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-06-15 12:57:25 -0700 |
| commit | a7af7fdede602a111401c2352e81311a9dc38b99 (patch) | |
| tree | daebcb8a73345231337d0a461c01ae7804b2b646 /src/alloc.c | |
| parent | 8c9b210626493dd93f236d7fb312c4f6dba62892 (diff) | |
| parent | b1c46f026de9d185ba86ffb1b23c50f2bd095ccf (diff) | |
| download | emacs-a7af7fdede602a111401c2352e81311a9dc38b99.tar.gz emacs-a7af7fdede602a111401c2352e81311a9dc38b99.zip | |
Integer overflow and signedness fixes (Bug#8873).
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 181 |
1 files changed, 80 insertions, 101 deletions
diff --git a/src/alloc.c b/src/alloc.c index cfbb79b2e61..00d330c1b6a 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -180,9 +180,9 @@ int abort_on_gc; | |||
| 180 | 180 | ||
| 181 | /* Number of live and free conses etc. */ | 181 | /* Number of live and free conses etc. */ |
| 182 | 182 | ||
| 183 | static int total_conses, total_markers, total_symbols, total_vector_size; | 183 | static EMACS_INT total_conses, total_markers, total_symbols, total_vector_size; |
| 184 | static int total_free_conses, total_free_markers, total_free_symbols; | 184 | static EMACS_INT total_free_conses, total_free_markers, total_free_symbols; |
| 185 | static int total_free_floats, total_floats; | 185 | static EMACS_INT total_free_floats, total_floats; |
| 186 | 186 | ||
| 187 | /* Points to memory space allocated as "spare", to be freed if we run | 187 | /* Points to memory space allocated as "spare", to be freed if we run |
| 188 | out of memory. We keep one large block, four cons-blocks, and | 188 | out of memory. We keep one large block, four cons-blocks, and |
| @@ -485,7 +485,9 @@ buffer_memory_full (EMACS_INT nbytes) | |||
| 485 | } | 485 | } |
| 486 | 486 | ||
| 487 | 487 | ||
| 488 | #ifdef XMALLOC_OVERRUN_CHECK | 488 | #ifndef XMALLOC_OVERRUN_CHECK |
| 489 | #define XMALLOC_OVERRUN_CHECK_SIZE 0 | ||
| 490 | #else | ||
| 489 | 491 | ||
| 490 | /* Check for overrun in malloc'ed buffers by wrapping a 16 byte header | 492 | /* Check for overrun in malloc'ed buffers by wrapping a 16 byte header |
| 491 | and a 16 byte trailer around each block. | 493 | and a 16 byte trailer around each block. |
| @@ -1336,16 +1338,12 @@ static int interval_block_index; | |||
| 1336 | 1338 | ||
| 1337 | /* Number of free and live intervals. */ | 1339 | /* Number of free and live intervals. */ |
| 1338 | 1340 | ||
| 1339 | static int total_free_intervals, total_intervals; | 1341 | static EMACS_INT total_free_intervals, total_intervals; |
| 1340 | 1342 | ||
| 1341 | /* List of free intervals. */ | 1343 | /* List of free intervals. */ |
| 1342 | 1344 | ||
| 1343 | static INTERVAL interval_free_list; | 1345 | static INTERVAL interval_free_list; |
| 1344 | 1346 | ||
| 1345 | /* Total number of interval blocks now in use. */ | ||
| 1346 | |||
| 1347 | static int n_interval_blocks; | ||
| 1348 | |||
| 1349 | 1347 | ||
| 1350 | /* Initialize interval allocation. */ | 1348 | /* Initialize interval allocation. */ |
| 1351 | 1349 | ||
| @@ -1355,7 +1353,6 @@ init_intervals (void) | |||
| 1355 | interval_block = NULL; | 1353 | interval_block = NULL; |
| 1356 | interval_block_index = INTERVAL_BLOCK_SIZE; | 1354 | interval_block_index = INTERVAL_BLOCK_SIZE; |
| 1357 | interval_free_list = 0; | 1355 | interval_free_list = 0; |
| 1358 | n_interval_blocks = 0; | ||
| 1359 | } | 1356 | } |
| 1360 | 1357 | ||
| 1361 | 1358 | ||
| @@ -1387,7 +1384,6 @@ make_interval (void) | |||
| 1387 | newi->next = interval_block; | 1384 | newi->next = interval_block; |
| 1388 | interval_block = newi; | 1385 | interval_block = newi; |
| 1389 | interval_block_index = 0; | 1386 | interval_block_index = 0; |
| 1390 | n_interval_blocks++; | ||
| 1391 | } | 1387 | } |
| 1392 | val = &interval_block->intervals[interval_block_index++]; | 1388 | val = &interval_block->intervals[interval_block_index++]; |
| 1393 | } | 1389 | } |
| @@ -1580,10 +1576,9 @@ static struct sblock *oldest_sblock, *current_sblock; | |||
| 1580 | 1576 | ||
| 1581 | static struct sblock *large_sblocks; | 1577 | static struct sblock *large_sblocks; |
| 1582 | 1578 | ||
| 1583 | /* List of string_block structures, and how many there are. */ | 1579 | /* List of string_block structures. */ |
| 1584 | 1580 | ||
| 1585 | static struct string_block *string_blocks; | 1581 | static struct string_block *string_blocks; |
| 1586 | static int n_string_blocks; | ||
| 1587 | 1582 | ||
| 1588 | /* Free-list of Lisp_Strings. */ | 1583 | /* Free-list of Lisp_Strings. */ |
| 1589 | 1584 | ||
| @@ -1591,7 +1586,7 @@ static struct Lisp_String *string_free_list; | |||
| 1591 | 1586 | ||
| 1592 | /* Number of live and free Lisp_Strings. */ | 1587 | /* Number of live and free Lisp_Strings. */ |
| 1593 | 1588 | ||
| 1594 | static int total_strings, total_free_strings; | 1589 | static EMACS_INT total_strings, total_free_strings; |
| 1595 | 1590 | ||
| 1596 | /* Number of bytes used by live strings. */ | 1591 | /* Number of bytes used by live strings. */ |
| 1597 | 1592 | ||
| @@ -1659,6 +1654,18 @@ static char const string_overrun_cookie[GC_STRING_OVERRUN_COOKIE_SIZE] = | |||
| 1659 | 1654 | ||
| 1660 | #define GC_STRING_EXTRA (GC_STRING_OVERRUN_COOKIE_SIZE) | 1655 | #define GC_STRING_EXTRA (GC_STRING_OVERRUN_COOKIE_SIZE) |
| 1661 | 1656 | ||
| 1657 | /* Exact bound on the number of bytes in a string, not counting the | ||
| 1658 | terminating null. A string cannot contain more bytes than | ||
| 1659 | STRING_BYTES_BOUND, nor can it be so long that the size_t | ||
| 1660 | arithmetic in allocate_string_data would overflow while it is | ||
| 1661 | calculating a value to be passed to malloc. */ | ||
| 1662 | #define STRING_BYTES_MAX \ | ||
| 1663 | min (STRING_BYTES_BOUND, \ | ||
| 1664 | ((SIZE_MAX - XMALLOC_OVERRUN_CHECK_SIZE - GC_STRING_EXTRA \ | ||
| 1665 | - offsetof (struct sblock, first_data) \ | ||
| 1666 | - SDATA_DATA_OFFSET) \ | ||
| 1667 | & ~(sizeof (EMACS_INT) - 1))) | ||
| 1668 | |||
| 1662 | /* Initialize string allocation. Called from init_alloc_once. */ | 1669 | /* Initialize string allocation. Called from init_alloc_once. */ |
| 1663 | 1670 | ||
| 1664 | static void | 1671 | static void |
| @@ -1667,7 +1674,6 @@ init_strings (void) | |||
| 1667 | total_strings = total_free_strings = total_string_size = 0; | 1674 | total_strings = total_free_strings = total_string_size = 0; |
| 1668 | oldest_sblock = current_sblock = large_sblocks = NULL; | 1675 | oldest_sblock = current_sblock = large_sblocks = NULL; |
| 1669 | string_blocks = NULL; | 1676 | string_blocks = NULL; |
| 1670 | n_string_blocks = 0; | ||
| 1671 | string_free_list = NULL; | 1677 | string_free_list = NULL; |
| 1672 | empty_unibyte_string = make_pure_string ("", 0, 0, 0); | 1678 | empty_unibyte_string = make_pure_string ("", 0, 0, 0); |
| 1673 | empty_multibyte_string = make_pure_string ("", 0, 0, 1); | 1679 | empty_multibyte_string = make_pure_string ("", 0, 0, 1); |
| @@ -1799,7 +1805,6 @@ allocate_string (void) | |||
| 1799 | memset (b, 0, sizeof *b); | 1805 | memset (b, 0, sizeof *b); |
| 1800 | b->next = string_blocks; | 1806 | b->next = string_blocks; |
| 1801 | string_blocks = b; | 1807 | string_blocks = b; |
| 1802 | ++n_string_blocks; | ||
| 1803 | 1808 | ||
| 1804 | for (i = STRING_BLOCK_SIZE - 1; i >= 0; --i) | 1809 | for (i = STRING_BLOCK_SIZE - 1; i >= 0; --i) |
| 1805 | { | 1810 | { |
| @@ -1858,6 +1863,9 @@ allocate_string_data (struct Lisp_String *s, | |||
| 1858 | struct sblock *b; | 1863 | struct sblock *b; |
| 1859 | EMACS_INT needed, old_nbytes; | 1864 | EMACS_INT needed, old_nbytes; |
| 1860 | 1865 | ||
| 1866 | if (STRING_BYTES_MAX < nbytes) | ||
| 1867 | string_overflow (); | ||
| 1868 | |||
| 1861 | /* Determine the number of bytes needed to store NBYTES bytes | 1869 | /* Determine the number of bytes needed to store NBYTES bytes |
| 1862 | of string data. */ | 1870 | of string data. */ |
| 1863 | needed = SDATA_SIZE (nbytes); | 1871 | needed = SDATA_SIZE (nbytes); |
| @@ -2025,7 +2033,6 @@ sweep_strings (void) | |||
| 2025 | && total_free_strings > STRING_BLOCK_SIZE) | 2033 | && total_free_strings > STRING_BLOCK_SIZE) |
| 2026 | { | 2034 | { |
| 2027 | lisp_free (b); | 2035 | lisp_free (b); |
| 2028 | --n_string_blocks; | ||
| 2029 | string_free_list = free_list_before; | 2036 | string_free_list = free_list_before; |
| 2030 | } | 2037 | } |
| 2031 | else | 2038 | else |
| @@ -2186,9 +2193,9 @@ INIT must be an integer that represents a character. */) | |||
| 2186 | EMACS_INT nbytes; | 2193 | EMACS_INT nbytes; |
| 2187 | 2194 | ||
| 2188 | CHECK_NATNUM (length); | 2195 | CHECK_NATNUM (length); |
| 2189 | CHECK_NUMBER (init); | 2196 | CHECK_CHARACTER (init); |
| 2190 | 2197 | ||
| 2191 | c = XINT (init); | 2198 | c = XFASTINT (init); |
| 2192 | if (ASCII_CHAR_P (c)) | 2199 | if (ASCII_CHAR_P (c)) |
| 2193 | { | 2200 | { |
| 2194 | nbytes = XINT (length); | 2201 | nbytes = XINT (length); |
| @@ -2229,7 +2236,6 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */) | |||
| 2229 | { | 2236 | { |
| 2230 | register Lisp_Object val; | 2237 | register Lisp_Object val; |
| 2231 | struct Lisp_Bool_Vector *p; | 2238 | struct Lisp_Bool_Vector *p; |
| 2232 | int real_init, i; | ||
| 2233 | EMACS_INT length_in_chars, length_in_elts; | 2239 | EMACS_INT length_in_chars, length_in_elts; |
| 2234 | int bits_per_value; | 2240 | int bits_per_value; |
| 2235 | 2241 | ||
| @@ -2251,9 +2257,7 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */) | |||
| 2251 | p = XBOOL_VECTOR (val); | 2257 | p = XBOOL_VECTOR (val); |
| 2252 | p->size = XFASTINT (length); | 2258 | p->size = XFASTINT (length); |
| 2253 | 2259 | ||
| 2254 | real_init = (NILP (init) ? 0 : -1); | 2260 | memset (p->data, NILP (init) ? 0 : -1, length_in_chars); |
| 2255 | for (i = 0; i < length_in_chars ; i++) | ||
| 2256 | p->data[i] = real_init; | ||
| 2257 | 2261 | ||
| 2258 | /* Clear the extraneous bits in the last byte. */ | 2262 | /* Clear the extraneous bits in the last byte. */ |
| 2259 | if (XINT (length) != length_in_chars * BOOL_VECTOR_BITS_PER_CHAR) | 2263 | if (XINT (length) != length_in_chars * BOOL_VECTOR_BITS_PER_CHAR) |
| @@ -2463,10 +2467,6 @@ static struct float_block *float_block; | |||
| 2463 | 2467 | ||
| 2464 | static int float_block_index; | 2468 | static int float_block_index; |
| 2465 | 2469 | ||
| 2466 | /* Total number of float blocks now in use. */ | ||
| 2467 | |||
| 2468 | static int n_float_blocks; | ||
| 2469 | |||
| 2470 | /* Free-list of Lisp_Floats. */ | 2470 | /* Free-list of Lisp_Floats. */ |
| 2471 | 2471 | ||
| 2472 | static struct Lisp_Float *float_free_list; | 2472 | static struct Lisp_Float *float_free_list; |
| @@ -2480,7 +2480,6 @@ init_float (void) | |||
| 2480 | float_block = NULL; | 2480 | float_block = NULL; |
| 2481 | float_block_index = FLOAT_BLOCK_SIZE; /* Force alloc of new float_block. */ | 2481 | float_block_index = FLOAT_BLOCK_SIZE; /* Force alloc of new float_block. */ |
| 2482 | float_free_list = 0; | 2482 | float_free_list = 0; |
| 2483 | n_float_blocks = 0; | ||
| 2484 | } | 2483 | } |
| 2485 | 2484 | ||
| 2486 | 2485 | ||
| @@ -2514,7 +2513,6 @@ make_float (double float_value) | |||
| 2514 | memset (new->gcmarkbits, 0, sizeof new->gcmarkbits); | 2513 | memset (new->gcmarkbits, 0, sizeof new->gcmarkbits); |
| 2515 | float_block = new; | 2514 | float_block = new; |
| 2516 | float_block_index = 0; | 2515 | float_block_index = 0; |
| 2517 | n_float_blocks++; | ||
| 2518 | } | 2516 | } |
| 2519 | XSETFLOAT (val, &float_block->floats[float_block_index]); | 2517 | XSETFLOAT (val, &float_block->floats[float_block_index]); |
| 2520 | float_block_index++; | 2518 | float_block_index++; |
| @@ -2579,10 +2577,6 @@ static int cons_block_index; | |||
| 2579 | 2577 | ||
| 2580 | static struct Lisp_Cons *cons_free_list; | 2578 | static struct Lisp_Cons *cons_free_list; |
| 2581 | 2579 | ||
| 2582 | /* Total number of cons blocks now in use. */ | ||
| 2583 | |||
| 2584 | static int n_cons_blocks; | ||
| 2585 | |||
| 2586 | 2580 | ||
| 2587 | /* Initialize cons allocation. */ | 2581 | /* Initialize cons allocation. */ |
| 2588 | 2582 | ||
| @@ -2592,7 +2586,6 @@ init_cons (void) | |||
| 2592 | cons_block = NULL; | 2586 | cons_block = NULL; |
| 2593 | cons_block_index = CONS_BLOCK_SIZE; /* Force alloc of new cons_block. */ | 2587 | cons_block_index = CONS_BLOCK_SIZE; /* Force alloc of new cons_block. */ |
| 2594 | cons_free_list = 0; | 2588 | cons_free_list = 0; |
| 2595 | n_cons_blocks = 0; | ||
| 2596 | } | 2589 | } |
| 2597 | 2590 | ||
| 2598 | 2591 | ||
| @@ -2636,7 +2629,6 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0, | |||
| 2636 | new->next = cons_block; | 2629 | new->next = cons_block; |
| 2637 | cons_block = new; | 2630 | cons_block = new; |
| 2638 | cons_block_index = 0; | 2631 | cons_block_index = 0; |
| 2639 | n_cons_blocks++; | ||
| 2640 | } | 2632 | } |
| 2641 | XSETCONS (val, &cons_block->conses[cons_block_index]); | 2633 | XSETCONS (val, &cons_block->conses[cons_block_index]); |
| 2642 | cons_block_index++; | 2634 | cons_block_index++; |
| @@ -2705,7 +2697,7 @@ DEFUN ("list", Flist, Slist, 0, MANY, 0, | |||
| 2705 | doc: /* Return a newly created list with specified arguments as elements. | 2697 | doc: /* Return a newly created list with specified arguments as elements. |
| 2706 | Any number of arguments, even zero arguments, are allowed. | 2698 | Any number of arguments, even zero arguments, are allowed. |
| 2707 | usage: (list &rest OBJECTS) */) | 2699 | usage: (list &rest OBJECTS) */) |
| 2708 | (size_t nargs, register Lisp_Object *args) | 2700 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2709 | { | 2701 | { |
| 2710 | register Lisp_Object val; | 2702 | register Lisp_Object val; |
| 2711 | val = Qnil; | 2703 | val = Qnil; |
| @@ -2775,10 +2767,12 @@ DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0, | |||
| 2775 | 2767 | ||
| 2776 | static struct Lisp_Vector *all_vectors; | 2768 | static struct Lisp_Vector *all_vectors; |
| 2777 | 2769 | ||
| 2778 | /* Total number of vector-like objects now in use. */ | 2770 | /* Handy constants for vectorlike objects. */ |
| 2779 | 2771 | enum | |
| 2780 | static int n_vectors; | 2772 | { |
| 2781 | 2773 | header_size = offsetof (struct Lisp_Vector, contents), | |
| 2774 | word_size = sizeof (Lisp_Object) | ||
| 2775 | }; | ||
| 2782 | 2776 | ||
| 2783 | /* Value is a pointer to a newly allocated Lisp_Vector structure | 2777 | /* Value is a pointer to a newly allocated Lisp_Vector structure |
| 2784 | with room for LEN Lisp_Objects. */ | 2778 | with room for LEN Lisp_Objects. */ |
| @@ -2788,11 +2782,6 @@ allocate_vectorlike (EMACS_INT len) | |||
| 2788 | { | 2782 | { |
| 2789 | struct Lisp_Vector *p; | 2783 | struct Lisp_Vector *p; |
| 2790 | size_t nbytes; | 2784 | size_t nbytes; |
| 2791 | int header_size = offsetof (struct Lisp_Vector, contents); | ||
| 2792 | int word_size = sizeof p->contents[0]; | ||
| 2793 | |||
| 2794 | if ((SIZE_MAX - header_size) / word_size < len) | ||
| 2795 | memory_full (SIZE_MAX); | ||
| 2796 | 2785 | ||
| 2797 | MALLOC_BLOCK_INPUT; | 2786 | MALLOC_BLOCK_INPUT; |
| 2798 | 2787 | ||
| @@ -2822,18 +2811,22 @@ allocate_vectorlike (EMACS_INT len) | |||
| 2822 | 2811 | ||
| 2823 | MALLOC_UNBLOCK_INPUT; | 2812 | MALLOC_UNBLOCK_INPUT; |
| 2824 | 2813 | ||
| 2825 | ++n_vectors; | ||
| 2826 | return p; | 2814 | return p; |
| 2827 | } | 2815 | } |
| 2828 | 2816 | ||
| 2829 | 2817 | ||
| 2830 | /* Allocate a vector with NSLOTS slots. */ | 2818 | /* Allocate a vector with LEN slots. */ |
| 2831 | 2819 | ||
| 2832 | struct Lisp_Vector * | 2820 | struct Lisp_Vector * |
| 2833 | allocate_vector (EMACS_INT nslots) | 2821 | allocate_vector (EMACS_INT len) |
| 2834 | { | 2822 | { |
| 2835 | struct Lisp_Vector *v = allocate_vectorlike (nslots); | 2823 | struct Lisp_Vector *v; |
| 2836 | v->header.size = nslots; | 2824 | ptrdiff_t nbytes_max = min (PTRDIFF_MAX, SIZE_MAX); |
| 2825 | |||
| 2826 | if (min ((nbytes_max - header_size) / word_size, MOST_POSITIVE_FIXNUM) < len) | ||
| 2827 | memory_full (SIZE_MAX); | ||
| 2828 | v = allocate_vectorlike (len); | ||
| 2829 | v->header.size = len; | ||
| 2837 | return v; | 2830 | return v; |
| 2838 | } | 2831 | } |
| 2839 | 2832 | ||
| @@ -2844,7 +2837,7 @@ struct Lisp_Vector * | |||
| 2844 | allocate_pseudovector (int memlen, int lisplen, EMACS_INT tag) | 2837 | allocate_pseudovector (int memlen, int lisplen, EMACS_INT tag) |
| 2845 | { | 2838 | { |
| 2846 | struct Lisp_Vector *v = allocate_vectorlike (memlen); | 2839 | struct Lisp_Vector *v = allocate_vectorlike (memlen); |
| 2847 | EMACS_INT i; | 2840 | int i; |
| 2848 | 2841 | ||
| 2849 | /* Only the first lisplen slots will be traced normally by the GC. */ | 2842 | /* Only the first lisplen slots will be traced normally by the GC. */ |
| 2850 | for (i = 0; i < lisplen; ++i) | 2843 | for (i = 0; i < lisplen; ++i) |
| @@ -2925,10 +2918,10 @@ DEFUN ("vector", Fvector, Svector, 0, MANY, 0, | |||
| 2925 | doc: /* Return a newly created vector with specified arguments as elements. | 2918 | doc: /* Return a newly created vector with specified arguments as elements. |
| 2926 | Any number of arguments, even zero arguments, are allowed. | 2919 | Any number of arguments, even zero arguments, are allowed. |
| 2927 | usage: (vector &rest OBJECTS) */) | 2920 | usage: (vector &rest OBJECTS) */) |
| 2928 | (register size_t nargs, Lisp_Object *args) | 2921 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2929 | { | 2922 | { |
| 2930 | register Lisp_Object len, val; | 2923 | register Lisp_Object len, val; |
| 2931 | register size_t i; | 2924 | ptrdiff_t i; |
| 2932 | register struct Lisp_Vector *p; | 2925 | register struct Lisp_Vector *p; |
| 2933 | 2926 | ||
| 2934 | XSETFASTINT (len, nargs); | 2927 | XSETFASTINT (len, nargs); |
| @@ -2956,15 +2949,15 @@ argument to catch the left-over arguments. If such an integer is used, the | |||
| 2956 | arguments will not be dynamically bound but will be instead pushed on the | 2949 | arguments will not be dynamically bound but will be instead pushed on the |
| 2957 | stack before executing the byte-code. | 2950 | stack before executing the byte-code. |
| 2958 | usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INTERACTIVE-SPEC &rest ELEMENTS) */) | 2951 | usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INTERACTIVE-SPEC &rest ELEMENTS) */) |
| 2959 | (register size_t nargs, Lisp_Object *args) | 2952 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2960 | { | 2953 | { |
| 2961 | register Lisp_Object len, val; | 2954 | register Lisp_Object len, val; |
| 2962 | register size_t i; | 2955 | ptrdiff_t i; |
| 2963 | register struct Lisp_Vector *p; | 2956 | register struct Lisp_Vector *p; |
| 2964 | 2957 | ||
| 2965 | XSETFASTINT (len, nargs); | 2958 | XSETFASTINT (len, nargs); |
| 2966 | if (!NILP (Vpurify_flag)) | 2959 | if (!NILP (Vpurify_flag)) |
| 2967 | val = make_pure_vector ((EMACS_INT) nargs); | 2960 | val = make_pure_vector (nargs); |
| 2968 | else | 2961 | else |
| 2969 | val = Fmake_vector (len, Qnil); | 2962 | val = Fmake_vector (len, Qnil); |
| 2970 | 2963 | ||
| @@ -3018,10 +3011,6 @@ static int symbol_block_index; | |||
| 3018 | 3011 | ||
| 3019 | static struct Lisp_Symbol *symbol_free_list; | 3012 | static struct Lisp_Symbol *symbol_free_list; |
| 3020 | 3013 | ||
| 3021 | /* Total number of symbol blocks now in use. */ | ||
| 3022 | |||
| 3023 | static int n_symbol_blocks; | ||
| 3024 | |||
| 3025 | 3014 | ||
| 3026 | /* Initialize symbol allocation. */ | 3015 | /* Initialize symbol allocation. */ |
| 3027 | 3016 | ||
| @@ -3031,7 +3020,6 @@ init_symbol (void) | |||
| 3031 | symbol_block = NULL; | 3020 | symbol_block = NULL; |
| 3032 | symbol_block_index = SYMBOL_BLOCK_SIZE; | 3021 | symbol_block_index = SYMBOL_BLOCK_SIZE; |
| 3033 | symbol_free_list = 0; | 3022 | symbol_free_list = 0; |
| 3034 | n_symbol_blocks = 0; | ||
| 3035 | } | 3023 | } |
| 3036 | 3024 | ||
| 3037 | 3025 | ||
| @@ -3064,7 +3052,6 @@ Its value and function definition are void, and its property list is nil. */) | |||
| 3064 | new->next = symbol_block; | 3052 | new->next = symbol_block; |
| 3065 | symbol_block = new; | 3053 | symbol_block = new; |
| 3066 | symbol_block_index = 0; | 3054 | symbol_block_index = 0; |
| 3067 | n_symbol_blocks++; | ||
| 3068 | } | 3055 | } |
| 3069 | XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index]); | 3056 | XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index]); |
| 3070 | symbol_block_index++; | 3057 | symbol_block_index++; |
| @@ -3112,17 +3099,12 @@ static int marker_block_index; | |||
| 3112 | 3099 | ||
| 3113 | static union Lisp_Misc *marker_free_list; | 3100 | static union Lisp_Misc *marker_free_list; |
| 3114 | 3101 | ||
| 3115 | /* Total number of marker blocks now in use. */ | ||
| 3116 | |||
| 3117 | static int n_marker_blocks; | ||
| 3118 | |||
| 3119 | static void | 3102 | static void |
| 3120 | init_marker (void) | 3103 | init_marker (void) |
| 3121 | { | 3104 | { |
| 3122 | marker_block = NULL; | 3105 | marker_block = NULL; |
| 3123 | marker_block_index = MARKER_BLOCK_SIZE; | 3106 | marker_block_index = MARKER_BLOCK_SIZE; |
| 3124 | marker_free_list = 0; | 3107 | marker_free_list = 0; |
| 3125 | n_marker_blocks = 0; | ||
| 3126 | } | 3108 | } |
| 3127 | 3109 | ||
| 3128 | /* Return a newly allocated Lisp_Misc object, with no substructure. */ | 3110 | /* Return a newly allocated Lisp_Misc object, with no substructure. */ |
| @@ -3151,7 +3133,6 @@ allocate_misc (void) | |||
| 3151 | new->next = marker_block; | 3133 | new->next = marker_block; |
| 3152 | marker_block = new; | 3134 | marker_block = new; |
| 3153 | marker_block_index = 0; | 3135 | marker_block_index = 0; |
| 3154 | n_marker_blocks++; | ||
| 3155 | total_free_markers += MARKER_BLOCK_SIZE; | 3136 | total_free_markers += MARKER_BLOCK_SIZE; |
| 3156 | } | 3137 | } |
| 3157 | XSETMISC (val, &marker_block->markers[marker_block_index]); | 3138 | XSETMISC (val, &marker_block->markers[marker_block_index]); |
| @@ -3184,7 +3165,7 @@ free_misc (Lisp_Object misc) | |||
| 3184 | The unwind function can get the C values back using XSAVE_VALUE. */ | 3165 | The unwind function can get the C values back using XSAVE_VALUE. */ |
| 3185 | 3166 | ||
| 3186 | Lisp_Object | 3167 | Lisp_Object |
| 3187 | make_save_value (void *pointer, int integer) | 3168 | make_save_value (void *pointer, ptrdiff_t integer) |
| 3188 | { | 3169 | { |
| 3189 | register Lisp_Object val; | 3170 | register Lisp_Object val; |
| 3190 | register struct Lisp_Save_Value *p; | 3171 | register struct Lisp_Save_Value *p; |
| @@ -3929,11 +3910,11 @@ static Lisp_Object zombies[MAX_ZOMBIES]; | |||
| 3929 | 3910 | ||
| 3930 | /* Number of zombie objects. */ | 3911 | /* Number of zombie objects. */ |
| 3931 | 3912 | ||
| 3932 | static int nzombies; | 3913 | static EMACS_INT nzombies; |
| 3933 | 3914 | ||
| 3934 | /* Number of garbage collections. */ | 3915 | /* Number of garbage collections. */ |
| 3935 | 3916 | ||
| 3936 | static int ngcs; | 3917 | static EMACS_INT ngcs; |
| 3937 | 3918 | ||
| 3938 | /* Average percentage of zombies per collection. */ | 3919 | /* Average percentage of zombies per collection. */ |
| 3939 | 3920 | ||
| @@ -3941,7 +3922,7 @@ static double avg_zombies; | |||
| 3941 | 3922 | ||
| 3942 | /* Max. number of live and zombie objects. */ | 3923 | /* Max. number of live and zombie objects. */ |
| 3943 | 3924 | ||
| 3944 | static int max_live, max_zombies; | 3925 | static EMACS_INT max_live, max_zombies; |
| 3945 | 3926 | ||
| 3946 | /* Average number of live objects per GC. */ | 3927 | /* Average number of live objects per GC. */ |
| 3947 | 3928 | ||
| @@ -3952,7 +3933,7 @@ DEFUN ("gc-status", Fgc_status, Sgc_status, 0, 0, "", | |||
| 3952 | (void) | 3933 | (void) |
| 3953 | { | 3934 | { |
| 3954 | Lisp_Object args[8], zombie_list = Qnil; | 3935 | Lisp_Object args[8], zombie_list = Qnil; |
| 3955 | int i; | 3936 | EMACS_INT i; |
| 3956 | for (i = 0; i < nzombies; i++) | 3937 | for (i = 0; i < nzombies; i++) |
| 3957 | zombie_list = Fcons (zombies[i], zombie_list); | 3938 | zombie_list = Fcons (zombies[i], zombie_list); |
| 3958 | args[0] = build_string ("%d GCs, avg live/zombies = %.2f/%.2f (%f%%), max %d/%d\nzombies: %S"); | 3939 | args[0] = build_string ("%d GCs, avg live/zombies = %.2f/%.2f (%f%%), max %d/%d\nzombies: %S"); |
| @@ -4262,7 +4243,7 @@ static void | |||
| 4262 | check_gcpros (void) | 4243 | check_gcpros (void) |
| 4263 | { | 4244 | { |
| 4264 | struct gcpro *p; | 4245 | struct gcpro *p; |
| 4265 | size_t i; | 4246 | ptrdiff_t i; |
| 4266 | 4247 | ||
| 4267 | for (p = gcprolist; p; p = p->next) | 4248 | for (p = gcprolist; p; p = p->next) |
| 4268 | for (i = 0; i < p->nvars; ++i) | 4249 | for (i = 0; i < p->nvars; ++i) |
| @@ -4279,7 +4260,7 @@ dump_zombies (void) | |||
| 4279 | { | 4260 | { |
| 4280 | int i; | 4261 | int i; |
| 4281 | 4262 | ||
| 4282 | fprintf (stderr, "\nZombies kept alive = %d:\n", nzombies); | 4263 | fprintf (stderr, "\nZombies kept alive = %"pI":\n", nzombies); |
| 4283 | for (i = 0; i < min (MAX_ZOMBIES, nzombies); ++i) | 4264 | for (i = 0; i < min (MAX_ZOMBIES, nzombies); ++i) |
| 4284 | { | 4265 | { |
| 4285 | fprintf (stderr, " %d = ", i); | 4266 | fprintf (stderr, " %d = ", i); |
| @@ -4851,9 +4832,8 @@ int | |||
| 4851 | inhibit_garbage_collection (void) | 4832 | inhibit_garbage_collection (void) |
| 4852 | { | 4833 | { |
| 4853 | int count = SPECPDL_INDEX (); | 4834 | int count = SPECPDL_INDEX (); |
| 4854 | int nbits = min (VALBITS, BITS_PER_INT); | ||
| 4855 | 4835 | ||
| 4856 | specbind (Qgc_cons_threshold, make_number (((EMACS_INT) 1 << (nbits - 1)) - 1)); | 4836 | specbind (Qgc_cons_threshold, make_number (MOST_POSITIVE_FIXNUM)); |
| 4857 | return count; | 4837 | return count; |
| 4858 | } | 4838 | } |
| 4859 | 4839 | ||
| @@ -4873,7 +4853,7 @@ returns nil, because real GC can't be done. */) | |||
| 4873 | { | 4853 | { |
| 4874 | register struct specbinding *bind; | 4854 | register struct specbinding *bind; |
| 4875 | char stack_top_variable; | 4855 | char stack_top_variable; |
| 4876 | register size_t i; | 4856 | ptrdiff_t i; |
| 4877 | int message_p; | 4857 | int message_p; |
| 4878 | Lisp_Object total[8]; | 4858 | Lisp_Object total[8]; |
| 4879 | int count = SPECPDL_INDEX (); | 4859 | int count = SPECPDL_INDEX (); |
| @@ -5103,9 +5083,10 @@ returns nil, because real GC can't be done. */) | |||
| 5103 | if (gc_cons_threshold < 10000) | 5083 | if (gc_cons_threshold < 10000) |
| 5104 | gc_cons_threshold = 10000; | 5084 | gc_cons_threshold = 10000; |
| 5105 | 5085 | ||
| 5086 | gc_relative_threshold = 0; | ||
| 5106 | if (FLOATP (Vgc_cons_percentage)) | 5087 | if (FLOATP (Vgc_cons_percentage)) |
| 5107 | { /* Set gc_cons_combined_threshold. */ | 5088 | { /* Set gc_cons_combined_threshold. */ |
| 5108 | EMACS_INT tot = 0; | 5089 | double tot = 0; |
| 5109 | 5090 | ||
| 5110 | tot += total_conses * sizeof (struct Lisp_Cons); | 5091 | tot += total_conses * sizeof (struct Lisp_Cons); |
| 5111 | tot += total_symbols * sizeof (struct Lisp_Symbol); | 5092 | tot += total_symbols * sizeof (struct Lisp_Symbol); |
| @@ -5116,10 +5097,15 @@ returns nil, because real GC can't be done. */) | |||
| 5116 | tot += total_intervals * sizeof (struct interval); | 5097 | tot += total_intervals * sizeof (struct interval); |
| 5117 | tot += total_strings * sizeof (struct Lisp_String); | 5098 | tot += total_strings * sizeof (struct Lisp_String); |
| 5118 | 5099 | ||
| 5119 | gc_relative_threshold = tot * XFLOAT_DATA (Vgc_cons_percentage); | 5100 | tot *= XFLOAT_DATA (Vgc_cons_percentage); |
| 5101 | if (0 < tot) | ||
| 5102 | { | ||
| 5103 | if (tot < TYPE_MAXIMUM (EMACS_INT)) | ||
| 5104 | gc_relative_threshold = tot; | ||
| 5105 | else | ||
| 5106 | gc_relative_threshold = TYPE_MAXIMUM (EMACS_INT); | ||
| 5107 | } | ||
| 5120 | } | 5108 | } |
| 5121 | else | ||
| 5122 | gc_relative_threshold = 0; | ||
| 5123 | 5109 | ||
| 5124 | if (garbage_collection_messages) | 5110 | if (garbage_collection_messages) |
| 5125 | { | 5111 | { |
| @@ -5250,8 +5236,8 @@ static size_t mark_object_loop_halt; | |||
| 5250 | static void | 5236 | static void |
| 5251 | mark_vectorlike (struct Lisp_Vector *ptr) | 5237 | mark_vectorlike (struct Lisp_Vector *ptr) |
| 5252 | { | 5238 | { |
| 5253 | register EMACS_UINT size = ptr->header.size; | 5239 | EMACS_INT size = ptr->header.size; |
| 5254 | register EMACS_UINT i; | 5240 | EMACS_INT i; |
| 5255 | 5241 | ||
| 5256 | eassert (!VECTOR_MARKED_P (ptr)); | 5242 | eassert (!VECTOR_MARKED_P (ptr)); |
| 5257 | VECTOR_MARK (ptr); /* Else mark it */ | 5243 | VECTOR_MARK (ptr); /* Else mark it */ |
| @@ -5273,8 +5259,8 @@ mark_vectorlike (struct Lisp_Vector *ptr) | |||
| 5273 | static void | 5259 | static void |
| 5274 | mark_char_table (struct Lisp_Vector *ptr) | 5260 | mark_char_table (struct Lisp_Vector *ptr) |
| 5275 | { | 5261 | { |
| 5276 | register EMACS_UINT size = ptr->header.size & PSEUDOVECTOR_SIZE_MASK; | 5262 | int size = ptr->header.size & PSEUDOVECTOR_SIZE_MASK; |
| 5277 | register EMACS_UINT i; | 5263 | int i; |
| 5278 | 5264 | ||
| 5279 | eassert (!VECTOR_MARKED_P (ptr)); | 5265 | eassert (!VECTOR_MARKED_P (ptr)); |
| 5280 | VECTOR_MARK (ptr); | 5266 | VECTOR_MARK (ptr); |
| @@ -5402,12 +5388,11 @@ mark_object (Lisp_Object arg) | |||
| 5402 | recursion there. */ | 5388 | recursion there. */ |
| 5403 | { | 5389 | { |
| 5404 | register struct Lisp_Vector *ptr = XVECTOR (obj); | 5390 | register struct Lisp_Vector *ptr = XVECTOR (obj); |
| 5405 | register EMACS_UINT size = ptr->header.size; | 5391 | int size = ptr->header.size & PSEUDOVECTOR_SIZE_MASK; |
| 5406 | register EMACS_UINT i; | 5392 | int i; |
| 5407 | 5393 | ||
| 5408 | CHECK_LIVE (live_vector_p); | 5394 | CHECK_LIVE (live_vector_p); |
| 5409 | VECTOR_MARK (ptr); /* Else mark it */ | 5395 | VECTOR_MARK (ptr); /* Else mark it */ |
| 5410 | size &= PSEUDOVECTOR_SIZE_MASK; | ||
| 5411 | for (i = 0; i < size; i++) /* and then mark its elements */ | 5396 | for (i = 0; i < size; i++) /* and then mark its elements */ |
| 5412 | { | 5397 | { |
| 5413 | if (i != COMPILED_CONSTANTS) | 5398 | if (i != COMPILED_CONSTANTS) |
| @@ -5534,7 +5519,7 @@ mark_object (Lisp_Object arg) | |||
| 5534 | if (ptr->dogc) | 5519 | if (ptr->dogc) |
| 5535 | { | 5520 | { |
| 5536 | Lisp_Object *p = (Lisp_Object *) ptr->pointer; | 5521 | Lisp_Object *p = (Lisp_Object *) ptr->pointer; |
| 5537 | int nelt; | 5522 | ptrdiff_t nelt; |
| 5538 | for (nelt = ptr->integer; nelt > 0; nelt--, p++) | 5523 | for (nelt = ptr->integer; nelt > 0; nelt--, p++) |
| 5539 | mark_maybe_object (*p); | 5524 | mark_maybe_object (*p); |
| 5540 | } | 5525 | } |
| @@ -5734,7 +5719,7 @@ gc_sweep (void) | |||
| 5734 | register struct cons_block *cblk; | 5719 | register struct cons_block *cblk; |
| 5735 | struct cons_block **cprev = &cons_block; | 5720 | struct cons_block **cprev = &cons_block; |
| 5736 | register int lim = cons_block_index; | 5721 | register int lim = cons_block_index; |
| 5737 | register int num_free = 0, num_used = 0; | 5722 | EMACS_INT num_free = 0, num_used = 0; |
| 5738 | 5723 | ||
| 5739 | cons_free_list = 0; | 5724 | cons_free_list = 0; |
| 5740 | 5725 | ||
| @@ -5795,7 +5780,6 @@ gc_sweep (void) | |||
| 5795 | /* Unhook from the free list. */ | 5780 | /* Unhook from the free list. */ |
| 5796 | cons_free_list = cblk->conses[0].u.chain; | 5781 | cons_free_list = cblk->conses[0].u.chain; |
| 5797 | lisp_align_free (cblk); | 5782 | lisp_align_free (cblk); |
| 5798 | n_cons_blocks--; | ||
| 5799 | } | 5783 | } |
| 5800 | else | 5784 | else |
| 5801 | { | 5785 | { |
| @@ -5812,7 +5796,7 @@ gc_sweep (void) | |||
| 5812 | register struct float_block *fblk; | 5796 | register struct float_block *fblk; |
| 5813 | struct float_block **fprev = &float_block; | 5797 | struct float_block **fprev = &float_block; |
| 5814 | register int lim = float_block_index; | 5798 | register int lim = float_block_index; |
| 5815 | register int num_free = 0, num_used = 0; | 5799 | EMACS_INT num_free = 0, num_used = 0; |
| 5816 | 5800 | ||
| 5817 | float_free_list = 0; | 5801 | float_free_list = 0; |
| 5818 | 5802 | ||
| @@ -5842,7 +5826,6 @@ gc_sweep (void) | |||
| 5842 | /* Unhook from the free list. */ | 5826 | /* Unhook from the free list. */ |
| 5843 | float_free_list = fblk->floats[0].u.chain; | 5827 | float_free_list = fblk->floats[0].u.chain; |
| 5844 | lisp_align_free (fblk); | 5828 | lisp_align_free (fblk); |
| 5845 | n_float_blocks--; | ||
| 5846 | } | 5829 | } |
| 5847 | else | 5830 | else |
| 5848 | { | 5831 | { |
| @@ -5859,7 +5842,7 @@ gc_sweep (void) | |||
| 5859 | register struct interval_block *iblk; | 5842 | register struct interval_block *iblk; |
| 5860 | struct interval_block **iprev = &interval_block; | 5843 | struct interval_block **iprev = &interval_block; |
| 5861 | register int lim = interval_block_index; | 5844 | register int lim = interval_block_index; |
| 5862 | register int num_free = 0, num_used = 0; | 5845 | EMACS_INT num_free = 0, num_used = 0; |
| 5863 | 5846 | ||
| 5864 | interval_free_list = 0; | 5847 | interval_free_list = 0; |
| 5865 | 5848 | ||
| @@ -5892,7 +5875,6 @@ gc_sweep (void) | |||
| 5892 | /* Unhook from the free list. */ | 5875 | /* Unhook from the free list. */ |
| 5893 | interval_free_list = INTERVAL_PARENT (&iblk->intervals[0]); | 5876 | interval_free_list = INTERVAL_PARENT (&iblk->intervals[0]); |
| 5894 | lisp_free (iblk); | 5877 | lisp_free (iblk); |
| 5895 | n_interval_blocks--; | ||
| 5896 | } | 5878 | } |
| 5897 | else | 5879 | else |
| 5898 | { | 5880 | { |
| @@ -5909,7 +5891,7 @@ gc_sweep (void) | |||
| 5909 | register struct symbol_block *sblk; | 5891 | register struct symbol_block *sblk; |
| 5910 | struct symbol_block **sprev = &symbol_block; | 5892 | struct symbol_block **sprev = &symbol_block; |
| 5911 | register int lim = symbol_block_index; | 5893 | register int lim = symbol_block_index; |
| 5912 | register int num_free = 0, num_used = 0; | 5894 | EMACS_INT num_free = 0, num_used = 0; |
| 5913 | 5895 | ||
| 5914 | symbol_free_list = NULL; | 5896 | symbol_free_list = NULL; |
| 5915 | 5897 | ||
| @@ -5956,7 +5938,6 @@ gc_sweep (void) | |||
| 5956 | /* Unhook from the free list. */ | 5938 | /* Unhook from the free list. */ |
| 5957 | symbol_free_list = sblk->symbols[0].next; | 5939 | symbol_free_list = sblk->symbols[0].next; |
| 5958 | lisp_free (sblk); | 5940 | lisp_free (sblk); |
| 5959 | n_symbol_blocks--; | ||
| 5960 | } | 5941 | } |
| 5961 | else | 5942 | else |
| 5962 | { | 5943 | { |
| @@ -5974,7 +5955,7 @@ gc_sweep (void) | |||
| 5974 | register struct marker_block *mblk; | 5955 | register struct marker_block *mblk; |
| 5975 | struct marker_block **mprev = &marker_block; | 5956 | struct marker_block **mprev = &marker_block; |
| 5976 | register int lim = marker_block_index; | 5957 | register int lim = marker_block_index; |
| 5977 | register int num_free = 0, num_used = 0; | 5958 | EMACS_INT num_free = 0, num_used = 0; |
| 5978 | 5959 | ||
| 5979 | marker_free_list = 0; | 5960 | marker_free_list = 0; |
| 5980 | 5961 | ||
| @@ -6013,7 +5994,6 @@ gc_sweep (void) | |||
| 6013 | /* Unhook from the free list. */ | 5994 | /* Unhook from the free list. */ |
| 6014 | marker_free_list = mblk->markers[0].u_free.chain; | 5995 | marker_free_list = mblk->markers[0].u_free.chain; |
| 6015 | lisp_free (mblk); | 5996 | lisp_free (mblk); |
| 6016 | n_marker_blocks--; | ||
| 6017 | } | 5997 | } |
| 6018 | else | 5998 | else |
| 6019 | { | 5999 | { |
| @@ -6063,7 +6043,6 @@ gc_sweep (void) | |||
| 6063 | all_vectors = vector->header.next.vector; | 6043 | all_vectors = vector->header.next.vector; |
| 6064 | next = vector->header.next.vector; | 6044 | next = vector->header.next.vector; |
| 6065 | lisp_free (vector); | 6045 | lisp_free (vector); |
| 6066 | n_vectors--; | ||
| 6067 | vector = next; | 6046 | vector = next; |
| 6068 | 6047 | ||
| 6069 | } | 6048 | } |