aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c448
1 files changed, 48 insertions, 400 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 0bfbb0c88b1..02ba2f5f9e3 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -85,68 +85,8 @@ extern void *sbrk ();
85 85
86#define MMAP_MAX_AREAS 100000000 86#define MMAP_MAX_AREAS 100000000
87 87
88#else /* not DOUG_LEA_MALLOC */
89
90/* The following come from gmalloc.c. */
91
92extern size_t _bytes_used;
93extern size_t __malloc_extra_blocks;
94extern void *_malloc_internal (size_t);
95extern void _free_internal (void *);
96
97#endif /* not DOUG_LEA_MALLOC */ 88#endif /* not DOUG_LEA_MALLOC */
98 89
99#if ! defined SYSTEM_MALLOC && ! defined SYNC_INPUT
100#ifdef HAVE_PTHREAD
101
102# include "syssignal.h"
103
104/* When GTK uses the file chooser dialog, different backends can be loaded
105 dynamically. One such a backend is the Gnome VFS backend that gets loaded
106 if you run Gnome. That backend creates several threads and also allocates
107 memory with malloc.
108
109 Also, gconf and gsettings may create several threads.
110
111 If Emacs sets malloc hooks (! SYSTEM_MALLOC) and the emacs_blocked_*
112 functions below are called from malloc, there is a chance that one
113 of these threads preempts the Emacs main thread and the hook variables
114 end up in an inconsistent state. So we have a mutex to prevent that (note
115 that the backend handles concurrent access to malloc within its own threads
116 but Emacs code running in the main thread is not included in that control).
117
118 When UNBLOCK_INPUT is called, reinvoke_input_signal may be called. If this
119 happens in one of the backend threads we will have two threads that tries
120 to run Emacs code at once, and the code is not prepared for that.
121 To prevent that, we only call BLOCK/UNBLOCK from the main thread. */
122
123static pthread_mutex_t alloc_mutex;
124
125#define BLOCK_INPUT_ALLOC \
126 do \
127 { \
128 if (pthread_equal (pthread_self (), main_thread)) \
129 BLOCK_INPUT; \
130 pthread_mutex_lock (&alloc_mutex); \
131 } \
132 while (0)
133#define UNBLOCK_INPUT_ALLOC \
134 do \
135 { \
136 pthread_mutex_unlock (&alloc_mutex); \
137 if (pthread_equal (pthread_self (), main_thread)) \
138 UNBLOCK_INPUT; \
139 } \
140 while (0)
141
142#else /* ! defined HAVE_PTHREAD */
143
144#define BLOCK_INPUT_ALLOC BLOCK_INPUT
145#define UNBLOCK_INPUT_ALLOC UNBLOCK_INPUT
146
147#endif /* ! defined HAVE_PTHREAD */
148#endif /* ! defined SYSTEM_MALLOC && ! defined SYNC_INPUT */
149
150/* Mark, unmark, query mark bit of a Lisp string. S must be a pointer 90/* Mark, unmark, query mark bit of a Lisp string. S must be a pointer
151 to a struct Lisp_String. */ 91 to a struct Lisp_String. */
152 92
@@ -205,10 +145,6 @@ static char *spare_memory[7];
205 145
206#define SPARE_MEMORY (1 << 14) 146#define SPARE_MEMORY (1 << 14)
207 147
208/* Number of extra blocks malloc should get when it needs more core. */
209
210static int malloc_hysteresis;
211
212/* Initialize it to a nonzero value to force it into data space 148/* Initialize it to a nonzero value to force it into data space
213 (rather than bss space). That way unexec will remap it into text 149 (rather than bss space). That way unexec will remap it into text
214 space (pure), on some systems. We have not implemented the 150 space (pure), on some systems. We have not implemented the
@@ -413,12 +349,12 @@ static void mark_memory (void *, void *);
413static void mem_init (void); 349static void mem_init (void);
414static struct mem_node *mem_insert (void *, void *, enum mem_type); 350static struct mem_node *mem_insert (void *, void *, enum mem_type);
415static void mem_insert_fixup (struct mem_node *); 351static void mem_insert_fixup (struct mem_node *);
416#endif
417static void mem_rotate_left (struct mem_node *); 352static void mem_rotate_left (struct mem_node *);
418static void mem_rotate_right (struct mem_node *); 353static void mem_rotate_right (struct mem_node *);
419static void mem_delete (struct mem_node *); 354static void mem_delete (struct mem_node *);
420static void mem_delete_fixup (struct mem_node *); 355static void mem_delete_fixup (struct mem_node *);
421static inline struct mem_node *mem_find (void *); 356static inline struct mem_node *mem_find (void *);
357#endif
422 358
423 359
424#if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS 360#if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS
@@ -587,39 +523,17 @@ xmalloc_get_size (unsigned char *ptr)
587} 523}
588 524
589 525
590/* The call depth in overrun_check functions. For example, this might happen:
591 xmalloc()
592 overrun_check_malloc()
593 -> malloc -> (via hook)_-> emacs_blocked_malloc
594 -> overrun_check_malloc
595 call malloc (hooks are NULL, so real malloc is called).
596 malloc returns 10000.
597 add overhead, return 10016.
598 <- (back in overrun_check_malloc)
599 add overhead again, return 10032
600 xmalloc returns 10032.
601
602 (time passes).
603
604 xfree(10032)
605 overrun_check_free(10032)
606 decrease overhead
607 free(10016) <- crash, because 10000 is the original pointer. */
608
609static ptrdiff_t check_depth;
610
611/* Like malloc, but wraps allocated block with header and trailer. */ 526/* Like malloc, but wraps allocated block with header and trailer. */
612 527
613static void * 528static void *
614overrun_check_malloc (size_t size) 529overrun_check_malloc (size_t size)
615{ 530{
616 register unsigned char *val; 531 register unsigned char *val;
617 int overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_OVERHEAD : 0; 532 if (SIZE_MAX - XMALLOC_OVERRUN_CHECK_OVERHEAD < size)
618 if (SIZE_MAX - overhead < size)
619 emacs_abort (); 533 emacs_abort ();
620 534
621 val = malloc (size + overhead); 535 val = malloc (size + XMALLOC_OVERRUN_CHECK_OVERHEAD);
622 if (val && check_depth == 1) 536 if (val)
623 { 537 {
624 memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE); 538 memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE);
625 val += XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE; 539 val += XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE;
@@ -627,7 +541,6 @@ overrun_check_malloc (size_t size)
627 memcpy (val + size, xmalloc_overrun_check_trailer, 541 memcpy (val + size, xmalloc_overrun_check_trailer,
628 XMALLOC_OVERRUN_CHECK_SIZE); 542 XMALLOC_OVERRUN_CHECK_SIZE);
629 } 543 }
630 --check_depth;
631 return val; 544 return val;
632} 545}
633 546
@@ -639,12 +552,10 @@ static void *
639overrun_check_realloc (void *block, size_t size) 552overrun_check_realloc (void *block, size_t size)
640{ 553{
641 register unsigned char *val = (unsigned char *) block; 554 register unsigned char *val = (unsigned char *) block;
642 int overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_OVERHEAD : 0; 555 if (SIZE_MAX - XMALLOC_OVERRUN_CHECK_OVERHEAD < size)
643 if (SIZE_MAX - overhead < size)
644 emacs_abort (); 556 emacs_abort ();
645 557
646 if (val 558 if (val
647 && check_depth == 1
648 && memcmp (xmalloc_overrun_check_header, 559 && memcmp (xmalloc_overrun_check_header,
649 val - XMALLOC_OVERRUN_CHECK_SIZE - XMALLOC_OVERRUN_SIZE_SIZE, 560 val - XMALLOC_OVERRUN_CHECK_SIZE - XMALLOC_OVERRUN_SIZE_SIZE,
650 XMALLOC_OVERRUN_CHECK_SIZE) == 0) 561 XMALLOC_OVERRUN_CHECK_SIZE) == 0)
@@ -658,9 +569,9 @@ overrun_check_realloc (void *block, size_t size)
658 memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE); 569 memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE);
659 } 570 }
660 571
661 val = realloc (val, size + overhead); 572 val = realloc (val, size + XMALLOC_OVERRUN_CHECK_OVERHEAD);
662 573
663 if (val && check_depth == 1) 574 if (val)
664 { 575 {
665 memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE); 576 memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE);
666 val += XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE; 577 val += XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE;
@@ -668,7 +579,6 @@ overrun_check_realloc (void *block, size_t size)
668 memcpy (val + size, xmalloc_overrun_check_trailer, 579 memcpy (val + size, xmalloc_overrun_check_trailer,
669 XMALLOC_OVERRUN_CHECK_SIZE); 580 XMALLOC_OVERRUN_CHECK_SIZE);
670 } 581 }
671 --check_depth;
672 return val; 582 return val;
673} 583}
674 584
@@ -679,9 +589,7 @@ overrun_check_free (void *block)
679{ 589{
680 unsigned char *val = (unsigned char *) block; 590 unsigned char *val = (unsigned char *) block;
681 591
682 ++check_depth;
683 if (val 592 if (val
684 && check_depth == 1
685 && memcmp (xmalloc_overrun_check_header, 593 && memcmp (xmalloc_overrun_check_header,
686 val - XMALLOC_OVERRUN_CHECK_SIZE - XMALLOC_OVERRUN_SIZE_SIZE, 594 val - XMALLOC_OVERRUN_CHECK_SIZE - XMALLOC_OVERRUN_SIZE_SIZE,
687 XMALLOC_OVERRUN_CHECK_SIZE) == 0) 595 XMALLOC_OVERRUN_CHECK_SIZE) == 0)
@@ -701,7 +609,6 @@ overrun_check_free (void *block)
701 } 609 }
702 610
703 free (val); 611 free (val);
704 --check_depth;
705} 612}
706 613
707#undef malloc 614#undef malloc
@@ -712,14 +619,33 @@ overrun_check_free (void *block)
712#define free overrun_check_free 619#define free overrun_check_free
713#endif 620#endif
714 621
715#ifdef SYNC_INPUT 622/* If compiled with XMALLOC_BLOCK_INPUT_CHECK, define a symbol
716/* When using SYNC_INPUT, we don't call malloc from a signal handler, so 623 BLOCK_INPUT_IN_MEMORY_ALLOCATORS that is visible to the debugger.
717 there's no need to block input around malloc. */ 624 If that variable is set, block input while in one of Emacs's memory
718#define MALLOC_BLOCK_INPUT ((void)0) 625 allocation functions. There should be no need for this debugging
719#define MALLOC_UNBLOCK_INPUT ((void)0) 626 option, since signal handlers do not allocate memory, but Emacs
627 formerly allocated memory in signal handlers and this compile-time
628 option remains as a way to help debug the issue should it rear its
629 ugly head again. */
630#ifdef XMALLOC_BLOCK_INPUT_CHECK
631bool block_input_in_memory_allocators EXTERNALLY_VISIBLE;
632static void
633malloc_block_input (void)
634{
635 if (block_input_in_memory_allocators)
636 BLOCK_INPUT;
637}
638static void
639malloc_unblock_input (void)
640{
641 if (block_input_in_memory_allocators)
642 UNBLOCK_INPUT;
643}
644# define MALLOC_BLOCK_INPUT malloc_block_input ()
645# define MALLOC_UNBLOCK_INPUT malloc_unblock_input ()
720#else 646#else
721#define MALLOC_BLOCK_INPUT BLOCK_INPUT 647# define MALLOC_BLOCK_INPUT ((void) 0)
722#define MALLOC_UNBLOCK_INPUT UNBLOCK_INPUT 648# define MALLOC_UNBLOCK_INPUT ((void) 0)
723#endif 649#endif
724 650
725/* Like malloc but check for no memory and block interrupt input.. */ 651/* Like malloc but check for no memory and block interrupt input.. */
@@ -788,8 +714,7 @@ xfree (void *block)
788 free (block); 714 free (block);
789 MALLOC_UNBLOCK_INPUT; 715 MALLOC_UNBLOCK_INPUT;
790 /* We don't call refill_memory_reserve here 716 /* We don't call refill_memory_reserve here
791 because that duplicates doing so in emacs_blocked_free 717 because in practice the call in r_alloc_free seems to suffice. */
792 and the criterion should go there. */
793} 718}
794 719
795 720
@@ -1216,256 +1141,6 @@ lisp_align_free (void *block)
1216} 1141}
1217 1142
1218 1143
1219#ifndef SYSTEM_MALLOC
1220
1221/* Arranging to disable input signals while we're in malloc.
1222
1223 This only works with GNU malloc. To help out systems which can't
1224 use GNU malloc, all the calls to malloc, realloc, and free
1225 elsewhere in the code should be inside a BLOCK_INPUT/UNBLOCK_INPUT
1226 pair; unfortunately, we have no idea what C library functions
1227 might call malloc, so we can't really protect them unless you're
1228 using GNU malloc. Fortunately, most of the major operating systems
1229 can use GNU malloc. */
1230
1231#ifndef SYNC_INPUT
1232/* When using SYNC_INPUT, we don't call malloc from a signal handler, so
1233 there's no need to block input around malloc. */
1234
1235#ifndef DOUG_LEA_MALLOC
1236extern void * (*__malloc_hook) (size_t, const void *);
1237extern void * (*__realloc_hook) (void *, size_t, const void *);
1238extern void (*__free_hook) (void *, const void *);
1239/* Else declared in malloc.h, perhaps with an extra arg. */
1240#endif /* DOUG_LEA_MALLOC */
1241static void * (*old_malloc_hook) (size_t, const void *);
1242static void * (*old_realloc_hook) (void *, size_t, const void*);
1243static void (*old_free_hook) (void*, const void*);
1244
1245#ifdef DOUG_LEA_MALLOC
1246# define BYTES_USED (mallinfo ().uordblks)
1247#else
1248# define BYTES_USED _bytes_used
1249#endif
1250
1251#ifdef GC_MALLOC_CHECK
1252static bool dont_register_blocks;
1253#endif
1254
1255static size_t bytes_used_when_reconsidered;
1256
1257/* Value of _bytes_used, when spare_memory was freed. */
1258
1259static size_t bytes_used_when_full;
1260
1261/* This function is used as the hook for free to call. */
1262
1263static void
1264emacs_blocked_free (void *ptr, const void *ptr2)
1265{
1266 BLOCK_INPUT_ALLOC;
1267
1268#ifdef GC_MALLOC_CHECK
1269 if (ptr)
1270 {
1271 struct mem_node *m;
1272
1273 m = mem_find (ptr);
1274 if (m == MEM_NIL || m->start != ptr)
1275 {
1276 fprintf (stderr,
1277 "Freeing `%p' which wasn't allocated with malloc\n", ptr);
1278 emacs_abort ();
1279 }
1280 else
1281 {
1282 /* fprintf (stderr, "free %p...%p (%p)\n", m->start, m->end, ptr); */
1283 mem_delete (m);
1284 }
1285 }
1286#endif /* GC_MALLOC_CHECK */
1287
1288 __free_hook = old_free_hook;
1289 free (ptr);
1290
1291 /* If we released our reserve (due to running out of memory),
1292 and we have a fair amount free once again,
1293 try to set aside another reserve in case we run out once more. */
1294 if (! NILP (Vmemory_full)
1295 /* Verify there is enough space that even with the malloc
1296 hysteresis this call won't run out again.
1297 The code here is correct as long as SPARE_MEMORY
1298 is substantially larger than the block size malloc uses. */
1299 && (bytes_used_when_full
1300 > ((bytes_used_when_reconsidered = BYTES_USED)
1301 + max (malloc_hysteresis, 4) * SPARE_MEMORY)))
1302 refill_memory_reserve ();
1303
1304 __free_hook = emacs_blocked_free;
1305 UNBLOCK_INPUT_ALLOC;
1306}
1307
1308
1309/* This function is the malloc hook that Emacs uses. */
1310
1311static void *
1312emacs_blocked_malloc (size_t size, const void *ptr)
1313{
1314 void *value;
1315
1316 BLOCK_INPUT_ALLOC;
1317 __malloc_hook = old_malloc_hook;
1318#ifdef DOUG_LEA_MALLOC
1319 /* Segfaults on my system. --lorentey */
1320 /* mallopt (M_TOP_PAD, malloc_hysteresis * 4096); */
1321#else
1322 __malloc_extra_blocks = malloc_hysteresis;
1323#endif
1324
1325 value = malloc (size);
1326
1327#ifdef GC_MALLOC_CHECK
1328 {
1329 struct mem_node *m = mem_find (value);
1330 if (m != MEM_NIL)
1331 {
1332 fprintf (stderr, "Malloc returned %p which is already in use\n",
1333 value);
1334 fprintf (stderr, "Region in use is %p...%p, %td bytes, type %d\n",
1335 m->start, m->end, (char *) m->end - (char *) m->start,
1336 m->type);
1337 emacs_abort ();
1338 }
1339
1340 if (!dont_register_blocks)
1341 {
1342 mem_insert (value, (char *) value + max (1, size), allocated_mem_type);
1343 allocated_mem_type = MEM_TYPE_NON_LISP;
1344 }
1345 }
1346#endif /* GC_MALLOC_CHECK */
1347
1348 __malloc_hook = emacs_blocked_malloc;
1349 UNBLOCK_INPUT_ALLOC;
1350
1351 /* fprintf (stderr, "%p malloc\n", value); */
1352 return value;
1353}
1354
1355
1356/* This function is the realloc hook that Emacs uses. */
1357
1358static void *
1359emacs_blocked_realloc (void *ptr, size_t size, const void *ptr2)
1360{
1361 void *value;
1362
1363 BLOCK_INPUT_ALLOC;
1364 __realloc_hook = old_realloc_hook;
1365
1366#ifdef GC_MALLOC_CHECK
1367 if (ptr)
1368 {
1369 struct mem_node *m = mem_find (ptr);
1370 if (m == MEM_NIL || m->start != ptr)
1371 {
1372 fprintf (stderr,
1373 "Realloc of %p which wasn't allocated with malloc\n",
1374 ptr);
1375 emacs_abort ();
1376 }
1377
1378 mem_delete (m);
1379 }
1380
1381 /* fprintf (stderr, "%p -> realloc\n", ptr); */
1382
1383 /* Prevent malloc from registering blocks. */
1384 dont_register_blocks = 1;
1385#endif /* GC_MALLOC_CHECK */
1386
1387 value = realloc (ptr, size);
1388
1389#ifdef GC_MALLOC_CHECK
1390 dont_register_blocks = 0;
1391
1392 {
1393 struct mem_node *m = mem_find (value);
1394 if (m != MEM_NIL)
1395 {
1396 fprintf (stderr, "Realloc returns memory that is already in use\n");
1397 emacs_abort ();
1398 }
1399
1400 /* Can't handle zero size regions in the red-black tree. */
1401 mem_insert (value, (char *) value + max (size, 1), MEM_TYPE_NON_LISP);
1402 }
1403
1404 /* fprintf (stderr, "%p <- realloc\n", value); */
1405#endif /* GC_MALLOC_CHECK */
1406
1407 __realloc_hook = emacs_blocked_realloc;
1408 UNBLOCK_INPUT_ALLOC;
1409
1410 return value;
1411}
1412
1413
1414#ifdef HAVE_PTHREAD
1415/* Called from Fdump_emacs so that when the dumped Emacs starts, it has a
1416 normal malloc. Some thread implementations need this as they call
1417 malloc before main. The pthread_self call in BLOCK_INPUT_ALLOC then
1418 calls malloc because it is the first call, and we have an endless loop. */
1419
1420void
1421reset_malloc_hooks (void)
1422{
1423 __free_hook = old_free_hook;
1424 __malloc_hook = old_malloc_hook;
1425 __realloc_hook = old_realloc_hook;
1426}
1427#endif /* HAVE_PTHREAD */
1428
1429
1430/* Called from main to set up malloc to use our hooks. */
1431
1432void
1433uninterrupt_malloc (void)
1434{
1435#ifdef HAVE_PTHREAD
1436#ifdef DOUG_LEA_MALLOC
1437 pthread_mutexattr_t attr;
1438
1439 /* GLIBC has a faster way to do this, but let's keep it portable.
1440 This is according to the Single UNIX Specification. */
1441 pthread_mutexattr_init (&attr);
1442 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
1443 pthread_mutex_init (&alloc_mutex, &attr);
1444#else /* !DOUG_LEA_MALLOC */
1445 /* Some systems such as Solaris 2.6 don't have a recursive mutex,
1446 and the bundled gmalloc.c doesn't require it. */
1447 pthread_mutex_init (&alloc_mutex, NULL);
1448#endif /* !DOUG_LEA_MALLOC */
1449#endif /* HAVE_PTHREAD */
1450
1451 if (__free_hook != emacs_blocked_free)
1452 old_free_hook = __free_hook;
1453 __free_hook = emacs_blocked_free;
1454
1455 if (__malloc_hook != emacs_blocked_malloc)
1456 old_malloc_hook = __malloc_hook;
1457 __malloc_hook = emacs_blocked_malloc;
1458
1459 if (__realloc_hook != emacs_blocked_realloc)
1460 old_realloc_hook = __realloc_hook;
1461 __realloc_hook = emacs_blocked_realloc;
1462}
1463
1464#endif /* not SYNC_INPUT */
1465#endif /* not SYSTEM_MALLOC */
1466
1467
1468
1469/*********************************************************************** 1144/***********************************************************************
1470 Interval Allocation 1145 Interval Allocation
1471 ***********************************************************************/ 1146 ***********************************************************************/
@@ -1511,8 +1186,6 @@ make_interval (void)
1511{ 1186{
1512 INTERVAL val; 1187 INTERVAL val;
1513 1188
1514 /* eassert (!handling_signal); */
1515
1516 MALLOC_BLOCK_INPUT; 1189 MALLOC_BLOCK_INPUT;
1517 1190
1518 if (interval_free_list) 1191 if (interval_free_list)
@@ -1896,8 +1569,6 @@ allocate_string (void)
1896{ 1569{
1897 struct Lisp_String *s; 1570 struct Lisp_String *s;
1898 1571
1899 /* eassert (!handling_signal); */
1900
1901 MALLOC_BLOCK_INPUT; 1572 MALLOC_BLOCK_INPUT;
1902 1573
1903 /* If the free-list is empty, allocate a new string_block, and 1574 /* If the free-list is empty, allocate a new string_block, and
@@ -2589,8 +2260,6 @@ make_float (double float_value)
2589{ 2260{
2590 register Lisp_Object val; 2261 register Lisp_Object val;
2591 2262
2592 /* eassert (!handling_signal); */
2593
2594 MALLOC_BLOCK_INPUT; 2263 MALLOC_BLOCK_INPUT;
2595 2264
2596 if (float_free_list) 2265 if (float_free_list)
@@ -2698,8 +2367,6 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0,
2698{ 2367{
2699 register Lisp_Object val; 2368 register Lisp_Object val;
2700 2369
2701 /* eassert (!handling_signal); */
2702
2703 MALLOC_BLOCK_INPUT; 2370 MALLOC_BLOCK_INPUT;
2704 2371
2705 if (cons_free_list) 2372 if (cons_free_list)
@@ -3205,9 +2872,6 @@ allocate_vectorlike (ptrdiff_t len)
3205 2872
3206 MALLOC_BLOCK_INPUT; 2873 MALLOC_BLOCK_INPUT;
3207 2874
3208 /* This gets triggered by code which I haven't bothered to fix. --Stef */
3209 /* eassert (!handling_signal); */
3210
3211 if (len == 0) 2875 if (len == 0)
3212 p = XVECTOR (zero_vector); 2876 p = XVECTOR (zero_vector);
3213 else 2877 else
@@ -3492,8 +3156,6 @@ Its value and function definition are void, and its property list is nil. */)
3492 3156
3493 CHECK_STRING (name); 3157 CHECK_STRING (name);
3494 3158
3495 /* eassert (!handling_signal); */
3496
3497 MALLOC_BLOCK_INPUT; 3159 MALLOC_BLOCK_INPUT;
3498 3160
3499 if (symbol_free_list) 3161 if (symbol_free_list)
@@ -3578,8 +3240,6 @@ allocate_misc (enum Lisp_Misc_Type type)
3578{ 3240{
3579 Lisp_Object val; 3241 Lisp_Object val;
3580 3242
3581 /* eassert (!handling_signal); */
3582
3583 MALLOC_BLOCK_INPUT; 3243 MALLOC_BLOCK_INPUT;
3584 3244
3585 if (marker_free_list) 3245 if (marker_free_list)
@@ -3799,12 +3459,6 @@ memory_full (size_t nbytes)
3799 lisp_free (spare_memory[i]); 3459 lisp_free (spare_memory[i]);
3800 spare_memory[i] = 0; 3460 spare_memory[i] = 0;
3801 } 3461 }
3802
3803 /* Record the space now used. When it decreases substantially,
3804 we can refill the memory reserve. */
3805#if !defined SYSTEM_MALLOC && !defined SYNC_INPUT
3806 bytes_used_when_full = BYTES_USED;
3807#endif
3808 } 3462 }
3809 3463
3810 /* This used to call error, but if we've run out of memory, we could 3464 /* This used to call error, but if we've run out of memory, we could
@@ -3942,7 +3596,7 @@ mem_insert (void *start, void *end, enum mem_type type)
3942 3596
3943 /* Create a new node. */ 3597 /* Create a new node. */
3944#ifdef GC_MALLOC_CHECK 3598#ifdef GC_MALLOC_CHECK
3945 x = _malloc_internal (sizeof *x); 3599 x = malloc (sizeof *x);
3946 if (x == NULL) 3600 if (x == NULL)
3947 emacs_abort (); 3601 emacs_abort ();
3948#else 3602#else
@@ -4166,7 +3820,7 @@ mem_delete (struct mem_node *z)
4166 mem_delete_fixup (x); 3820 mem_delete_fixup (x);
4167 3821
4168#ifdef GC_MALLOC_CHECK 3822#ifdef GC_MALLOC_CHECK
4169 _free_internal (y); 3823 free (y);
4170#else 3824#else
4171 xfree (y); 3825 xfree (y);
4172#endif 3826#endif
@@ -5867,7 +5521,7 @@ mark_buffer (struct buffer *buffer)
5867} 5521}
5868 5522
5869/* Remove killed buffers or items whose car is a killed buffer from 5523/* Remove killed buffers or items whose car is a killed buffer from
5870 LIST, and mark other items. Return changed LIST, which is marked. */ 5524 LIST, and mark other items. Return changed LIST, which is marked. */
5871 5525
5872static Lisp_Object 5526static Lisp_Object
5873mark_discard_killed_buffers (Lisp_Object list) 5527mark_discard_killed_buffers (Lisp_Object list)
@@ -5889,6 +5543,7 @@ mark_discard_killed_buffers (Lisp_Object list)
5889 prev = &XCDR_AS_LVALUE (tail); 5543 prev = &XCDR_AS_LVALUE (tail);
5890 } 5544 }
5891 } 5545 }
5546 mark_object (tail);
5892 return list; 5547 return list;
5893} 5548}
5894 5549
@@ -6037,18 +5692,8 @@ mark_object (Lisp_Object arg)
6037 struct window *w = (struct window *) ptr; 5692 struct window *w = (struct window *) ptr;
6038 bool leaf = NILP (w->hchild) && NILP (w->vchild); 5693 bool leaf = NILP (w->hchild) && NILP (w->vchild);
6039 5694
6040 /* For live windows, Lisp code filters out killed buffers
6041 from both buffer lists. For dead windows, we do it here
6042 in attempt to help GC to reclaim killed buffers faster. */
6043 if (leaf && NILP (w->buffer))
6044 {
6045 wset_prev_buffers
6046 (w, mark_discard_killed_buffers (w->prev_buffers));
6047 wset_next_buffers
6048 (w, mark_discard_killed_buffers (w->next_buffers));
6049 }
6050
6051 mark_vectorlike (ptr); 5695 mark_vectorlike (ptr);
5696
6052 /* Mark glyphs for leaf windows. Marking window 5697 /* Mark glyphs for leaf windows. Marking window
6053 matrices is sufficient because frame matrices 5698 matrices is sufficient because frame matrices
6054 use the same glyph memory. */ 5699 use the same glyph memory. */
@@ -6057,6 +5702,15 @@ mark_object (Lisp_Object arg)
6057 mark_glyph_matrix (w->current_matrix); 5702 mark_glyph_matrix (w->current_matrix);
6058 mark_glyph_matrix (w->desired_matrix); 5703 mark_glyph_matrix (w->desired_matrix);
6059 } 5704 }
5705
5706 /* Filter out killed buffers from both buffer lists
5707 in attempt to help GC to reclaim killed buffers faster.
5708 We can do it elsewhere for live windows, but this is the
5709 best place to do it for dead windows. */
5710 wset_prev_buffers
5711 (w, mark_discard_killed_buffers (w->prev_buffers));
5712 wset_next_buffers
5713 (w, mark_discard_killed_buffers (w->next_buffers));
6060 } 5714 }
6061 break; 5715 break;
6062 5716
@@ -6767,12 +6421,6 @@ init_alloc_once (void)
6767 init_strings (); 6421 init_strings ();
6768 init_vectors (); 6422 init_vectors ();
6769 6423
6770#ifdef REL_ALLOC
6771 malloc_hysteresis = 32;
6772#else
6773 malloc_hysteresis = 0;
6774#endif
6775
6776 refill_memory_reserve (); 6424 refill_memory_reserve ();
6777 gc_cons_threshold = GC_DEFAULT_THRESHOLD; 6425 gc_cons_threshold = GC_DEFAULT_THRESHOLD;
6778} 6426}