diff options
| author | Stefan Kangas | 2025-04-14 20:40:49 +0200 |
|---|---|---|
| committer | Stefan Kangas | 2025-04-14 20:40:49 +0200 |
| commit | a7f5d183a8c13dfb7fb43777abdf96233df0ca0c (patch) | |
| tree | bb596b74cc10379538ef54b32f18f0978c8872ac /src/alloc.c | |
| parent | 74df372398dbc90f6c0185f1701af28129073de7 (diff) | |
| download | emacs-a7f5d183a8c13dfb7fb43777abdf96233df0ca0c.tar.gz emacs-a7f5d183a8c13dfb7fb43777abdf96233df0ca0c.zip | |
Remove unused XMALLOC_BLOCK_INPUT_CHECK debug facility
The compile-time option XMALLOC_BLOCK_INPUT_CHECK was added in
2012 (commit 4d7e6e51dd4acecff) to allow blocking input during
malloc-family calls, in case any issues arose from related
changes in Emacs 24.3. However, it has not been referenced on
emacs-devel or the bug tracker in over a decade.
It is clear that we do not need it, as our signal handlers do not
allocate memory. Removing it simplifies the allocation function
wrappers and eliminates dead debug code.
Ref: https://debbugs.gnu.org/12450
* src/alloc.c [XMALLOC_BLOCK_INPUT_CHECK]
(malloc_block_input, malloc_unblock_input): Delete functions.
(MALLOC_BLOCK_INPUT, MALLOC_UNBLOCK_INPUT): Delete macros. Update
all callers.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 111 |
1 files changed, 6 insertions, 105 deletions
diff --git a/src/alloc.c b/src/alloc.c index c0d68e6c964..167be74d2f7 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -635,39 +635,6 @@ static_assert (LISP_ALIGNMENT % GCALIGNMENT == 0); | |||
| 635 | enum { MALLOC_IS_LISP_ALIGNED = alignof (max_align_t) % LISP_ALIGNMENT == 0 }; | 635 | enum { MALLOC_IS_LISP_ALIGNED = alignof (max_align_t) % LISP_ALIGNMENT == 0 }; |
| 636 | static_assert (MALLOC_IS_LISP_ALIGNED); | 636 | static_assert (MALLOC_IS_LISP_ALIGNED); |
| 637 | 637 | ||
| 638 | /* If compiled with XMALLOC_BLOCK_INPUT_CHECK, define a symbol | ||
| 639 | BLOCK_INPUT_IN_MEMORY_ALLOCATORS that is visible to the debugger. | ||
| 640 | If that variable is set, block input while in one of Emacs's memory | ||
| 641 | allocation functions. There should be no need for this debugging | ||
| 642 | option, since signal handlers do not allocate memory, but Emacs | ||
| 643 | formerly allocated memory in signal handlers and this compile-time | ||
| 644 | option remains as a way to help debug the issue should it rear its | ||
| 645 | ugly head again. */ | ||
| 646 | #ifdef XMALLOC_BLOCK_INPUT_CHECK | ||
| 647 | bool block_input_in_memory_allocators EXTERNALLY_VISIBLE; | ||
| 648 | static void | ||
| 649 | malloc_block_input (void) | ||
| 650 | { | ||
| 651 | if (block_input_in_memory_allocators) | ||
| 652 | block_input (); | ||
| 653 | } | ||
| 654 | static void | ||
| 655 | malloc_unblock_input (void) | ||
| 656 | { | ||
| 657 | if (block_input_in_memory_allocators) | ||
| 658 | { | ||
| 659 | int err = errno; | ||
| 660 | unblock_input (); | ||
| 661 | errno = err; | ||
| 662 | } | ||
| 663 | } | ||
| 664 | # define MALLOC_BLOCK_INPUT malloc_block_input () | ||
| 665 | # define MALLOC_UNBLOCK_INPUT malloc_unblock_input () | ||
| 666 | #else | ||
| 667 | # define MALLOC_BLOCK_INPUT ((void) 0) | ||
| 668 | # define MALLOC_UNBLOCK_INPUT ((void) 0) | ||
| 669 | #endif | ||
| 670 | |||
| 671 | #define MALLOC_PROBE(size) \ | 638 | #define MALLOC_PROBE(size) \ |
| 672 | do { \ | 639 | do { \ |
| 673 | if (profiler_memory_running) \ | 640 | if (profiler_memory_running) \ |
| @@ -679,12 +646,7 @@ malloc_unblock_input (void) | |||
| 679 | void * | 646 | void * |
| 680 | xmalloc (size_t size) | 647 | xmalloc (size_t size) |
| 681 | { | 648 | { |
| 682 | void *val; | 649 | void *val = malloc (size); |
| 683 | |||
| 684 | MALLOC_BLOCK_INPUT; | ||
| 685 | val = malloc (size); | ||
| 686 | MALLOC_UNBLOCK_INPUT; | ||
| 687 | |||
| 688 | if (!val) | 650 | if (!val) |
| 689 | memory_full (size); | 651 | memory_full (size); |
| 690 | MALLOC_PROBE (size); | 652 | MALLOC_PROBE (size); |
| @@ -696,12 +658,7 @@ xmalloc (size_t size) | |||
| 696 | void * | 658 | void * |
| 697 | xzalloc (size_t size) | 659 | xzalloc (size_t size) |
| 698 | { | 660 | { |
| 699 | void *val; | 661 | void *val = calloc (1, size); |
| 700 | |||
| 701 | MALLOC_BLOCK_INPUT; | ||
| 702 | val = calloc (1, size); | ||
| 703 | MALLOC_UNBLOCK_INPUT; | ||
| 704 | |||
| 705 | if (!val) | 662 | if (!val) |
| 706 | memory_full (size); | 663 | memory_full (size); |
| 707 | MALLOC_PROBE (size); | 664 | MALLOC_PROBE (size); |
| @@ -713,12 +670,7 @@ xzalloc (size_t size) | |||
| 713 | void * | 670 | void * |
| 714 | xrealloc (void *block, size_t size) | 671 | xrealloc (void *block, size_t size) |
| 715 | { | 672 | { |
| 716 | void *val; | 673 | void *val = realloc (block, size); |
| 717 | |||
| 718 | MALLOC_BLOCK_INPUT; | ||
| 719 | val = realloc (block, size); | ||
| 720 | MALLOC_UNBLOCK_INPUT; | ||
| 721 | |||
| 722 | if (!val) | 674 | if (!val) |
| 723 | memory_full (size); | 675 | memory_full (size); |
| 724 | MALLOC_PROBE (size); | 676 | MALLOC_PROBE (size); |
| @@ -735,9 +687,7 @@ xfree (void *block) | |||
| 735 | return; | 687 | return; |
| 736 | if (pdumper_object_p (block)) | 688 | if (pdumper_object_p (block)) |
| 737 | return; | 689 | return; |
| 738 | MALLOC_BLOCK_INPUT; | ||
| 739 | free (block); | 690 | free (block); |
| 740 | MALLOC_UNBLOCK_INPUT; | ||
| 741 | /* We don't call refill_memory_reserve here | 691 | /* We don't call refill_memory_reserve here |
| 742 | because in practice the call in r_alloc_free seems to suffice. */ | 692 | because in practice the call in r_alloc_free seems to suffice. */ |
| 743 | } | 693 | } |
| @@ -922,15 +872,11 @@ void *lisp_malloc_loser EXTERNALLY_VISIBLE; | |||
| 922 | static void * | 872 | static void * |
| 923 | lisp_malloc (size_t nbytes, bool clearit, enum mem_type type) | 873 | lisp_malloc (size_t nbytes, bool clearit, enum mem_type type) |
| 924 | { | 874 | { |
| 925 | register void *val; | ||
| 926 | |||
| 927 | MALLOC_BLOCK_INPUT; | ||
| 928 | |||
| 929 | #ifdef GC_MALLOC_CHECK | 875 | #ifdef GC_MALLOC_CHECK |
| 930 | allocated_mem_type = type; | 876 | allocated_mem_type = type; |
| 931 | #endif | 877 | #endif |
| 932 | 878 | ||
| 933 | val = clearit ? calloc (1, nbytes) : malloc (nbytes); | 879 | void *val = clearit ? calloc (1, nbytes) : malloc (nbytes); |
| 934 | 880 | ||
| 935 | #if ! USE_LSB_TAG | 881 | #if ! USE_LSB_TAG |
| 936 | /* If the memory just allocated cannot be addressed thru a Lisp | 882 | /* If the memory just allocated cannot be addressed thru a Lisp |
| @@ -954,7 +900,6 @@ lisp_malloc (size_t nbytes, bool clearit, enum mem_type type) | |||
| 954 | mem_insert (val, (char *) val + nbytes, type); | 900 | mem_insert (val, (char *) val + nbytes, type); |
| 955 | #endif | 901 | #endif |
| 956 | 902 | ||
| 957 | MALLOC_UNBLOCK_INPUT; | ||
| 958 | if (!val) | 903 | if (!val) |
| 959 | memory_full (nbytes); | 904 | memory_full (nbytes); |
| 960 | MALLOC_PROBE (nbytes); | 905 | MALLOC_PROBE (nbytes); |
| @@ -970,7 +915,6 @@ lisp_free (void *block) | |||
| 970 | if (pdumper_object_p (block)) | 915 | if (pdumper_object_p (block)) |
| 971 | return; | 916 | return; |
| 972 | 917 | ||
| 973 | MALLOC_BLOCK_INPUT; | ||
| 974 | #ifndef GC_MALLOC_CHECK | 918 | #ifndef GC_MALLOC_CHECK |
| 975 | struct mem_node *m = mem_find (block); | 919 | struct mem_node *m = mem_find (block); |
| 976 | #endif | 920 | #endif |
| @@ -978,7 +922,6 @@ lisp_free (void *block) | |||
| 978 | #ifndef GC_MALLOC_CHECK | 922 | #ifndef GC_MALLOC_CHECK |
| 979 | mem_delete (m); | 923 | mem_delete (m); |
| 980 | #endif | 924 | #endif |
| 981 | MALLOC_UNBLOCK_INPUT; | ||
| 982 | } | 925 | } |
| 983 | 926 | ||
| 984 | /***** Allocation of aligned blocks of memory to store Lisp data. *****/ | 927 | /***** Allocation of aligned blocks of memory to store Lisp data. *****/ |
| @@ -1116,8 +1059,6 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) | |||
| 1116 | 1059 | ||
| 1117 | eassert (nbytes <= BLOCK_BYTES); | 1060 | eassert (nbytes <= BLOCK_BYTES); |
| 1118 | 1061 | ||
| 1119 | MALLOC_BLOCK_INPUT; | ||
| 1120 | |||
| 1121 | #ifdef GC_MALLOC_CHECK | 1062 | #ifdef GC_MALLOC_CHECK |
| 1122 | allocated_mem_type = type; | 1063 | allocated_mem_type = type; |
| 1123 | #endif | 1064 | #endif |
| @@ -1141,10 +1082,7 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) | |||
| 1141 | #endif | 1082 | #endif |
| 1142 | 1083 | ||
| 1143 | if (base == 0) | 1084 | if (base == 0) |
| 1144 | { | 1085 | memory_full (ABLOCKS_BYTES); |
| 1145 | MALLOC_UNBLOCK_INPUT; | ||
| 1146 | memory_full (ABLOCKS_BYTES); | ||
| 1147 | } | ||
| 1148 | 1086 | ||
| 1149 | aligned = (base == abase); | 1087 | aligned = (base == abase); |
| 1150 | if (!aligned) | 1088 | if (!aligned) |
| @@ -1168,7 +1106,6 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) | |||
| 1168 | { | 1106 | { |
| 1169 | lisp_malloc_loser = base; | 1107 | lisp_malloc_loser = base; |
| 1170 | free (base); | 1108 | free (base); |
| 1171 | MALLOC_UNBLOCK_INPUT; | ||
| 1172 | memory_full (SIZE_MAX); | 1109 | memory_full (SIZE_MAX); |
| 1173 | } | 1110 | } |
| 1174 | } | 1111 | } |
| @@ -1205,8 +1142,6 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) | |||
| 1205 | mem_insert (val, (char *) val + nbytes, type); | 1142 | mem_insert (val, (char *) val + nbytes, type); |
| 1206 | #endif | 1143 | #endif |
| 1207 | 1144 | ||
| 1208 | MALLOC_UNBLOCK_INPUT; | ||
| 1209 | |||
| 1210 | MALLOC_PROBE (nbytes); | 1145 | MALLOC_PROBE (nbytes); |
| 1211 | 1146 | ||
| 1212 | eassert (0 == ((uintptr_t) val) % BLOCK_ALIGN); | 1147 | eassert (0 == ((uintptr_t) val) % BLOCK_ALIGN); |
| @@ -1219,7 +1154,6 @@ lisp_align_free (void *block) | |||
| 1219 | struct ablock *ablock = block; | 1154 | struct ablock *ablock = block; |
| 1220 | struct ablocks *abase = ABLOCK_ABASE (ablock); | 1155 | struct ablocks *abase = ABLOCK_ABASE (ablock); |
| 1221 | 1156 | ||
| 1222 | MALLOC_BLOCK_INPUT; | ||
| 1223 | #ifndef GC_MALLOC_CHECK | 1157 | #ifndef GC_MALLOC_CHECK |
| 1224 | mem_delete (mem_find (block)); | 1158 | mem_delete (mem_find (block)); |
| 1225 | #endif | 1159 | #endif |
| @@ -1259,7 +1193,6 @@ lisp_align_free (void *block) | |||
| 1259 | #endif | 1193 | #endif |
| 1260 | free (ABLOCKS_BASE (abase)); | 1194 | free (ABLOCKS_BASE (abase)); |
| 1261 | } | 1195 | } |
| 1262 | MALLOC_UNBLOCK_INPUT; | ||
| 1263 | } | 1196 | } |
| 1264 | 1197 | ||
| 1265 | 1198 | ||
| @@ -1322,8 +1255,6 @@ make_interval (void) | |||
| 1322 | { | 1255 | { |
| 1323 | INTERVAL val; | 1256 | INTERVAL val; |
| 1324 | 1257 | ||
| 1325 | MALLOC_BLOCK_INPUT; | ||
| 1326 | |||
| 1327 | if (interval_free_list) | 1258 | if (interval_free_list) |
| 1328 | { | 1259 | { |
| 1329 | val = interval_free_list; | 1260 | val = interval_free_list; |
| @@ -1346,8 +1277,6 @@ make_interval (void) | |||
| 1346 | ASAN_UNPOISON_INTERVAL (val); | 1277 | ASAN_UNPOISON_INTERVAL (val); |
| 1347 | } | 1278 | } |
| 1348 | 1279 | ||
| 1349 | MALLOC_UNBLOCK_INPUT; | ||
| 1350 | |||
| 1351 | tally_consing (sizeof (struct interval)); | 1280 | tally_consing (sizeof (struct interval)); |
| 1352 | intervals_consed++; | 1281 | intervals_consed++; |
| 1353 | RESET_INTERVAL (val); | 1282 | RESET_INTERVAL (val); |
| @@ -1735,8 +1664,6 @@ allocate_string (void) | |||
| 1735 | { | 1664 | { |
| 1736 | struct Lisp_String *s; | 1665 | struct Lisp_String *s; |
| 1737 | 1666 | ||
| 1738 | MALLOC_BLOCK_INPUT; | ||
| 1739 | |||
| 1740 | /* If the free-list is empty, allocate a new string_block, and | 1667 | /* If the free-list is empty, allocate a new string_block, and |
| 1741 | add all the Lisp_Strings in it to the free-list. */ | 1668 | add all the Lisp_Strings in it to the free-list. */ |
| 1742 | if (string_free_list == NULL) | 1669 | if (string_free_list == NULL) |
| @@ -1765,8 +1692,6 @@ allocate_string (void) | |||
| 1765 | ASAN_UNPOISON_STRING (s); | 1692 | ASAN_UNPOISON_STRING (s); |
| 1766 | string_free_list = NEXT_FREE_LISP_STRING (s); | 1693 | string_free_list = NEXT_FREE_LISP_STRING (s); |
| 1767 | 1694 | ||
| 1768 | MALLOC_UNBLOCK_INPUT; | ||
| 1769 | |||
| 1770 | ++strings_consed; | 1695 | ++strings_consed; |
| 1771 | tally_consing (sizeof *s); | 1696 | tally_consing (sizeof *s); |
| 1772 | 1697 | ||
| @@ -1810,8 +1735,6 @@ allocate_string_data (struct Lisp_String *s, | |||
| 1810 | of string data. */ | 1735 | of string data. */ |
| 1811 | ptrdiff_t needed = sdata_size (nbytes); | 1736 | ptrdiff_t needed = sdata_size (nbytes); |
| 1812 | 1737 | ||
| 1813 | MALLOC_BLOCK_INPUT; | ||
| 1814 | |||
| 1815 | if (nbytes > LARGE_STRING_BYTES || immovable) | 1738 | if (nbytes > LARGE_STRING_BYTES || immovable) |
| 1816 | { | 1739 | { |
| 1817 | size_t size = FLEXSIZEOF (struct sblock, data, needed); | 1740 | size_t size = FLEXSIZEOF (struct sblock, data, needed); |
| @@ -1875,8 +1798,6 @@ allocate_string_data (struct Lisp_String *s, | |||
| 1875 | b->next_free = (sdata *) ((char *) data + needed + GC_STRING_EXTRA); | 1798 | b->next_free = (sdata *) ((char *) data + needed + GC_STRING_EXTRA); |
| 1876 | eassert ((uintptr_t) b->next_free % alignof (sdata) == 0); | 1799 | eassert ((uintptr_t) b->next_free % alignof (sdata) == 0); |
| 1877 | 1800 | ||
| 1878 | MALLOC_UNBLOCK_INPUT; | ||
| 1879 | |||
| 1880 | s->u.s.data = SDATA_DATA (data); | 1801 | s->u.s.data = SDATA_DATA (data); |
| 1881 | #ifdef GC_CHECK_STRING_BYTES | 1802 | #ifdef GC_CHECK_STRING_BYTES |
| 1882 | SDATA_NBYTES (data) = nbytes; | 1803 | SDATA_NBYTES (data) = nbytes; |
| @@ -2606,8 +2527,6 @@ make_float (double float_value) | |||
| 2606 | { | 2527 | { |
| 2607 | register Lisp_Object val; | 2528 | register Lisp_Object val; |
| 2608 | 2529 | ||
| 2609 | MALLOC_BLOCK_INPUT; | ||
| 2610 | |||
| 2611 | if (float_free_list) | 2530 | if (float_free_list) |
| 2612 | { | 2531 | { |
| 2613 | XSETFLOAT (val, float_free_list); | 2532 | XSETFLOAT (val, float_free_list); |
| @@ -2631,8 +2550,6 @@ make_float (double float_value) | |||
| 2631 | float_block_index++; | 2550 | float_block_index++; |
| 2632 | } | 2551 | } |
| 2633 | 2552 | ||
| 2634 | MALLOC_UNBLOCK_INPUT; | ||
| 2635 | |||
| 2636 | XFLOAT_INIT (val, float_value); | 2553 | XFLOAT_INIT (val, float_value); |
| 2637 | eassert (!XFLOAT_MARKED_P (XFLOAT (val))); | 2554 | eassert (!XFLOAT_MARKED_P (XFLOAT (val))); |
| 2638 | tally_consing (sizeof (struct Lisp_Float)); | 2555 | tally_consing (sizeof (struct Lisp_Float)); |
| @@ -2730,8 +2647,6 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0, | |||
| 2730 | { | 2647 | { |
| 2731 | register Lisp_Object val; | 2648 | register Lisp_Object val; |
| 2732 | 2649 | ||
| 2733 | MALLOC_BLOCK_INPUT; | ||
| 2734 | |||
| 2735 | if (cons_free_list) | 2650 | if (cons_free_list) |
| 2736 | { | 2651 | { |
| 2737 | ASAN_UNPOISON_CONS (cons_free_list); | 2652 | ASAN_UNPOISON_CONS (cons_free_list); |
| @@ -2755,8 +2670,6 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0, | |||
| 2755 | cons_block_index++; | 2670 | cons_block_index++; |
| 2756 | } | 2671 | } |
| 2757 | 2672 | ||
| 2758 | MALLOC_UNBLOCK_INPUT; | ||
| 2759 | |||
| 2760 | XSETCAR (val, car); | 2673 | XSETCAR (val, car); |
| 2761 | XSETCDR (val, cdr); | 2674 | XSETCDR (val, cdr); |
| 2762 | eassert (!XCONS_MARKED_P (XCONS (val))); | 2675 | eassert (!XCONS_MARKED_P (XCONS (val))); |
| @@ -3488,8 +3401,6 @@ allocate_vectorlike (ptrdiff_t len, bool clearit) | |||
| 3488 | ptrdiff_t nbytes = header_size + len * word_size; | 3401 | ptrdiff_t nbytes = header_size + len * word_size; |
| 3489 | struct Lisp_Vector *p; | 3402 | struct Lisp_Vector *p; |
| 3490 | 3403 | ||
| 3491 | MALLOC_BLOCK_INPUT; | ||
| 3492 | |||
| 3493 | #ifdef DOUG_LEA_MALLOC | 3404 | #ifdef DOUG_LEA_MALLOC |
| 3494 | if (!mmap_lisp_allowed_p ()) | 3405 | if (!mmap_lisp_allowed_p ()) |
| 3495 | mallopt (M_MMAP_MAX, 0); | 3406 | mallopt (M_MMAP_MAX, 0); |
| @@ -3518,8 +3429,6 @@ allocate_vectorlike (ptrdiff_t len, bool clearit) | |||
| 3518 | tally_consing (nbytes); | 3429 | tally_consing (nbytes); |
| 3519 | vector_cells_consed += len; | 3430 | vector_cells_consed += len; |
| 3520 | 3431 | ||
| 3521 | MALLOC_UNBLOCK_INPUT; | ||
| 3522 | |||
| 3523 | return p; | 3432 | return p; |
| 3524 | } | 3433 | } |
| 3525 | 3434 | ||
| @@ -3817,8 +3726,6 @@ Its value is void, and its function definition and property list are nil. */) | |||
| 3817 | 3726 | ||
| 3818 | CHECK_STRING (name); | 3727 | CHECK_STRING (name); |
| 3819 | 3728 | ||
| 3820 | MALLOC_BLOCK_INPUT; | ||
| 3821 | |||
| 3822 | if (symbol_free_list) | 3729 | if (symbol_free_list) |
| 3823 | { | 3730 | { |
| 3824 | ASAN_UNPOISON_SYMBOL (symbol_free_list); | 3731 | ASAN_UNPOISON_SYMBOL (symbol_free_list); |
| @@ -3842,8 +3749,6 @@ Its value is void, and its function definition and property list are nil. */) | |||
| 3842 | symbol_block_index++; | 3749 | symbol_block_index++; |
| 3843 | } | 3750 | } |
| 3844 | 3751 | ||
| 3845 | MALLOC_UNBLOCK_INPUT; | ||
| 3846 | |||
| 3847 | init_symbol (val, name); | 3752 | init_symbol (val, name); |
| 3848 | tally_consing (sizeof (struct Lisp_Symbol)); | 3753 | tally_consing (sizeof (struct Lisp_Symbol)); |
| 3849 | symbols_consed++; | 3754 | symbols_consed++; |
| @@ -4250,16 +4155,12 @@ memory_full (size_t nbytes) | |||
| 4250 | bool enough_free_memory = false; | 4155 | bool enough_free_memory = false; |
| 4251 | if (SPARE_MEMORY < nbytes) | 4156 | if (SPARE_MEMORY < nbytes) |
| 4252 | { | 4157 | { |
| 4253 | void *p; | 4158 | void *p = malloc (SPARE_MEMORY); |
| 4254 | |||
| 4255 | MALLOC_BLOCK_INPUT; | ||
| 4256 | p = malloc (SPARE_MEMORY); | ||
| 4257 | if (p) | 4159 | if (p) |
| 4258 | { | 4160 | { |
| 4259 | free (p); | 4161 | free (p); |
| 4260 | enough_free_memory = true; | 4162 | enough_free_memory = true; |
| 4261 | } | 4163 | } |
| 4262 | MALLOC_UNBLOCK_INPUT; | ||
| 4263 | } | 4164 | } |
| 4264 | 4165 | ||
| 4265 | if (! enough_free_memory) | 4166 | if (! enough_free_memory) |