diff options
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 55 |
1 files changed, 29 insertions, 26 deletions
diff --git a/src/alloc.c b/src/alloc.c index d5a6d9167ea..602282e5704 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -112,9 +112,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 112 | adds sizeof (size_t) to SIZE for internal overhead, and then rounds | 112 | adds sizeof (size_t) to SIZE for internal overhead, and then rounds |
| 113 | up to a multiple of MALLOC_ALIGNMENT. Emacs can improve | 113 | up to a multiple of MALLOC_ALIGNMENT. Emacs can improve |
| 114 | performance a bit on GNU platforms by arranging for the resulting | 114 | performance a bit on GNU platforms by arranging for the resulting |
| 115 | size to be a power of two. This heuristic is good for glibc 2.0 | 115 | size to be a power of two. This heuristic is good for glibc 2.26 |
| 116 | (1997) through at least glibc 2.31 (2020), and does not affect | 116 | (2017) and later, and does not affect correctness on other |
| 117 | correctness on other platforms. */ | 117 | platforms. */ |
| 118 | 118 | ||
| 119 | #define MALLOC_SIZE_NEAR(n) \ | 119 | #define MALLOC_SIZE_NEAR(n) \ |
| 120 | (ROUNDUP (max (n, sizeof (size_t)), MALLOC_ALIGNMENT) - sizeof (size_t)) | 120 | (ROUNDUP (max (n, sizeof (size_t)), MALLOC_ALIGNMENT) - sizeof (size_t)) |
| @@ -655,28 +655,30 @@ buffer_memory_full (ptrdiff_t nbytes) | |||
| 655 | #define COMMON_MULTIPLE(a, b) \ | 655 | #define COMMON_MULTIPLE(a, b) \ |
| 656 | ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b)) | 656 | ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b)) |
| 657 | 657 | ||
| 658 | /* LISP_ALIGNMENT is the alignment of Lisp objects. It must be at | 658 | /* A lower bound on the alignment of malloc. For better performance |
| 659 | least GCALIGNMENT so that pointers can be tagged. It also must be | 659 | this bound should be tighter. For glibc 2.26 and later a tighter |
| 660 | at least as strict as the alignment of all the C types used to | 660 | bound is known. */ |
| 661 | implement Lisp objects; since pseudovectors can contain any C type, | 661 | #if 2 < __GLIBC__ + (26 <= __GLIBC_MINOR__) |
| 662 | this is max_align_t. On recent GNU/Linux x86 and x86-64 this can | 662 | enum { MALLOC_ALIGNMENT_BOUND = MALLOC_ALIGNMENT }; |
| 663 | often waste up to 8 bytes, since alignof (max_align_t) is 16 but | 663 | #else |
| 664 | typical vectors need only an alignment of 8. Although shrinking | 664 | /* A bound known to work for all Emacs porting targets. Tightening |
| 665 | the alignment to 8 would save memory, it cost a 20% hit to Emacs | 665 | this looser bound by using max_align_t instead of long long int |
| 666 | CPU performance on Fedora 28 x86-64 when compiled with gcc -m32. */ | 666 | would break buggy malloc implementations like MinGW circa 2020. */ |
| 667 | enum { LISP_ALIGNMENT = alignof (union { max_align_t x; | 667 | enum { MALLOC_ALIGNMENT_BOUND = alignof (long long int) }; |
| 668 | GCALIGNED_UNION_MEMBER }) }; | 668 | #endif |
| 669 | verify (LISP_ALIGNMENT % GCALIGNMENT == 0); | 669 | |
| 670 | /* A lower bound on the alignment of Lisp objects. All Lisp objects | ||
| 671 | must have an address that is a multiple of LISP_ALIGNMENT; | ||
| 672 | otherwise maybe_lisp_pointer can issue false negatives, causing crashes. | ||
| 673 | It's good to make this bound tight: if Lisp objects are always | ||
| 674 | aligned more strictly than LISP_ALIGNMENT, maybe_lisp_pointer will | ||
| 675 | issue more false positives, hurting performance. */ | ||
| 676 | enum { LISP_ALIGNMENT = max (max (GCALIGNMENT, MALLOC_ALIGNMENT_BOUND), | ||
| 677 | alignof (union emacs_align_type)) }; | ||
| 670 | 678 | ||
| 671 | /* True if malloc (N) is known to return storage suitably aligned for | 679 | /* True if malloc (N) is known to return storage suitably aligned for |
| 672 | Lisp objects whenever N is a multiple of LISP_ALIGNMENT. In | 680 | Lisp objects whenever N is a multiple of LISP_ALIGNMENT. */ |
| 673 | practice this is true whenever alignof (max_align_t) is also a | 681 | enum { MALLOC_IS_LISP_ALIGNED = MALLOC_ALIGNMENT_BOUND % LISP_ALIGNMENT == 0 }; |
| 674 | multiple of LISP_ALIGNMENT. This works even for x86, where some | ||
| 675 | platform combinations (e.g., GCC 7 and later, glibc 2.25 and | ||
| 676 | earlier) have bugs where alignof (max_align_t) is 16 even though | ||
| 677 | the malloc alignment is only 8, and where Emacs still works because | ||
| 678 | it never does anything that requires an alignment of 16. */ | ||
| 679 | enum { MALLOC_IS_LISP_ALIGNED = alignof (max_align_t) % LISP_ALIGNMENT == 0 }; | ||
| 680 | 682 | ||
| 681 | /* If compiled with XMALLOC_BLOCK_INPUT_CHECK, define a symbol | 683 | /* If compiled with XMALLOC_BLOCK_INPUT_CHECK, define a symbol |
| 682 | BLOCK_INPUT_IN_MEMORY_ALLOCATORS that is visible to the debugger. | 684 | BLOCK_INPUT_IN_MEMORY_ALLOCATORS that is visible to the debugger. |
| @@ -4885,9 +4887,10 @@ test_setjmp (void) | |||
| 4885 | as a stack scan limit. */ | 4887 | as a stack scan limit. */ |
| 4886 | typedef union | 4888 | typedef union |
| 4887 | { | 4889 | { |
| 4888 | /* Align the stack top properly. Even if !HAVE___BUILTIN_UNWIND_INIT, | 4890 | /* Make sure stack_top and m_stack_bottom are properly aligned as GC |
| 4889 | jmp_buf may not be aligned enough on darwin-ppc64. */ | 4891 | expects. */ |
| 4890 | max_align_t o; | 4892 | Lisp_Object o; |
| 4893 | void *p; | ||
| 4891 | #ifndef HAVE___BUILTIN_UNWIND_INIT | 4894 | #ifndef HAVE___BUILTIN_UNWIND_INIT |
| 4892 | sys_jmp_buf j; | 4895 | sys_jmp_buf j; |
| 4893 | char c; | 4896 | char c; |