diff options
| author | Stefan Kangas | 2025-02-01 04:56:52 +0100 |
|---|---|---|
| committer | Stefan Kangas | 2025-02-01 04:56:52 +0100 |
| commit | bf97946d7dc460b7d3c3ce03193041b891b51faf (patch) | |
| tree | c799f87903ca3dcba8b804bd185b519aacc0a636 /src/gmalloc.c | |
| parent | a4a0957b6b3b1db858524ac6d4dc3d951f65960b (diff) | |
| parent | aa07e94439c663f768c32a689d14506d25a7a5bc (diff) | |
| download | emacs-bf97946d7dc460b7d3c3ce03193041b891b51faf.tar.gz emacs-bf97946d7dc460b7d3c3ce03193041b891b51faf.zip | |
Merge branch 'scratch/no-purespace' into 'master'
Diffstat (limited to 'src/gmalloc.c')
| -rw-r--r-- | src/gmalloc.c | 167 |
1 files changed, 9 insertions, 158 deletions
diff --git a/src/gmalloc.c b/src/gmalloc.c index fe6a0412a9b..18b993f78d0 100644 --- a/src/gmalloc.c +++ b/src/gmalloc.c | |||
| @@ -21,7 +21,7 @@ License along with this library. If not, see <https://www.gnu.org/licenses/>. | |||
| 21 | 21 | ||
| 22 | #include <config.h> | 22 | #include <config.h> |
| 23 | 23 | ||
| 24 | #if defined HAVE_PTHREAD && !defined HYBRID_MALLOC | 24 | #if defined HAVE_PTHREAD |
| 25 | #define USE_PTHREAD | 25 | #define USE_PTHREAD |
| 26 | #endif | 26 | #endif |
| 27 | 27 | ||
| @@ -57,13 +57,6 @@ extern void *(*__morecore) (ptrdiff_t); | |||
| 57 | extern void (*__MALLOC_HOOK_VOLATILE __malloc_initialize_hook) (void); | 57 | extern void (*__MALLOC_HOOK_VOLATILE __malloc_initialize_hook) (void); |
| 58 | #endif /* !defined HAVE_MALLOC_H || glibc >= 2.24 */ | 58 | #endif /* !defined HAVE_MALLOC_H || glibc >= 2.24 */ |
| 59 | 59 | ||
| 60 | /* If HYBRID_MALLOC is defined, then temacs will use malloc, | ||
| 61 | realloc... as defined in this file (and renamed gmalloc, | ||
| 62 | grealloc... via the macros that follow). The dumped emacs, | ||
| 63 | however, will use the system malloc, realloc.... In other source | ||
| 64 | files, malloc, realloc... are renamed hybrid_malloc, | ||
| 65 | hybrid_realloc... via macros in lisp.h. hybrid_malloc and | ||
| 66 | friends are wrapper functions defined later in this file. */ | ||
| 67 | #undef malloc | 60 | #undef malloc |
| 68 | #undef realloc | 61 | #undef realloc |
| 69 | #undef calloc | 62 | #undef calloc |
| @@ -76,19 +69,11 @@ extern void (*__MALLOC_HOOK_VOLATILE __malloc_initialize_hook) (void); | |||
| 76 | #define free gfree | 69 | #define free gfree |
| 77 | #define malloc_info gmalloc_info | 70 | #define malloc_info gmalloc_info |
| 78 | 71 | ||
| 79 | #ifdef HYBRID_MALLOC | ||
| 80 | # include "sheap.h" | ||
| 81 | #endif | ||
| 82 | |||
| 83 | #ifdef __cplusplus | 72 | #ifdef __cplusplus |
| 84 | extern "C" | 73 | extern "C" |
| 85 | { | 74 | { |
| 86 | #endif | 75 | #endif |
| 87 | 76 | ||
| 88 | #ifdef HYBRID_MALLOC | ||
| 89 | #define extern static | ||
| 90 | #endif | ||
| 91 | |||
| 92 | /* Allocate SIZE bytes of memory. */ | 77 | /* Allocate SIZE bytes of memory. */ |
| 93 | extern void *malloc (size_t size) ATTRIBUTE_MALLOC_SIZE ((1)); | 78 | extern void *malloc (size_t size) ATTRIBUTE_MALLOC_SIZE ((1)); |
| 94 | /* Re-allocate the previously allocated block | 79 | /* Re-allocate the previously allocated block |
| @@ -327,8 +312,6 @@ void (*__MALLOC_HOOK_VOLATILE __malloc_initialize_hook) (void); | |||
| 327 | void (*__MALLOC_HOOK_VOLATILE __after_morecore_hook) (void); | 312 | void (*__MALLOC_HOOK_VOLATILE __after_morecore_hook) (void); |
| 328 | void *(*__morecore) (ptrdiff_t); | 313 | void *(*__morecore) (ptrdiff_t); |
| 329 | 314 | ||
| 330 | #ifndef HYBRID_MALLOC | ||
| 331 | |||
| 332 | /* Pointer to the base of the first block. */ | 315 | /* Pointer to the base of the first block. */ |
| 333 | char *_heapbase; | 316 | char *_heapbase; |
| 334 | 317 | ||
| @@ -350,11 +333,9 @@ size_t _bytes_free; | |||
| 350 | /* Are you experienced? */ | 333 | /* Are you experienced? */ |
| 351 | int __malloc_initialized; | 334 | int __malloc_initialized; |
| 352 | 335 | ||
| 353 | #endif /* HYBRID_MALLOC */ | ||
| 354 | |||
| 355 | /* Number of extra blocks to get each time we ask for more core. | 336 | /* Number of extra blocks to get each time we ask for more core. |
| 356 | This reduces the frequency of calling `(*__morecore)'. */ | 337 | This reduces the frequency of calling `(*__morecore)'. */ |
| 357 | #if defined DOUG_LEA_MALLOC || defined HYBRID_MALLOC || defined SYSTEM_MALLOC | 338 | #if defined DOUG_LEA_MALLOC || defined SYSTEM_MALLOC |
| 358 | static | 339 | static |
| 359 | #endif | 340 | #endif |
| 360 | size_t __malloc_extra_blocks; | 341 | size_t __malloc_extra_blocks; |
| @@ -917,7 +898,7 @@ malloc (size_t size) | |||
| 917 | return (hook ? hook : _malloc_internal) (size); | 898 | return (hook ? hook : _malloc_internal) (size); |
| 918 | } | 899 | } |
| 919 | 900 | ||
| 920 | #if !(defined (_LIBC) || defined (HYBRID_MALLOC)) | 901 | #if !(defined (_LIBC)) |
| 921 | 902 | ||
| 922 | /* On some ANSI C systems, some libc functions call _malloc, _free | 903 | /* On some ANSI C systems, some libc functions call _malloc, _free |
| 923 | and _realloc. Make them use the GNU functions. */ | 904 | and _realloc. Make them use the GNU functions. */ |
| @@ -969,11 +950,8 @@ License along with this library. If not, see <https://www.gnu.org/licenses/>. | |||
| 969 | /* Debugging hook for free. */ | 950 | /* Debugging hook for free. */ |
| 970 | static void (*__MALLOC_HOOK_VOLATILE gfree_hook) (void *); | 951 | static void (*__MALLOC_HOOK_VOLATILE gfree_hook) (void *); |
| 971 | 952 | ||
| 972 | #ifndef HYBRID_MALLOC | ||
| 973 | |||
| 974 | /* List of blocks allocated by aligned_alloc. */ | 953 | /* List of blocks allocated by aligned_alloc. */ |
| 975 | struct alignlist *_aligned_blocks = NULL; | 954 | struct alignlist *_aligned_blocks = NULL; |
| 976 | #endif | ||
| 977 | 955 | ||
| 978 | /* Return memory to the heap. | 956 | /* Return memory to the heap. |
| 979 | Like `_free_internal' but don't lock mutex. */ | 957 | Like `_free_internal' but don't lock mutex. */ |
| @@ -1244,7 +1222,6 @@ free (void *ptr) | |||
| 1244 | _free_internal (ptr); | 1222 | _free_internal (ptr); |
| 1245 | } | 1223 | } |
| 1246 | 1224 | ||
| 1247 | #ifndef HYBRID_MALLOC | ||
| 1248 | /* Define the `cfree' alias for `free'. */ | 1225 | /* Define the `cfree' alias for `free'. */ |
| 1249 | #ifdef weak_alias | 1226 | #ifdef weak_alias |
| 1250 | weak_alias (free, cfree) | 1227 | weak_alias (free, cfree) |
| @@ -1255,7 +1232,6 @@ cfree (void *ptr) | |||
| 1255 | free (ptr); | 1232 | free (ptr); |
| 1256 | } | 1233 | } |
| 1257 | #endif | 1234 | #endif |
| 1258 | #endif | ||
| 1259 | /* Change the size of a block allocated by `malloc'. | 1235 | /* Change the size of a block allocated by `malloc'. |
| 1260 | Copyright (C) 1990-1993, 1995-1996, 1999, 2002-2007, 2013-2025 Free | 1236 | Copyright (C) 1990-1993, 1995-1996, 1999, 2002-2007, 2013-2025 Free |
| 1261 | Software Foundation, Inc. | 1237 | Software Foundation, Inc. |
| @@ -1495,12 +1471,6 @@ extern void *__sbrk (ptrdiff_t increment); | |||
| 1495 | static void * | 1471 | static void * |
| 1496 | gdefault_morecore (ptrdiff_t increment) | 1472 | gdefault_morecore (ptrdiff_t increment) |
| 1497 | { | 1473 | { |
| 1498 | #ifdef HYBRID_MALLOC | ||
| 1499 | if (!definitely_will_not_unexec_p ()) | ||
| 1500 | { | ||
| 1501 | return bss_sbrk (increment); | ||
| 1502 | } | ||
| 1503 | #endif | ||
| 1504 | #ifdef HAVE_SBRK | 1474 | #ifdef HAVE_SBRK |
| 1505 | void *result = (void *) __sbrk (increment); | 1475 | void *result = (void *) __sbrk (increment); |
| 1506 | if (result != (void *) -1) | 1476 | if (result != (void *) -1) |
| @@ -1610,7 +1580,6 @@ aligned_alloc (size_t alignment, size_t size) | |||
| 1610 | } | 1580 | } |
| 1611 | 1581 | ||
| 1612 | /* Note that memalign and posix_memalign are not used in Emacs. */ | 1582 | /* Note that memalign and posix_memalign are not used in Emacs. */ |
| 1613 | #ifndef HYBRID_MALLOC | ||
| 1614 | /* An obsolete alias for aligned_alloc, for any old libraries that use | 1583 | /* An obsolete alias for aligned_alloc, for any old libraries that use |
| 1615 | this alias. */ | 1584 | this alias. */ |
| 1616 | 1585 | ||
| @@ -1620,8 +1589,6 @@ memalign (size_t alignment, size_t size) | |||
| 1620 | return aligned_alloc (alignment, size); | 1589 | return aligned_alloc (alignment, size); |
| 1621 | } | 1590 | } |
| 1622 | 1591 | ||
| 1623 | /* If HYBRID_MALLOC is defined, we may want to use the system | ||
| 1624 | posix_memalign below. */ | ||
| 1625 | int | 1592 | int |
| 1626 | posix_memalign (void **memptr, size_t alignment, size_t size) | 1593 | posix_memalign (void **memptr, size_t alignment, size_t size) |
| 1627 | { | 1594 | { |
| @@ -1640,7 +1607,6 @@ posix_memalign (void **memptr, size_t alignment, size_t size) | |||
| 1640 | 1607 | ||
| 1641 | return 0; | 1608 | return 0; |
| 1642 | } | 1609 | } |
| 1643 | #endif | ||
| 1644 | 1610 | ||
| 1645 | /* Allocate memory on a page boundary. | 1611 | /* Allocate memory on a page boundary. |
| 1646 | Copyright (C) 1990-1993, 1995-1996, 1999, 2002-2007, 2013-2025 Free | 1612 | Copyright (C) 1990-1993, 1995-1996, 1999, 2002-2007, 2013-2025 Free |
| @@ -1662,18 +1628,16 @@ License along with this library. If not, see <https://www.gnu.org/licenses/>. | |||
| 1662 | The author may be reached (Email) at the address mike@ai.mit.edu, | 1628 | The author may be reached (Email) at the address mike@ai.mit.edu, |
| 1663 | or (US mail) as Mike Haertel c/o Free Software Foundation. */ | 1629 | or (US mail) as Mike Haertel c/o Free Software Foundation. */ |
| 1664 | 1630 | ||
| 1665 | #ifndef HYBRID_MALLOC | 1631 | #ifndef HAVE_MALLOC_H |
| 1666 | |||
| 1667 | # ifndef HAVE_MALLOC_H | ||
| 1668 | /* Allocate SIZE bytes on a page boundary. */ | 1632 | /* Allocate SIZE bytes on a page boundary. */ |
| 1669 | extern void *valloc (size_t); | 1633 | extern void *valloc (size_t); |
| 1670 | # endif | 1634 | #endif |
| 1671 | 1635 | ||
| 1672 | # if defined _SC_PAGESIZE || !defined HAVE_GETPAGESIZE | 1636 | #if defined _SC_PAGESIZE || !defined HAVE_GETPAGESIZE |
| 1673 | # include "getpagesize.h" | 1637 | # include "getpagesize.h" |
| 1674 | # elif !defined getpagesize | 1638 | #elif !defined getpagesize |
| 1675 | extern int getpagesize (void); | 1639 | extern int getpagesize (void); |
| 1676 | # endif | 1640 | #endif |
| 1677 | 1641 | ||
| 1678 | static size_t pagesize; | 1642 | static size_t pagesize; |
| 1679 | 1643 | ||
| @@ -1685,7 +1649,6 @@ valloc (size_t size) | |||
| 1685 | 1649 | ||
| 1686 | return aligned_alloc (pagesize, size); | 1650 | return aligned_alloc (pagesize, size); |
| 1687 | } | 1651 | } |
| 1688 | #endif /* HYBRID_MALLOC */ | ||
| 1689 | 1652 | ||
| 1690 | #undef malloc | 1653 | #undef malloc |
| 1691 | #undef realloc | 1654 | #undef realloc |
| @@ -1693,116 +1656,6 @@ valloc (size_t size) | |||
| 1693 | #undef aligned_alloc | 1656 | #undef aligned_alloc |
| 1694 | #undef free | 1657 | #undef free |
| 1695 | 1658 | ||
| 1696 | #ifdef HYBRID_MALLOC | ||
| 1697 | |||
| 1698 | /* Assuming PTR was allocated via the hybrid malloc, return true if | ||
| 1699 | PTR was allocated via gmalloc, not the system malloc. Also, return | ||
| 1700 | true if _heaplimit is zero; this can happen temporarily when | ||
| 1701 | gmalloc calls itself for internal use, and in that case PTR is | ||
| 1702 | already known to be allocated via gmalloc. */ | ||
| 1703 | |||
| 1704 | static bool | ||
| 1705 | allocated_via_gmalloc (void *ptr) | ||
| 1706 | { | ||
| 1707 | if (!__malloc_initialized) | ||
| 1708 | return false; | ||
| 1709 | size_t block = BLOCK (ptr); | ||
| 1710 | size_t blockmax = _heaplimit - 1; | ||
| 1711 | return block <= blockmax && _heapinfo[block].busy.type != 0; | ||
| 1712 | } | ||
| 1713 | |||
| 1714 | /* See the comments near the beginning of this file for explanations | ||
| 1715 | of the following functions. */ | ||
| 1716 | |||
| 1717 | void * | ||
| 1718 | hybrid_malloc (size_t size) | ||
| 1719 | { | ||
| 1720 | if (definitely_will_not_unexec_p ()) | ||
| 1721 | return malloc (size); | ||
| 1722 | return gmalloc (size); | ||
| 1723 | } | ||
| 1724 | |||
| 1725 | void * | ||
| 1726 | hybrid_calloc (size_t nmemb, size_t size) | ||
| 1727 | { | ||
| 1728 | if (definitely_will_not_unexec_p ()) | ||
| 1729 | return calloc (nmemb, size); | ||
| 1730 | return gcalloc (nmemb, size); | ||
| 1731 | } | ||
| 1732 | |||
| 1733 | static void | ||
| 1734 | hybrid_free_1 (void *ptr) | ||
| 1735 | { | ||
| 1736 | if (allocated_via_gmalloc (ptr)) | ||
| 1737 | gfree (ptr); | ||
| 1738 | else | ||
| 1739 | free (ptr); | ||
| 1740 | } | ||
| 1741 | |||
| 1742 | void | ||
| 1743 | hybrid_free (void *ptr) | ||
| 1744 | { | ||
| 1745 | /* Stolen from Gnulib, to make sure we preserve errno. */ | ||
| 1746 | #if defined __GNUC__ && !defined __clang__ | ||
| 1747 | int err[2]; | ||
| 1748 | err[0] = errno; | ||
| 1749 | err[1] = errno; | ||
| 1750 | errno = 0; | ||
| 1751 | hybrid_free_1 (ptr); | ||
| 1752 | errno = err[errno == 0]; | ||
| 1753 | #else | ||
| 1754 | int err = errno; | ||
| 1755 | hybrid_free_1 (ptr); | ||
| 1756 | errno = err; | ||
| 1757 | #endif | ||
| 1758 | } | ||
| 1759 | |||
| 1760 | #if defined HAVE_ALIGNED_ALLOC || defined HAVE_POSIX_MEMALIGN | ||
| 1761 | void * | ||
| 1762 | hybrid_aligned_alloc (size_t alignment, size_t size) | ||
| 1763 | { | ||
| 1764 | if (!definitely_will_not_unexec_p ()) | ||
| 1765 | return galigned_alloc (alignment, size); | ||
| 1766 | /* The following is copied from alloc.c */ | ||
| 1767 | #ifdef HAVE_ALIGNED_ALLOC | ||
| 1768 | return aligned_alloc (alignment, size); | ||
| 1769 | #else /* HAVE_POSIX_MEMALIGN */ | ||
| 1770 | void *p; | ||
| 1771 | return posix_memalign (&p, alignment, size) == 0 ? p : 0; | ||
| 1772 | #endif | ||
| 1773 | } | ||
| 1774 | #endif | ||
| 1775 | |||
| 1776 | void * | ||
| 1777 | hybrid_realloc (void *ptr, size_t size) | ||
| 1778 | { | ||
| 1779 | void *result; | ||
| 1780 | int type; | ||
| 1781 | size_t block, oldsize; | ||
| 1782 | |||
| 1783 | if (!ptr) | ||
| 1784 | return hybrid_malloc (size); | ||
| 1785 | if (!allocated_via_gmalloc (ptr)) | ||
| 1786 | return realloc (ptr, size); | ||
| 1787 | if (!definitely_will_not_unexec_p ()) | ||
| 1788 | return grealloc (ptr, size); | ||
| 1789 | |||
| 1790 | /* The dumped emacs is trying to realloc storage allocated before | ||
| 1791 | dumping via gmalloc. Allocate new space and copy the data. Do | ||
| 1792 | not bother with gfree (ptr), as that would just waste time. */ | ||
| 1793 | block = BLOCK (ptr); | ||
| 1794 | type = _heapinfo[block].busy.type; | ||
| 1795 | oldsize = | ||
| 1796 | type < 0 ? _heapinfo[block].busy.info.size * BLOCKSIZE | ||
| 1797 | : (size_t) 1 << type; | ||
| 1798 | result = malloc (size); | ||
| 1799 | if (result) | ||
| 1800 | return memcpy (result, ptr, min (oldsize, size)); | ||
| 1801 | return result; | ||
| 1802 | } | ||
| 1803 | |||
| 1804 | #else /* ! HYBRID_MALLOC */ | ||
| 1805 | |||
| 1806 | void * | 1659 | void * |
| 1807 | malloc (size_t size) | 1660 | malloc (size_t size) |
| 1808 | { | 1661 | { |
| @@ -1833,8 +1686,6 @@ realloc (void *ptr, size_t size) | |||
| 1833 | return grealloc (ptr, size); | 1686 | return grealloc (ptr, size); |
| 1834 | } | 1687 | } |
| 1835 | 1688 | ||
| 1836 | #endif /* HYBRID_MALLOC */ | ||
| 1837 | |||
| 1838 | #ifdef GC_MCHECK | 1689 | #ifdef GC_MCHECK |
| 1839 | 1690 | ||
| 1840 | /* Standard debugging hooks for `malloc'. | 1691 | /* Standard debugging hooks for `malloc'. |