Mercurial > emacs
comparison src/alloc.c @ 91041:bdb3fe0ba9fa
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
| author | Miles Bader <miles@gnu.org> |
|---|---|
| date | Thu, 11 Oct 2007 16:22:07 +0000 |
| parents | aaccdab0ee26 0161d8024935 |
| children | 35069180a991 |
comparison
equal
deleted
inserted
replaced
| 91040:14c4a6aac623 | 91041:bdb3fe0ba9fa |
|---|---|
| 53 #include "keyboard.h" | 53 #include "keyboard.h" |
| 54 #include "frame.h" | 54 #include "frame.h" |
| 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 |
| 61 memory. Can do this only if using gmalloc.c. */ | 62 memory. Can do this only if using gmalloc.c. */ |
| 62 | 63 |
| 339 | 340 |
| 340 Lisp_Object Vgc_elapsed; /* accumulated elapsed time in GC */ | 341 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 *)); |
| 348 static void mark_face_cache P_ ((struct face_cache *)); | 351 static void mark_face_cache P_ ((struct face_cache *)); |
| 349 | 352 |
| 371 MEM_TYPE_CONS, | 374 MEM_TYPE_CONS, |
| 372 MEM_TYPE_STRING, | 375 MEM_TYPE_STRING, |
| 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)); |
| 387 static POINTER_TYPE *lisp_malloc P_ ((size_t, enum mem_type)); | 387 static POINTER_TYPE *lisp_malloc P_ ((size_t, enum mem_type)); |
| 388 void refill_memory_reserve (); | 388 void refill_memory_reserve (); |
| 465 | 465 |
| 466 static struct mem_node mem_z; | 466 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 *)); |
| 474 static int live_buffer_p P_ ((struct mem_node *, void *)); | 474 static int live_buffer_p P_ ((struct mem_node *, void *)); |
| 475 static int live_string_p P_ ((struct mem_node *, void *)); | 475 static int live_string_p P_ ((struct mem_node *, void *)); |
| 741 #define malloc overrun_check_malloc | 741 #define malloc overrun_check_malloc |
| 742 #define realloc overrun_check_realloc | 742 #define realloc overrun_check_realloc |
| 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 |
| 749 POINTER_TYPE * | 758 POINTER_TYPE * |
| 750 xmalloc (size) | 759 xmalloc (size) |
| 751 size_t size; | 760 size_t 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 (); |
| 761 return val; | 770 return val; |
| 762 } | 771 } |
| 769 POINTER_TYPE *block; | 778 POINTER_TYPE *block; |
| 770 size_t size; | 779 size_t 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; |
| 785 } | 794 } |
| 786 | 795 |
| 789 | 798 |
| 790 void | 799 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. */ |
| 800 } | 809 } |
| 801 | 810 |
| 842 size_t nbytes; | 851 size_t nbytes; |
| 843 enum mem_type type; | 852 enum mem_type 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; |
| 851 #endif | 860 #endif |
| 852 | 861 |
| 872 #if GC_MARK_STACK && !defined GC_MALLOC_CHECK | 881 #if GC_MARK_STACK && !defined GC_MALLOC_CHECK |
| 873 if (val && type != MEM_TYPE_NON_LISP) | 882 if (val && type != MEM_TYPE_NON_LISP) |
| 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; |
| 881 } | 890 } |
| 882 | 891 |
| 885 | 894 |
| 886 static void | 895 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. */ |
| 899 /* The entry point is lisp_align_malloc which returns blocks of at most */ | 908 /* The entry point is lisp_align_malloc which returns blocks of at most */ |
| 900 /* BLOCK_BYTES and guarantees they are aligned on a BLOCK_ALIGN boundary. */ | 909 /* BLOCK_BYTES and guarantees they are aligned on a BLOCK_ALIGN boundary. */ |
| 991 void *base, *val; | 1000 void *base, *val; |
| 992 struct ablocks *abase; | 1001 struct ablocks *abase; |
| 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; |
| 1000 #endif | 1009 #endif |
| 1001 | 1010 |
| 1023 abase = ALIGN (base, BLOCK_ALIGN); | 1032 abase = ALIGN (base, BLOCK_ALIGN); |
| 1024 #endif | 1033 #endif |
| 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 |
| 1032 aligned = (base == abase); | 1041 aligned = (base == abase); |
| 1033 if (!aligned) | 1042 if (!aligned) |
| 1049 XSETCONS (tem, end); | 1058 XSETCONS (tem, end); |
| 1050 if ((char *) XCONS (tem) != end) | 1059 if ((char *) XCONS (tem) != end) |
| 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 } |
| 1058 #endif | 1067 #endif |
| 1059 | 1068 |
| 1082 #if GC_MARK_STACK && !defined GC_MALLOC_CHECK | 1091 #if GC_MARK_STACK && !defined GC_MALLOC_CHECK |
| 1083 if (val && type != MEM_TYPE_NON_LISP) | 1092 if (val && type != MEM_TYPE_NON_LISP) |
| 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 |
| 1091 eassert (0 == ((EMACS_UINT)val) % BLOCK_ALIGN); | 1100 eassert (0 == ((EMACS_UINT)val) % BLOCK_ALIGN); |
| 1092 return val; | 1101 return val; |
| 1097 POINTER_TYPE *block; | 1106 POINTER_TYPE *block; |
| 1098 { | 1107 { |
| 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 |
| 1106 /* Put on free list. */ | 1115 /* Put on free list. */ |
| 1107 ablock->x.next_free = free_ablock; | 1116 ablock->x.next_free = free_ablock; |
| 1130 #ifdef USE_POSIX_MEMALIGN | 1139 #ifdef USE_POSIX_MEMALIGN |
| 1131 eassert ((unsigned long)ABLOCKS_BASE (abase) % BLOCK_ALIGN == 0); | 1140 eassert ((unsigned long)ABLOCKS_BASE (abase) % BLOCK_ALIGN == 0); |
| 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 |
| 1139 a call to lisp_malloc. */ | 1148 a call to lisp_malloc. */ |
| 1140 | 1149 |
| 1159 might call malloc, so we can't really protect them unless you're | 1168 might call malloc, so we can't really protect them unless you're |
| 1160 using GNU malloc. Fortunately, most of the major operating systems | 1169 using GNU malloc. Fortunately, most of the major operating systems |
| 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 *)); |
| 1167 extern void * (*__realloc_hook) P_ ((void *, size_t, const void *)); | 1178 extern void * (*__realloc_hook) P_ ((void *, size_t, const void *)); |
| 1168 extern void (*__free_hook) P_ ((void *, const void *)); | 1179 extern void (*__free_hook) P_ ((void *, const void *)); |
| 1232 void *value; | 1243 void *value; |
| 1233 | 1244 |
| 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 |
| 1241 | 1253 |
| 1242 value = (void *) malloc (size); | 1254 value = (void *) malloc (size); |
| 1338 calls malloc because it is the first call, and we have an endless loop. */ | 1350 calls malloc because it is the first call, and we have an endless loop. */ |
| 1339 | 1351 |
| 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 |
| 1349 | 1361 |
| 1350 /* Called from main to set up malloc to use our hooks. */ | 1362 /* Called from main to set up malloc to use our hooks. */ |
| 1442 { | 1454 { |
| 1443 INTERVAL val; | 1455 INTERVAL val; |
| 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 { |
| 1453 val = interval_free_list; | 1463 val = interval_free_list; |
| 1454 interval_free_list = INTERVAL_PARENT (interval_free_list); | 1464 interval_free_list = INTERVAL_PARENT (interval_free_list); |
| 1468 n_interval_blocks++; | 1478 n_interval_blocks++; |
| 1469 } | 1479 } |
| 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++; |
| 1479 RESET_INTERVAL (val); | 1487 RESET_INTERVAL (val); |
| 1480 val->gcmarkbit = 0; | 1488 val->gcmarkbit = 0; |
| 1873 { | 1881 { |
| 1874 struct Lisp_String *s; | 1882 struct Lisp_String *s; |
| 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. */ |
| 1884 if (string_free_list == NULL) | 1890 if (string_free_list == NULL) |
| 1885 { | 1891 { |
| 1906 | 1912 |
| 1907 /* Pop a Lisp_String off the free-list. */ | 1913 /* Pop a Lisp_String off the free-list. */ |
| 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); |
| 1917 | 1921 |
| 1918 --total_free_strings; | 1922 --total_free_strings; |
| 1960 of string data. */ | 1964 of string data. */ |
| 1961 needed = SDATA_SIZE (nbytes); | 1965 needed = SDATA_SIZE (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 { |
| 1971 size_t size = sizeof *b - sizeof (struct sdata) + needed; | 1973 size_t size = sizeof *b - sizeof (struct sdata) + needed; |
| 1972 | 1974 |
| 1978 In case you think of allowing it in a dumped Emacs at the | 1980 In case you think of allowing it in a dumped Emacs at the |
| 1979 cost of not being able to re-dump, there's another reason: | 1981 cost of not being able to re-dump, there's another reason: |
| 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; |
| 1998 b->first_data.string = NULL; | 1996 b->first_data.string = NULL; |
| 1999 b->next = large_sblocks; | 1997 b->next = large_sblocks; |
| 2020 b = current_sblock; | 2018 b = current_sblock; |
| 2021 | 2019 |
| 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); |
| 2031 #ifdef GC_CHECK_STRING_BYTES | 2027 #ifdef GC_CHECK_STRING_BYTES |
| 2032 SDATA_NBYTES (data) = nbytes; | 2028 SDATA_NBYTES (data) = nbytes; |
| 2340 / BOOL_VECTOR_BITS_PER_CHAR); | 2336 / BOOL_VECTOR_BITS_PER_CHAR); |
| 2341 | 2337 |
| 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); |
| 2341 | |
| 2342 /* Get rid of any bits that would cause confusion. */ | |
| 2343 XVECTOR (val)->size = 0; /* No Lisp_Object to trace in there. */ | |
| 2344 /* Use XVECTOR (val) rather than `p' because p->size is not TRT. */ | |
| 2345 XSETPVECTYPE (XVECTOR (val), PVEC_BOOL_VECTOR); | |
| 2346 | |
| 2345 p = XBOOL_VECTOR (val); | 2347 p = XBOOL_VECTOR (val); |
| 2346 | |
| 2347 /* Get rid of any bits that would cause confusion. */ | |
| 2348 p->vector_size = 0; | |
| 2349 XSETBOOL_VECTOR (val, p); | |
| 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); |
| 2353 for (i = 0; i < length_in_chars ; i++) | 2351 for (i = 0; i < length_in_chars ; i++) |
| 2354 p->data[i] = real_init; | 2352 p->data[i] = real_init; |
| 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; |
| 2362 } | 2360 } |
| 2363 | 2361 |
| 2611 { | 2609 { |
| 2612 register Lisp_Object val; | 2610 register Lisp_Object val; |
| 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 { |
| 2622 /* We use the data field for chaining the free list | 2618 /* We use the data field for chaining the free list |
| 2623 so that we won't use the same field that has the mark bit. */ | 2619 so that we won't use the same field that has the mark bit. */ |
| 2640 } | 2636 } |
| 2641 XSETFLOAT (val, &float_block->floats[float_block_index]); | 2637 XSETFLOAT (val, &float_block->floats[float_block_index]); |
| 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))); |
| 2651 consing_since_gc += sizeof (struct Lisp_Float); | 2645 consing_since_gc += sizeof (struct Lisp_Float); |
| 2652 floats_consed++; | 2646 floats_consed++; |
| 2740 { | 2734 { |
| 2741 register Lisp_Object val; | 2735 register Lisp_Object val; |
| 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 { |
| 2751 /* We use the cdr for chaining the free list | 2743 /* We use the cdr for chaining the free list |
| 2752 so that we won't use the same field that has the mark bit. */ | 2744 so that we won't use the same field that has the mark bit. */ |
| 2768 } | 2760 } |
| 2769 XSETCONS (val, &cons_block->conses[cons_block_index]); | 2761 XSETCONS (val, &cons_block->conses[cons_block_index]); |
| 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); |
| 2779 eassert (!CONS_MARKED_P (XCONS (val))); | 2769 eassert (!CONS_MARKED_P (XCONS (val))); |
| 2780 consing_since_gc += sizeof (struct Lisp_Cons); | 2770 consing_since_gc += sizeof (struct Lisp_Cons); |
| 2920 | 2910 |
| 2921 /* Value is a pointer to a newly allocated Lisp_Vector structure | 2911 /* Value is a pointer to a newly allocated Lisp_Vector structure |
| 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; |
| 2920 | |
| 2921 MALLOC_BLOCK_INPUT; | |
| 2931 | 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; |
| 2970 } | 2951 } |
| 2971 | 2952 |
| 2974 | 2955 |
| 2975 struct Lisp_Vector * | 2956 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 } |
| 2983 | 2964 |
| 2984 | 2965 |
| 2985 /* Allocate other vector-like structures. */ | 2966 /* Allocate other vector-like structures. */ |
| 2986 | 2967 |
| 2968 static struct Lisp_Vector * | |
| 2969 allocate_pseudovector (memlen, lisplen, tag) | |
| 2970 int memlen, lisplen; | |
| 2971 EMACS_INT tag; | |
| 2972 { | |
| 2973 struct Lisp_Vector *v = allocate_vectorlike (memlen); | |
| 2974 EMACS_INT i; | |
| 2975 | |
| 2976 /* Only the first lisplen slots will be traced normally by the GC. */ | |
| 2977 v->size = lisplen; | |
| 2978 for (i = 0; i < lisplen; ++i) | |
| 2979 v->contents[i] = Qnil; | |
| 2980 | |
| 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 | |
| 2987 struct Lisp_Hash_Table * | 2989 struct Lisp_Hash_Table * |
| 2988 allocate_hash_table () | 2990 allocate_hash_table (void) |
| 2989 { | 2991 { |
| 2990 EMACS_INT len = VECSIZE (struct Lisp_Hash_Table); | 2992 return ALLOCATE_PSEUDOVECTOR (struct Lisp_Hash_Table, count, PVEC_HASH_TABLE); |
| 2991 struct Lisp_Vector *v = allocate_vectorlike (len, MEM_TYPE_HASH_TABLE); | |
| 2992 EMACS_INT i; | |
| 2993 | |
| 2994 v->size = len; | |
| 2995 for (i = 0; i < len; ++i) | |
| 2996 v->contents[i] = Qnil; | |
| 2997 | |
| 2998 return (struct Lisp_Hash_Table *) v; | |
| 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; | 3001 |
| 3008 | 3002 |
| 3009 for (i = 0; i < len; ++i) | 3003 struct terminal * |
| 3010 v->contents[i] = Qnil; | 3004 allocate_terminal () |
| 3011 v->size = len; | 3005 { |
| 3012 | 3006 struct terminal *t = ALLOCATE_PSEUDOVECTOR (struct terminal, |
| 3013 return (struct window *) v; | 3007 next_terminal, PVEC_TERMINAL); |
| 3014 } | 3008 /* Zero out the non-GC'd fields. FIXME: This should be made unnecessary. */ |
| 3015 | 3009 bzero (&(t->next_terminal), |
| 3010 ((char*)(t+1)) - ((char*)&(t->next_terminal))); | |
| 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); | 3031 } |
| 3036 /* Size if we only count the actual Lisp_Object fields (which need to be | 3032 |
| 3037 traced by the GC). */ | 3033 |
| 3038 EMACS_INT lisplen = PSEUDOVECSIZE (struct Lisp_Process, pid); | 3034 /* Only used for PVEC_WINDOW_CONFIGURATION. */ |
| 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 } | |
| 3048 | |
| 3049 | |
| 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) |
| 3058 v->contents[i] = Qnil; | 3043 v->contents[i] = Qnil; |
| 3059 v->size = len; | 3044 v->size = len; |
| 3079 p = allocate_vector (sizei); | 3064 p = allocate_vector (sizei); |
| 3080 for (index = 0; index < sizei; index++) | 3065 for (index = 0; index < sizei; index++) |
| 3081 p->contents[index] = init; | 3066 p->contents[index] = init; |
| 3082 | 3067 |
| 3083 XSETVECTOR (vector, p); | 3068 XSETVECTOR (vector, p); |
| 3069 return vector; | |
| 3070 } | |
| 3071 | |
| 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)); | |
| 3084 return vector; | 3114 return vector; |
| 3085 } | 3115 } |
| 3086 | 3116 |
| 3087 | 3117 |
| 3088 DEFUN ("vector", Fvector, Svector, 0, MANY, 0, | 3118 DEFUN ("vector", Fvector, Svector, 0, MANY, 0, |
| 3140 { | 3170 { |
| 3141 if (!NILP (Vpurify_flag)) | 3171 if (!NILP (Vpurify_flag)) |
| 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 } |
| 3148 | 3179 |
| 3149 | 3180 |
| 3204 | 3235 |
| 3205 CHECK_STRING (name); | 3236 CHECK_STRING (name); |
| 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 { |
| 3215 XSETSYMBOL (val, symbol_free_list); | 3244 XSETSYMBOL (val, symbol_free_list); |
| 3216 symbol_free_list = symbol_free_list->next; | 3245 symbol_free_list = symbol_free_list->next; |
| 3229 } | 3258 } |
| 3230 XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index]); | 3259 XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index]); |
| 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; |
| 3240 p->plist = Qnil; | 3267 p->plist = Qnil; |
| 3241 p->value = Qunbound; | 3268 p->value = Qunbound; |
| 3294 { | 3321 { |
| 3295 Lisp_Object val; | 3322 Lisp_Object val; |
| 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 { |
| 3305 XSETMISC (val, marker_free_list); | 3330 XSETMISC (val, marker_free_list); |
| 3306 marker_free_list = marker_free_list->u_free.chain; | 3331 marker_free_list = marker_free_list->u_free.chain; |
| 3320 } | 3345 } |
| 3321 XSETMISC (val, &marker_block->markers[marker_block_index]); | 3346 XSETMISC (val, &marker_block->markers[marker_block_index]); |
| 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); |
| 3331 misc_objects_consed++; | 3354 misc_objects_consed++; |
| 3332 XMARKER (val)->gcmarkbit = 0; | 3355 XMARKER (val)->gcmarkbit = 0; |
| 4068 static INLINE int | 4091 static INLINE int |
| 4069 live_vector_p (m, p) | 4092 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 |
| 4079 /* Value is non-zero if P is a pointer to a live buffer. M is a | 4100 /* Value is non-zero if P is a pointer to a live buffer. M is a |
| 4080 pointer to the mem_block for P. */ | 4101 pointer to the mem_block for P. */ |
| 4268 case MEM_TYPE_FLOAT: | 4289 case MEM_TYPE_FLOAT: |
| 4269 if (live_float_p (m, p) && !FLOAT_MARKED_P (p)) | 4290 if (live_float_p (m, p) && !FLOAT_MARKED_P (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; |
| 4281 XSETVECTOR (tem, p); | 4298 XSETVECTOR (tem, p); |
| 4282 if (!SUBRP (tem) && !VECTOR_MARKED_P (XVECTOR (tem))) | 4299 if (!SUBRP (tem) && !VECTOR_MARKED_P (XVECTOR (tem))) |
| 4672 return live_symbol_p (m, p); | 4689 return live_symbol_p (m, p); |
| 4673 | 4690 |
| 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: |
| 4685 break; | 4698 break; |
| 4686 } | 4699 } |
| 5126 for (bind = specpdl; bind != specpdl_ptr; bind++) | 5139 for (bind = specpdl; bind != specpdl_ptr; bind++) |
| 5127 { | 5140 { |
| 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 { |
| 5135 extern void xg_mark_data (); | 5150 extern void xg_mark_data (); |
| 5136 xg_mark_data (); | 5151 xg_mark_data (); |
| 5413 links of a list, in mark_object. In debugging, | 5428 links of a list, in mark_object. In debugging, |
| 5414 the call to abort will hit a breakpoint. | 5429 the call to abort will hit a breakpoint. |
| 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; |
| 5421 { | 5459 { |
| 5422 register Lisp_Object obj = arg; | 5460 register Lisp_Object obj = arg; |
| 5542 goto loop; | 5580 goto loop; |
| 5543 } | 5581 } |
| 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: |
| 5673 { | 5628 { |
| 5674 register struct Lisp_Symbol *ptr = XSYMBOL (obj); | 5629 register struct Lisp_Symbol *ptr = XSYMBOL (obj); |
| 5855 XSETBUFFER (base_buffer, buffer->base_buffer); | 5810 XSETBUFFER (base_buffer, buffer->base_buffer); |
| 5856 mark_buffer (base_buffer); | 5811 mark_buffer (base_buffer); |
| 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. */ |
| 5863 | 5833 |
| 5864 int | 5834 int |
| 5930 | 5900 |
| 5931 cons_free_list = 0; | 5901 cons_free_list = 0; |
| 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 |
| 5955 this block. */ | 5953 this block. */ |
| 5956 if (this_free == CONS_BLOCK_SIZE && num_free > CONS_BLOCK_SIZE) | 5954 if (this_free == CONS_BLOCK_SIZE && num_free > CONS_BLOCK_SIZE) |
