diff options
| author | Miles Bader | 2007-10-11 16:24:58 +0000 |
|---|---|---|
| committer | Miles Bader | 2007-10-11 16:24:58 +0000 |
| commit | c73bd236f75b742ad4642ec94798987ae6e3e1e8 (patch) | |
| tree | ef5edc8db557fc1d25a17c379e4ae63a38b3ba5c /src/alloc.c | |
| parent | ecb21060d5c1752d41d7a742be565c59b5fcb855 (diff) | |
| parent | 58ade22bf16a9ec2ff0aee6c59d8db4d1703e94f (diff) | |
| download | emacs-c73bd236f75b742ad4642ec94798987ae6e3e1e8.tar.gz emacs-c73bd236f75b742ad4642ec94798987ae6e3e1e8.zip | |
Merge from emacs--devo--0
Patches applied:
* emacs--devo--0 (patch 866-879)
- Merge multi-tty branch
- Update from CVS
- Merge from emacs--rel--22
Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-257
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 530 |
1 files changed, 264 insertions, 266 deletions
diff --git a/src/alloc.c b/src/alloc.c index 2e88afc00ac..fccdf2a88a7 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -55,6 +55,7 @@ Boston, MA 02110-1301, USA. */ | |||
| 55 | #include "blockinput.h" | 55 | #include "blockinput.h" |
| 56 | #include "character.h" | 56 | #include "character.h" |
| 57 | #include "syssignal.h" | 57 | #include "syssignal.h" |
| 58 | #include "termhooks.h" /* For struct terminal. */ | ||
| 58 | #include <setjmp.h> | 59 | #include <setjmp.h> |
| 59 | 60 | ||
| 60 | /* GC_MALLOC_CHECK defined means perform validity checks of malloc'd | 61 | /* GC_MALLOC_CHECK defined means perform validity checks of malloc'd |
| @@ -341,7 +342,9 @@ Lisp_Object Vgc_elapsed; /* accumulated elapsed time in GC */ | |||
| 341 | EMACS_INT gcs_done; /* accumulated GCs */ | 342 | EMACS_INT gcs_done; /* accumulated GCs */ |
| 342 | 343 | ||
| 343 | static void mark_buffer P_ ((Lisp_Object)); | 344 | static void mark_buffer P_ ((Lisp_Object)); |
| 345 | static void mark_terminals P_ ((void)); | ||
| 344 | extern void mark_kboards P_ ((void)); | 346 | extern void mark_kboards P_ ((void)); |
| 347 | extern void mark_ttys P_ ((void)); | ||
| 345 | extern void mark_backtrace P_ ((void)); | 348 | extern void mark_backtrace P_ ((void)); |
| 346 | static void gc_sweep P_ ((void)); | 349 | static void gc_sweep P_ ((void)); |
| 347 | static void mark_glyph_matrix P_ ((struct glyph_matrix *)); | 350 | static void mark_glyph_matrix P_ ((struct glyph_matrix *)); |
| @@ -373,14 +376,11 @@ enum mem_type | |||
| 373 | MEM_TYPE_MISC, | 376 | MEM_TYPE_MISC, |
| 374 | MEM_TYPE_SYMBOL, | 377 | MEM_TYPE_SYMBOL, |
| 375 | MEM_TYPE_FLOAT, | 378 | MEM_TYPE_FLOAT, |
| 376 | /* Keep the following vector-like types together, with | 379 | /* We used to keep separate mem_types for subtypes of vectors such as |
| 377 | MEM_TYPE_WINDOW being the last, and MEM_TYPE_VECTOR the | 380 | process, hash_table, frame, terminal, and window, but we never made |
| 378 | first. Or change the code of live_vector_p, for instance. */ | 381 | use of the distinction, so it only caused source-code complexity |
| 379 | MEM_TYPE_VECTOR, | 382 | and runtime slowdown. Minor but pointless. */ |
| 380 | MEM_TYPE_PROCESS, | 383 | MEM_TYPE_VECTORLIKE |
| 381 | MEM_TYPE_HASH_TABLE, | ||
| 382 | MEM_TYPE_FRAME, | ||
| 383 | MEM_TYPE_WINDOW | ||
| 384 | }; | 384 | }; |
| 385 | 385 | ||
| 386 | static POINTER_TYPE *lisp_align_malloc P_ ((size_t, enum mem_type)); | 386 | static POINTER_TYPE *lisp_align_malloc P_ ((size_t, enum mem_type)); |
| @@ -467,7 +467,7 @@ static struct mem_node mem_z; | |||
| 467 | #define MEM_NIL &mem_z | 467 | #define MEM_NIL &mem_z |
| 468 | 468 | ||
| 469 | static POINTER_TYPE *lisp_malloc P_ ((size_t, enum mem_type)); | 469 | static POINTER_TYPE *lisp_malloc P_ ((size_t, enum mem_type)); |
| 470 | static struct Lisp_Vector *allocate_vectorlike P_ ((EMACS_INT, enum mem_type)); | 470 | static struct Lisp_Vector *allocate_vectorlike P_ ((EMACS_INT)); |
| 471 | static void lisp_free P_ ((POINTER_TYPE *)); | 471 | static void lisp_free P_ ((POINTER_TYPE *)); |
| 472 | static void mark_stack P_ ((void)); | 472 | static void mark_stack P_ ((void)); |
| 473 | static int live_vector_p P_ ((struct mem_node *, void *)); | 473 | static int live_vector_p P_ ((struct mem_node *, void *)); |
| @@ -743,6 +743,15 @@ overrun_check_free (block) | |||
| 743 | #define free overrun_check_free | 743 | #define free overrun_check_free |
| 744 | #endif | 744 | #endif |
| 745 | 745 | ||
| 746 | #ifdef SYNC_INPUT | ||
| 747 | /* When using SYNC_INPUT, we don't call malloc from a signal handler, so | ||
| 748 | there's no need to block input around malloc. */ | ||
| 749 | #define MALLOC_BLOCK_INPUT ((void)0) | ||
| 750 | #define MALLOC_UNBLOCK_INPUT ((void)0) | ||
| 751 | #else | ||
| 752 | #define MALLOC_BLOCK_INPUT BLOCK_INPUT | ||
| 753 | #define MALLOC_UNBLOCK_INPUT UNBLOCK_INPUT | ||
| 754 | #endif | ||
| 746 | 755 | ||
| 747 | /* Like malloc but check for no memory and block interrupt input.. */ | 756 | /* Like malloc but check for no memory and block interrupt input.. */ |
| 748 | 757 | ||
| @@ -752,9 +761,9 @@ xmalloc (size) | |||
| 752 | { | 761 | { |
| 753 | register POINTER_TYPE *val; | 762 | register POINTER_TYPE *val; |
| 754 | 763 | ||
| 755 | BLOCK_INPUT; | 764 | MALLOC_BLOCK_INPUT; |
| 756 | val = (POINTER_TYPE *) malloc (size); | 765 | val = (POINTER_TYPE *) malloc (size); |
| 757 | UNBLOCK_INPUT; | 766 | MALLOC_UNBLOCK_INPUT; |
| 758 | 767 | ||
| 759 | if (!val && size) | 768 | if (!val && size) |
| 760 | memory_full (); | 769 | memory_full (); |
| @@ -771,14 +780,14 @@ xrealloc (block, size) | |||
| 771 | { | 780 | { |
| 772 | register POINTER_TYPE *val; | 781 | register POINTER_TYPE *val; |
| 773 | 782 | ||
| 774 | BLOCK_INPUT; | 783 | MALLOC_BLOCK_INPUT; |
| 775 | /* We must call malloc explicitly when BLOCK is 0, since some | 784 | /* We must call malloc explicitly when BLOCK is 0, since some |
| 776 | reallocs don't do this. */ | 785 | reallocs don't do this. */ |
| 777 | if (! block) | 786 | if (! block) |
| 778 | val = (POINTER_TYPE *) malloc (size); | 787 | val = (POINTER_TYPE *) malloc (size); |
| 779 | else | 788 | else |
| 780 | val = (POINTER_TYPE *) realloc (block, size); | 789 | val = (POINTER_TYPE *) realloc (block, size); |
| 781 | UNBLOCK_INPUT; | 790 | MALLOC_UNBLOCK_INPUT; |
| 782 | 791 | ||
| 783 | if (!val && size) memory_full (); | 792 | if (!val && size) memory_full (); |
| 784 | return val; | 793 | return val; |
| @@ -791,9 +800,9 @@ void | |||
| 791 | xfree (block) | 800 | xfree (block) |
| 792 | POINTER_TYPE *block; | 801 | POINTER_TYPE *block; |
| 793 | { | 802 | { |
| 794 | BLOCK_INPUT; | 803 | MALLOC_BLOCK_INPUT; |
| 795 | free (block); | 804 | free (block); |
| 796 | UNBLOCK_INPUT; | 805 | MALLOC_UNBLOCK_INPUT; |
| 797 | /* We don't call refill_memory_reserve here | 806 | /* We don't call refill_memory_reserve here |
| 798 | because that duplicates doing so in emacs_blocked_free | 807 | because that duplicates doing so in emacs_blocked_free |
| 799 | and the criterion should go there. */ | 808 | and the criterion should go there. */ |
| @@ -844,7 +853,7 @@ lisp_malloc (nbytes, type) | |||
| 844 | { | 853 | { |
| 845 | register void *val; | 854 | register void *val; |
| 846 | 855 | ||
| 847 | BLOCK_INPUT; | 856 | MALLOC_BLOCK_INPUT; |
| 848 | 857 | ||
| 849 | #ifdef GC_MALLOC_CHECK | 858 | #ifdef GC_MALLOC_CHECK |
| 850 | allocated_mem_type = type; | 859 | allocated_mem_type = type; |
| @@ -874,7 +883,7 @@ lisp_malloc (nbytes, type) | |||
| 874 | mem_insert (val, (char *) val + nbytes, type); | 883 | mem_insert (val, (char *) val + nbytes, type); |
| 875 | #endif | 884 | #endif |
| 876 | 885 | ||
| 877 | UNBLOCK_INPUT; | 886 | MALLOC_UNBLOCK_INPUT; |
| 878 | if (!val && nbytes) | 887 | if (!val && nbytes) |
| 879 | memory_full (); | 888 | memory_full (); |
| 880 | return val; | 889 | return val; |
| @@ -887,12 +896,12 @@ static void | |||
| 887 | lisp_free (block) | 896 | lisp_free (block) |
| 888 | POINTER_TYPE *block; | 897 | POINTER_TYPE *block; |
| 889 | { | 898 | { |
| 890 | BLOCK_INPUT; | 899 | MALLOC_BLOCK_INPUT; |
| 891 | free (block); | 900 | free (block); |
| 892 | #if GC_MARK_STACK && !defined GC_MALLOC_CHECK | 901 | #if GC_MARK_STACK && !defined GC_MALLOC_CHECK |
| 893 | mem_delete (mem_find (block)); | 902 | mem_delete (mem_find (block)); |
| 894 | #endif | 903 | #endif |
| 895 | UNBLOCK_INPUT; | 904 | MALLOC_UNBLOCK_INPUT; |
| 896 | } | 905 | } |
| 897 | 906 | ||
| 898 | /* Allocation of aligned blocks of memory to store Lisp data. */ | 907 | /* Allocation of aligned blocks of memory to store Lisp data. */ |
| @@ -993,7 +1002,7 @@ lisp_align_malloc (nbytes, type) | |||
| 993 | 1002 | ||
| 994 | eassert (nbytes <= BLOCK_BYTES); | 1003 | eassert (nbytes <= BLOCK_BYTES); |
| 995 | 1004 | ||
| 996 | BLOCK_INPUT; | 1005 | MALLOC_BLOCK_INPUT; |
| 997 | 1006 | ||
| 998 | #ifdef GC_MALLOC_CHECK | 1007 | #ifdef GC_MALLOC_CHECK |
| 999 | allocated_mem_type = type; | 1008 | allocated_mem_type = type; |
| @@ -1025,7 +1034,7 @@ lisp_align_malloc (nbytes, type) | |||
| 1025 | 1034 | ||
| 1026 | if (base == 0) | 1035 | if (base == 0) |
| 1027 | { | 1036 | { |
| 1028 | UNBLOCK_INPUT; | 1037 | MALLOC_UNBLOCK_INPUT; |
| 1029 | memory_full (); | 1038 | memory_full (); |
| 1030 | } | 1039 | } |
| 1031 | 1040 | ||
| @@ -1051,7 +1060,7 @@ lisp_align_malloc (nbytes, type) | |||
| 1051 | { | 1060 | { |
| 1052 | lisp_malloc_loser = base; | 1061 | lisp_malloc_loser = base; |
| 1053 | free (base); | 1062 | free (base); |
| 1054 | UNBLOCK_INPUT; | 1063 | MALLOC_UNBLOCK_INPUT; |
| 1055 | memory_full (); | 1064 | memory_full (); |
| 1056 | } | 1065 | } |
| 1057 | } | 1066 | } |
| @@ -1084,7 +1093,7 @@ lisp_align_malloc (nbytes, type) | |||
| 1084 | mem_insert (val, (char *) val + nbytes, type); | 1093 | mem_insert (val, (char *) val + nbytes, type); |
| 1085 | #endif | 1094 | #endif |
| 1086 | 1095 | ||
| 1087 | UNBLOCK_INPUT; | 1096 | MALLOC_UNBLOCK_INPUT; |
| 1088 | if (!val && nbytes) | 1097 | if (!val && nbytes) |
| 1089 | memory_full (); | 1098 | memory_full (); |
| 1090 | 1099 | ||
| @@ -1099,7 +1108,7 @@ lisp_align_free (block) | |||
| 1099 | struct ablock *ablock = block; | 1108 | struct ablock *ablock = block; |
| 1100 | struct ablocks *abase = ABLOCK_ABASE (ablock); | 1109 | struct ablocks *abase = ABLOCK_ABASE (ablock); |
| 1101 | 1110 | ||
| 1102 | BLOCK_INPUT; | 1111 | MALLOC_BLOCK_INPUT; |
| 1103 | #if GC_MARK_STACK && !defined GC_MALLOC_CHECK | 1112 | #if GC_MARK_STACK && !defined GC_MALLOC_CHECK |
| 1104 | mem_delete (mem_find (block)); | 1113 | mem_delete (mem_find (block)); |
| 1105 | #endif | 1114 | #endif |
| @@ -1132,7 +1141,7 @@ lisp_align_free (block) | |||
| 1132 | #endif | 1141 | #endif |
| 1133 | free (ABLOCKS_BASE (abase)); | 1142 | free (ABLOCKS_BASE (abase)); |
| 1134 | } | 1143 | } |
| 1135 | UNBLOCK_INPUT; | 1144 | MALLOC_UNBLOCK_INPUT; |
| 1136 | } | 1145 | } |
| 1137 | 1146 | ||
| 1138 | /* Return a new buffer structure allocated from the heap with | 1147 | /* Return a new buffer structure allocated from the heap with |
| @@ -1161,6 +1170,8 @@ allocate_buffer () | |||
| 1161 | can use GNU malloc. */ | 1170 | can use GNU malloc. */ |
| 1162 | 1171 | ||
| 1163 | #ifndef SYNC_INPUT | 1172 | #ifndef SYNC_INPUT |
| 1173 | /* When using SYNC_INPUT, we don't call malloc from a signal handler, so | ||
| 1174 | there's no need to block input around malloc. */ | ||
| 1164 | 1175 | ||
| 1165 | #ifndef DOUG_LEA_MALLOC | 1176 | #ifndef DOUG_LEA_MALLOC |
| 1166 | extern void * (*__malloc_hook) P_ ((size_t, const void *)); | 1177 | extern void * (*__malloc_hook) P_ ((size_t, const void *)); |
| @@ -1234,7 +1245,8 @@ emacs_blocked_malloc (size, ptr) | |||
| 1234 | BLOCK_INPUT_ALLOC; | 1245 | BLOCK_INPUT_ALLOC; |
| 1235 | __malloc_hook = old_malloc_hook; | 1246 | __malloc_hook = old_malloc_hook; |
| 1236 | #ifdef DOUG_LEA_MALLOC | 1247 | #ifdef DOUG_LEA_MALLOC |
| 1237 | mallopt (M_TOP_PAD, malloc_hysteresis * 4096); | 1248 | /* Segfaults on my system. --lorentey */ |
| 1249 | /* mallopt (M_TOP_PAD, malloc_hysteresis * 4096); */ | ||
| 1238 | #else | 1250 | #else |
| 1239 | __malloc_extra_blocks = malloc_hysteresis; | 1251 | __malloc_extra_blocks = malloc_hysteresis; |
| 1240 | #endif | 1252 | #endif |
| @@ -1340,9 +1352,9 @@ emacs_blocked_realloc (ptr, size, ptr2) | |||
| 1340 | void | 1352 | void |
| 1341 | reset_malloc_hooks () | 1353 | reset_malloc_hooks () |
| 1342 | { | 1354 | { |
| 1343 | __free_hook = 0; | 1355 | __free_hook = old_free_hook; |
| 1344 | __malloc_hook = 0; | 1356 | __malloc_hook = old_malloc_hook; |
| 1345 | __realloc_hook = 0; | 1357 | __realloc_hook = old_realloc_hook; |
| 1346 | } | 1358 | } |
| 1347 | #endif /* HAVE_GTK_AND_PTHREAD */ | 1359 | #endif /* HAVE_GTK_AND_PTHREAD */ |
| 1348 | 1360 | ||
| @@ -1444,9 +1456,7 @@ make_interval () | |||
| 1444 | 1456 | ||
| 1445 | /* eassert (!handling_signal); */ | 1457 | /* eassert (!handling_signal); */ |
| 1446 | 1458 | ||
| 1447 | #ifndef SYNC_INPUT | 1459 | MALLOC_BLOCK_INPUT; |
| 1448 | BLOCK_INPUT; | ||
| 1449 | #endif | ||
| 1450 | 1460 | ||
| 1451 | if (interval_free_list) | 1461 | if (interval_free_list) |
| 1452 | { | 1462 | { |
| @@ -1470,9 +1480,7 @@ make_interval () | |||
| 1470 | val = &interval_block->intervals[interval_block_index++]; | 1480 | val = &interval_block->intervals[interval_block_index++]; |
| 1471 | } | 1481 | } |
| 1472 | 1482 | ||
| 1473 | #ifndef SYNC_INPUT | 1483 | MALLOC_UNBLOCK_INPUT; |
| 1474 | UNBLOCK_INPUT; | ||
| 1475 | #endif | ||
| 1476 | 1484 | ||
| 1477 | consing_since_gc += sizeof (struct interval); | 1485 | consing_since_gc += sizeof (struct interval); |
| 1478 | intervals_consed++; | 1486 | intervals_consed++; |
| @@ -1875,9 +1883,7 @@ allocate_string () | |||
| 1875 | 1883 | ||
| 1876 | /* eassert (!handling_signal); */ | 1884 | /* eassert (!handling_signal); */ |
| 1877 | 1885 | ||
| 1878 | #ifndef SYNC_INPUT | 1886 | MALLOC_BLOCK_INPUT; |
| 1879 | BLOCK_INPUT; | ||
| 1880 | #endif | ||
| 1881 | 1887 | ||
| 1882 | /* If the free-list is empty, allocate a new string_block, and | 1888 | /* If the free-list is empty, allocate a new string_block, and |
| 1883 | add all the Lisp_Strings in it to the free-list. */ | 1889 | add all the Lisp_Strings in it to the free-list. */ |
| @@ -1908,9 +1914,7 @@ allocate_string () | |||
| 1908 | s = string_free_list; | 1914 | s = string_free_list; |
| 1909 | string_free_list = NEXT_FREE_LISP_STRING (s); | 1915 | string_free_list = NEXT_FREE_LISP_STRING (s); |
| 1910 | 1916 | ||
| 1911 | #ifndef SYNC_INPUT | 1917 | MALLOC_UNBLOCK_INPUT; |
| 1912 | UNBLOCK_INPUT; | ||
| 1913 | #endif | ||
| 1914 | 1918 | ||
| 1915 | /* Probably not strictly necessary, but play it safe. */ | 1919 | /* Probably not strictly necessary, but play it safe. */ |
| 1916 | bzero (s, sizeof *s); | 1920 | bzero (s, sizeof *s); |
| @@ -1962,9 +1966,7 @@ allocate_string_data (s, nchars, nbytes) | |||
| 1962 | old_data = s->data ? SDATA_OF_STRING (s) : NULL; | 1966 | old_data = s->data ? SDATA_OF_STRING (s) : NULL; |
| 1963 | old_nbytes = GC_STRING_BYTES (s); | 1967 | old_nbytes = GC_STRING_BYTES (s); |
| 1964 | 1968 | ||
| 1965 | #ifndef SYNC_INPUT | 1969 | MALLOC_BLOCK_INPUT; |
| 1966 | BLOCK_INPUT; | ||
| 1967 | #endif | ||
| 1968 | 1970 | ||
| 1969 | if (nbytes > LARGE_STRING_BYTES) | 1971 | if (nbytes > LARGE_STRING_BYTES) |
| 1970 | { | 1972 | { |
| @@ -1980,18 +1982,14 @@ allocate_string_data (s, nchars, nbytes) | |||
| 1980 | mmap'ed data typically have an address towards the top of the | 1982 | mmap'ed data typically have an address towards the top of the |
| 1981 | address space, which won't fit into an EMACS_INT (at least on | 1983 | address space, which won't fit into an EMACS_INT (at least on |
| 1982 | 32-bit systems with the current tagging scheme). --fx */ | 1984 | 32-bit systems with the current tagging scheme). --fx */ |
| 1983 | BLOCK_INPUT; | ||
| 1984 | mallopt (M_MMAP_MAX, 0); | 1985 | mallopt (M_MMAP_MAX, 0); |
| 1985 | UNBLOCK_INPUT; | ||
| 1986 | #endif | 1986 | #endif |
| 1987 | 1987 | ||
| 1988 | b = (struct sblock *) lisp_malloc (size + GC_STRING_EXTRA, MEM_TYPE_NON_LISP); | 1988 | b = (struct sblock *) lisp_malloc (size + GC_STRING_EXTRA, MEM_TYPE_NON_LISP); |
| 1989 | 1989 | ||
| 1990 | #ifdef DOUG_LEA_MALLOC | 1990 | #ifdef DOUG_LEA_MALLOC |
| 1991 | /* Back to a reasonable maximum of mmap'ed areas. */ | 1991 | /* Back to a reasonable maximum of mmap'ed areas. */ |
| 1992 | BLOCK_INPUT; | ||
| 1993 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); | 1992 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); |
| 1994 | UNBLOCK_INPUT; | ||
| 1995 | #endif | 1993 | #endif |
| 1996 | 1994 | ||
| 1997 | b->next_free = &b->first_data; | 1995 | b->next_free = &b->first_data; |
| @@ -2022,9 +2020,7 @@ allocate_string_data (s, nchars, nbytes) | |||
| 2022 | data = b->next_free; | 2020 | data = b->next_free; |
| 2023 | b->next_free = (struct sdata *) ((char *) data + needed + GC_STRING_EXTRA); | 2021 | b->next_free = (struct sdata *) ((char *) data + needed + GC_STRING_EXTRA); |
| 2024 | 2022 | ||
| 2025 | #ifndef SYNC_INPUT | 2023 | MALLOC_UNBLOCK_INPUT; |
| 2026 | UNBLOCK_INPUT; | ||
| 2027 | #endif | ||
| 2028 | 2024 | ||
| 2029 | data->string = s; | 2025 | data->string = s; |
| 2030 | s->data = SDATA_DATA (data); | 2026 | s->data = SDATA_DATA (data); |
| @@ -2342,11 +2338,13 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */) | |||
| 2342 | /* We must allocate one more elements than LENGTH_IN_ELTS for the | 2338 | /* We must allocate one more elements than LENGTH_IN_ELTS for the |
| 2343 | slot `size' of the struct Lisp_Bool_Vector. */ | 2339 | slot `size' of the struct Lisp_Bool_Vector. */ |
| 2344 | val = Fmake_vector (make_number (length_in_elts + 1), Qnil); | 2340 | val = Fmake_vector (make_number (length_in_elts + 1), Qnil); |
| 2345 | p = XBOOL_VECTOR (val); | ||
| 2346 | 2341 | ||
| 2347 | /* Get rid of any bits that would cause confusion. */ | 2342 | /* Get rid of any bits that would cause confusion. */ |
| 2348 | p->vector_size = 0; | 2343 | XVECTOR (val)->size = 0; /* No Lisp_Object to trace in there. */ |
| 2349 | XSETBOOL_VECTOR (val, p); | 2344 | /* Use XVECTOR (val) rather than `p' because p->size is not TRT. */ |
| 2345 | XSETPVECTYPE (XVECTOR (val), PVEC_BOOL_VECTOR); | ||
| 2346 | |||
| 2347 | p = XBOOL_VECTOR (val); | ||
| 2350 | p->size = XFASTINT (length); | 2348 | p->size = XFASTINT (length); |
| 2351 | 2349 | ||
| 2352 | real_init = (NILP (init) ? 0 : -1); | 2350 | real_init = (NILP (init) ? 0 : -1); |
| @@ -2355,7 +2353,7 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */) | |||
| 2355 | 2353 | ||
| 2356 | /* Clear the extraneous bits in the last byte. */ | 2354 | /* Clear the extraneous bits in the last byte. */ |
| 2357 | if (XINT (length) != length_in_chars * BOOL_VECTOR_BITS_PER_CHAR) | 2355 | if (XINT (length) != length_in_chars * BOOL_VECTOR_BITS_PER_CHAR) |
| 2358 | XBOOL_VECTOR (val)->data[length_in_chars - 1] | 2356 | p->data[length_in_chars - 1] |
| 2359 | &= (1 << (XINT (length) % BOOL_VECTOR_BITS_PER_CHAR)) - 1; | 2357 | &= (1 << (XINT (length) % BOOL_VECTOR_BITS_PER_CHAR)) - 1; |
| 2360 | 2358 | ||
| 2361 | return val; | 2359 | return val; |
| @@ -2613,9 +2611,7 @@ make_float (float_value) | |||
| 2613 | 2611 | ||
| 2614 | /* eassert (!handling_signal); */ | 2612 | /* eassert (!handling_signal); */ |
| 2615 | 2613 | ||
| 2616 | #ifndef SYNC_INPUT | 2614 | MALLOC_BLOCK_INPUT; |
| 2617 | BLOCK_INPUT; | ||
| 2618 | #endif | ||
| 2619 | 2615 | ||
| 2620 | if (float_free_list) | 2616 | if (float_free_list) |
| 2621 | { | 2617 | { |
| @@ -2642,9 +2638,7 @@ make_float (float_value) | |||
| 2642 | float_block_index++; | 2638 | float_block_index++; |
| 2643 | } | 2639 | } |
| 2644 | 2640 | ||
| 2645 | #ifndef SYNC_INPUT | 2641 | MALLOC_UNBLOCK_INPUT; |
| 2646 | UNBLOCK_INPUT; | ||
| 2647 | #endif | ||
| 2648 | 2642 | ||
| 2649 | XFLOAT_DATA (val) = float_value; | 2643 | XFLOAT_DATA (val) = float_value; |
| 2650 | eassert (!FLOAT_MARKED_P (XFLOAT (val))); | 2644 | eassert (!FLOAT_MARKED_P (XFLOAT (val))); |
| @@ -2742,9 +2736,7 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0, | |||
| 2742 | 2736 | ||
| 2743 | /* eassert (!handling_signal); */ | 2737 | /* eassert (!handling_signal); */ |
| 2744 | 2738 | ||
| 2745 | #ifndef SYNC_INPUT | 2739 | MALLOC_BLOCK_INPUT; |
| 2746 | BLOCK_INPUT; | ||
| 2747 | #endif | ||
| 2748 | 2740 | ||
| 2749 | if (cons_free_list) | 2741 | if (cons_free_list) |
| 2750 | { | 2742 | { |
| @@ -2770,9 +2762,7 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0, | |||
| 2770 | cons_block_index++; | 2762 | cons_block_index++; |
| 2771 | } | 2763 | } |
| 2772 | 2764 | ||
| 2773 | #ifndef SYNC_INPUT | 2765 | MALLOC_UNBLOCK_INPUT; |
| 2774 | UNBLOCK_INPUT; | ||
| 2775 | #endif | ||
| 2776 | 2766 | ||
| 2777 | XSETCAR (val, car); | 2767 | XSETCAR (val, car); |
| 2778 | XSETCDR (val, cdr); | 2768 | XSETCDR (val, cdr); |
| @@ -2922,48 +2912,39 @@ int n_vectors; | |||
| 2922 | with room for LEN Lisp_Objects. */ | 2912 | with room for LEN Lisp_Objects. */ |
| 2923 | 2913 | ||
| 2924 | static struct Lisp_Vector * | 2914 | static struct Lisp_Vector * |
| 2925 | allocate_vectorlike (len, type) | 2915 | allocate_vectorlike (len) |
| 2926 | EMACS_INT len; | 2916 | EMACS_INT len; |
| 2927 | enum mem_type type; | ||
| 2928 | { | 2917 | { |
| 2929 | struct Lisp_Vector *p; | 2918 | struct Lisp_Vector *p; |
| 2930 | size_t nbytes; | 2919 | size_t nbytes; |
| 2931 | 2920 | ||
| 2921 | MALLOC_BLOCK_INPUT; | ||
| 2922 | |||
| 2932 | #ifdef DOUG_LEA_MALLOC | 2923 | #ifdef DOUG_LEA_MALLOC |
| 2933 | /* Prevent mmap'ing the chunk. Lisp data may not be mmap'ed | 2924 | /* Prevent mmap'ing the chunk. Lisp data may not be mmap'ed |
| 2934 | because mapped region contents are not preserved in | 2925 | because mapped region contents are not preserved in |
| 2935 | a dumped Emacs. */ | 2926 | a dumped Emacs. */ |
| 2936 | BLOCK_INPUT; | ||
| 2937 | mallopt (M_MMAP_MAX, 0); | 2927 | mallopt (M_MMAP_MAX, 0); |
| 2938 | UNBLOCK_INPUT; | ||
| 2939 | #endif | 2928 | #endif |
| 2940 | 2929 | ||
| 2941 | /* This gets triggered by code which I haven't bothered to fix. --Stef */ | 2930 | /* This gets triggered by code which I haven't bothered to fix. --Stef */ |
| 2942 | /* eassert (!handling_signal); */ | 2931 | /* eassert (!handling_signal); */ |
| 2943 | 2932 | ||
| 2944 | nbytes = sizeof *p + (len - 1) * sizeof p->contents[0]; | 2933 | nbytes = sizeof *p + (len - 1) * sizeof p->contents[0]; |
| 2945 | p = (struct Lisp_Vector *) lisp_malloc (nbytes, type); | 2934 | p = (struct Lisp_Vector *) lisp_malloc (nbytes, MEM_TYPE_VECTORLIKE); |
| 2946 | 2935 | ||
| 2947 | #ifdef DOUG_LEA_MALLOC | 2936 | #ifdef DOUG_LEA_MALLOC |
| 2948 | /* Back to a reasonable maximum of mmap'ed areas. */ | 2937 | /* Back to a reasonable maximum of mmap'ed areas. */ |
| 2949 | BLOCK_INPUT; | ||
| 2950 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); | 2938 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); |
| 2951 | UNBLOCK_INPUT; | ||
| 2952 | #endif | 2939 | #endif |
| 2953 | 2940 | ||
| 2954 | consing_since_gc += nbytes; | 2941 | consing_since_gc += nbytes; |
| 2955 | vector_cells_consed += len; | 2942 | vector_cells_consed += len; |
| 2956 | 2943 | ||
| 2957 | #ifndef SYNC_INPUT | ||
| 2958 | BLOCK_INPUT; | ||
| 2959 | #endif | ||
| 2960 | |||
| 2961 | p->next = all_vectors; | 2944 | p->next = all_vectors; |
| 2962 | all_vectors = p; | 2945 | all_vectors = p; |
| 2963 | 2946 | ||
| 2964 | #ifndef SYNC_INPUT | 2947 | MALLOC_UNBLOCK_INPUT; |
| 2965 | UNBLOCK_INPUT; | ||
| 2966 | #endif | ||
| 2967 | 2948 | ||
| 2968 | ++n_vectors; | 2949 | ++n_vectors; |
| 2969 | return p; | 2950 | return p; |
| @@ -2976,7 +2957,7 @@ struct Lisp_Vector * | |||
| 2976 | allocate_vector (nslots) | 2957 | allocate_vector (nslots) |
| 2977 | EMACS_INT nslots; | 2958 | EMACS_INT nslots; |
| 2978 | { | 2959 | { |
| 2979 | struct Lisp_Vector *v = allocate_vectorlike (nslots, MEM_TYPE_VECTOR); | 2960 | struct Lisp_Vector *v = allocate_vectorlike (nslots); |
| 2980 | v->size = nslots; | 2961 | v->size = nslots; |
| 2981 | return v; | 2962 | return v; |
| 2982 | } | 2963 | } |
| @@ -2984,74 +2965,78 @@ allocate_vector (nslots) | |||
| 2984 | 2965 | ||
| 2985 | /* Allocate other vector-like structures. */ | 2966 | /* Allocate other vector-like structures. */ |
| 2986 | 2967 | ||
| 2987 | struct Lisp_Hash_Table * | 2968 | static struct Lisp_Vector * |
| 2988 | allocate_hash_table () | 2969 | allocate_pseudovector (memlen, lisplen, tag) |
| 2970 | int memlen, lisplen; | ||
| 2971 | EMACS_INT tag; | ||
| 2989 | { | 2972 | { |
| 2990 | EMACS_INT len = VECSIZE (struct Lisp_Hash_Table); | 2973 | struct Lisp_Vector *v = allocate_vectorlike (memlen); |
| 2991 | struct Lisp_Vector *v = allocate_vectorlike (len, MEM_TYPE_HASH_TABLE); | ||
| 2992 | EMACS_INT i; | 2974 | EMACS_INT i; |
| 2993 | 2975 | ||
| 2994 | v->size = len; | 2976 | /* Only the first lisplen slots will be traced normally by the GC. */ |
| 2995 | for (i = 0; i < len; ++i) | 2977 | v->size = lisplen; |
| 2978 | for (i = 0; i < lisplen; ++i) | ||
| 2996 | v->contents[i] = Qnil; | 2979 | v->contents[i] = Qnil; |
| 2997 | 2980 | ||
| 2998 | return (struct Lisp_Hash_Table *) v; | 2981 | XSETPVECTYPE (v, tag); /* Add the appropriate tag. */ |
| 2982 | return v; | ||
| 2983 | } | ||
| 2984 | #define ALLOCATE_PSEUDOVECTOR(typ,field,tag) \ | ||
| 2985 | ((typ*) \ | ||
| 2986 | allocate_pseudovector \ | ||
| 2987 | (VECSIZE (typ), PSEUDOVECSIZE (typ, field), tag)) | ||
| 2988 | |||
| 2989 | struct Lisp_Hash_Table * | ||
| 2990 | allocate_hash_table (void) | ||
| 2991 | { | ||
| 2992 | return ALLOCATE_PSEUDOVECTOR (struct Lisp_Hash_Table, count, PVEC_HASH_TABLE); | ||
| 2999 | } | 2993 | } |
| 3000 | 2994 | ||
| 3001 | 2995 | ||
| 3002 | struct window * | 2996 | struct window * |
| 3003 | allocate_window () | 2997 | allocate_window () |
| 3004 | { | 2998 | { |
| 3005 | EMACS_INT len = VECSIZE (struct window); | 2999 | return ALLOCATE_PSEUDOVECTOR(struct window, current_matrix, PVEC_WINDOW); |
| 3006 | struct Lisp_Vector *v = allocate_vectorlike (len, MEM_TYPE_WINDOW); | 3000 | } |
| 3007 | EMACS_INT i; | ||
| 3008 | 3001 | ||
| 3009 | for (i = 0; i < len; ++i) | ||
| 3010 | v->contents[i] = Qnil; | ||
| 3011 | v->size = len; | ||
| 3012 | 3002 | ||
| 3013 | return (struct window *) v; | 3003 | struct terminal * |
| 3014 | } | 3004 | allocate_terminal () |
| 3005 | { | ||
| 3006 | struct terminal *t = ALLOCATE_PSEUDOVECTOR (struct terminal, | ||
| 3007 | next_terminal, PVEC_TERMINAL); | ||
| 3008 | /* Zero out the non-GC'd fields. FIXME: This should be made unnecessary. */ | ||
| 3009 | bzero (&(t->next_terminal), | ||
| 3010 | ((char*)(t+1)) - ((char*)&(t->next_terminal))); | ||
| 3015 | 3011 | ||
| 3012 | return t; | ||
| 3013 | } | ||
| 3016 | 3014 | ||
| 3017 | struct frame * | 3015 | struct frame * |
| 3018 | allocate_frame () | 3016 | allocate_frame () |
| 3019 | { | 3017 | { |
| 3020 | EMACS_INT len = VECSIZE (struct frame); | 3018 | struct frame *f = ALLOCATE_PSEUDOVECTOR (struct frame, |
| 3021 | struct Lisp_Vector *v = allocate_vectorlike (len, MEM_TYPE_FRAME); | 3019 | face_cache, PVEC_FRAME); |
| 3022 | EMACS_INT i; | 3020 | /* Zero out the non-GC'd fields. FIXME: This should be made unnecessary. */ |
| 3023 | 3021 | bzero (&(f->face_cache), | |
| 3024 | for (i = 0; i < len; ++i) | 3022 | ((char*)(f+1)) - ((char*)&(f->face_cache))); |
| 3025 | v->contents[i] = make_number (0); | 3023 | return f; |
| 3026 | v->size = len; | ||
| 3027 | return (struct frame *) v; | ||
| 3028 | } | 3024 | } |
| 3029 | 3025 | ||
| 3030 | 3026 | ||
| 3031 | struct Lisp_Process * | 3027 | struct Lisp_Process * |
| 3032 | allocate_process () | 3028 | allocate_process () |
| 3033 | { | 3029 | { |
| 3034 | /* Memory-footprint of the object in nb of Lisp_Object fields. */ | 3030 | return ALLOCATE_PSEUDOVECTOR (struct Lisp_Process, pid, PVEC_PROCESS); |
| 3035 | EMACS_INT memlen = VECSIZE (struct Lisp_Process); | ||
| 3036 | /* Size if we only count the actual Lisp_Object fields (which need to be | ||
| 3037 | traced by the GC). */ | ||
| 3038 | EMACS_INT lisplen = PSEUDOVECSIZE (struct Lisp_Process, pid); | ||
| 3039 | struct Lisp_Vector *v = allocate_vectorlike (memlen, MEM_TYPE_PROCESS); | ||
| 3040 | EMACS_INT i; | ||
| 3041 | |||
| 3042 | for (i = 0; i < lisplen; ++i) | ||
| 3043 | v->contents[i] = Qnil; | ||
| 3044 | v->size = lisplen; | ||
| 3045 | |||
| 3046 | return (struct Lisp_Process *) v; | ||
| 3047 | } | 3031 | } |
| 3048 | 3032 | ||
| 3049 | 3033 | ||
| 3034 | /* Only used for PVEC_WINDOW_CONFIGURATION. */ | ||
| 3050 | struct Lisp_Vector * | 3035 | struct Lisp_Vector * |
| 3051 | allocate_other_vector (len) | 3036 | allocate_other_vector (len) |
| 3052 | EMACS_INT len; | 3037 | EMACS_INT len; |
| 3053 | { | 3038 | { |
| 3054 | struct Lisp_Vector *v = allocate_vectorlike (len, MEM_TYPE_VECTOR); | 3039 | struct Lisp_Vector *v = allocate_vectorlike (len); |
| 3055 | EMACS_INT i; | 3040 | EMACS_INT i; |
| 3056 | 3041 | ||
| 3057 | for (i = 0; i < len; ++i) | 3042 | for (i = 0; i < len; ++i) |
| @@ -3085,6 +3070,51 @@ See also the function `vector'. */) | |||
| 3085 | } | 3070 | } |
| 3086 | 3071 | ||
| 3087 | 3072 | ||
| 3073 | DEFUN ("make-char-table", Fmake_char_table, Smake_char_table, 1, 2, 0, | ||
| 3074 | doc: /* Return a newly created char-table, with purpose PURPOSE. | ||
| 3075 | Each element is initialized to INIT, which defaults to nil. | ||
| 3076 | PURPOSE should be a symbol which has a `char-table-extra-slots' property. | ||
| 3077 | The property's value should be an integer between 0 and 10. */) | ||
| 3078 | (purpose, init) | ||
| 3079 | register Lisp_Object purpose, init; | ||
| 3080 | { | ||
| 3081 | Lisp_Object vector; | ||
| 3082 | Lisp_Object n; | ||
| 3083 | CHECK_SYMBOL (purpose); | ||
| 3084 | n = Fget (purpose, Qchar_table_extra_slots); | ||
| 3085 | CHECK_NUMBER (n); | ||
| 3086 | if (XINT (n) < 0 || XINT (n) > 10) | ||
| 3087 | args_out_of_range (n, Qnil); | ||
| 3088 | /* Add 2 to the size for the defalt and parent slots. */ | ||
| 3089 | vector = Fmake_vector (make_number (CHAR_TABLE_STANDARD_SLOTS + XINT (n)), | ||
| 3090 | init); | ||
| 3091 | XSETPVECTYPE (XVECTOR (vector), PVEC_CHAR_TABLE); | ||
| 3092 | XCHAR_TABLE (vector)->top = Qt; | ||
| 3093 | XCHAR_TABLE (vector)->parent = Qnil; | ||
| 3094 | XCHAR_TABLE (vector)->purpose = purpose; | ||
| 3095 | XSETCHAR_TABLE (vector, XCHAR_TABLE (vector)); | ||
| 3096 | return vector; | ||
| 3097 | } | ||
| 3098 | |||
| 3099 | |||
| 3100 | /* Return a newly created sub char table with slots initialized by INIT. | ||
| 3101 | Since a sub char table does not appear as a top level Emacs Lisp | ||
| 3102 | object, we don't need a Lisp interface to make it. */ | ||
| 3103 | |||
| 3104 | Lisp_Object | ||
| 3105 | make_sub_char_table (init) | ||
| 3106 | Lisp_Object init; | ||
| 3107 | { | ||
| 3108 | Lisp_Object vector | ||
| 3109 | = Fmake_vector (make_number (SUB_CHAR_TABLE_STANDARD_SLOTS), init); | ||
| 3110 | XSETPVECTYPE (XVECTOR (vector), PVEC_CHAR_TABLE); | ||
| 3111 | XCHAR_TABLE (vector)->top = Qnil; | ||
| 3112 | XCHAR_TABLE (vector)->defalt = Qnil; | ||
| 3113 | XSETCHAR_TABLE (vector, XCHAR_TABLE (vector)); | ||
| 3114 | return vector; | ||
| 3115 | } | ||
| 3116 | |||
| 3117 | |||
| 3088 | DEFUN ("vector", Fvector, Svector, 0, MANY, 0, | 3118 | DEFUN ("vector", Fvector, Svector, 0, MANY, 0, |
| 3089 | doc: /* Return a newly created vector with specified arguments as elements. | 3119 | doc: /* Return a newly created vector with specified arguments as elements. |
| 3090 | Any number of arguments, even zero arguments, are allowed. | 3120 | Any number of arguments, even zero arguments, are allowed. |
| @@ -3142,6 +3172,7 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT | |||
| 3142 | args[index] = Fpurecopy (args[index]); | 3172 | args[index] = Fpurecopy (args[index]); |
| 3143 | p->contents[index] = args[index]; | 3173 | p->contents[index] = args[index]; |
| 3144 | } | 3174 | } |
| 3175 | XSETPVECTYPE (p, PVEC_COMPILED); | ||
| 3145 | XSETCOMPILED (val, p); | 3176 | XSETCOMPILED (val, p); |
| 3146 | return val; | 3177 | return val; |
| 3147 | } | 3178 | } |
| @@ -3206,9 +3237,7 @@ Its value and function definition are void, and its property list is nil. */) | |||
| 3206 | 3237 | ||
| 3207 | /* eassert (!handling_signal); */ | 3238 | /* eassert (!handling_signal); */ |
| 3208 | 3239 | ||
| 3209 | #ifndef SYNC_INPUT | 3240 | MALLOC_BLOCK_INPUT; |
| 3210 | BLOCK_INPUT; | ||
| 3211 | #endif | ||
| 3212 | 3241 | ||
| 3213 | if (symbol_free_list) | 3242 | if (symbol_free_list) |
| 3214 | { | 3243 | { |
| @@ -3231,9 +3260,7 @@ Its value and function definition are void, and its property list is nil. */) | |||
| 3231 | symbol_block_index++; | 3260 | symbol_block_index++; |
| 3232 | } | 3261 | } |
| 3233 | 3262 | ||
| 3234 | #ifndef SYNC_INPUT | 3263 | MALLOC_UNBLOCK_INPUT; |
| 3235 | UNBLOCK_INPUT; | ||
| 3236 | #endif | ||
| 3237 | 3264 | ||
| 3238 | p = XSYMBOL (val); | 3265 | p = XSYMBOL (val); |
| 3239 | p->xname = name; | 3266 | p->xname = name; |
| @@ -3296,9 +3323,7 @@ allocate_misc () | |||
| 3296 | 3323 | ||
| 3297 | /* eassert (!handling_signal); */ | 3324 | /* eassert (!handling_signal); */ |
| 3298 | 3325 | ||
| 3299 | #ifndef SYNC_INPUT | 3326 | MALLOC_BLOCK_INPUT; |
| 3300 | BLOCK_INPUT; | ||
| 3301 | #endif | ||
| 3302 | 3327 | ||
| 3303 | if (marker_free_list) | 3328 | if (marker_free_list) |
| 3304 | { | 3329 | { |
| @@ -3322,9 +3347,7 @@ allocate_misc () | |||
| 3322 | marker_block_index++; | 3347 | marker_block_index++; |
| 3323 | } | 3348 | } |
| 3324 | 3349 | ||
| 3325 | #ifndef SYNC_INPUT | 3350 | MALLOC_UNBLOCK_INPUT; |
| 3326 | UNBLOCK_INPUT; | ||
| 3327 | #endif | ||
| 3328 | 3351 | ||
| 3329 | --total_free_markers; | 3352 | --total_free_markers; |
| 3330 | consing_since_gc += sizeof (union Lisp_Misc); | 3353 | consing_since_gc += sizeof (union Lisp_Misc); |
| @@ -4070,9 +4093,7 @@ live_vector_p (m, p) | |||
| 4070 | struct mem_node *m; | 4093 | struct mem_node *m; |
| 4071 | void *p; | 4094 | void *p; |
| 4072 | { | 4095 | { |
| 4073 | return (p == m->start | 4096 | return (p == m->start && m->type == MEM_TYPE_VECTORLIKE); |
| 4074 | && m->type >= MEM_TYPE_VECTOR | ||
| 4075 | && m->type <= MEM_TYPE_WINDOW); | ||
| 4076 | } | 4097 | } |
| 4077 | 4098 | ||
| 4078 | 4099 | ||
| @@ -4270,11 +4291,7 @@ mark_maybe_pointer (p) | |||
| 4270 | XSETFLOAT (obj, p); | 4291 | XSETFLOAT (obj, p); |
| 4271 | break; | 4292 | break; |
| 4272 | 4293 | ||
| 4273 | case MEM_TYPE_VECTOR: | 4294 | case MEM_TYPE_VECTORLIKE: |
| 4274 | case MEM_TYPE_PROCESS: | ||
| 4275 | case MEM_TYPE_HASH_TABLE: | ||
| 4276 | case MEM_TYPE_FRAME: | ||
| 4277 | case MEM_TYPE_WINDOW: | ||
| 4278 | if (live_vector_p (m, p)) | 4295 | if (live_vector_p (m, p)) |
| 4279 | { | 4296 | { |
| 4280 | Lisp_Object tem; | 4297 | Lisp_Object tem; |
| @@ -4674,11 +4691,7 @@ valid_lisp_object_p (obj) | |||
| 4674 | case MEM_TYPE_FLOAT: | 4691 | case MEM_TYPE_FLOAT: |
| 4675 | return live_float_p (m, p); | 4692 | return live_float_p (m, p); |
| 4676 | 4693 | ||
| 4677 | case MEM_TYPE_VECTOR: | 4694 | case MEM_TYPE_VECTORLIKE: |
| 4678 | case MEM_TYPE_PROCESS: | ||
| 4679 | case MEM_TYPE_HASH_TABLE: | ||
| 4680 | case MEM_TYPE_FRAME: | ||
| 4681 | case MEM_TYPE_WINDOW: | ||
| 4682 | return live_vector_p (m, p); | 4695 | return live_vector_p (m, p); |
| 4683 | 4696 | ||
| 4684 | default: | 4697 | default: |
| @@ -5128,7 +5141,9 @@ returns nil, because real GC can't be done. */) | |||
| 5128 | mark_object (bind->symbol); | 5141 | mark_object (bind->symbol); |
| 5129 | mark_object (bind->old_value); | 5142 | mark_object (bind->old_value); |
| 5130 | } | 5143 | } |
| 5144 | mark_terminals (); | ||
| 5131 | mark_kboards (); | 5145 | mark_kboards (); |
| 5146 | mark_ttys (); | ||
| 5132 | 5147 | ||
| 5133 | #ifdef USE_GTK | 5148 | #ifdef USE_GTK |
| 5134 | { | 5149 | { |
| @@ -5415,6 +5430,29 @@ int last_marked_index; | |||
| 5415 | Normally this is zero and the check never goes off. */ | 5430 | Normally this is zero and the check never goes off. */ |
| 5416 | int mark_object_loop_halt; | 5431 | int mark_object_loop_halt; |
| 5417 | 5432 | ||
| 5433 | /* Return non-zero if the object was not yet marked. */ | ||
| 5434 | static int | ||
| 5435 | mark_vectorlike (ptr) | ||
| 5436 | struct Lisp_Vector *ptr; | ||
| 5437 | { | ||
| 5438 | register EMACS_INT size = ptr->size; | ||
| 5439 | register int i; | ||
| 5440 | |||
| 5441 | if (VECTOR_MARKED_P (ptr)) | ||
| 5442 | return 0; /* Already marked */ | ||
| 5443 | VECTOR_MARK (ptr); /* Else mark it */ | ||
| 5444 | if (size & PSEUDOVECTOR_FLAG) | ||
| 5445 | size &= PSEUDOVECTOR_SIZE_MASK; | ||
| 5446 | |||
| 5447 | /* Note that this size is not the memory-footprint size, but only | ||
| 5448 | the number of Lisp_Object fields that we should trace. | ||
| 5449 | The distinction is used e.g. by Lisp_Process which places extra | ||
| 5450 | non-Lisp_Object fields at the end of the structure. */ | ||
| 5451 | for (i = 0; i < size; i++) /* and then mark its elements */ | ||
| 5452 | mark_object (ptr->contents[i]); | ||
| 5453 | return 1; | ||
| 5454 | } | ||
| 5455 | |||
| 5418 | void | 5456 | void |
| 5419 | mark_object (arg) | 5457 | mark_object (arg) |
| 5420 | Lisp_Object arg; | 5458 | Lisp_Object arg; |
| @@ -5544,129 +5582,46 @@ mark_object (arg) | |||
| 5544 | else if (FRAMEP (obj)) | 5582 | else if (FRAMEP (obj)) |
| 5545 | { | 5583 | { |
| 5546 | register struct frame *ptr = XFRAME (obj); | 5584 | register struct frame *ptr = XFRAME (obj); |
| 5547 | 5585 | if (mark_vectorlike (XVECTOR (obj))) | |
| 5548 | if (VECTOR_MARKED_P (ptr)) break; /* Already marked */ | 5586 | { |
| 5549 | VECTOR_MARK (ptr); /* Else mark it */ | 5587 | mark_face_cache (ptr->face_cache); |
| 5550 | |||
| 5551 | CHECK_LIVE (live_vector_p); | ||
| 5552 | mark_object (ptr->name); | ||
| 5553 | mark_object (ptr->icon_name); | ||
| 5554 | mark_object (ptr->title); | ||
| 5555 | mark_object (ptr->focus_frame); | ||
| 5556 | mark_object (ptr->selected_window); | ||
| 5557 | mark_object (ptr->minibuffer_window); | ||
| 5558 | mark_object (ptr->param_alist); | ||
| 5559 | mark_object (ptr->scroll_bars); | ||
| 5560 | mark_object (ptr->condemned_scroll_bars); | ||
| 5561 | mark_object (ptr->menu_bar_items); | ||
| 5562 | mark_object (ptr->face_alist); | ||
| 5563 | mark_object (ptr->menu_bar_vector); | ||
| 5564 | mark_object (ptr->buffer_predicate); | ||
| 5565 | mark_object (ptr->buffer_list); | ||
| 5566 | mark_object (ptr->menu_bar_window); | ||
| 5567 | mark_object (ptr->tool_bar_window); | ||
| 5568 | mark_face_cache (ptr->face_cache); | ||
| 5569 | #ifdef HAVE_WINDOW_SYSTEM | 5588 | #ifdef HAVE_WINDOW_SYSTEM |
| 5570 | mark_image_cache (ptr); | 5589 | mark_image_cache (ptr); |
| 5571 | mark_object (ptr->tool_bar_items); | ||
| 5572 | mark_object (ptr->desired_tool_bar_string); | ||
| 5573 | mark_object (ptr->current_tool_bar_string); | ||
| 5574 | #endif /* HAVE_WINDOW_SYSTEM */ | 5590 | #endif /* HAVE_WINDOW_SYSTEM */ |
| 5575 | } | 5591 | } |
| 5576 | else if (BOOL_VECTOR_P (obj)) | ||
| 5577 | { | ||
| 5578 | register struct Lisp_Vector *ptr = XVECTOR (obj); | ||
| 5579 | |||
| 5580 | if (VECTOR_MARKED_P (ptr)) | ||
| 5581 | break; /* Already marked */ | ||
| 5582 | CHECK_LIVE (live_vector_p); | ||
| 5583 | VECTOR_MARK (ptr); /* Else mark it */ | ||
| 5584 | } | 5592 | } |
| 5585 | else if (WINDOWP (obj)) | 5593 | else if (WINDOWP (obj)) |
| 5586 | { | 5594 | { |
| 5587 | register struct Lisp_Vector *ptr = XVECTOR (obj); | 5595 | register struct Lisp_Vector *ptr = XVECTOR (obj); |
| 5588 | struct window *w = XWINDOW (obj); | 5596 | struct window *w = XWINDOW (obj); |
| 5589 | register int i; | 5597 | if (mark_vectorlike (ptr)) |
| 5590 | |||
| 5591 | /* Stop if already marked. */ | ||
| 5592 | if (VECTOR_MARKED_P (ptr)) | ||
| 5593 | break; | ||
| 5594 | |||
| 5595 | /* Mark it. */ | ||
| 5596 | CHECK_LIVE (live_vector_p); | ||
| 5597 | VECTOR_MARK (ptr); | ||
| 5598 | |||
| 5599 | /* There is no Lisp data above The member CURRENT_MATRIX in | ||
| 5600 | struct WINDOW. Stop marking when that slot is reached. */ | ||
| 5601 | for (i = 0; | ||
| 5602 | (char *) &ptr->contents[i] < (char *) &w->current_matrix; | ||
| 5603 | i++) | ||
| 5604 | mark_object (ptr->contents[i]); | ||
| 5605 | |||
| 5606 | /* Mark glyphs for leaf windows. Marking window matrices is | ||
| 5607 | sufficient because frame matrices use the same glyph | ||
| 5608 | memory. */ | ||
| 5609 | if (NILP (w->hchild) | ||
| 5610 | && NILP (w->vchild) | ||
| 5611 | && w->current_matrix) | ||
| 5612 | { | 5598 | { |
| 5613 | mark_glyph_matrix (w->current_matrix); | 5599 | /* Mark glyphs for leaf windows. Marking window matrices is |
| 5614 | mark_glyph_matrix (w->desired_matrix); | 5600 | sufficient because frame matrices use the same glyph |
| 5601 | memory. */ | ||
| 5602 | if (NILP (w->hchild) | ||
| 5603 | && NILP (w->vchild) | ||
| 5604 | && w->current_matrix) | ||
| 5605 | { | ||
| 5606 | mark_glyph_matrix (w->current_matrix); | ||
| 5607 | mark_glyph_matrix (w->desired_matrix); | ||
| 5608 | } | ||
| 5615 | } | 5609 | } |
| 5616 | } | 5610 | } |
| 5617 | else if (HASH_TABLE_P (obj)) | 5611 | else if (HASH_TABLE_P (obj)) |
| 5618 | { | 5612 | { |
| 5619 | struct Lisp_Hash_Table *h = XHASH_TABLE (obj); | 5613 | struct Lisp_Hash_Table *h = XHASH_TABLE (obj); |
| 5620 | 5614 | if (mark_vectorlike ((struct Lisp_Vector *)h)) | |
| 5621 | /* Stop if already marked. */ | 5615 | { /* If hash table is not weak, mark all keys and values. |
| 5622 | if (VECTOR_MARKED_P (h)) | 5616 | For weak tables, mark only the vector. */ |
| 5623 | break; | 5617 | if (NILP (h->weak)) |
| 5624 | 5618 | mark_object (h->key_and_value); | |
| 5625 | /* Mark it. */ | 5619 | else |
| 5626 | CHECK_LIVE (live_vector_p); | 5620 | VECTOR_MARK (XVECTOR (h->key_and_value)); |
| 5627 | VECTOR_MARK (h); | 5621 | } |
| 5628 | |||
| 5629 | /* Mark contents. */ | ||
| 5630 | /* Do not mark next_free or next_weak. | ||
| 5631 | Being in the next_weak chain | ||
| 5632 | should not keep the hash table alive. | ||
| 5633 | No need to mark `count' since it is an integer. */ | ||
| 5634 | mark_object (h->test); | ||
| 5635 | mark_object (h->weak); | ||
| 5636 | mark_object (h->rehash_size); | ||
| 5637 | mark_object (h->rehash_threshold); | ||
| 5638 | mark_object (h->hash); | ||
| 5639 | mark_object (h->next); | ||
| 5640 | mark_object (h->index); | ||
| 5641 | mark_object (h->user_hash_function); | ||
| 5642 | mark_object (h->user_cmp_function); | ||
| 5643 | |||
| 5644 | /* If hash table is not weak, mark all keys and values. | ||
| 5645 | For weak tables, mark only the vector. */ | ||
| 5646 | if (NILP (h->weak)) | ||
| 5647 | mark_object (h->key_and_value); | ||
| 5648 | else | ||
| 5649 | VECTOR_MARK (XVECTOR (h->key_and_value)); | ||
| 5650 | } | 5622 | } |
| 5651 | else | 5623 | else |
| 5652 | { | 5624 | mark_vectorlike (XVECTOR (obj)); |
| 5653 | register struct Lisp_Vector *ptr = XVECTOR (obj); | ||
| 5654 | register EMACS_INT size = ptr->size; | ||
| 5655 | register int i; | ||
| 5656 | |||
| 5657 | if (VECTOR_MARKED_P (ptr)) break; /* Already marked */ | ||
| 5658 | CHECK_LIVE (live_vector_p); | ||
| 5659 | VECTOR_MARK (ptr); /* Else mark it */ | ||
| 5660 | if (size & PSEUDOVECTOR_FLAG) | ||
| 5661 | size &= PSEUDOVECTOR_SIZE_MASK; | ||
| 5662 | |||
| 5663 | /* Note that this size is not the memory-footprint size, but only | ||
| 5664 | the number of Lisp_Object fields that we should trace. | ||
| 5665 | The distinction is used e.g. by Lisp_Process which places extra | ||
| 5666 | non-Lisp_Object fields at the end of the structure. */ | ||
| 5667 | for (i = 0; i < size; i++) /* and then mark its elements */ | ||
| 5668 | mark_object (ptr->contents[i]); | ||
| 5669 | } | ||
| 5670 | break; | 5625 | break; |
| 5671 | 5626 | ||
| 5672 | case Lisp_Symbol: | 5627 | case Lisp_Symbol: |
| @@ -5857,6 +5812,21 @@ mark_buffer (buf) | |||
| 5857 | } | 5812 | } |
| 5858 | } | 5813 | } |
| 5859 | 5814 | ||
| 5815 | /* Mark the Lisp pointers in the terminal objects. | ||
| 5816 | Called by the Fgarbage_collector. */ | ||
| 5817 | |||
| 5818 | static void | ||
| 5819 | mark_terminals (void) | ||
| 5820 | { | ||
| 5821 | struct terminal *t; | ||
| 5822 | for (t = terminal_list; t; t = t->next_terminal) | ||
| 5823 | { | ||
| 5824 | eassert (t->name != NULL); | ||
| 5825 | mark_vectorlike ((struct Lisp_Vector *)t); | ||
| 5826 | } | ||
| 5827 | } | ||
| 5828 | |||
| 5829 | |||
| 5860 | 5830 | ||
| 5861 | /* Value is non-zero if OBJ will survive the current GC because it's | 5831 | /* Value is non-zero if OBJ will survive the current GC because it's |
| 5862 | either marked or does not need to be marked to survive. */ | 5832 | either marked or does not need to be marked to survive. */ |
| @@ -5932,23 +5902,51 @@ gc_sweep () | |||
| 5932 | 5902 | ||
| 5933 | for (cblk = cons_block; cblk; cblk = *cprev) | 5903 | for (cblk = cons_block; cblk; cblk = *cprev) |
| 5934 | { | 5904 | { |
| 5935 | register int i; | 5905 | register int i = 0; |
| 5936 | int this_free = 0; | 5906 | int this_free = 0; |
| 5937 | for (i = 0; i < lim; i++) | 5907 | int ilim = (lim + BITS_PER_INT - 1) / BITS_PER_INT; |
| 5938 | if (!CONS_MARKED_P (&cblk->conses[i])) | 5908 | |
| 5939 | { | 5909 | /* Scan the mark bits an int at a time. */ |
| 5940 | this_free++; | 5910 | for (i = 0; i <= ilim; i++) |
| 5941 | cblk->conses[i].u.chain = cons_free_list; | 5911 | { |
| 5942 | cons_free_list = &cblk->conses[i]; | 5912 | if (cblk->gcmarkbits[i] == -1) |
| 5913 | { | ||
| 5914 | /* Fast path - all cons cells for this int are marked. */ | ||
| 5915 | cblk->gcmarkbits[i] = 0; | ||
| 5916 | num_used += BITS_PER_INT; | ||
| 5917 | } | ||
| 5918 | else | ||
| 5919 | { | ||
| 5920 | /* Some cons cells for this int are not marked. | ||
| 5921 | Find which ones, and free them. */ | ||
| 5922 | int start, pos, stop; | ||
| 5923 | |||
| 5924 | start = i * BITS_PER_INT; | ||
| 5925 | stop = lim - start; | ||
| 5926 | if (stop > BITS_PER_INT) | ||
| 5927 | stop = BITS_PER_INT; | ||
| 5928 | stop += start; | ||
| 5929 | |||
| 5930 | for (pos = start; pos < stop; pos++) | ||
| 5931 | { | ||
| 5932 | if (!CONS_MARKED_P (&cblk->conses[pos])) | ||
| 5933 | { | ||
| 5934 | this_free++; | ||
| 5935 | cblk->conses[pos].u.chain = cons_free_list; | ||
| 5936 | cons_free_list = &cblk->conses[pos]; | ||
| 5943 | #if GC_MARK_STACK | 5937 | #if GC_MARK_STACK |
| 5944 | cons_free_list->car = Vdead; | 5938 | cons_free_list->car = Vdead; |
| 5945 | #endif | 5939 | #endif |
| 5946 | } | 5940 | } |
| 5947 | else | 5941 | else |
| 5948 | { | 5942 | { |
| 5949 | num_used++; | 5943 | num_used++; |
| 5950 | CONS_UNMARK (&cblk->conses[i]); | 5944 | CONS_UNMARK (&cblk->conses[pos]); |
| 5951 | } | 5945 | } |
| 5946 | } | ||
| 5947 | } | ||
| 5948 | } | ||
| 5949 | |||
| 5952 | lim = CONS_BLOCK_SIZE; | 5950 | lim = CONS_BLOCK_SIZE; |
| 5953 | /* If this block contains only free conses and we have already | 5951 | /* If this block contains only free conses and we have already |
| 5954 | seen more than two blocks worth of free conses then deallocate | 5952 | seen more than two blocks worth of free conses then deallocate |