diff options
| author | Joakim Verona | 2011-06-16 00:22:07 +0200 |
|---|---|---|
| committer | Joakim Verona | 2011-06-16 00:22:07 +0200 |
| commit | a7513ade3bc0fe79430d5541d88c9dcda0932bec (patch) | |
| tree | 4383951ba698a11e9f8933a9d8c72e00aa872a10 /src/alloc.c | |
| parent | 4bd51ad5c3445b644dfb017d5b57b10a90aa325f (diff) | |
| parent | 4bba86e6210a74326e843a8fdc8409127105e1fe (diff) | |
| download | emacs-a7513ade3bc0fe79430d5541d88c9dcda0932bec.tar.gz emacs-a7513ade3bc0fe79430d5541d88c9dcda0932bec.zip | |
merge from upstream
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 709 |
1 files changed, 364 insertions, 345 deletions
diff --git a/src/alloc.c b/src/alloc.c index 67d34d25642..00d330c1b6a 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -22,10 +22,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 22 | #include <limits.h> /* For CHAR_BIT. */ | 22 | #include <limits.h> /* For CHAR_BIT. */ |
| 23 | #include <setjmp.h> | 23 | #include <setjmp.h> |
| 24 | 24 | ||
| 25 | #ifdef ALLOC_DEBUG | ||
| 26 | #undef INLINE | ||
| 27 | #endif | ||
| 28 | |||
| 29 | #include <signal.h> | 25 | #include <signal.h> |
| 30 | 26 | ||
| 31 | #ifdef HAVE_GTK_AND_PTHREAD | 27 | #ifdef HAVE_GTK_AND_PTHREAD |
| @@ -92,7 +88,8 @@ extern __malloc_size_t __malloc_extra_blocks; | |||
| 92 | 88 | ||
| 93 | #endif /* not DOUG_LEA_MALLOC */ | 89 | #endif /* not DOUG_LEA_MALLOC */ |
| 94 | 90 | ||
| 95 | #if ! defined (SYSTEM_MALLOC) && defined (HAVE_GTK_AND_PTHREAD) | 91 | #if ! defined SYSTEM_MALLOC && ! defined SYNC_INPUT |
| 92 | #ifdef HAVE_GTK_AND_PTHREAD | ||
| 96 | 93 | ||
| 97 | /* When GTK uses the file chooser dialog, different backends can be loaded | 94 | /* When GTK uses the file chooser dialog, different backends can be loaded |
| 98 | dynamically. One such a backend is the Gnome VFS backend that gets loaded | 95 | dynamically. One such a backend is the Gnome VFS backend that gets loaded |
| @@ -130,16 +127,13 @@ static pthread_mutex_t alloc_mutex; | |||
| 130 | } \ | 127 | } \ |
| 131 | while (0) | 128 | while (0) |
| 132 | 129 | ||
| 133 | #else /* SYSTEM_MALLOC || not HAVE_GTK_AND_PTHREAD */ | 130 | #else /* ! defined HAVE_GTK_AND_PTHREAD */ |
| 134 | 131 | ||
| 135 | #define BLOCK_INPUT_ALLOC BLOCK_INPUT | 132 | #define BLOCK_INPUT_ALLOC BLOCK_INPUT |
| 136 | #define UNBLOCK_INPUT_ALLOC UNBLOCK_INPUT | 133 | #define UNBLOCK_INPUT_ALLOC UNBLOCK_INPUT |
| 137 | 134 | ||
| 138 | #endif /* SYSTEM_MALLOC || not HAVE_GTK_AND_PTHREAD */ | 135 | #endif /* ! defined HAVE_GTK_AND_PTHREAD */ |
| 139 | 136 | #endif /* ! defined SYSTEM_MALLOC && ! defined SYNC_INPUT */ | |
| 140 | /* Value of _bytes_used, when spare_memory was freed. */ | ||
| 141 | |||
| 142 | static __malloc_size_t bytes_used_when_full; | ||
| 143 | 137 | ||
| 144 | /* Mark, unmark, query mark bit of a Lisp string. S must be a pointer | 138 | /* Mark, unmark, query mark bit of a Lisp string. S must be a pointer |
| 145 | to a struct Lisp_String. */ | 139 | to a struct Lisp_String. */ |
| @@ -148,24 +142,22 @@ static __malloc_size_t bytes_used_when_full; | |||
| 148 | #define UNMARK_STRING(S) ((S)->size &= ~ARRAY_MARK_FLAG) | 142 | #define UNMARK_STRING(S) ((S)->size &= ~ARRAY_MARK_FLAG) |
| 149 | #define STRING_MARKED_P(S) (((S)->size & ARRAY_MARK_FLAG) != 0) | 143 | #define STRING_MARKED_P(S) (((S)->size & ARRAY_MARK_FLAG) != 0) |
| 150 | 144 | ||
| 151 | #define VECTOR_MARK(V) ((V)->size |= ARRAY_MARK_FLAG) | 145 | #define VECTOR_MARK(V) ((V)->header.size |= ARRAY_MARK_FLAG) |
| 152 | #define VECTOR_UNMARK(V) ((V)->size &= ~ARRAY_MARK_FLAG) | 146 | #define VECTOR_UNMARK(V) ((V)->header.size &= ~ARRAY_MARK_FLAG) |
| 153 | #define VECTOR_MARKED_P(V) (((V)->size & ARRAY_MARK_FLAG) != 0) | 147 | #define VECTOR_MARKED_P(V) (((V)->header.size & ARRAY_MARK_FLAG) != 0) |
| 154 | 148 | ||
| 155 | /* Value is the number of bytes/chars of S, a pointer to a struct | 149 | /* Value is the number of bytes of S, a pointer to a struct Lisp_String. |
| 156 | Lisp_String. This must be used instead of STRING_BYTES (S) or | 150 | Be careful during GC, because S->size contains the mark bit for |
| 157 | S->size during GC, because S->size contains the mark bit for | ||
| 158 | strings. */ | 151 | strings. */ |
| 159 | 152 | ||
| 160 | #define GC_STRING_BYTES(S) (STRING_BYTES (S)) | 153 | #define GC_STRING_BYTES(S) (STRING_BYTES (S)) |
| 161 | #define GC_STRING_CHARS(S) ((S)->size & ~ARRAY_MARK_FLAG) | ||
| 162 | 154 | ||
| 163 | /* Global variables. */ | 155 | /* Global variables. */ |
| 164 | struct emacs_globals globals; | 156 | struct emacs_globals globals; |
| 165 | 157 | ||
| 166 | /* Number of bytes of consing done since the last gc. */ | 158 | /* Number of bytes of consing done since the last gc. */ |
| 167 | 159 | ||
| 168 | int consing_since_gc; | 160 | EMACS_INT consing_since_gc; |
| 169 | 161 | ||
| 170 | /* Similar minimum, computed from Vgc_cons_percentage. */ | 162 | /* Similar minimum, computed from Vgc_cons_percentage. */ |
| 171 | 163 | ||
| @@ -188,9 +180,9 @@ int abort_on_gc; | |||
| 188 | 180 | ||
| 189 | /* Number of live and free conses etc. */ | 181 | /* Number of live and free conses etc. */ |
| 190 | 182 | ||
| 191 | static int total_conses, total_markers, total_symbols, total_vector_size; | 183 | static EMACS_INT total_conses, total_markers, total_symbols, total_vector_size; |
| 192 | static int total_free_conses, total_free_markers, total_free_symbols; | 184 | static EMACS_INT total_free_conses, total_free_markers, total_free_symbols; |
| 193 | static int total_free_floats, total_floats; | 185 | static EMACS_INT total_free_floats, total_floats; |
| 194 | 186 | ||
| 195 | /* 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 |
| 196 | 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 |
| @@ -198,7 +190,8 @@ static int total_free_floats, total_floats; | |||
| 198 | 190 | ||
| 199 | static char *spare_memory[7]; | 191 | static char *spare_memory[7]; |
| 200 | 192 | ||
| 201 | /* Amount of spare memory to keep in large reserve block. */ | 193 | /* Amount of spare memory to keep in large reserve block, or to see |
| 194 | whether this much is available when malloc fails on a larger request. */ | ||
| 202 | 195 | ||
| 203 | #define SPARE_MEMORY (1 << 14) | 196 | #define SPARE_MEMORY (1 << 14) |
| 204 | 197 | ||
| @@ -212,6 +205,9 @@ static int malloc_hysteresis; | |||
| 212 | remapping on more recent systems because this is less important | 205 | remapping on more recent systems because this is less important |
| 213 | nowadays than in the days of small memories and timesharing. */ | 206 | nowadays than in the days of small memories and timesharing. */ |
| 214 | 207 | ||
| 208 | #ifndef VIRT_ADDR_VARIES | ||
| 209 | static | ||
| 210 | #endif | ||
| 215 | EMACS_INT pure[(PURESIZE + sizeof (EMACS_INT) - 1) / sizeof (EMACS_INT)] = {1,}; | 211 | EMACS_INT pure[(PURESIZE + sizeof (EMACS_INT) - 1) / sizeof (EMACS_INT)] = {1,}; |
| 216 | #define PUREBEG (char *) pure | 212 | #define PUREBEG (char *) pure |
| 217 | 213 | ||
| @@ -254,39 +250,37 @@ const char *pending_malloc_warning; | |||
| 254 | 250 | ||
| 255 | /* Buffer in which we save a copy of the C stack at each GC. */ | 251 | /* Buffer in which we save a copy of the C stack at each GC. */ |
| 256 | 252 | ||
| 253 | #if MAX_SAVE_STACK > 0 | ||
| 257 | static char *stack_copy; | 254 | static char *stack_copy; |
| 258 | static int stack_copy_size; | 255 | static size_t stack_copy_size; |
| 256 | #endif | ||
| 259 | 257 | ||
| 260 | /* Non-zero means ignore malloc warnings. Set during initialization. | 258 | /* Non-zero means ignore malloc warnings. Set during initialization. |
| 261 | Currently not used. */ | 259 | Currently not used. */ |
| 262 | 260 | ||
| 263 | static int ignore_warnings; | 261 | static int ignore_warnings; |
| 264 | 262 | ||
| 265 | Lisp_Object Qgc_cons_threshold, Qchar_table_extra_slots; | 263 | static Lisp_Object Qgc_cons_threshold; |
| 264 | Lisp_Object Qchar_table_extra_slots; | ||
| 266 | 265 | ||
| 267 | /* Hook run after GC has finished. */ | 266 | /* Hook run after GC has finished. */ |
| 268 | 267 | ||
| 269 | Lisp_Object Qpost_gc_hook; | 268 | static Lisp_Object Qpost_gc_hook; |
| 270 | 269 | ||
| 271 | static void mark_buffer (Lisp_Object); | 270 | static void mark_buffer (Lisp_Object); |
| 272 | static void mark_terminals (void); | 271 | static void mark_terminals (void); |
| 273 | extern void mark_kboards (void); | ||
| 274 | extern void mark_ttys (void); | ||
| 275 | extern void mark_backtrace (void); | ||
| 276 | static void gc_sweep (void); | 272 | static void gc_sweep (void); |
| 277 | static void mark_glyph_matrix (struct glyph_matrix *); | 273 | static void mark_glyph_matrix (struct glyph_matrix *); |
| 278 | static void mark_face_cache (struct face_cache *); | 274 | static void mark_face_cache (struct face_cache *); |
| 279 | 275 | ||
| 280 | #ifdef HAVE_WINDOW_SYSTEM | 276 | #if !defined REL_ALLOC || defined SYSTEM_MALLOC |
| 281 | extern void mark_fringe_data (void); | 277 | static void refill_memory_reserve (void); |
| 282 | #endif /* HAVE_WINDOW_SYSTEM */ | 278 | #endif |
| 283 | |||
| 284 | static struct Lisp_String *allocate_string (void); | 279 | static struct Lisp_String *allocate_string (void); |
| 285 | static void compact_small_strings (void); | 280 | static void compact_small_strings (void); |
| 286 | static void free_large_strings (void); | 281 | static void free_large_strings (void); |
| 287 | static void sweep_strings (void); | 282 | static void sweep_strings (void); |
| 288 | 283 | static void free_misc (Lisp_Object); | |
| 289 | extern int message_enable_multibyte; | ||
| 290 | 284 | ||
| 291 | /* When scanning the C stack for live Lisp objects, Emacs keeps track | 285 | /* When scanning the C stack for live Lisp objects, Emacs keeps track |
| 292 | of what memory allocated via lisp_malloc is intended for what | 286 | of what memory allocated via lisp_malloc is intended for what |
| @@ -409,7 +403,7 @@ static void mem_rotate_left (struct mem_node *); | |||
| 409 | static void mem_rotate_right (struct mem_node *); | 403 | static void mem_rotate_right (struct mem_node *); |
| 410 | static void mem_delete (struct mem_node *); | 404 | static void mem_delete (struct mem_node *); |
| 411 | static void mem_delete_fixup (struct mem_node *); | 405 | static void mem_delete_fixup (struct mem_node *); |
| 412 | static INLINE struct mem_node *mem_find (void *); | 406 | static inline struct mem_node *mem_find (void *); |
| 413 | 407 | ||
| 414 | 408 | ||
| 415 | #if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS | 409 | #if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS |
| @@ -439,7 +433,7 @@ static POINTER_TYPE *pure_alloc (size_t, int); | |||
| 439 | ALIGNMENT must be a power of 2. */ | 433 | ALIGNMENT must be a power of 2. */ |
| 440 | 434 | ||
| 441 | #define ALIGN(ptr, ALIGNMENT) \ | 435 | #define ALIGN(ptr, ALIGNMENT) \ |
| 442 | ((POINTER_TYPE *) ((((EMACS_UINT)(ptr)) + (ALIGNMENT) - 1) \ | 436 | ((POINTER_TYPE *) ((((uintptr_t) (ptr)) + (ALIGNMENT) - 1) \ |
| 443 | & ~((ALIGNMENT) - 1))) | 437 | & ~((ALIGNMENT) - 1))) |
| 444 | 438 | ||
| 445 | 439 | ||
| @@ -468,18 +462,11 @@ display_malloc_warning (void) | |||
| 468 | intern ("emergency")); | 462 | intern ("emergency")); |
| 469 | pending_malloc_warning = 0; | 463 | pending_malloc_warning = 0; |
| 470 | } | 464 | } |
| 471 | |||
| 472 | |||
| 473 | #ifdef DOUG_LEA_MALLOC | ||
| 474 | # define BYTES_USED (mallinfo ().uordblks) | ||
| 475 | #else | ||
| 476 | # define BYTES_USED _bytes_used | ||
| 477 | #endif | ||
| 478 | 465 | ||
| 479 | /* Called if we can't allocate relocatable space for a buffer. */ | 466 | /* Called if we can't allocate relocatable space for a buffer. */ |
| 480 | 467 | ||
| 481 | void | 468 | void |
| 482 | buffer_memory_full (void) | 469 | buffer_memory_full (EMACS_INT nbytes) |
| 483 | { | 470 | { |
| 484 | /* If buffers use the relocating allocator, no need to free | 471 | /* If buffers use the relocating allocator, no need to free |
| 485 | spare_memory, because we may have plenty of malloc space left | 472 | spare_memory, because we may have plenty of malloc space left |
| @@ -489,7 +476,7 @@ buffer_memory_full (void) | |||
| 489 | malloc. */ | 476 | malloc. */ |
| 490 | 477 | ||
| 491 | #ifndef REL_ALLOC | 478 | #ifndef REL_ALLOC |
| 492 | memory_full (); | 479 | memory_full (nbytes); |
| 493 | #endif | 480 | #endif |
| 494 | 481 | ||
| 495 | /* This used to call error, but if we've run out of memory, we could | 482 | /* This used to call error, but if we've run out of memory, we could |
| @@ -498,7 +485,9 @@ buffer_memory_full (void) | |||
| 498 | } | 485 | } |
| 499 | 486 | ||
| 500 | 487 | ||
| 501 | #ifdef XMALLOC_OVERRUN_CHECK | 488 | #ifndef XMALLOC_OVERRUN_CHECK |
| 489 | #define XMALLOC_OVERRUN_CHECK_SIZE 0 | ||
| 490 | #else | ||
| 502 | 491 | ||
| 503 | /* 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 |
| 504 | and a 16 byte trailer around each block. | 493 | and a 16 byte trailer around each block. |
| @@ -563,9 +552,8 @@ static int check_depth; | |||
| 563 | 552 | ||
| 564 | /* Like malloc, but wraps allocated block with header and trailer. */ | 553 | /* Like malloc, but wraps allocated block with header and trailer. */ |
| 565 | 554 | ||
| 566 | POINTER_TYPE * | 555 | static POINTER_TYPE * |
| 567 | overrun_check_malloc (size) | 556 | overrun_check_malloc (size_t size) |
| 568 | size_t size; | ||
| 569 | { | 557 | { |
| 570 | register unsigned char *val; | 558 | register unsigned char *val; |
| 571 | size_t overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_SIZE*2 : 0; | 559 | size_t overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_SIZE*2 : 0; |
| @@ -588,12 +576,10 @@ overrun_check_malloc (size) | |||
| 588 | /* Like realloc, but checks old block for overrun, and wraps new block | 576 | /* Like realloc, but checks old block for overrun, and wraps new block |
| 589 | with header and trailer. */ | 577 | with header and trailer. */ |
| 590 | 578 | ||
| 591 | POINTER_TYPE * | 579 | static POINTER_TYPE * |
| 592 | overrun_check_realloc (block, size) | 580 | overrun_check_realloc (POINTER_TYPE *block, size_t size) |
| 593 | POINTER_TYPE *block; | ||
| 594 | size_t size; | ||
| 595 | { | 581 | { |
| 596 | register unsigned char *val = (unsigned char *)block; | 582 | register unsigned char *val = (unsigned char *) block; |
| 597 | size_t overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_SIZE*2 : 0; | 583 | size_t overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_SIZE*2 : 0; |
| 598 | 584 | ||
| 599 | if (val | 585 | if (val |
| @@ -628,11 +614,10 @@ overrun_check_realloc (block, size) | |||
| 628 | 614 | ||
| 629 | /* Like free, but checks block for overrun. */ | 615 | /* Like free, but checks block for overrun. */ |
| 630 | 616 | ||
| 631 | void | 617 | static void |
| 632 | overrun_check_free (block) | 618 | overrun_check_free (POINTER_TYPE *block) |
| 633 | POINTER_TYPE *block; | ||
| 634 | { | 619 | { |
| 635 | unsigned char *val = (unsigned char *)block; | 620 | unsigned char *val = (unsigned char *) block; |
| 636 | 621 | ||
| 637 | ++check_depth; | 622 | ++check_depth; |
| 638 | if (val | 623 | if (val |
| @@ -689,7 +674,7 @@ xmalloc (size_t size) | |||
| 689 | MALLOC_UNBLOCK_INPUT; | 674 | MALLOC_UNBLOCK_INPUT; |
| 690 | 675 | ||
| 691 | if (!val && size) | 676 | if (!val && size) |
| 692 | memory_full (); | 677 | memory_full (size); |
| 693 | return val; | 678 | return val; |
| 694 | } | 679 | } |
| 695 | 680 | ||
| @@ -710,7 +695,8 @@ xrealloc (POINTER_TYPE *block, size_t size) | |||
| 710 | val = (POINTER_TYPE *) realloc (block, size); | 695 | val = (POINTER_TYPE *) realloc (block, size); |
| 711 | MALLOC_UNBLOCK_INPUT; | 696 | MALLOC_UNBLOCK_INPUT; |
| 712 | 697 | ||
| 713 | if (!val && size) memory_full (); | 698 | if (!val && size) |
| 699 | memory_full (size); | ||
| 714 | return val; | 700 | return val; |
| 715 | } | 701 | } |
| 716 | 702 | ||
| @@ -803,7 +789,7 @@ lisp_malloc (size_t nbytes, enum mem_type type) | |||
| 803 | 789 | ||
| 804 | MALLOC_UNBLOCK_INPUT; | 790 | MALLOC_UNBLOCK_INPUT; |
| 805 | if (!val && nbytes) | 791 | if (!val && nbytes) |
| 806 | memory_full (); | 792 | memory_full (nbytes); |
| 807 | return val; | 793 | return val; |
| 808 | } | 794 | } |
| 809 | 795 | ||
| @@ -847,7 +833,7 @@ lisp_free (POINTER_TYPE *block) | |||
| 847 | nothing else. */ | 833 | nothing else. */ |
| 848 | #define BLOCK_PADDING 0 | 834 | #define BLOCK_PADDING 0 |
| 849 | #define BLOCK_BYTES \ | 835 | #define BLOCK_BYTES \ |
| 850 | (BLOCK_ALIGN - sizeof (struct ablock *) - BLOCK_PADDING) | 836 | (BLOCK_ALIGN - sizeof (struct ablocks *) - BLOCK_PADDING) |
| 851 | 837 | ||
| 852 | /* Internal data structures and constants. */ | 838 | /* Internal data structures and constants. */ |
| 853 | 839 | ||
| @@ -888,7 +874,7 @@ struct ablocks | |||
| 888 | #define ABLOCKS_BYTES (sizeof (struct ablocks) - BLOCK_PADDING) | 874 | #define ABLOCKS_BYTES (sizeof (struct ablocks) - BLOCK_PADDING) |
| 889 | 875 | ||
| 890 | #define ABLOCK_ABASE(block) \ | 876 | #define ABLOCK_ABASE(block) \ |
| 891 | (((unsigned long) (block)->abase) <= (1 + 2 * ABLOCKS_SIZE) \ | 877 | (((uintptr_t) (block)->abase) <= (1 + 2 * ABLOCKS_SIZE) \ |
| 892 | ? (struct ablocks *)(block) \ | 878 | ? (struct ablocks *)(block) \ |
| 893 | : (block)->abase) | 879 | : (block)->abase) |
| 894 | 880 | ||
| @@ -900,7 +886,7 @@ struct ablocks | |||
| 900 | #define ABLOCKS_BASE(abase) (abase) | 886 | #define ABLOCKS_BASE(abase) (abase) |
| 901 | #else | 887 | #else |
| 902 | #define ABLOCKS_BASE(abase) \ | 888 | #define ABLOCKS_BASE(abase) \ |
| 903 | (1 & (long) ABLOCKS_BUSY (abase) ? abase : ((void**)abase)[-1]) | 889 | (1 & (intptr_t) ABLOCKS_BUSY (abase) ? abase : ((void**)abase)[-1]) |
| 904 | #endif | 890 | #endif |
| 905 | 891 | ||
| 906 | /* The list of free ablock. */ | 892 | /* The list of free ablock. */ |
| @@ -926,7 +912,7 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) | |||
| 926 | if (!free_ablock) | 912 | if (!free_ablock) |
| 927 | { | 913 | { |
| 928 | int i; | 914 | int i; |
| 929 | EMACS_INT aligned; /* int gets warning casting to 64-bit pointer. */ | 915 | intptr_t aligned; /* int gets warning casting to 64-bit pointer. */ |
| 930 | 916 | ||
| 931 | #ifdef DOUG_LEA_MALLOC | 917 | #ifdef DOUG_LEA_MALLOC |
| 932 | /* Prevent mmap'ing the chunk. Lisp data may not be mmap'ed | 918 | /* Prevent mmap'ing the chunk. Lisp data may not be mmap'ed |
| @@ -950,7 +936,7 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) | |||
| 950 | if (base == 0) | 936 | if (base == 0) |
| 951 | { | 937 | { |
| 952 | MALLOC_UNBLOCK_INPUT; | 938 | MALLOC_UNBLOCK_INPUT; |
| 953 | memory_full (); | 939 | memory_full (ABLOCKS_BYTES); |
| 954 | } | 940 | } |
| 955 | 941 | ||
| 956 | aligned = (base == abase); | 942 | aligned = (base == abase); |
| @@ -976,7 +962,7 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) | |||
| 976 | lisp_malloc_loser = base; | 962 | lisp_malloc_loser = base; |
| 977 | free (base); | 963 | free (base); |
| 978 | MALLOC_UNBLOCK_INPUT; | 964 | MALLOC_UNBLOCK_INPUT; |
| 979 | memory_full (); | 965 | memory_full (SIZE_MAX); |
| 980 | } | 966 | } |
| 981 | } | 967 | } |
| 982 | #endif | 968 | #endif |
| @@ -989,30 +975,29 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) | |||
| 989 | abase->blocks[i].x.next_free = free_ablock; | 975 | abase->blocks[i].x.next_free = free_ablock; |
| 990 | free_ablock = &abase->blocks[i]; | 976 | free_ablock = &abase->blocks[i]; |
| 991 | } | 977 | } |
| 992 | ABLOCKS_BUSY (abase) = (struct ablocks *) (long) aligned; | 978 | ABLOCKS_BUSY (abase) = (struct ablocks *) aligned; |
| 993 | 979 | ||
| 994 | eassert (0 == ((EMACS_UINT)abase) % BLOCK_ALIGN); | 980 | eassert (0 == ((uintptr_t) abase) % BLOCK_ALIGN); |
| 995 | eassert (ABLOCK_ABASE (&abase->blocks[3]) == abase); /* 3 is arbitrary */ | 981 | eassert (ABLOCK_ABASE (&abase->blocks[3]) == abase); /* 3 is arbitrary */ |
| 996 | eassert (ABLOCK_ABASE (&abase->blocks[0]) == abase); | 982 | eassert (ABLOCK_ABASE (&abase->blocks[0]) == abase); |
| 997 | eassert (ABLOCKS_BASE (abase) == base); | 983 | eassert (ABLOCKS_BASE (abase) == base); |
| 998 | eassert (aligned == (long) ABLOCKS_BUSY (abase)); | 984 | eassert (aligned == (intptr_t) ABLOCKS_BUSY (abase)); |
| 999 | } | 985 | } |
| 1000 | 986 | ||
| 1001 | abase = ABLOCK_ABASE (free_ablock); | 987 | abase = ABLOCK_ABASE (free_ablock); |
| 1002 | ABLOCKS_BUSY (abase) = (struct ablocks *) (2 + (long) ABLOCKS_BUSY (abase)); | 988 | ABLOCKS_BUSY (abase) = |
| 989 | (struct ablocks *) (2 + (intptr_t) ABLOCKS_BUSY (abase)); | ||
| 1003 | val = free_ablock; | 990 | val = free_ablock; |
| 1004 | free_ablock = free_ablock->x.next_free; | 991 | free_ablock = free_ablock->x.next_free; |
| 1005 | 992 | ||
| 1006 | #if GC_MARK_STACK && !defined GC_MALLOC_CHECK | 993 | #if GC_MARK_STACK && !defined GC_MALLOC_CHECK |
| 1007 | if (val && type != MEM_TYPE_NON_LISP) | 994 | if (type != MEM_TYPE_NON_LISP) |
| 1008 | mem_insert (val, (char *) val + nbytes, type); | 995 | mem_insert (val, (char *) val + nbytes, type); |
| 1009 | #endif | 996 | #endif |
| 1010 | 997 | ||
| 1011 | MALLOC_UNBLOCK_INPUT; | 998 | MALLOC_UNBLOCK_INPUT; |
| 1012 | if (!val && nbytes) | ||
| 1013 | memory_full (); | ||
| 1014 | 999 | ||
| 1015 | eassert (0 == ((EMACS_UINT)val) % BLOCK_ALIGN); | 1000 | eassert (0 == ((uintptr_t) val) % BLOCK_ALIGN); |
| 1016 | return val; | 1001 | return val; |
| 1017 | } | 1002 | } |
| 1018 | 1003 | ||
| @@ -1030,11 +1015,12 @@ lisp_align_free (POINTER_TYPE *block) | |||
| 1030 | ablock->x.next_free = free_ablock; | 1015 | ablock->x.next_free = free_ablock; |
| 1031 | free_ablock = ablock; | 1016 | free_ablock = ablock; |
| 1032 | /* Update busy count. */ | 1017 | /* Update busy count. */ |
| 1033 | ABLOCKS_BUSY (abase) = (struct ablocks *) (-2 + (long) ABLOCKS_BUSY (abase)); | 1018 | ABLOCKS_BUSY (abase) = |
| 1019 | (struct ablocks *) (-2 + (intptr_t) ABLOCKS_BUSY (abase)); | ||
| 1034 | 1020 | ||
| 1035 | if (2 > (long) ABLOCKS_BUSY (abase)) | 1021 | if (2 > (intptr_t) ABLOCKS_BUSY (abase)) |
| 1036 | { /* All the blocks are free. */ | 1022 | { /* All the blocks are free. */ |
| 1037 | int i = 0, aligned = (long) ABLOCKS_BUSY (abase); | 1023 | int i = 0, aligned = (intptr_t) ABLOCKS_BUSY (abase); |
| 1038 | struct ablock **tem = &free_ablock; | 1024 | struct ablock **tem = &free_ablock; |
| 1039 | struct ablock *atop = &abase->blocks[aligned ? ABLOCKS_SIZE : ABLOCKS_SIZE - 1]; | 1025 | struct ablock *atop = &abase->blocks[aligned ? ABLOCKS_SIZE : ABLOCKS_SIZE - 1]; |
| 1040 | 1026 | ||
| @@ -1051,7 +1037,7 @@ lisp_align_free (POINTER_TYPE *block) | |||
| 1051 | eassert ((aligned & 1) == aligned); | 1037 | eassert ((aligned & 1) == aligned); |
| 1052 | eassert (i == (aligned ? ABLOCKS_SIZE : ABLOCKS_SIZE - 1)); | 1038 | eassert (i == (aligned ? ABLOCKS_SIZE : ABLOCKS_SIZE - 1)); |
| 1053 | #ifdef USE_POSIX_MEMALIGN | 1039 | #ifdef USE_POSIX_MEMALIGN |
| 1054 | eassert ((unsigned long)ABLOCKS_BASE (abase) % BLOCK_ALIGN == 0); | 1040 | eassert ((uintptr_t) ABLOCKS_BASE (abase) % BLOCK_ALIGN == 0); |
| 1055 | #endif | 1041 | #endif |
| 1056 | free (ABLOCKS_BASE (abase)); | 1042 | free (ABLOCKS_BASE (abase)); |
| 1057 | } | 1043 | } |
| @@ -1067,8 +1053,9 @@ allocate_buffer (void) | |||
| 1067 | struct buffer *b | 1053 | struct buffer *b |
| 1068 | = (struct buffer *) lisp_malloc (sizeof (struct buffer), | 1054 | = (struct buffer *) lisp_malloc (sizeof (struct buffer), |
| 1069 | MEM_TYPE_BUFFER); | 1055 | MEM_TYPE_BUFFER); |
| 1070 | b->size = sizeof (struct buffer) / sizeof (EMACS_INT); | 1056 | XSETPVECTYPESIZE (b, PVEC_BUFFER, |
| 1071 | XSETPVECTYPE (b, PVEC_BUFFER); | 1057 | ((sizeof (struct buffer) + sizeof (EMACS_INT) - 1) |
| 1058 | / sizeof (EMACS_INT))); | ||
| 1072 | return b; | 1059 | return b; |
| 1073 | } | 1060 | } |
| 1074 | 1061 | ||
| @@ -1099,8 +1086,18 @@ static void * (*old_malloc_hook) (size_t, const void *); | |||
| 1099 | static void * (*old_realloc_hook) (void *, size_t, const void*); | 1086 | static void * (*old_realloc_hook) (void *, size_t, const void*); |
| 1100 | static void (*old_free_hook) (void*, const void*); | 1087 | static void (*old_free_hook) (void*, const void*); |
| 1101 | 1088 | ||
| 1089 | #ifdef DOUG_LEA_MALLOC | ||
| 1090 | # define BYTES_USED (mallinfo ().uordblks) | ||
| 1091 | #else | ||
| 1092 | # define BYTES_USED _bytes_used | ||
| 1093 | #endif | ||
| 1094 | |||
| 1102 | static __malloc_size_t bytes_used_when_reconsidered; | 1095 | static __malloc_size_t bytes_used_when_reconsidered; |
| 1103 | 1096 | ||
| 1097 | /* Value of _bytes_used, when spare_memory was freed. */ | ||
| 1098 | |||
| 1099 | static __malloc_size_t bytes_used_when_full; | ||
| 1100 | |||
| 1104 | /* This function is used as the hook for free to call. */ | 1101 | /* This function is used as the hook for free to call. */ |
| 1105 | 1102 | ||
| 1106 | static void | 1103 | static void |
| @@ -1341,15 +1338,11 @@ static int interval_block_index; | |||
| 1341 | 1338 | ||
| 1342 | /* Number of free and live intervals. */ | 1339 | /* Number of free and live intervals. */ |
| 1343 | 1340 | ||
| 1344 | static int total_free_intervals, total_intervals; | 1341 | static EMACS_INT total_free_intervals, total_intervals; |
| 1345 | 1342 | ||
| 1346 | /* List of free intervals. */ | 1343 | /* List of free intervals. */ |
| 1347 | 1344 | ||
| 1348 | INTERVAL interval_free_list; | 1345 | static INTERVAL interval_free_list; |
| 1349 | |||
| 1350 | /* Total number of interval blocks now in use. */ | ||
| 1351 | |||
| 1352 | static int n_interval_blocks; | ||
| 1353 | 1346 | ||
| 1354 | 1347 | ||
| 1355 | /* Initialize interval allocation. */ | 1348 | /* Initialize interval allocation. */ |
| @@ -1360,7 +1353,6 @@ init_intervals (void) | |||
| 1360 | interval_block = NULL; | 1353 | interval_block = NULL; |
| 1361 | interval_block_index = INTERVAL_BLOCK_SIZE; | 1354 | interval_block_index = INTERVAL_BLOCK_SIZE; |
| 1362 | interval_free_list = 0; | 1355 | interval_free_list = 0; |
| 1363 | n_interval_blocks = 0; | ||
| 1364 | } | 1356 | } |
| 1365 | 1357 | ||
| 1366 | 1358 | ||
| @@ -1392,7 +1384,6 @@ make_interval (void) | |||
| 1392 | newi->next = interval_block; | 1384 | newi->next = interval_block; |
| 1393 | interval_block = newi; | 1385 | interval_block = newi; |
| 1394 | interval_block_index = 0; | 1386 | interval_block_index = 0; |
| 1395 | n_interval_blocks++; | ||
| 1396 | } | 1387 | } |
| 1397 | val = &interval_block->intervals[interval_block_index++]; | 1388 | val = &interval_block->intervals[interval_block_index++]; |
| 1398 | } | 1389 | } |
| @@ -1518,23 +1509,26 @@ struct sdata | |||
| 1518 | 1509 | ||
| 1519 | #define SDATA_NBYTES(S) (S)->nbytes | 1510 | #define SDATA_NBYTES(S) (S)->nbytes |
| 1520 | #define SDATA_DATA(S) (S)->data | 1511 | #define SDATA_DATA(S) (S)->data |
| 1512 | #define SDATA_SELECTOR(member) member | ||
| 1521 | 1513 | ||
| 1522 | #else /* not GC_CHECK_STRING_BYTES */ | 1514 | #else /* not GC_CHECK_STRING_BYTES */ |
| 1523 | 1515 | ||
| 1524 | union | 1516 | union |
| 1525 | { | 1517 | { |
| 1526 | /* When STRING in non-null. */ | 1518 | /* When STRING is non-null. */ |
| 1527 | unsigned char data[1]; | 1519 | unsigned char data[1]; |
| 1528 | 1520 | ||
| 1529 | /* When STRING is null. */ | 1521 | /* When STRING is null. */ |
| 1530 | EMACS_INT nbytes; | 1522 | EMACS_INT nbytes; |
| 1531 | } u; | 1523 | } u; |
| 1532 | 1524 | ||
| 1533 | |||
| 1534 | #define SDATA_NBYTES(S) (S)->u.nbytes | 1525 | #define SDATA_NBYTES(S) (S)->u.nbytes |
| 1535 | #define SDATA_DATA(S) (S)->u.data | 1526 | #define SDATA_DATA(S) (S)->u.data |
| 1527 | #define SDATA_SELECTOR(member) u.member | ||
| 1536 | 1528 | ||
| 1537 | #endif /* not GC_CHECK_STRING_BYTES */ | 1529 | #endif /* not GC_CHECK_STRING_BYTES */ |
| 1530 | |||
| 1531 | #define SDATA_DATA_OFFSET offsetof (struct sdata, SDATA_SELECTOR (data)) | ||
| 1538 | }; | 1532 | }; |
| 1539 | 1533 | ||
| 1540 | 1534 | ||
| @@ -1582,10 +1576,9 @@ static struct sblock *oldest_sblock, *current_sblock; | |||
| 1582 | 1576 | ||
| 1583 | static struct sblock *large_sblocks; | 1577 | static struct sblock *large_sblocks; |
| 1584 | 1578 | ||
| 1585 | /* List of string_block structures, and how many there are. */ | 1579 | /* List of string_block structures. */ |
| 1586 | 1580 | ||
| 1587 | static struct string_block *string_blocks; | 1581 | static struct string_block *string_blocks; |
| 1588 | static int n_string_blocks; | ||
| 1589 | 1582 | ||
| 1590 | /* Free-list of Lisp_Strings. */ | 1583 | /* Free-list of Lisp_Strings. */ |
| 1591 | 1584 | ||
| @@ -1593,7 +1586,7 @@ static struct Lisp_String *string_free_list; | |||
| 1593 | 1586 | ||
| 1594 | /* Number of live and free Lisp_Strings. */ | 1587 | /* Number of live and free Lisp_Strings. */ |
| 1595 | 1588 | ||
| 1596 | static int total_strings, total_free_strings; | 1589 | static EMACS_INT total_strings, total_free_strings; |
| 1597 | 1590 | ||
| 1598 | /* Number of bytes used by live strings. */ | 1591 | /* Number of bytes used by live strings. */ |
| 1599 | 1592 | ||
| @@ -1610,18 +1603,7 @@ static EMACS_INT total_string_size; | |||
| 1610 | a pointer to the `u.data' member of its sdata structure; the | 1603 | a pointer to the `u.data' member of its sdata structure; the |
| 1611 | structure starts at a constant offset in front of that. */ | 1604 | structure starts at a constant offset in front of that. */ |
| 1612 | 1605 | ||
| 1613 | #ifdef GC_CHECK_STRING_BYTES | 1606 | #define SDATA_OF_STRING(S) ((struct sdata *) ((S)->data - SDATA_DATA_OFFSET)) |
| 1614 | |||
| 1615 | #define SDATA_OF_STRING(S) \ | ||
| 1616 | ((struct sdata *) ((S)->data - sizeof (struct Lisp_String *) \ | ||
| 1617 | - sizeof (EMACS_INT))) | ||
| 1618 | |||
| 1619 | #else /* not GC_CHECK_STRING_BYTES */ | ||
| 1620 | |||
| 1621 | #define SDATA_OF_STRING(S) \ | ||
| 1622 | ((struct sdata *) ((S)->data - sizeof (struct Lisp_String *))) | ||
| 1623 | |||
| 1624 | #endif /* not GC_CHECK_STRING_BYTES */ | ||
| 1625 | 1607 | ||
| 1626 | 1608 | ||
| 1627 | #ifdef GC_CHECK_STRING_OVERRUN | 1609 | #ifdef GC_CHECK_STRING_OVERRUN |
| @@ -1631,8 +1613,8 @@ static EMACS_INT total_string_size; | |||
| 1631 | presence of this cookie during GC. */ | 1613 | presence of this cookie during GC. */ |
| 1632 | 1614 | ||
| 1633 | #define GC_STRING_OVERRUN_COOKIE_SIZE 4 | 1615 | #define GC_STRING_OVERRUN_COOKIE_SIZE 4 |
| 1634 | static char string_overrun_cookie[GC_STRING_OVERRUN_COOKIE_SIZE] = | 1616 | static char const string_overrun_cookie[GC_STRING_OVERRUN_COOKIE_SIZE] = |
| 1635 | { 0xde, 0xad, 0xbe, 0xef }; | 1617 | { '\xde', '\xad', '\xbe', '\xef' }; |
| 1636 | 1618 | ||
| 1637 | #else | 1619 | #else |
| 1638 | #define GC_STRING_OVERRUN_COOKIE_SIZE 0 | 1620 | #define GC_STRING_OVERRUN_COOKIE_SIZE 0 |
| @@ -1645,18 +1627,25 @@ static char string_overrun_cookie[GC_STRING_OVERRUN_COOKIE_SIZE] = | |||
| 1645 | #ifdef GC_CHECK_STRING_BYTES | 1627 | #ifdef GC_CHECK_STRING_BYTES |
| 1646 | 1628 | ||
| 1647 | #define SDATA_SIZE(NBYTES) \ | 1629 | #define SDATA_SIZE(NBYTES) \ |
| 1648 | ((sizeof (struct Lisp_String *) \ | 1630 | ((SDATA_DATA_OFFSET \ |
| 1649 | + (NBYTES) + 1 \ | 1631 | + (NBYTES) + 1 \ |
| 1650 | + sizeof (EMACS_INT) \ | ||
| 1651 | + sizeof (EMACS_INT) - 1) \ | 1632 | + sizeof (EMACS_INT) - 1) \ |
| 1652 | & ~(sizeof (EMACS_INT) - 1)) | 1633 | & ~(sizeof (EMACS_INT) - 1)) |
| 1653 | 1634 | ||
| 1654 | #else /* not GC_CHECK_STRING_BYTES */ | 1635 | #else /* not GC_CHECK_STRING_BYTES */ |
| 1655 | 1636 | ||
| 1656 | #define SDATA_SIZE(NBYTES) \ | 1637 | /* The 'max' reserves space for the nbytes union member even when NBYTES + 1 is |
| 1657 | ((sizeof (struct Lisp_String *) \ | 1638 | less than the size of that member. The 'max' is not needed when |
| 1658 | + (NBYTES) + 1 \ | 1639 | SDATA_DATA_OFFSET is a multiple of sizeof (EMACS_INT), because then the |
| 1659 | + sizeof (EMACS_INT) - 1) \ | 1640 | alignment code reserves enough space. */ |
| 1641 | |||
| 1642 | #define SDATA_SIZE(NBYTES) \ | ||
| 1643 | ((SDATA_DATA_OFFSET \ | ||
| 1644 | + (SDATA_DATA_OFFSET % sizeof (EMACS_INT) == 0 \ | ||
| 1645 | ? NBYTES \ | ||
| 1646 | : max (NBYTES, sizeof (EMACS_INT) - 1)) \ | ||
| 1647 | + 1 \ | ||
| 1648 | + sizeof (EMACS_INT) - 1) \ | ||
| 1660 | & ~(sizeof (EMACS_INT) - 1)) | 1649 | & ~(sizeof (EMACS_INT) - 1)) |
| 1661 | 1650 | ||
| 1662 | #endif /* not GC_CHECK_STRING_BYTES */ | 1651 | #endif /* not GC_CHECK_STRING_BYTES */ |
| @@ -1665,6 +1654,18 @@ static char string_overrun_cookie[GC_STRING_OVERRUN_COOKIE_SIZE] = | |||
| 1665 | 1654 | ||
| 1666 | #define GC_STRING_EXTRA (GC_STRING_OVERRUN_COOKIE_SIZE) | 1655 | #define GC_STRING_EXTRA (GC_STRING_OVERRUN_COOKIE_SIZE) |
| 1667 | 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 | |||
| 1668 | /* Initialize string allocation. Called from init_alloc_once. */ | 1669 | /* Initialize string allocation. Called from init_alloc_once. */ |
| 1669 | 1670 | ||
| 1670 | static void | 1671 | static void |
| @@ -1673,7 +1674,6 @@ init_strings (void) | |||
| 1673 | total_strings = total_free_strings = total_string_size = 0; | 1674 | total_strings = total_free_strings = total_string_size = 0; |
| 1674 | oldest_sblock = current_sblock = large_sblocks = NULL; | 1675 | oldest_sblock = current_sblock = large_sblocks = NULL; |
| 1675 | string_blocks = NULL; | 1676 | string_blocks = NULL; |
| 1676 | n_string_blocks = 0; | ||
| 1677 | string_free_list = NULL; | 1677 | string_free_list = NULL; |
| 1678 | empty_unibyte_string = make_pure_string ("", 0, 0, 0); | 1678 | empty_unibyte_string = make_pure_string ("", 0, 0, 0); |
| 1679 | empty_multibyte_string = make_pure_string ("", 0, 0, 1); | 1679 | empty_multibyte_string = make_pure_string ("", 0, 0, 1); |
| @@ -1684,9 +1684,6 @@ init_strings (void) | |||
| 1684 | 1684 | ||
| 1685 | static int check_string_bytes_count; | 1685 | static int check_string_bytes_count; |
| 1686 | 1686 | ||
| 1687 | static void check_string_bytes (int); | ||
| 1688 | static void check_sblock (struct sblock *); | ||
| 1689 | |||
| 1690 | #define CHECK_STRING_BYTES(S) STRING_BYTES (S) | 1687 | #define CHECK_STRING_BYTES(S) STRING_BYTES (S) |
| 1691 | 1688 | ||
| 1692 | 1689 | ||
| @@ -1708,8 +1705,7 @@ string_bytes (struct Lisp_String *s) | |||
| 1708 | /* Check validity of Lisp strings' string_bytes member in B. */ | 1705 | /* Check validity of Lisp strings' string_bytes member in B. */ |
| 1709 | 1706 | ||
| 1710 | static void | 1707 | static void |
| 1711 | check_sblock (b) | 1708 | check_sblock (struct sblock *b) |
| 1712 | struct sblock *b; | ||
| 1713 | { | 1709 | { |
| 1714 | struct sdata *from, *end, *from_end; | 1710 | struct sdata *from, *end, *from_end; |
| 1715 | 1711 | ||
| @@ -1742,8 +1738,7 @@ check_sblock (b) | |||
| 1742 | recently allocated strings. Used for hunting a bug. */ | 1738 | recently allocated strings. Used for hunting a bug. */ |
| 1743 | 1739 | ||
| 1744 | static void | 1740 | static void |
| 1745 | check_string_bytes (all_p) | 1741 | check_string_bytes (int all_p) |
| 1746 | int all_p; | ||
| 1747 | { | 1742 | { |
| 1748 | if (all_p) | 1743 | if (all_p) |
| 1749 | { | 1744 | { |
| @@ -1771,7 +1766,7 @@ check_string_bytes (all_p) | |||
| 1771 | This may catch buffer overrun from a previous string. */ | 1766 | This may catch buffer overrun from a previous string. */ |
| 1772 | 1767 | ||
| 1773 | static void | 1768 | static void |
| 1774 | check_string_free_list () | 1769 | check_string_free_list (void) |
| 1775 | { | 1770 | { |
| 1776 | struct Lisp_String *s; | 1771 | struct Lisp_String *s; |
| 1777 | 1772 | ||
| @@ -1779,7 +1774,7 @@ check_string_free_list () | |||
| 1779 | s = string_free_list; | 1774 | s = string_free_list; |
| 1780 | while (s != NULL) | 1775 | while (s != NULL) |
| 1781 | { | 1776 | { |
| 1782 | if ((unsigned long)s < 1024) | 1777 | if ((uintptr_t) s < 1024) |
| 1783 | abort(); | 1778 | abort(); |
| 1784 | s = NEXT_FREE_LISP_STRING (s); | 1779 | s = NEXT_FREE_LISP_STRING (s); |
| 1785 | } | 1780 | } |
| @@ -1810,7 +1805,6 @@ allocate_string (void) | |||
| 1810 | memset (b, 0, sizeof *b); | 1805 | memset (b, 0, sizeof *b); |
| 1811 | b->next = string_blocks; | 1806 | b->next = string_blocks; |
| 1812 | string_blocks = b; | 1807 | string_blocks = b; |
| 1813 | ++n_string_blocks; | ||
| 1814 | 1808 | ||
| 1815 | for (i = STRING_BLOCK_SIZE - 1; i >= 0; --i) | 1809 | for (i = STRING_BLOCK_SIZE - 1; i >= 0; --i) |
| 1816 | { | 1810 | { |
| @@ -1869,6 +1863,9 @@ allocate_string_data (struct Lisp_String *s, | |||
| 1869 | struct sblock *b; | 1863 | struct sblock *b; |
| 1870 | EMACS_INT needed, old_nbytes; | 1864 | EMACS_INT needed, old_nbytes; |
| 1871 | 1865 | ||
| 1866 | if (STRING_BYTES_MAX < nbytes) | ||
| 1867 | string_overflow (); | ||
| 1868 | |||
| 1872 | /* Determine the number of bytes needed to store NBYTES bytes | 1869 | /* Determine the number of bytes needed to store NBYTES bytes |
| 1873 | of string data. */ | 1870 | of string data. */ |
| 1874 | needed = SDATA_SIZE (nbytes); | 1871 | needed = SDATA_SIZE (nbytes); |
| @@ -1879,7 +1876,7 @@ allocate_string_data (struct Lisp_String *s, | |||
| 1879 | 1876 | ||
| 1880 | if (nbytes > LARGE_STRING_BYTES) | 1877 | if (nbytes > LARGE_STRING_BYTES) |
| 1881 | { | 1878 | { |
| 1882 | size_t size = sizeof *b - sizeof (struct sdata) + needed; | 1879 | size_t size = offsetof (struct sblock, first_data) + needed; |
| 1883 | 1880 | ||
| 1884 | #ifdef DOUG_LEA_MALLOC | 1881 | #ifdef DOUG_LEA_MALLOC |
| 1885 | /* Prevent mmap'ing the chunk. Lisp data may not be mmap'ed | 1882 | /* Prevent mmap'ing the chunk. Lisp data may not be mmap'ed |
| @@ -1940,7 +1937,8 @@ allocate_string_data (struct Lisp_String *s, | |||
| 1940 | s->size_byte = nbytes; | 1937 | s->size_byte = nbytes; |
| 1941 | s->data[nbytes] = '\0'; | 1938 | s->data[nbytes] = '\0'; |
| 1942 | #ifdef GC_CHECK_STRING_OVERRUN | 1939 | #ifdef GC_CHECK_STRING_OVERRUN |
| 1943 | memcpy (data + needed, string_overrun_cookie, GC_STRING_OVERRUN_COOKIE_SIZE); | 1940 | memcpy ((char *) data + needed, string_overrun_cookie, |
| 1941 | GC_STRING_OVERRUN_COOKIE_SIZE); | ||
| 1944 | #endif | 1942 | #endif |
| 1945 | 1943 | ||
| 1946 | /* If S had already data assigned, mark that as free by setting its | 1944 | /* If S had already data assigned, mark that as free by setting its |
| @@ -2035,7 +2033,6 @@ sweep_strings (void) | |||
| 2035 | && total_free_strings > STRING_BLOCK_SIZE) | 2033 | && total_free_strings > STRING_BLOCK_SIZE) |
| 2036 | { | 2034 | { |
| 2037 | lisp_free (b); | 2035 | lisp_free (b); |
| 2038 | --n_string_blocks; | ||
| 2039 | string_free_list = free_list_before; | 2036 | string_free_list = free_list_before; |
| 2040 | } | 2037 | } |
| 2041 | else | 2038 | else |
| @@ -2154,7 +2151,7 @@ compact_small_strings (void) | |||
| 2154 | /* Copy, and update the string's `data' pointer. */ | 2151 | /* Copy, and update the string's `data' pointer. */ |
| 2155 | if (from != to) | 2152 | if (from != to) |
| 2156 | { | 2153 | { |
| 2157 | xassert (tb != b || to <= from); | 2154 | xassert (tb != b || to < from); |
| 2158 | memmove (to, from, nbytes + GC_STRING_EXTRA); | 2155 | memmove (to, from, nbytes + GC_STRING_EXTRA); |
| 2159 | to->string->data = SDATA_DATA (to); | 2156 | to->string->data = SDATA_DATA (to); |
| 2160 | } | 2157 | } |
| @@ -2178,6 +2175,11 @@ compact_small_strings (void) | |||
| 2178 | current_sblock = tb; | 2175 | current_sblock = tb; |
| 2179 | } | 2176 | } |
| 2180 | 2177 | ||
| 2178 | void | ||
| 2179 | string_overflow (void) | ||
| 2180 | { | ||
| 2181 | error ("Maximum string size exceeded"); | ||
| 2182 | } | ||
| 2181 | 2183 | ||
| 2182 | DEFUN ("make-string", Fmake_string, Smake_string, 2, 2, 0, | 2184 | DEFUN ("make-string", Fmake_string, Smake_string, 2, 2, 0, |
| 2183 | doc: /* Return a newly created string of length LENGTH, with INIT in each element. | 2185 | doc: /* Return a newly created string of length LENGTH, with INIT in each element. |
| @@ -2191,9 +2193,9 @@ INIT must be an integer that represents a character. */) | |||
| 2191 | EMACS_INT nbytes; | 2193 | EMACS_INT nbytes; |
| 2192 | 2194 | ||
| 2193 | CHECK_NATNUM (length); | 2195 | CHECK_NATNUM (length); |
| 2194 | CHECK_NUMBER (init); | 2196 | CHECK_CHARACTER (init); |
| 2195 | 2197 | ||
| 2196 | c = XINT (init); | 2198 | c = XFASTINT (init); |
| 2197 | if (ASCII_CHAR_P (c)) | 2199 | if (ASCII_CHAR_P (c)) |
| 2198 | { | 2200 | { |
| 2199 | nbytes = XINT (length); | 2201 | nbytes = XINT (length); |
| @@ -2209,8 +2211,8 @@ INIT must be an integer that represents a character. */) | |||
| 2209 | int len = CHAR_STRING (c, str); | 2211 | int len = CHAR_STRING (c, str); |
| 2210 | EMACS_INT string_len = XINT (length); | 2212 | EMACS_INT string_len = XINT (length); |
| 2211 | 2213 | ||
| 2212 | if (string_len > MOST_POSITIVE_FIXNUM / len) | 2214 | if (string_len > STRING_BYTES_MAX / len) |
| 2213 | error ("Maximum string size exceeded"); | 2215 | string_overflow (); |
| 2214 | nbytes = len * string_len; | 2216 | nbytes = len * string_len; |
| 2215 | val = make_uninit_multibyte_string (string_len, nbytes); | 2217 | val = make_uninit_multibyte_string (string_len, nbytes); |
| 2216 | p = SDATA (val); | 2218 | p = SDATA (val); |
| @@ -2234,7 +2236,6 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */) | |||
| 2234 | { | 2236 | { |
| 2235 | register Lisp_Object val; | 2237 | register Lisp_Object val; |
| 2236 | struct Lisp_Bool_Vector *p; | 2238 | struct Lisp_Bool_Vector *p; |
| 2237 | int real_init, i; | ||
| 2238 | EMACS_INT length_in_chars, length_in_elts; | 2239 | EMACS_INT length_in_chars, length_in_elts; |
| 2239 | int bits_per_value; | 2240 | int bits_per_value; |
| 2240 | 2241 | ||
| @@ -2250,17 +2251,13 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */) | |||
| 2250 | slot `size' of the struct Lisp_Bool_Vector. */ | 2251 | slot `size' of the struct Lisp_Bool_Vector. */ |
| 2251 | val = Fmake_vector (make_number (length_in_elts + 1), Qnil); | 2252 | val = Fmake_vector (make_number (length_in_elts + 1), Qnil); |
| 2252 | 2253 | ||
| 2253 | /* Get rid of any bits that would cause confusion. */ | 2254 | /* No Lisp_Object to trace in there. */ |
| 2254 | XVECTOR (val)->size = 0; /* No Lisp_Object to trace in there. */ | 2255 | XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0); |
| 2255 | /* Use XVECTOR (val) rather than `p' because p->size is not TRT. */ | ||
| 2256 | XSETPVECTYPE (XVECTOR (val), PVEC_BOOL_VECTOR); | ||
| 2257 | 2256 | ||
| 2258 | p = XBOOL_VECTOR (val); | 2257 | p = XBOOL_VECTOR (val); |
| 2259 | p->size = XFASTINT (length); | 2258 | p->size = XFASTINT (length); |
| 2260 | 2259 | ||
| 2261 | real_init = (NILP (init) ? 0 : -1); | 2260 | memset (p->data, NILP (init) ? 0 : -1, length_in_chars); |
| 2262 | for (i = 0; i < length_in_chars ; i++) | ||
| 2263 | p->data[i] = real_init; | ||
| 2264 | 2261 | ||
| 2265 | /* Clear the extraneous bits in the last byte. */ | 2262 | /* Clear the extraneous bits in the last byte. */ |
| 2266 | if (XINT (length) != length_in_chars * BOOL_VECTOR_BITS_PER_CHAR) | 2263 | if (XINT (length) != length_in_chars * BOOL_VECTOR_BITS_PER_CHAR) |
| @@ -2281,7 +2278,8 @@ make_string (const char *contents, EMACS_INT nbytes) | |||
| 2281 | register Lisp_Object val; | 2278 | register Lisp_Object val; |
| 2282 | EMACS_INT nchars, multibyte_nbytes; | 2279 | EMACS_INT nchars, multibyte_nbytes; |
| 2283 | 2280 | ||
| 2284 | parse_str_as_multibyte (contents, nbytes, &nchars, &multibyte_nbytes); | 2281 | parse_str_as_multibyte ((const unsigned char *) contents, nbytes, |
| 2282 | &nchars, &multibyte_nbytes); | ||
| 2285 | if (nbytes == nchars || nbytes != multibyte_nbytes) | 2283 | if (nbytes == nchars || nbytes != multibyte_nbytes) |
| 2286 | /* CONTENTS contains no multibyte sequences or contains an invalid | 2284 | /* CONTENTS contains no multibyte sequences or contains an invalid |
| 2287 | multibyte sequence. We must make unibyte string. */ | 2285 | multibyte sequence. We must make unibyte string. */ |
| @@ -2300,7 +2298,6 @@ make_unibyte_string (const char *contents, EMACS_INT length) | |||
| 2300 | register Lisp_Object val; | 2298 | register Lisp_Object val; |
| 2301 | val = make_uninit_string (length); | 2299 | val = make_uninit_string (length); |
| 2302 | memcpy (SDATA (val), contents, length); | 2300 | memcpy (SDATA (val), contents, length); |
| 2303 | STRING_SET_UNIBYTE (val); | ||
| 2304 | return val; | 2301 | return val; |
| 2305 | } | 2302 | } |
| 2306 | 2303 | ||
| @@ -2349,7 +2346,8 @@ make_specified_string (const char *contents, | |||
| 2349 | if (nchars < 0) | 2346 | if (nchars < 0) |
| 2350 | { | 2347 | { |
| 2351 | if (multibyte) | 2348 | if (multibyte) |
| 2352 | nchars = multibyte_chars_in_text (contents, nbytes); | 2349 | nchars = multibyte_chars_in_text ((const unsigned char *) contents, |
| 2350 | nbytes); | ||
| 2353 | else | 2351 | else |
| 2354 | nchars = nbytes; | 2352 | nchars = nbytes; |
| 2355 | } | 2353 | } |
| @@ -2439,10 +2437,10 @@ make_uninit_multibyte_string (EMACS_INT nchars, EMACS_INT nbytes) | |||
| 2439 | &= ~(1 << ((n) % (sizeof(int) * CHAR_BIT))) | 2437 | &= ~(1 << ((n) % (sizeof(int) * CHAR_BIT))) |
| 2440 | 2438 | ||
| 2441 | #define FLOAT_BLOCK(fptr) \ | 2439 | #define FLOAT_BLOCK(fptr) \ |
| 2442 | ((struct float_block *)(((EMACS_UINT)(fptr)) & ~(BLOCK_ALIGN - 1))) | 2440 | ((struct float_block *) (((uintptr_t) (fptr)) & ~(BLOCK_ALIGN - 1))) |
| 2443 | 2441 | ||
| 2444 | #define FLOAT_INDEX(fptr) \ | 2442 | #define FLOAT_INDEX(fptr) \ |
| 2445 | ((((EMACS_UINT)(fptr)) & (BLOCK_ALIGN - 1)) / sizeof (struct Lisp_Float)) | 2443 | ((((uintptr_t) (fptr)) & (BLOCK_ALIGN - 1)) / sizeof (struct Lisp_Float)) |
| 2446 | 2444 | ||
| 2447 | struct float_block | 2445 | struct float_block |
| 2448 | { | 2446 | { |
| @@ -2463,19 +2461,15 @@ struct float_block | |||
| 2463 | 2461 | ||
| 2464 | /* Current float_block. */ | 2462 | /* Current float_block. */ |
| 2465 | 2463 | ||
| 2466 | struct float_block *float_block; | 2464 | static struct float_block *float_block; |
| 2467 | 2465 | ||
| 2468 | /* Index of first unused Lisp_Float in the current float_block. */ | 2466 | /* Index of first unused Lisp_Float in the current float_block. */ |
| 2469 | 2467 | ||
| 2470 | int float_block_index; | 2468 | static int float_block_index; |
| 2471 | |||
| 2472 | /* Total number of float blocks now in use. */ | ||
| 2473 | |||
| 2474 | int n_float_blocks; | ||
| 2475 | 2469 | ||
| 2476 | /* Free-list of Lisp_Floats. */ | 2470 | /* Free-list of Lisp_Floats. */ |
| 2477 | 2471 | ||
| 2478 | struct Lisp_Float *float_free_list; | 2472 | static struct Lisp_Float *float_free_list; |
| 2479 | 2473 | ||
| 2480 | 2474 | ||
| 2481 | /* Initialize float allocation. */ | 2475 | /* Initialize float allocation. */ |
| @@ -2486,7 +2480,6 @@ init_float (void) | |||
| 2486 | float_block = NULL; | 2480 | float_block = NULL; |
| 2487 | 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. */ |
| 2488 | float_free_list = 0; | 2482 | float_free_list = 0; |
| 2489 | n_float_blocks = 0; | ||
| 2490 | } | 2483 | } |
| 2491 | 2484 | ||
| 2492 | 2485 | ||
| @@ -2520,7 +2513,6 @@ make_float (double float_value) | |||
| 2520 | memset (new->gcmarkbits, 0, sizeof new->gcmarkbits); | 2513 | memset (new->gcmarkbits, 0, sizeof new->gcmarkbits); |
| 2521 | float_block = new; | 2514 | float_block = new; |
| 2522 | float_block_index = 0; | 2515 | float_block_index = 0; |
| 2523 | n_float_blocks++; | ||
| 2524 | } | 2516 | } |
| 2525 | XSETFLOAT (val, &float_block->floats[float_block_index]); | 2517 | XSETFLOAT (val, &float_block->floats[float_block_index]); |
| 2526 | float_block_index++; | 2518 | float_block_index++; |
| @@ -2551,10 +2543,10 @@ make_float (double float_value) | |||
| 2551 | / (sizeof (struct Lisp_Cons) * CHAR_BIT + 1)) | 2543 | / (sizeof (struct Lisp_Cons) * CHAR_BIT + 1)) |
| 2552 | 2544 | ||
| 2553 | #define CONS_BLOCK(fptr) \ | 2545 | #define CONS_BLOCK(fptr) \ |
| 2554 | ((struct cons_block *)(((EMACS_UINT)(fptr)) & ~(BLOCK_ALIGN - 1))) | 2546 | ((struct cons_block *) ((uintptr_t) (fptr) & ~(BLOCK_ALIGN - 1))) |
| 2555 | 2547 | ||
| 2556 | #define CONS_INDEX(fptr) \ | 2548 | #define CONS_INDEX(fptr) \ |
| 2557 | ((((EMACS_UINT)(fptr)) & (BLOCK_ALIGN - 1)) / sizeof (struct Lisp_Cons)) | 2549 | (((uintptr_t) (fptr) & (BLOCK_ALIGN - 1)) / sizeof (struct Lisp_Cons)) |
| 2558 | 2550 | ||
| 2559 | struct cons_block | 2551 | struct cons_block |
| 2560 | { | 2552 | { |
| @@ -2575,19 +2567,15 @@ struct cons_block | |||
| 2575 | 2567 | ||
| 2576 | /* Current cons_block. */ | 2568 | /* Current cons_block. */ |
| 2577 | 2569 | ||
| 2578 | struct cons_block *cons_block; | 2570 | static struct cons_block *cons_block; |
| 2579 | 2571 | ||
| 2580 | /* Index of first unused Lisp_Cons in the current block. */ | 2572 | /* Index of first unused Lisp_Cons in the current block. */ |
| 2581 | 2573 | ||
| 2582 | int cons_block_index; | 2574 | static int cons_block_index; |
| 2583 | 2575 | ||
| 2584 | /* Free-list of Lisp_Cons structures. */ | 2576 | /* Free-list of Lisp_Cons structures. */ |
| 2585 | 2577 | ||
| 2586 | struct Lisp_Cons *cons_free_list; | 2578 | static struct Lisp_Cons *cons_free_list; |
| 2587 | |||
| 2588 | /* Total number of cons blocks now in use. */ | ||
| 2589 | |||
| 2590 | static int n_cons_blocks; | ||
| 2591 | 2579 | ||
| 2592 | 2580 | ||
| 2593 | /* Initialize cons allocation. */ | 2581 | /* Initialize cons allocation. */ |
| @@ -2598,7 +2586,6 @@ init_cons (void) | |||
| 2598 | cons_block = NULL; | 2586 | cons_block = NULL; |
| 2599 | 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. */ |
| 2600 | cons_free_list = 0; | 2588 | cons_free_list = 0; |
| 2601 | n_cons_blocks = 0; | ||
| 2602 | } | 2589 | } |
| 2603 | 2590 | ||
| 2604 | 2591 | ||
| @@ -2642,7 +2629,6 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0, | |||
| 2642 | new->next = cons_block; | 2629 | new->next = cons_block; |
| 2643 | cons_block = new; | 2630 | cons_block = new; |
| 2644 | cons_block_index = 0; | 2631 | cons_block_index = 0; |
| 2645 | n_cons_blocks++; | ||
| 2646 | } | 2632 | } |
| 2647 | XSETCONS (val, &cons_block->conses[cons_block_index]); | 2633 | XSETCONS (val, &cons_block->conses[cons_block_index]); |
| 2648 | cons_block_index++; | 2634 | cons_block_index++; |
| @@ -2658,17 +2644,17 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0, | |||
| 2658 | return val; | 2644 | return val; |
| 2659 | } | 2645 | } |
| 2660 | 2646 | ||
| 2647 | #ifdef GC_CHECK_CONS_LIST | ||
| 2661 | /* Get an error now if there's any junk in the cons free list. */ | 2648 | /* Get an error now if there's any junk in the cons free list. */ |
| 2662 | void | 2649 | void |
| 2663 | check_cons_list (void) | 2650 | check_cons_list (void) |
| 2664 | { | 2651 | { |
| 2665 | #ifdef GC_CHECK_CONS_LIST | ||
| 2666 | struct Lisp_Cons *tail = cons_free_list; | 2652 | struct Lisp_Cons *tail = cons_free_list; |
| 2667 | 2653 | ||
| 2668 | while (tail) | 2654 | while (tail) |
| 2669 | tail = tail->u.chain; | 2655 | tail = tail->u.chain; |
| 2670 | #endif | ||
| 2671 | } | 2656 | } |
| 2657 | #endif | ||
| 2672 | 2658 | ||
| 2673 | /* Make a list of 1, 2, 3, 4 or 5 specified objects. */ | 2659 | /* Make a list of 1, 2, 3, 4 or 5 specified objects. */ |
| 2674 | 2660 | ||
| @@ -2711,7 +2697,7 @@ DEFUN ("list", Flist, Slist, 0, MANY, 0, | |||
| 2711 | doc: /* Return a newly created list with specified arguments as elements. | 2697 | doc: /* Return a newly created list with specified arguments as elements. |
| 2712 | Any number of arguments, even zero arguments, are allowed. | 2698 | Any number of arguments, even zero arguments, are allowed. |
| 2713 | usage: (list &rest OBJECTS) */) | 2699 | usage: (list &rest OBJECTS) */) |
| 2714 | (int nargs, register Lisp_Object *args) | 2700 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2715 | { | 2701 | { |
| 2716 | register Lisp_Object val; | 2702 | register Lisp_Object val; |
| 2717 | val = Qnil; | 2703 | val = Qnil; |
| @@ -2781,10 +2767,12 @@ DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0, | |||
| 2781 | 2767 | ||
| 2782 | static struct Lisp_Vector *all_vectors; | 2768 | static struct Lisp_Vector *all_vectors; |
| 2783 | 2769 | ||
| 2784 | /* Total number of vector-like objects now in use. */ | 2770 | /* Handy constants for vectorlike objects. */ |
| 2785 | 2771 | enum | |
| 2786 | static int n_vectors; | 2772 | { |
| 2787 | 2773 | header_size = offsetof (struct Lisp_Vector, contents), | |
| 2774 | word_size = sizeof (Lisp_Object) | ||
| 2775 | }; | ||
| 2788 | 2776 | ||
| 2789 | /* Value is a pointer to a newly allocated Lisp_Vector structure | 2777 | /* Value is a pointer to a newly allocated Lisp_Vector structure |
| 2790 | with room for LEN Lisp_Objects. */ | 2778 | with room for LEN Lisp_Objects. */ |
| @@ -2807,7 +2795,7 @@ allocate_vectorlike (EMACS_INT len) | |||
| 2807 | /* This gets triggered by code which I haven't bothered to fix. --Stef */ | 2795 | /* This gets triggered by code which I haven't bothered to fix. --Stef */ |
| 2808 | /* eassert (!handling_signal); */ | 2796 | /* eassert (!handling_signal); */ |
| 2809 | 2797 | ||
| 2810 | nbytes = sizeof *p + (len - 1) * sizeof p->contents[0]; | 2798 | nbytes = header_size + len * word_size; |
| 2811 | p = (struct Lisp_Vector *) lisp_malloc (nbytes, MEM_TYPE_VECTORLIKE); | 2799 | p = (struct Lisp_Vector *) lisp_malloc (nbytes, MEM_TYPE_VECTORLIKE); |
| 2812 | 2800 | ||
| 2813 | #ifdef DOUG_LEA_MALLOC | 2801 | #ifdef DOUG_LEA_MALLOC |
| @@ -2818,23 +2806,27 @@ allocate_vectorlike (EMACS_INT len) | |||
| 2818 | consing_since_gc += nbytes; | 2806 | consing_since_gc += nbytes; |
| 2819 | vector_cells_consed += len; | 2807 | vector_cells_consed += len; |
| 2820 | 2808 | ||
| 2821 | p->next = all_vectors; | 2809 | p->header.next.vector = all_vectors; |
| 2822 | all_vectors = p; | 2810 | all_vectors = p; |
| 2823 | 2811 | ||
| 2824 | MALLOC_UNBLOCK_INPUT; | 2812 | MALLOC_UNBLOCK_INPUT; |
| 2825 | 2813 | ||
| 2826 | ++n_vectors; | ||
| 2827 | return p; | 2814 | return p; |
| 2828 | } | 2815 | } |
| 2829 | 2816 | ||
| 2830 | 2817 | ||
| 2831 | /* Allocate a vector with NSLOTS slots. */ | 2818 | /* Allocate a vector with LEN slots. */ |
| 2832 | 2819 | ||
| 2833 | struct Lisp_Vector * | 2820 | struct Lisp_Vector * |
| 2834 | allocate_vector (EMACS_INT nslots) | 2821 | allocate_vector (EMACS_INT len) |
| 2835 | { | 2822 | { |
| 2836 | struct Lisp_Vector *v = allocate_vectorlike (nslots); | 2823 | struct Lisp_Vector *v; |
| 2837 | v->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; | ||
| 2838 | return v; | 2830 | return v; |
| 2839 | } | 2831 | } |
| 2840 | 2832 | ||
| @@ -2845,14 +2837,13 @@ struct Lisp_Vector * | |||
| 2845 | allocate_pseudovector (int memlen, int lisplen, EMACS_INT tag) | 2837 | allocate_pseudovector (int memlen, int lisplen, EMACS_INT tag) |
| 2846 | { | 2838 | { |
| 2847 | struct Lisp_Vector *v = allocate_vectorlike (memlen); | 2839 | struct Lisp_Vector *v = allocate_vectorlike (memlen); |
| 2848 | EMACS_INT i; | 2840 | int i; |
| 2849 | 2841 | ||
| 2850 | /* 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. */ |
| 2851 | v->size = lisplen; | ||
| 2852 | for (i = 0; i < lisplen; ++i) | 2843 | for (i = 0; i < lisplen; ++i) |
| 2853 | v->contents[i] = Qnil; | 2844 | v->contents[i] = Qnil; |
| 2854 | 2845 | ||
| 2855 | XSETPVECTYPE (v, tag); /* Add the appropriate tag. */ | 2846 | XSETPVECTYPESIZE (v, tag, lisplen); |
| 2856 | return v; | 2847 | return v; |
| 2857 | } | 2848 | } |
| 2858 | 2849 | ||
| @@ -2908,15 +2899,15 @@ See also the function `vector'. */) | |||
| 2908 | { | 2899 | { |
| 2909 | Lisp_Object vector; | 2900 | Lisp_Object vector; |
| 2910 | register EMACS_INT sizei; | 2901 | register EMACS_INT sizei; |
| 2911 | register EMACS_INT index; | 2902 | register EMACS_INT i; |
| 2912 | register struct Lisp_Vector *p; | 2903 | register struct Lisp_Vector *p; |
| 2913 | 2904 | ||
| 2914 | CHECK_NATNUM (length); | 2905 | CHECK_NATNUM (length); |
| 2915 | sizei = XFASTINT (length); | 2906 | sizei = XFASTINT (length); |
| 2916 | 2907 | ||
| 2917 | p = allocate_vector (sizei); | 2908 | p = allocate_vector (sizei); |
| 2918 | for (index = 0; index < sizei; index++) | 2909 | for (i = 0; i < sizei; i++) |
| 2919 | p->contents[index] = init; | 2910 | p->contents[i] = init; |
| 2920 | 2911 | ||
| 2921 | XSETVECTOR (vector, p); | 2912 | XSETVECTOR (vector, p); |
| 2922 | return vector; | 2913 | return vector; |
| @@ -2927,37 +2918,46 @@ DEFUN ("vector", Fvector, Svector, 0, MANY, 0, | |||
| 2927 | doc: /* Return a newly created vector with specified arguments as elements. | 2918 | doc: /* Return a newly created vector with specified arguments as elements. |
| 2928 | Any number of arguments, even zero arguments, are allowed. | 2919 | Any number of arguments, even zero arguments, are allowed. |
| 2929 | usage: (vector &rest OBJECTS) */) | 2920 | usage: (vector &rest OBJECTS) */) |
| 2930 | (register int nargs, Lisp_Object *args) | 2921 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2931 | { | 2922 | { |
| 2932 | register Lisp_Object len, val; | 2923 | register Lisp_Object len, val; |
| 2933 | register int index; | 2924 | ptrdiff_t i; |
| 2934 | register struct Lisp_Vector *p; | 2925 | register struct Lisp_Vector *p; |
| 2935 | 2926 | ||
| 2936 | XSETFASTINT (len, nargs); | 2927 | XSETFASTINT (len, nargs); |
| 2937 | val = Fmake_vector (len, Qnil); | 2928 | val = Fmake_vector (len, Qnil); |
| 2938 | p = XVECTOR (val); | 2929 | p = XVECTOR (val); |
| 2939 | for (index = 0; index < nargs; index++) | 2930 | for (i = 0; i < nargs; i++) |
| 2940 | p->contents[index] = args[index]; | 2931 | p->contents[i] = args[i]; |
| 2941 | return val; | 2932 | return val; |
| 2942 | } | 2933 | } |
| 2943 | 2934 | ||
| 2944 | 2935 | ||
| 2945 | DEFUN ("make-byte-code", Fmake_byte_code, Smake_byte_code, 4, MANY, 0, | 2936 | DEFUN ("make-byte-code", Fmake_byte_code, Smake_byte_code, 4, MANY, 0, |
| 2946 | doc: /* Create a byte-code object with specified arguments as elements. | 2937 | doc: /* Create a byte-code object with specified arguments as elements. |
| 2947 | The arguments should be the arglist, bytecode-string, constant vector, | 2938 | The arguments should be the ARGLIST, bytecode-string BYTE-CODE, constant |
| 2948 | stack size, (optional) doc string, and (optional) interactive spec. | 2939 | vector CONSTANTS, maximum stack size DEPTH, (optional) DOCSTRING, |
| 2940 | and (optional) INTERACTIVE-SPEC. | ||
| 2949 | The first four arguments are required; at most six have any | 2941 | The first four arguments are required; at most six have any |
| 2950 | significance. | 2942 | significance. |
| 2943 | The ARGLIST can be either like the one of `lambda', in which case the arguments | ||
| 2944 | will be dynamically bound before executing the byte code, or it can be an | ||
| 2945 | integer of the form NNNNNNNRMMMMMMM where the 7bit MMMMMMM specifies the | ||
| 2946 | minimum number of arguments, the 7-bit NNNNNNN specifies the maximum number | ||
| 2947 | of arguments (ignoring &rest) and the R bit specifies whether there is a &rest | ||
| 2948 | argument to catch the left-over arguments. If such an integer is used, the | ||
| 2949 | arguments will not be dynamically bound but will be instead pushed on the | ||
| 2950 | stack before executing the byte-code. | ||
| 2951 | 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) */) |
| 2952 | (register int nargs, Lisp_Object *args) | 2952 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2953 | { | 2953 | { |
| 2954 | register Lisp_Object len, val; | 2954 | register Lisp_Object len, val; |
| 2955 | register int index; | 2955 | ptrdiff_t i; |
| 2956 | register struct Lisp_Vector *p; | 2956 | register struct Lisp_Vector *p; |
| 2957 | 2957 | ||
| 2958 | XSETFASTINT (len, nargs); | 2958 | XSETFASTINT (len, nargs); |
| 2959 | if (!NILP (Vpurify_flag)) | 2959 | if (!NILP (Vpurify_flag)) |
| 2960 | val = make_pure_vector ((EMACS_INT) nargs); | 2960 | val = make_pure_vector (nargs); |
| 2961 | else | 2961 | else |
| 2962 | val = Fmake_vector (len, Qnil); | 2962 | val = Fmake_vector (len, Qnil); |
| 2963 | 2963 | ||
| @@ -2970,11 +2970,11 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT | |||
| 2970 | args[1] = Fstring_as_unibyte (args[1]); | 2970 | args[1] = Fstring_as_unibyte (args[1]); |
| 2971 | 2971 | ||
| 2972 | p = XVECTOR (val); | 2972 | p = XVECTOR (val); |
| 2973 | for (index = 0; index < nargs; index++) | 2973 | for (i = 0; i < nargs; i++) |
| 2974 | { | 2974 | { |
| 2975 | if (!NILP (Vpurify_flag)) | 2975 | if (!NILP (Vpurify_flag)) |
| 2976 | args[index] = Fpurecopy (args[index]); | 2976 | args[i] = Fpurecopy (args[i]); |
| 2977 | p->contents[index] = args[index]; | 2977 | p->contents[i] = args[i]; |
| 2978 | } | 2978 | } |
| 2979 | XSETPVECTYPE (p, PVEC_COMPILED); | 2979 | XSETPVECTYPE (p, PVEC_COMPILED); |
| 2980 | XSETCOMPILED (val, p); | 2980 | XSETCOMPILED (val, p); |
| @@ -3011,10 +3011,6 @@ static int symbol_block_index; | |||
| 3011 | 3011 | ||
| 3012 | static struct Lisp_Symbol *symbol_free_list; | 3012 | static struct Lisp_Symbol *symbol_free_list; |
| 3013 | 3013 | ||
| 3014 | /* Total number of symbol blocks now in use. */ | ||
| 3015 | |||
| 3016 | static int n_symbol_blocks; | ||
| 3017 | |||
| 3018 | 3014 | ||
| 3019 | /* Initialize symbol allocation. */ | 3015 | /* Initialize symbol allocation. */ |
| 3020 | 3016 | ||
| @@ -3024,7 +3020,6 @@ init_symbol (void) | |||
| 3024 | symbol_block = NULL; | 3020 | symbol_block = NULL; |
| 3025 | symbol_block_index = SYMBOL_BLOCK_SIZE; | 3021 | symbol_block_index = SYMBOL_BLOCK_SIZE; |
| 3026 | symbol_free_list = 0; | 3022 | symbol_free_list = 0; |
| 3027 | n_symbol_blocks = 0; | ||
| 3028 | } | 3023 | } |
| 3029 | 3024 | ||
| 3030 | 3025 | ||
| @@ -3057,7 +3052,6 @@ Its value and function definition are void, and its property list is nil. */) | |||
| 3057 | new->next = symbol_block; | 3052 | new->next = symbol_block; |
| 3058 | symbol_block = new; | 3053 | symbol_block = new; |
| 3059 | symbol_block_index = 0; | 3054 | symbol_block_index = 0; |
| 3060 | n_symbol_blocks++; | ||
| 3061 | } | 3055 | } |
| 3062 | XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index]); | 3056 | XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index]); |
| 3063 | symbol_block_index++; | 3057 | symbol_block_index++; |
| @@ -3075,6 +3069,7 @@ Its value and function definition are void, and its property list is nil. */) | |||
| 3075 | p->gcmarkbit = 0; | 3069 | p->gcmarkbit = 0; |
| 3076 | p->interned = SYMBOL_UNINTERNED; | 3070 | p->interned = SYMBOL_UNINTERNED; |
| 3077 | p->constant = 0; | 3071 | p->constant = 0; |
| 3072 | p->declared_special = 0; | ||
| 3078 | consing_since_gc += sizeof (struct Lisp_Symbol); | 3073 | consing_since_gc += sizeof (struct Lisp_Symbol); |
| 3079 | symbols_consed++; | 3074 | symbols_consed++; |
| 3080 | return val; | 3075 | return val; |
| @@ -3104,17 +3099,12 @@ static int marker_block_index; | |||
| 3104 | 3099 | ||
| 3105 | static union Lisp_Misc *marker_free_list; | 3100 | static union Lisp_Misc *marker_free_list; |
| 3106 | 3101 | ||
| 3107 | /* Total number of marker blocks now in use. */ | ||
| 3108 | |||
| 3109 | static int n_marker_blocks; | ||
| 3110 | |||
| 3111 | static void | 3102 | static void |
| 3112 | init_marker (void) | 3103 | init_marker (void) |
| 3113 | { | 3104 | { |
| 3114 | marker_block = NULL; | 3105 | marker_block = NULL; |
| 3115 | marker_block_index = MARKER_BLOCK_SIZE; | 3106 | marker_block_index = MARKER_BLOCK_SIZE; |
| 3116 | marker_free_list = 0; | 3107 | marker_free_list = 0; |
| 3117 | n_marker_blocks = 0; | ||
| 3118 | } | 3108 | } |
| 3119 | 3109 | ||
| 3120 | /* Return a newly allocated Lisp_Misc object, with no substructure. */ | 3110 | /* Return a newly allocated Lisp_Misc object, with no substructure. */ |
| @@ -3143,7 +3133,6 @@ allocate_misc (void) | |||
| 3143 | new->next = marker_block; | 3133 | new->next = marker_block; |
| 3144 | marker_block = new; | 3134 | marker_block = new; |
| 3145 | marker_block_index = 0; | 3135 | marker_block_index = 0; |
| 3146 | n_marker_blocks++; | ||
| 3147 | total_free_markers += MARKER_BLOCK_SIZE; | 3136 | total_free_markers += MARKER_BLOCK_SIZE; |
| 3148 | } | 3137 | } |
| 3149 | XSETMISC (val, &marker_block->markers[marker_block_index]); | 3138 | XSETMISC (val, &marker_block->markers[marker_block_index]); |
| @@ -3161,7 +3150,7 @@ allocate_misc (void) | |||
| 3161 | 3150 | ||
| 3162 | /* Free a Lisp_Misc object */ | 3151 | /* Free a Lisp_Misc object */ |
| 3163 | 3152 | ||
| 3164 | void | 3153 | static void |
| 3165 | free_misc (Lisp_Object misc) | 3154 | free_misc (Lisp_Object misc) |
| 3166 | { | 3155 | { |
| 3167 | XMISCTYPE (misc) = Lisp_Misc_Free; | 3156 | XMISCTYPE (misc) = Lisp_Misc_Free; |
| @@ -3176,7 +3165,7 @@ free_misc (Lisp_Object misc) | |||
| 3176 | 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. */ |
| 3177 | 3166 | ||
| 3178 | Lisp_Object | 3167 | Lisp_Object |
| 3179 | make_save_value (void *pointer, int integer) | 3168 | make_save_value (void *pointer, ptrdiff_t integer) |
| 3180 | { | 3169 | { |
| 3181 | register Lisp_Object val; | 3170 | register Lisp_Object val; |
| 3182 | register struct Lisp_Save_Value *p; | 3171 | register struct Lisp_Save_Value *p; |
| @@ -3234,7 +3223,7 @@ make_event_array (register int nargs, Lisp_Object *args) | |||
| 3234 | are characters that are in 0...127, | 3223 | are characters that are in 0...127, |
| 3235 | after discarding the meta bit and all the bits above it. */ | 3224 | after discarding the meta bit and all the bits above it. */ |
| 3236 | if (!INTEGERP (args[i]) | 3225 | if (!INTEGERP (args[i]) |
| 3237 | || (XUINT (args[i]) & ~(-CHAR_META)) >= 0200) | 3226 | || (XINT (args[i]) & ~(-CHAR_META)) >= 0200) |
| 3238 | return Fvector (nargs, args); | 3227 | return Fvector (nargs, args); |
| 3239 | 3228 | ||
| 3240 | /* Since the loop exited, we know that all the things in it are | 3229 | /* Since the loop exited, we know that all the things in it are |
| @@ -3262,35 +3251,55 @@ make_event_array (register int nargs, Lisp_Object *args) | |||
| 3262 | ************************************************************************/ | 3251 | ************************************************************************/ |
| 3263 | 3252 | ||
| 3264 | 3253 | ||
| 3265 | /* Called if malloc returns zero. */ | 3254 | /* Called if malloc (NBYTES) returns zero. If NBYTES == SIZE_MAX, |
| 3255 | there may have been size_t overflow so that malloc was never | ||
| 3256 | called, or perhaps malloc was invoked successfully but the | ||
| 3257 | resulting pointer had problems fitting into a tagged EMACS_INT. In | ||
| 3258 | either case this counts as memory being full even though malloc did | ||
| 3259 | not fail. */ | ||
| 3266 | 3260 | ||
| 3267 | void | 3261 | void |
| 3268 | memory_full (void) | 3262 | memory_full (size_t nbytes) |
| 3269 | { | 3263 | { |
| 3270 | int i; | 3264 | /* Do not go into hysterics merely because a large request failed. */ |
| 3265 | int enough_free_memory = 0; | ||
| 3266 | if (SPARE_MEMORY < nbytes) | ||
| 3267 | { | ||
| 3268 | void *p = malloc (SPARE_MEMORY); | ||
| 3269 | if (p) | ||
| 3270 | { | ||
| 3271 | free (p); | ||
| 3272 | enough_free_memory = 1; | ||
| 3273 | } | ||
| 3274 | } | ||
| 3271 | 3275 | ||
| 3272 | Vmemory_full = Qt; | 3276 | if (! enough_free_memory) |
| 3277 | { | ||
| 3278 | int i; | ||
| 3273 | 3279 | ||
| 3274 | memory_full_cons_threshold = sizeof (struct cons_block); | 3280 | Vmemory_full = Qt; |
| 3275 | 3281 | ||
| 3276 | /* The first time we get here, free the spare memory. */ | 3282 | memory_full_cons_threshold = sizeof (struct cons_block); |
| 3277 | for (i = 0; i < sizeof (spare_memory) / sizeof (char *); i++) | ||
| 3278 | if (spare_memory[i]) | ||
| 3279 | { | ||
| 3280 | if (i == 0) | ||
| 3281 | free (spare_memory[i]); | ||
| 3282 | else if (i >= 1 && i <= 4) | ||
| 3283 | lisp_align_free (spare_memory[i]); | ||
| 3284 | else | ||
| 3285 | lisp_free (spare_memory[i]); | ||
| 3286 | spare_memory[i] = 0; | ||
| 3287 | } | ||
| 3288 | 3283 | ||
| 3289 | /* Record the space now used. When it decreases substantially, | 3284 | /* The first time we get here, free the spare memory. */ |
| 3290 | we can refill the memory reserve. */ | 3285 | for (i = 0; i < sizeof (spare_memory) / sizeof (char *); i++) |
| 3291 | #ifndef SYSTEM_MALLOC | 3286 | if (spare_memory[i]) |
| 3292 | bytes_used_when_full = BYTES_USED; | 3287 | { |
| 3288 | if (i == 0) | ||
| 3289 | free (spare_memory[i]); | ||
| 3290 | else if (i >= 1 && i <= 4) | ||
| 3291 | lisp_align_free (spare_memory[i]); | ||
| 3292 | else | ||
| 3293 | lisp_free (spare_memory[i]); | ||
| 3294 | spare_memory[i] = 0; | ||
| 3295 | } | ||
| 3296 | |||
| 3297 | /* Record the space now used. When it decreases substantially, | ||
| 3298 | we can refill the memory reserve. */ | ||
| 3299 | #if !defined SYSTEM_MALLOC && !defined SYNC_INPUT | ||
| 3300 | bytes_used_when_full = BYTES_USED; | ||
| 3293 | #endif | 3301 | #endif |
| 3302 | } | ||
| 3294 | 3303 | ||
| 3295 | /* This used to call error, but if we've run out of memory, we could | 3304 | /* This used to call error, but if we've run out of memory, we could |
| 3296 | get infinite recursion trying to build the string. */ | 3305 | get infinite recursion trying to build the string. */ |
| @@ -3366,7 +3375,7 @@ mem_init (void) | |||
| 3366 | /* Value is a pointer to the mem_node containing START. Value is | 3375 | /* Value is a pointer to the mem_node containing START. Value is |
| 3367 | MEM_NIL if there is no node in the tree containing START. */ | 3376 | MEM_NIL if there is no node in the tree containing START. */ |
| 3368 | 3377 | ||
| 3369 | static INLINE struct mem_node * | 3378 | static inline struct mem_node * |
| 3370 | mem_find (void *start) | 3379 | mem_find (void *start) |
| 3371 | { | 3380 | { |
| 3372 | struct mem_node *p; | 3381 | struct mem_node *p; |
| @@ -3742,7 +3751,7 @@ mem_delete_fixup (struct mem_node *x) | |||
| 3742 | /* Value is non-zero if P is a pointer to a live Lisp string on | 3751 | /* Value is non-zero if P is a pointer to a live Lisp string on |
| 3743 | the heap. M is a pointer to the mem_block for P. */ | 3752 | the heap. M is a pointer to the mem_block for P. */ |
| 3744 | 3753 | ||
| 3745 | static INLINE int | 3754 | static inline int |
| 3746 | live_string_p (struct mem_node *m, void *p) | 3755 | live_string_p (struct mem_node *m, void *p) |
| 3747 | { | 3756 | { |
| 3748 | if (m->type == MEM_TYPE_STRING) | 3757 | if (m->type == MEM_TYPE_STRING) |
| @@ -3765,7 +3774,7 @@ live_string_p (struct mem_node *m, void *p) | |||
| 3765 | /* Value is non-zero if P is a pointer to a live Lisp cons on | 3774 | /* Value is non-zero if P is a pointer to a live Lisp cons on |
| 3766 | the heap. M is a pointer to the mem_block for P. */ | 3775 | the heap. M is a pointer to the mem_block for P. */ |
| 3767 | 3776 | ||
| 3768 | static INLINE int | 3777 | static inline int |
| 3769 | live_cons_p (struct mem_node *m, void *p) | 3778 | live_cons_p (struct mem_node *m, void *p) |
| 3770 | { | 3779 | { |
| 3771 | if (m->type == MEM_TYPE_CONS) | 3780 | if (m->type == MEM_TYPE_CONS) |
| @@ -3791,7 +3800,7 @@ live_cons_p (struct mem_node *m, void *p) | |||
| 3791 | /* Value is non-zero if P is a pointer to a live Lisp symbol on | 3800 | /* Value is non-zero if P is a pointer to a live Lisp symbol on |
| 3792 | the heap. M is a pointer to the mem_block for P. */ | 3801 | the heap. M is a pointer to the mem_block for P. */ |
| 3793 | 3802 | ||
| 3794 | static INLINE int | 3803 | static inline int |
| 3795 | live_symbol_p (struct mem_node *m, void *p) | 3804 | live_symbol_p (struct mem_node *m, void *p) |
| 3796 | { | 3805 | { |
| 3797 | if (m->type == MEM_TYPE_SYMBOL) | 3806 | if (m->type == MEM_TYPE_SYMBOL) |
| @@ -3817,7 +3826,7 @@ live_symbol_p (struct mem_node *m, void *p) | |||
| 3817 | /* Value is non-zero if P is a pointer to a live Lisp float on | 3826 | /* Value is non-zero if P is a pointer to a live Lisp float on |
| 3818 | the heap. M is a pointer to the mem_block for P. */ | 3827 | the heap. M is a pointer to the mem_block for P. */ |
| 3819 | 3828 | ||
| 3820 | static INLINE int | 3829 | static inline int |
| 3821 | live_float_p (struct mem_node *m, void *p) | 3830 | live_float_p (struct mem_node *m, void *p) |
| 3822 | { | 3831 | { |
| 3823 | if (m->type == MEM_TYPE_FLOAT) | 3832 | if (m->type == MEM_TYPE_FLOAT) |
| @@ -3841,7 +3850,7 @@ live_float_p (struct mem_node *m, void *p) | |||
| 3841 | /* Value is non-zero if P is a pointer to a live Lisp Misc on | 3850 | /* Value is non-zero if P is a pointer to a live Lisp Misc on |
| 3842 | the heap. M is a pointer to the mem_block for P. */ | 3851 | the heap. M is a pointer to the mem_block for P. */ |
| 3843 | 3852 | ||
| 3844 | static INLINE int | 3853 | static inline int |
| 3845 | live_misc_p (struct mem_node *m, void *p) | 3854 | live_misc_p (struct mem_node *m, void *p) |
| 3846 | { | 3855 | { |
| 3847 | if (m->type == MEM_TYPE_MISC) | 3856 | if (m->type == MEM_TYPE_MISC) |
| @@ -3867,7 +3876,7 @@ live_misc_p (struct mem_node *m, void *p) | |||
| 3867 | /* Value is non-zero if P is a pointer to a live vector-like object. | 3876 | /* Value is non-zero if P is a pointer to a live vector-like object. |
| 3868 | M is a pointer to the mem_block for P. */ | 3877 | M is a pointer to the mem_block for P. */ |
| 3869 | 3878 | ||
| 3870 | static INLINE int | 3879 | static inline int |
| 3871 | live_vector_p (struct mem_node *m, void *p) | 3880 | live_vector_p (struct mem_node *m, void *p) |
| 3872 | { | 3881 | { |
| 3873 | return (p == m->start && m->type == MEM_TYPE_VECTORLIKE); | 3882 | return (p == m->start && m->type == MEM_TYPE_VECTORLIKE); |
| @@ -3877,14 +3886,14 @@ live_vector_p (struct mem_node *m, void *p) | |||
| 3877 | /* Value is non-zero if P is a pointer to a live buffer. M is a | 3886 | /* Value is non-zero if P is a pointer to a live buffer. M is a |
| 3878 | pointer to the mem_block for P. */ | 3887 | pointer to the mem_block for P. */ |
| 3879 | 3888 | ||
| 3880 | static INLINE int | 3889 | static inline int |
| 3881 | live_buffer_p (struct mem_node *m, void *p) | 3890 | live_buffer_p (struct mem_node *m, void *p) |
| 3882 | { | 3891 | { |
| 3883 | /* P must point to the start of the block, and the buffer | 3892 | /* P must point to the start of the block, and the buffer |
| 3884 | must not have been killed. */ | 3893 | must not have been killed. */ |
| 3885 | return (m->type == MEM_TYPE_BUFFER | 3894 | return (m->type == MEM_TYPE_BUFFER |
| 3886 | && p == m->start | 3895 | && p == m->start |
| 3887 | && !NILP (((struct buffer *) p)->name)); | 3896 | && !NILP (((struct buffer *) p)->BUFFER_INTERNAL_FIELD (name))); |
| 3888 | } | 3897 | } |
| 3889 | 3898 | ||
| 3890 | #endif /* GC_MARK_STACK || defined GC_MALLOC_CHECK */ | 3899 | #endif /* GC_MARK_STACK || defined GC_MALLOC_CHECK */ |
| @@ -3901,11 +3910,11 @@ static Lisp_Object zombies[MAX_ZOMBIES]; | |||
| 3901 | 3910 | ||
| 3902 | /* Number of zombie objects. */ | 3911 | /* Number of zombie objects. */ |
| 3903 | 3912 | ||
| 3904 | static int nzombies; | 3913 | static EMACS_INT nzombies; |
| 3905 | 3914 | ||
| 3906 | /* Number of garbage collections. */ | 3915 | /* Number of garbage collections. */ |
| 3907 | 3916 | ||
| 3908 | static int ngcs; | 3917 | static EMACS_INT ngcs; |
| 3909 | 3918 | ||
| 3910 | /* Average percentage of zombies per collection. */ | 3919 | /* Average percentage of zombies per collection. */ |
| 3911 | 3920 | ||
| @@ -3913,7 +3922,7 @@ static double avg_zombies; | |||
| 3913 | 3922 | ||
| 3914 | /* Max. number of live and zombie objects. */ | 3923 | /* Max. number of live and zombie objects. */ |
| 3915 | 3924 | ||
| 3916 | static int max_live, max_zombies; | 3925 | static EMACS_INT max_live, max_zombies; |
| 3917 | 3926 | ||
| 3918 | /* Average number of live objects per GC. */ | 3927 | /* Average number of live objects per GC. */ |
| 3919 | 3928 | ||
| @@ -3924,7 +3933,7 @@ DEFUN ("gc-status", Fgc_status, Sgc_status, 0, 0, "", | |||
| 3924 | (void) | 3933 | (void) |
| 3925 | { | 3934 | { |
| 3926 | Lisp_Object args[8], zombie_list = Qnil; | 3935 | Lisp_Object args[8], zombie_list = Qnil; |
| 3927 | int i; | 3936 | EMACS_INT i; |
| 3928 | for (i = 0; i < nzombies; i++) | 3937 | for (i = 0; i < nzombies; i++) |
| 3929 | zombie_list = Fcons (zombies[i], zombie_list); | 3938 | zombie_list = Fcons (zombies[i], zombie_list); |
| 3930 | 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"); |
| @@ -3943,7 +3952,7 @@ DEFUN ("gc-status", Fgc_status, Sgc_status, 0, 0, "", | |||
| 3943 | 3952 | ||
| 3944 | /* Mark OBJ if we can prove it's a Lisp_Object. */ | 3953 | /* Mark OBJ if we can prove it's a Lisp_Object. */ |
| 3945 | 3954 | ||
| 3946 | static INLINE void | 3955 | static inline void |
| 3947 | mark_maybe_object (Lisp_Object obj) | 3956 | mark_maybe_object (Lisp_Object obj) |
| 3948 | { | 3957 | { |
| 3949 | void *po; | 3958 | void *po; |
| @@ -4012,13 +4021,13 @@ mark_maybe_object (Lisp_Object obj) | |||
| 4012 | /* If P points to Lisp data, mark that as live if it isn't already | 4021 | /* If P points to Lisp data, mark that as live if it isn't already |
| 4013 | marked. */ | 4022 | marked. */ |
| 4014 | 4023 | ||
| 4015 | static INLINE void | 4024 | static inline void |
| 4016 | mark_maybe_pointer (void *p) | 4025 | mark_maybe_pointer (void *p) |
| 4017 | { | 4026 | { |
| 4018 | struct mem_node *m; | 4027 | struct mem_node *m; |
| 4019 | 4028 | ||
| 4020 | /* Quickly rule out some values which can't point to Lisp data. */ | 4029 | /* Quickly rule out some values which can't point to Lisp data. */ |
| 4021 | if ((EMACS_INT) p % | 4030 | if ((intptr_t) p % |
| 4022 | #ifdef USE_LSB_TAG | 4031 | #ifdef USE_LSB_TAG |
| 4023 | 8 /* USE_LSB_TAG needs Lisp data to be aligned on multiples of 8. */ | 4032 | 8 /* USE_LSB_TAG needs Lisp data to be aligned on multiples of 8. */ |
| 4024 | #else | 4033 | #else |
| @@ -4234,7 +4243,7 @@ static void | |||
| 4234 | check_gcpros (void) | 4243 | check_gcpros (void) |
| 4235 | { | 4244 | { |
| 4236 | struct gcpro *p; | 4245 | struct gcpro *p; |
| 4237 | int i; | 4246 | ptrdiff_t i; |
| 4238 | 4247 | ||
| 4239 | for (p = gcprolist; p; p = p->next) | 4248 | for (p = gcprolist; p; p = p->next) |
| 4240 | for (i = 0; i < p->nvars; ++i) | 4249 | for (i = 0; i < p->nvars; ++i) |
| @@ -4251,7 +4260,7 @@ dump_zombies (void) | |||
| 4251 | { | 4260 | { |
| 4252 | int i; | 4261 | int i; |
| 4253 | 4262 | ||
| 4254 | fprintf (stderr, "\nZombies kept alive = %d:\n", nzombies); | 4263 | fprintf (stderr, "\nZombies kept alive = %"pI":\n", nzombies); |
| 4255 | for (i = 0; i < min (MAX_ZOMBIES, nzombies); ++i) | 4264 | for (i = 0; i < min (MAX_ZOMBIES, nzombies); ++i) |
| 4256 | { | 4265 | { |
| 4257 | fprintf (stderr, " %d = ", i); | 4266 | fprintf (stderr, " %d = ", i); |
| @@ -4317,12 +4326,6 @@ static void | |||
| 4317 | mark_stack (void) | 4326 | mark_stack (void) |
| 4318 | { | 4327 | { |
| 4319 | int i; | 4328 | int i; |
| 4320 | /* jmp_buf may not be aligned enough on darwin-ppc64 */ | ||
| 4321 | union aligned_jmpbuf { | ||
| 4322 | Lisp_Object o; | ||
| 4323 | jmp_buf j; | ||
| 4324 | } j; | ||
| 4325 | volatile int stack_grows_down_p = (char *) &j > (char *) stack_base; | ||
| 4326 | void *end; | 4329 | void *end; |
| 4327 | 4330 | ||
| 4328 | #ifdef HAVE___BUILTIN_UNWIND_INIT | 4331 | #ifdef HAVE___BUILTIN_UNWIND_INIT |
| @@ -4332,6 +4335,14 @@ mark_stack (void) | |||
| 4332 | __builtin_unwind_init (); | 4335 | __builtin_unwind_init (); |
| 4333 | end = &end; | 4336 | end = &end; |
| 4334 | #else /* not HAVE___BUILTIN_UNWIND_INIT */ | 4337 | #else /* not HAVE___BUILTIN_UNWIND_INIT */ |
| 4338 | #ifndef GC_SAVE_REGISTERS_ON_STACK | ||
| 4339 | /* jmp_buf may not be aligned enough on darwin-ppc64 */ | ||
| 4340 | union aligned_jmpbuf { | ||
| 4341 | Lisp_Object o; | ||
| 4342 | jmp_buf j; | ||
| 4343 | } j; | ||
| 4344 | volatile int stack_grows_down_p = (char *) &j > (char *) stack_base; | ||
| 4345 | #endif | ||
| 4335 | /* This trick flushes the register windows so that all the state of | 4346 | /* This trick flushes the register windows so that all the state of |
| 4336 | the process is contained in the stack. */ | 4347 | the process is contained in the stack. */ |
| 4337 | /* Fixme: Code in the Boehm GC suggests flushing (with `flushrs') is | 4348 | /* Fixme: Code in the Boehm GC suggests flushing (with `flushrs') is |
| @@ -4563,8 +4574,9 @@ void | |||
| 4563 | check_pure_size (void) | 4574 | check_pure_size (void) |
| 4564 | { | 4575 | { |
| 4565 | if (pure_bytes_used_before_overflow) | 4576 | if (pure_bytes_used_before_overflow) |
| 4566 | message ("emacs:0:Pure Lisp storage overflow (approx. %d bytes needed)", | 4577 | message (("emacs:0:Pure Lisp storage overflow (approx. %"pI"d" |
| 4567 | (int) (pure_bytes_used + pure_bytes_used_before_overflow)); | 4578 | " bytes needed)"), |
| 4579 | pure_bytes_used + pure_bytes_used_before_overflow); | ||
| 4568 | } | 4580 | } |
| 4569 | 4581 | ||
| 4570 | 4582 | ||
| @@ -4650,7 +4662,7 @@ make_pure_string (const char *data, | |||
| 4650 | struct Lisp_String *s; | 4662 | struct Lisp_String *s; |
| 4651 | 4663 | ||
| 4652 | s = (struct Lisp_String *) pure_alloc (sizeof *s, Lisp_String); | 4664 | s = (struct Lisp_String *) pure_alloc (sizeof *s, Lisp_String); |
| 4653 | s->data = find_string_data_in_pure (data, nbytes); | 4665 | s->data = (unsigned char *) find_string_data_in_pure (data, nbytes); |
| 4654 | if (s->data == NULL) | 4666 | if (s->data == NULL) |
| 4655 | { | 4667 | { |
| 4656 | s->data = (unsigned char *) pure_alloc (nbytes + 1, -1); | 4668 | s->data = (unsigned char *) pure_alloc (nbytes + 1, -1); |
| @@ -4723,11 +4735,12 @@ make_pure_vector (EMACS_INT len) | |||
| 4723 | { | 4735 | { |
| 4724 | Lisp_Object new; | 4736 | Lisp_Object new; |
| 4725 | struct Lisp_Vector *p; | 4737 | struct Lisp_Vector *p; |
| 4726 | size_t size = sizeof *p + (len - 1) * sizeof (Lisp_Object); | 4738 | size_t size = (offsetof (struct Lisp_Vector, contents) |
| 4739 | + len * sizeof (Lisp_Object)); | ||
| 4727 | 4740 | ||
| 4728 | p = (struct Lisp_Vector *) pure_alloc (size, Lisp_Vectorlike); | 4741 | p = (struct Lisp_Vector *) pure_alloc (size, Lisp_Vectorlike); |
| 4729 | XSETVECTOR (new, p); | 4742 | XSETVECTOR (new, p); |
| 4730 | XVECTOR (new)->size = len; | 4743 | XVECTOR (new)->header.size = len; |
| 4731 | return new; | 4744 | return new; |
| 4732 | } | 4745 | } |
| 4733 | 4746 | ||
| @@ -4765,7 +4778,7 @@ Does not copy symbols. Copies strings without text properties. */) | |||
| 4765 | register EMACS_INT i; | 4778 | register EMACS_INT i; |
| 4766 | EMACS_INT size; | 4779 | EMACS_INT size; |
| 4767 | 4780 | ||
| 4768 | size = XVECTOR (obj)->size; | 4781 | size = ASIZE (obj); |
| 4769 | if (size & PSEUDOVECTOR_FLAG) | 4782 | if (size & PSEUDOVECTOR_FLAG) |
| 4770 | size &= PSEUDOVECTOR_SIZE_MASK; | 4783 | size &= PSEUDOVECTOR_SIZE_MASK; |
| 4771 | vec = XVECTOR (make_pure_vector (size)); | 4784 | vec = XVECTOR (make_pure_vector (size)); |
| @@ -4819,9 +4832,8 @@ int | |||
| 4819 | inhibit_garbage_collection (void) | 4832 | inhibit_garbage_collection (void) |
| 4820 | { | 4833 | { |
| 4821 | int count = SPECPDL_INDEX (); | 4834 | int count = SPECPDL_INDEX (); |
| 4822 | int nbits = min (VALBITS, BITS_PER_INT); | ||
| 4823 | 4835 | ||
| 4824 | specbind (Qgc_cons_threshold, make_number (((EMACS_INT) 1 << (nbits - 1)) - 1)); | 4836 | specbind (Qgc_cons_threshold, make_number (MOST_POSITIVE_FIXNUM)); |
| 4825 | return count; | 4837 | return count; |
| 4826 | } | 4838 | } |
| 4827 | 4839 | ||
| @@ -4840,10 +4852,8 @@ returns nil, because real GC can't be done. */) | |||
| 4840 | (void) | 4852 | (void) |
| 4841 | { | 4853 | { |
| 4842 | register struct specbinding *bind; | 4854 | register struct specbinding *bind; |
| 4843 | struct catchtag *catch; | ||
| 4844 | struct handler *handler; | ||
| 4845 | char stack_top_variable; | 4855 | char stack_top_variable; |
| 4846 | register int i; | 4856 | ptrdiff_t i; |
| 4847 | int message_p; | 4857 | int message_p; |
| 4848 | Lisp_Object total[8]; | 4858 | Lisp_Object total[8]; |
| 4849 | int count = SPECPDL_INDEX (); | 4859 | int count = SPECPDL_INDEX (); |
| @@ -4870,11 +4880,11 @@ returns nil, because real GC can't be done. */) | |||
| 4870 | turned off in that buffer. Calling truncate_undo_list on | 4880 | turned off in that buffer. Calling truncate_undo_list on |
| 4871 | Qt tends to return NULL, which effectively turns undo back on. | 4881 | Qt tends to return NULL, which effectively turns undo back on. |
| 4872 | So don't call truncate_undo_list if undo_list is Qt. */ | 4882 | So don't call truncate_undo_list if undo_list is Qt. */ |
| 4873 | if (! NILP (nextb->name) && ! EQ (nextb->undo_list, Qt)) | 4883 | if (! NILP (nextb->BUFFER_INTERNAL_FIELD (name)) && ! EQ (nextb->BUFFER_INTERNAL_FIELD (undo_list), Qt)) |
| 4874 | truncate_undo_list (nextb); | 4884 | truncate_undo_list (nextb); |
| 4875 | 4885 | ||
| 4876 | /* Shrink buffer gaps, but skip indirect and dead buffers. */ | 4886 | /* Shrink buffer gaps, but skip indirect and dead buffers. */ |
| 4877 | if (nextb->base_buffer == 0 && !NILP (nextb->name) | 4887 | if (nextb->base_buffer == 0 && !NILP (nextb->BUFFER_INTERNAL_FIELD (name)) |
| 4878 | && ! nextb->text->inhibit_shrinking) | 4888 | && ! nextb->text->inhibit_shrinking) |
| 4879 | { | 4889 | { |
| 4880 | /* If a buffer's gap size is more than 10% of the buffer | 4890 | /* If a buffer's gap size is more than 10% of the buffer |
| @@ -4891,7 +4901,7 @@ returns nil, because real GC can't be done. */) | |||
| 4891 | } | 4901 | } |
| 4892 | } | 4902 | } |
| 4893 | 4903 | ||
| 4894 | nextb = nextb->next; | 4904 | nextb = nextb->header.next.buffer; |
| 4895 | } | 4905 | } |
| 4896 | } | 4906 | } |
| 4897 | 4907 | ||
| @@ -4909,21 +4919,26 @@ returns nil, because real GC can't be done. */) | |||
| 4909 | #if MAX_SAVE_STACK > 0 | 4919 | #if MAX_SAVE_STACK > 0 |
| 4910 | if (NILP (Vpurify_flag)) | 4920 | if (NILP (Vpurify_flag)) |
| 4911 | { | 4921 | { |
| 4912 | i = &stack_top_variable - stack_bottom; | 4922 | char *stack; |
| 4913 | if (i < 0) i = -i; | 4923 | size_t stack_size; |
| 4914 | if (i < MAX_SAVE_STACK) | 4924 | if (&stack_top_variable < stack_bottom) |
| 4925 | { | ||
| 4926 | stack = &stack_top_variable; | ||
| 4927 | stack_size = stack_bottom - &stack_top_variable; | ||
| 4928 | } | ||
| 4929 | else | ||
| 4915 | { | 4930 | { |
| 4916 | if (stack_copy == 0) | 4931 | stack = stack_bottom; |
| 4917 | stack_copy = (char *) xmalloc (stack_copy_size = i); | 4932 | stack_size = &stack_top_variable - stack_bottom; |
| 4918 | else if (stack_copy_size < i) | 4933 | } |
| 4919 | stack_copy = (char *) xrealloc (stack_copy, (stack_copy_size = i)); | 4934 | if (stack_size <= MAX_SAVE_STACK) |
| 4920 | if (stack_copy) | 4935 | { |
| 4936 | if (stack_copy_size < stack_size) | ||
| 4921 | { | 4937 | { |
| 4922 | if ((EMACS_INT) (&stack_top_variable - stack_bottom) > 0) | 4938 | stack_copy = (char *) xrealloc (stack_copy, stack_size); |
| 4923 | memcpy (stack_copy, stack_bottom, i); | 4939 | stack_copy_size = stack_size; |
| 4924 | else | ||
| 4925 | memcpy (stack_copy, &stack_top_variable, i); | ||
| 4926 | } | 4940 | } |
| 4941 | memcpy (stack_copy, stack, stack_size); | ||
| 4927 | } | 4942 | } |
| 4928 | } | 4943 | } |
| 4929 | #endif /* MAX_SAVE_STACK > 0 */ | 4944 | #endif /* MAX_SAVE_STACK > 0 */ |
| @@ -4970,9 +4985,11 @@ returns nil, because real GC can't be done. */) | |||
| 4970 | for (i = 0; i < tail->nvars; i++) | 4985 | for (i = 0; i < tail->nvars; i++) |
| 4971 | mark_object (tail->var[i]); | 4986 | mark_object (tail->var[i]); |
| 4972 | } | 4987 | } |
| 4973 | #endif | ||
| 4974 | |||
| 4975 | mark_byte_stack (); | 4988 | mark_byte_stack (); |
| 4989 | { | ||
| 4990 | struct catchtag *catch; | ||
| 4991 | struct handler *handler; | ||
| 4992 | |||
| 4976 | for (catch = catchlist; catch; catch = catch->next) | 4993 | for (catch = catchlist; catch; catch = catch->next) |
| 4977 | { | 4994 | { |
| 4978 | mark_object (catch->tag); | 4995 | mark_object (catch->tag); |
| @@ -4983,7 +5000,9 @@ returns nil, because real GC can't be done. */) | |||
| 4983 | mark_object (handler->handler); | 5000 | mark_object (handler->handler); |
| 4984 | mark_object (handler->var); | 5001 | mark_object (handler->var); |
| 4985 | } | 5002 | } |
| 5003 | } | ||
| 4986 | mark_backtrace (); | 5004 | mark_backtrace (); |
| 5005 | #endif | ||
| 4987 | 5006 | ||
| 4988 | #ifdef HAVE_WINDOW_SYSTEM | 5007 | #ifdef HAVE_WINDOW_SYSTEM |
| 4989 | mark_fringe_data (); | 5008 | mark_fringe_data (); |
| @@ -5007,10 +5026,10 @@ returns nil, because real GC can't be done. */) | |||
| 5007 | turned off in that buffer. Calling truncate_undo_list on | 5026 | turned off in that buffer. Calling truncate_undo_list on |
| 5008 | Qt tends to return NULL, which effectively turns undo back on. | 5027 | Qt tends to return NULL, which effectively turns undo back on. |
| 5009 | So don't call truncate_undo_list if undo_list is Qt. */ | 5028 | So don't call truncate_undo_list if undo_list is Qt. */ |
| 5010 | if (! EQ (nextb->undo_list, Qt)) | 5029 | if (! EQ (nextb->BUFFER_INTERNAL_FIELD (undo_list), Qt)) |
| 5011 | { | 5030 | { |
| 5012 | Lisp_Object tail, prev; | 5031 | Lisp_Object tail, prev; |
| 5013 | tail = nextb->undo_list; | 5032 | tail = nextb->BUFFER_INTERNAL_FIELD (undo_list); |
| 5014 | prev = Qnil; | 5033 | prev = Qnil; |
| 5015 | while (CONSP (tail)) | 5034 | while (CONSP (tail)) |
| 5016 | { | 5035 | { |
| @@ -5019,7 +5038,7 @@ returns nil, because real GC can't be done. */) | |||
| 5019 | && !XMARKER (XCAR (XCAR (tail)))->gcmarkbit) | 5038 | && !XMARKER (XCAR (XCAR (tail)))->gcmarkbit) |
| 5020 | { | 5039 | { |
| 5021 | if (NILP (prev)) | 5040 | if (NILP (prev)) |
| 5022 | nextb->undo_list = tail = XCDR (tail); | 5041 | nextb->BUFFER_INTERNAL_FIELD (undo_list) = tail = XCDR (tail); |
| 5023 | else | 5042 | else |
| 5024 | { | 5043 | { |
| 5025 | tail = XCDR (tail); | 5044 | tail = XCDR (tail); |
| @@ -5035,9 +5054,9 @@ returns nil, because real GC can't be done. */) | |||
| 5035 | } | 5054 | } |
| 5036 | /* Now that we have stripped the elements that need not be in the | 5055 | /* Now that we have stripped the elements that need not be in the |
| 5037 | undo_list any more, we can finally mark the list. */ | 5056 | undo_list any more, we can finally mark the list. */ |
| 5038 | mark_object (nextb->undo_list); | 5057 | mark_object (nextb->BUFFER_INTERNAL_FIELD (undo_list)); |
| 5039 | 5058 | ||
| 5040 | nextb = nextb->next; | 5059 | nextb = nextb->header.next.buffer; |
| 5041 | } | 5060 | } |
| 5042 | } | 5061 | } |
| 5043 | 5062 | ||
| @@ -5064,23 +5083,29 @@ returns nil, because real GC can't be done. */) | |||
| 5064 | if (gc_cons_threshold < 10000) | 5083 | if (gc_cons_threshold < 10000) |
| 5065 | gc_cons_threshold = 10000; | 5084 | gc_cons_threshold = 10000; |
| 5066 | 5085 | ||
| 5086 | gc_relative_threshold = 0; | ||
| 5067 | if (FLOATP (Vgc_cons_percentage)) | 5087 | if (FLOATP (Vgc_cons_percentage)) |
| 5068 | { /* Set gc_cons_combined_threshold. */ | 5088 | { /* Set gc_cons_combined_threshold. */ |
| 5069 | EMACS_INT total = 0; | 5089 | double tot = 0; |
| 5070 | 5090 | ||
| 5071 | total += total_conses * sizeof (struct Lisp_Cons); | 5091 | tot += total_conses * sizeof (struct Lisp_Cons); |
| 5072 | total += total_symbols * sizeof (struct Lisp_Symbol); | 5092 | tot += total_symbols * sizeof (struct Lisp_Symbol); |
| 5073 | total += total_markers * sizeof (union Lisp_Misc); | 5093 | tot += total_markers * sizeof (union Lisp_Misc); |
| 5074 | total += total_string_size; | 5094 | tot += total_string_size; |
| 5075 | total += total_vector_size * sizeof (Lisp_Object); | 5095 | tot += total_vector_size * sizeof (Lisp_Object); |
| 5076 | total += total_floats * sizeof (struct Lisp_Float); | 5096 | tot += total_floats * sizeof (struct Lisp_Float); |
| 5077 | total += total_intervals * sizeof (struct interval); | 5097 | tot += total_intervals * sizeof (struct interval); |
| 5078 | total += total_strings * sizeof (struct Lisp_String); | 5098 | tot += total_strings * sizeof (struct Lisp_String); |
| 5079 | 5099 | ||
| 5080 | gc_relative_threshold = total * 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 | } | ||
| 5081 | } | 5108 | } |
| 5082 | else | ||
| 5083 | gc_relative_threshold = 0; | ||
| 5084 | 5109 | ||
| 5085 | if (garbage_collection_messages) | 5110 | if (garbage_collection_messages) |
| 5086 | { | 5111 | { |
| @@ -5126,9 +5151,9 @@ returns nil, because real GC can't be done. */) | |||
| 5126 | 5151 | ||
| 5127 | if (!NILP (Vpost_gc_hook)) | 5152 | if (!NILP (Vpost_gc_hook)) |
| 5128 | { | 5153 | { |
| 5129 | int count = inhibit_garbage_collection (); | 5154 | int gc_count = inhibit_garbage_collection (); |
| 5130 | safe_run_hooks (Qpost_gc_hook); | 5155 | safe_run_hooks (Qpost_gc_hook); |
| 5131 | unbind_to (count, Qnil); | 5156 | unbind_to (gc_count, Qnil); |
| 5132 | } | 5157 | } |
| 5133 | 5158 | ||
| 5134 | /* Accumulate statistics. */ | 5159 | /* Accumulate statistics. */ |
| @@ -5200,19 +5225,19 @@ mark_face_cache (struct face_cache *c) | |||
| 5200 | 5225 | ||
| 5201 | #define LAST_MARKED_SIZE 500 | 5226 | #define LAST_MARKED_SIZE 500 |
| 5202 | static Lisp_Object last_marked[LAST_MARKED_SIZE]; | 5227 | static Lisp_Object last_marked[LAST_MARKED_SIZE]; |
| 5203 | int last_marked_index; | 5228 | static int last_marked_index; |
| 5204 | 5229 | ||
| 5205 | /* For debugging--call abort when we cdr down this many | 5230 | /* For debugging--call abort when we cdr down this many |
| 5206 | links of a list, in mark_object. In debugging, | 5231 | links of a list, in mark_object. In debugging, |
| 5207 | the call to abort will hit a breakpoint. | 5232 | the call to abort will hit a breakpoint. |
| 5208 | Normally this is zero and the check never goes off. */ | 5233 | Normally this is zero and the check never goes off. */ |
| 5209 | static int mark_object_loop_halt; | 5234 | static size_t mark_object_loop_halt; |
| 5210 | 5235 | ||
| 5211 | static void | 5236 | static void |
| 5212 | mark_vectorlike (struct Lisp_Vector *ptr) | 5237 | mark_vectorlike (struct Lisp_Vector *ptr) |
| 5213 | { | 5238 | { |
| 5214 | register EMACS_UINT size = ptr->size; | 5239 | EMACS_INT size = ptr->header.size; |
| 5215 | register EMACS_UINT i; | 5240 | EMACS_INT i; |
| 5216 | 5241 | ||
| 5217 | eassert (!VECTOR_MARKED_P (ptr)); | 5242 | eassert (!VECTOR_MARKED_P (ptr)); |
| 5218 | VECTOR_MARK (ptr); /* Else mark it */ | 5243 | VECTOR_MARK (ptr); /* Else mark it */ |
| @@ -5234,8 +5259,8 @@ mark_vectorlike (struct Lisp_Vector *ptr) | |||
| 5234 | static void | 5259 | static void |
| 5235 | mark_char_table (struct Lisp_Vector *ptr) | 5260 | mark_char_table (struct Lisp_Vector *ptr) |
| 5236 | { | 5261 | { |
| 5237 | register EMACS_UINT size = ptr->size & PSEUDOVECTOR_SIZE_MASK; | 5262 | int size = ptr->header.size & PSEUDOVECTOR_SIZE_MASK; |
| 5238 | register EMACS_UINT i; | 5263 | int i; |
| 5239 | 5264 | ||
| 5240 | eassert (!VECTOR_MARKED_P (ptr)); | 5265 | eassert (!VECTOR_MARKED_P (ptr)); |
| 5241 | VECTOR_MARK (ptr); | 5266 | VECTOR_MARK (ptr); |
| @@ -5263,7 +5288,7 @@ mark_object (Lisp_Object arg) | |||
| 5263 | void *po; | 5288 | void *po; |
| 5264 | struct mem_node *m; | 5289 | struct mem_node *m; |
| 5265 | #endif | 5290 | #endif |
| 5266 | int cdr_count = 0; | 5291 | size_t cdr_count = 0; |
| 5267 | 5292 | ||
| 5268 | loop: | 5293 | loop: |
| 5269 | 5294 | ||
| @@ -5307,7 +5332,6 @@ mark_object (Lisp_Object arg) | |||
| 5307 | 5332 | ||
| 5308 | #else /* not GC_CHECK_MARKED_OBJECTS */ | 5333 | #else /* not GC_CHECK_MARKED_OBJECTS */ |
| 5309 | 5334 | ||
| 5310 | #define CHECK_ALLOCATED() (void) 0 | ||
| 5311 | #define CHECK_LIVE(LIVEP) (void) 0 | 5335 | #define CHECK_LIVE(LIVEP) (void) 0 |
| 5312 | #define CHECK_ALLOCATED_AND_LIVE(LIVEP) (void) 0 | 5336 | #define CHECK_ALLOCATED_AND_LIVE(LIVEP) (void) 0 |
| 5313 | 5337 | ||
| @@ -5348,7 +5372,7 @@ mark_object (Lisp_Object arg) | |||
| 5348 | if (po != &buffer_defaults && po != &buffer_local_symbols) | 5372 | if (po != &buffer_defaults && po != &buffer_local_symbols) |
| 5349 | { | 5373 | { |
| 5350 | struct buffer *b; | 5374 | struct buffer *b; |
| 5351 | for (b = all_buffers; b && b != po; b = b->next) | 5375 | for (b = all_buffers; b && b != po; b = b->header.next.buffer) |
| 5352 | ; | 5376 | ; |
| 5353 | if (b == NULL) | 5377 | if (b == NULL) |
| 5354 | abort (); | 5378 | abort (); |
| @@ -5364,12 +5388,11 @@ mark_object (Lisp_Object arg) | |||
| 5364 | recursion there. */ | 5388 | recursion there. */ |
| 5365 | { | 5389 | { |
| 5366 | register struct Lisp_Vector *ptr = XVECTOR (obj); | 5390 | register struct Lisp_Vector *ptr = XVECTOR (obj); |
| 5367 | register EMACS_UINT size = ptr->size; | 5391 | int size = ptr->header.size & PSEUDOVECTOR_SIZE_MASK; |
| 5368 | register EMACS_UINT i; | 5392 | int i; |
| 5369 | 5393 | ||
| 5370 | CHECK_LIVE (live_vector_p); | 5394 | CHECK_LIVE (live_vector_p); |
| 5371 | VECTOR_MARK (ptr); /* Else mark it */ | 5395 | VECTOR_MARK (ptr); /* Else mark it */ |
| 5372 | size &= PSEUDOVECTOR_SIZE_MASK; | ||
| 5373 | for (i = 0; i < size; i++) /* and then mark its elements */ | 5396 | for (i = 0; i < size; i++) /* and then mark its elements */ |
| 5374 | { | 5397 | { |
| 5375 | if (i != COMPILED_CONSTANTS) | 5398 | if (i != COMPILED_CONSTANTS) |
| @@ -5496,7 +5519,7 @@ mark_object (Lisp_Object arg) | |||
| 5496 | if (ptr->dogc) | 5519 | if (ptr->dogc) |
| 5497 | { | 5520 | { |
| 5498 | Lisp_Object *p = (Lisp_Object *) ptr->pointer; | 5521 | Lisp_Object *p = (Lisp_Object *) ptr->pointer; |
| 5499 | int nelt; | 5522 | ptrdiff_t nelt; |
| 5500 | for (nelt = ptr->integer; nelt > 0; nelt--, p++) | 5523 | for (nelt = ptr->integer; nelt > 0; nelt--, p++) |
| 5501 | mark_maybe_object (*p); | 5524 | mark_maybe_object (*p); |
| 5502 | } | 5525 | } |
| @@ -5593,7 +5616,7 @@ mark_buffer (Lisp_Object buf) | |||
| 5593 | 5616 | ||
| 5594 | /* buffer-local Lisp variables start at `undo_list', | 5617 | /* buffer-local Lisp variables start at `undo_list', |
| 5595 | tho only the ones from `name' on are GC'd normally. */ | 5618 | tho only the ones from `name' on are GC'd normally. */ |
| 5596 | for (ptr = &buffer->name; | 5619 | for (ptr = &buffer->BUFFER_INTERNAL_FIELD (name); |
| 5597 | (char *)ptr < (char *)buffer + sizeof (struct buffer); | 5620 | (char *)ptr < (char *)buffer + sizeof (struct buffer); |
| 5598 | ptr++) | 5621 | ptr++) |
| 5599 | mark_object (*ptr); | 5622 | mark_object (*ptr); |
| @@ -5696,7 +5719,7 @@ gc_sweep (void) | |||
| 5696 | register struct cons_block *cblk; | 5719 | register struct cons_block *cblk; |
| 5697 | struct cons_block **cprev = &cons_block; | 5720 | struct cons_block **cprev = &cons_block; |
| 5698 | register int lim = cons_block_index; | 5721 | register int lim = cons_block_index; |
| 5699 | register int num_free = 0, num_used = 0; | 5722 | EMACS_INT num_free = 0, num_used = 0; |
| 5700 | 5723 | ||
| 5701 | cons_free_list = 0; | 5724 | cons_free_list = 0; |
| 5702 | 5725 | ||
| @@ -5757,7 +5780,6 @@ gc_sweep (void) | |||
| 5757 | /* Unhook from the free list. */ | 5780 | /* Unhook from the free list. */ |
| 5758 | cons_free_list = cblk->conses[0].u.chain; | 5781 | cons_free_list = cblk->conses[0].u.chain; |
| 5759 | lisp_align_free (cblk); | 5782 | lisp_align_free (cblk); |
| 5760 | n_cons_blocks--; | ||
| 5761 | } | 5783 | } |
| 5762 | else | 5784 | else |
| 5763 | { | 5785 | { |
| @@ -5774,7 +5796,7 @@ gc_sweep (void) | |||
| 5774 | register struct float_block *fblk; | 5796 | register struct float_block *fblk; |
| 5775 | struct float_block **fprev = &float_block; | 5797 | struct float_block **fprev = &float_block; |
| 5776 | register int lim = float_block_index; | 5798 | register int lim = float_block_index; |
| 5777 | register int num_free = 0, num_used = 0; | 5799 | EMACS_INT num_free = 0, num_used = 0; |
| 5778 | 5800 | ||
| 5779 | float_free_list = 0; | 5801 | float_free_list = 0; |
| 5780 | 5802 | ||
| @@ -5804,7 +5826,6 @@ gc_sweep (void) | |||
| 5804 | /* Unhook from the free list. */ | 5826 | /* Unhook from the free list. */ |
| 5805 | float_free_list = fblk->floats[0].u.chain; | 5827 | float_free_list = fblk->floats[0].u.chain; |
| 5806 | lisp_align_free (fblk); | 5828 | lisp_align_free (fblk); |
| 5807 | n_float_blocks--; | ||
| 5808 | } | 5829 | } |
| 5809 | else | 5830 | else |
| 5810 | { | 5831 | { |
| @@ -5821,7 +5842,7 @@ gc_sweep (void) | |||
| 5821 | register struct interval_block *iblk; | 5842 | register struct interval_block *iblk; |
| 5822 | struct interval_block **iprev = &interval_block; | 5843 | struct interval_block **iprev = &interval_block; |
| 5823 | register int lim = interval_block_index; | 5844 | register int lim = interval_block_index; |
| 5824 | register int num_free = 0, num_used = 0; | 5845 | EMACS_INT num_free = 0, num_used = 0; |
| 5825 | 5846 | ||
| 5826 | interval_free_list = 0; | 5847 | interval_free_list = 0; |
| 5827 | 5848 | ||
| @@ -5854,7 +5875,6 @@ gc_sweep (void) | |||
| 5854 | /* Unhook from the free list. */ | 5875 | /* Unhook from the free list. */ |
| 5855 | interval_free_list = INTERVAL_PARENT (&iblk->intervals[0]); | 5876 | interval_free_list = INTERVAL_PARENT (&iblk->intervals[0]); |
| 5856 | lisp_free (iblk); | 5877 | lisp_free (iblk); |
| 5857 | n_interval_blocks--; | ||
| 5858 | } | 5878 | } |
| 5859 | else | 5879 | else |
| 5860 | { | 5880 | { |
| @@ -5871,7 +5891,7 @@ gc_sweep (void) | |||
| 5871 | register struct symbol_block *sblk; | 5891 | register struct symbol_block *sblk; |
| 5872 | struct symbol_block **sprev = &symbol_block; | 5892 | struct symbol_block **sprev = &symbol_block; |
| 5873 | register int lim = symbol_block_index; | 5893 | register int lim = symbol_block_index; |
| 5874 | register int num_free = 0, num_used = 0; | 5894 | EMACS_INT num_free = 0, num_used = 0; |
| 5875 | 5895 | ||
| 5876 | symbol_free_list = NULL; | 5896 | symbol_free_list = NULL; |
| 5877 | 5897 | ||
| @@ -5918,7 +5938,6 @@ gc_sweep (void) | |||
| 5918 | /* Unhook from the free list. */ | 5938 | /* Unhook from the free list. */ |
| 5919 | symbol_free_list = sblk->symbols[0].next; | 5939 | symbol_free_list = sblk->symbols[0].next; |
| 5920 | lisp_free (sblk); | 5940 | lisp_free (sblk); |
| 5921 | n_symbol_blocks--; | ||
| 5922 | } | 5941 | } |
| 5923 | else | 5942 | else |
| 5924 | { | 5943 | { |
| @@ -5936,7 +5955,7 @@ gc_sweep (void) | |||
| 5936 | register struct marker_block *mblk; | 5955 | register struct marker_block *mblk; |
| 5937 | struct marker_block **mprev = &marker_block; | 5956 | struct marker_block **mprev = &marker_block; |
| 5938 | register int lim = marker_block_index; | 5957 | register int lim = marker_block_index; |
| 5939 | register int num_free = 0, num_used = 0; | 5958 | EMACS_INT num_free = 0, num_used = 0; |
| 5940 | 5959 | ||
| 5941 | marker_free_list = 0; | 5960 | marker_free_list = 0; |
| 5942 | 5961 | ||
| @@ -5975,7 +5994,6 @@ gc_sweep (void) | |||
| 5975 | /* Unhook from the free list. */ | 5994 | /* Unhook from the free list. */ |
| 5976 | marker_free_list = mblk->markers[0].u_free.chain; | 5995 | marker_free_list = mblk->markers[0].u_free.chain; |
| 5977 | lisp_free (mblk); | 5996 | lisp_free (mblk); |
| 5978 | n_marker_blocks--; | ||
| 5979 | } | 5997 | } |
| 5980 | else | 5998 | else |
| 5981 | { | 5999 | { |
| @@ -5996,10 +6014,10 @@ gc_sweep (void) | |||
| 5996 | if (!VECTOR_MARKED_P (buffer)) | 6014 | if (!VECTOR_MARKED_P (buffer)) |
| 5997 | { | 6015 | { |
| 5998 | if (prev) | 6016 | if (prev) |
| 5999 | prev->next = buffer->next; | 6017 | prev->header.next = buffer->header.next; |
| 6000 | else | 6018 | else |
| 6001 | all_buffers = buffer->next; | 6019 | all_buffers = buffer->header.next.buffer; |
| 6002 | next = buffer->next; | 6020 | next = buffer->header.next.buffer; |
| 6003 | lisp_free (buffer); | 6021 | lisp_free (buffer); |
| 6004 | buffer = next; | 6022 | buffer = next; |
| 6005 | } | 6023 | } |
| @@ -6007,7 +6025,7 @@ gc_sweep (void) | |||
| 6007 | { | 6025 | { |
| 6008 | VECTOR_UNMARK (buffer); | 6026 | VECTOR_UNMARK (buffer); |
| 6009 | UNMARK_BALANCE_INTERVALS (BUF_INTERVALS (buffer)); | 6027 | UNMARK_BALANCE_INTERVALS (BUF_INTERVALS (buffer)); |
| 6010 | prev = buffer, buffer = buffer->next; | 6028 | prev = buffer, buffer = buffer->header.next.buffer; |
| 6011 | } | 6029 | } |
| 6012 | } | 6030 | } |
| 6013 | 6031 | ||
| @@ -6020,23 +6038,22 @@ gc_sweep (void) | |||
| 6020 | if (!VECTOR_MARKED_P (vector)) | 6038 | if (!VECTOR_MARKED_P (vector)) |
| 6021 | { | 6039 | { |
| 6022 | if (prev) | 6040 | if (prev) |
| 6023 | prev->next = vector->next; | 6041 | prev->header.next = vector->header.next; |
| 6024 | else | 6042 | else |
| 6025 | all_vectors = vector->next; | 6043 | all_vectors = vector->header.next.vector; |
| 6026 | next = vector->next; | 6044 | next = vector->header.next.vector; |
| 6027 | lisp_free (vector); | 6045 | lisp_free (vector); |
| 6028 | n_vectors--; | ||
| 6029 | vector = next; | 6046 | vector = next; |
| 6030 | 6047 | ||
| 6031 | } | 6048 | } |
| 6032 | else | 6049 | else |
| 6033 | { | 6050 | { |
| 6034 | VECTOR_UNMARK (vector); | 6051 | VECTOR_UNMARK (vector); |
| 6035 | if (vector->size & PSEUDOVECTOR_FLAG) | 6052 | if (vector->header.size & PSEUDOVECTOR_FLAG) |
| 6036 | total_vector_size += (PSEUDOVECTOR_SIZE_MASK & vector->size); | 6053 | total_vector_size += PSEUDOVECTOR_SIZE_MASK & vector->header.size; |
| 6037 | else | 6054 | else |
| 6038 | total_vector_size += vector->size; | 6055 | total_vector_size += vector->header.size; |
| 6039 | prev = vector, vector = vector->next; | 6056 | prev = vector, vector = vector->header.next.vector; |
| 6040 | } | 6057 | } |
| 6041 | } | 6058 | } |
| 6042 | 6059 | ||
| @@ -6059,7 +6076,7 @@ We divide the value by 1024 to make sure it fits in a Lisp integer. */) | |||
| 6059 | { | 6076 | { |
| 6060 | Lisp_Object end; | 6077 | Lisp_Object end; |
| 6061 | 6078 | ||
| 6062 | XSETINT (end, (EMACS_INT) sbrk (0) / 1024); | 6079 | XSETINT (end, (intptr_t) (char *) sbrk (0) / 1024); |
| 6063 | 6080 | ||
| 6064 | return end; | 6081 | return end; |
| 6065 | } | 6082 | } |
| @@ -6093,6 +6110,7 @@ Frames, windows, buffers, and subprocesses count as vectors | |||
| 6093 | return Flist (8, consed); | 6110 | return Flist (8, consed); |
| 6094 | } | 6111 | } |
| 6095 | 6112 | ||
| 6113 | #ifdef ENABLE_CHECKING | ||
| 6096 | int suppress_checking; | 6114 | int suppress_checking; |
| 6097 | 6115 | ||
| 6098 | void | 6116 | void |
| @@ -6102,6 +6120,7 @@ die (const char *msg, const char *file, int line) | |||
| 6102 | file, line, msg); | 6120 | file, line, msg); |
| 6103 | abort (); | 6121 | abort (); |
| 6104 | } | 6122 | } |
| 6123 | #endif | ||
| 6105 | 6124 | ||
| 6106 | /* Initialization */ | 6125 | /* Initialization */ |
| 6107 | 6126 | ||