diff options
| author | Paul Eggert | 2025-02-01 22:20:04 -0800 |
|---|---|---|
| committer | Paul Eggert | 2025-02-01 22:55:30 -0800 |
| commit | 7ac05c33b182ce3f3bd26b730a9c87ad4ec8cdd5 (patch) | |
| tree | 4463ea66ef8bc89d6541fbea70dd4c643e113ff4 /src/alloc.c | |
| parent | 354b2907fce6a4ce9f5e8ea0faf69974e21e749b (diff) | |
| download | emacs-7ac05c33b182ce3f3bd26b730a9c87ad4ec8cdd5.tar.gz emacs-7ac05c33b182ce3f3bd26b730a9c87ad4ec8cdd5.zip | |
Improve malloc Lisp alignment commentary
Prompted by a private email from Pip Cet.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/src/alloc.c b/src/alloc.c index c39459e1f2e..7fa05e54202 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -608,23 +608,28 @@ buffer_memory_full (ptrdiff_t nbytes) | |||
| 608 | #define COMMON_MULTIPLE(a, b) \ | 608 | #define COMMON_MULTIPLE(a, b) \ |
| 609 | ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b)) | 609 | ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b)) |
| 610 | 610 | ||
| 611 | /* Alignment needed for memory blocks that are allocated via malloc | 611 | /* Alignment needed for memory blocks managed by the garbage collector. */ |
| 612 | and that contain Lisp objects. */ | ||
| 613 | enum { LISP_ALIGNMENT = alignof (union { union emacs_align_type x; | 612 | enum { LISP_ALIGNMENT = alignof (union { union emacs_align_type x; |
| 614 | GCALIGNED_UNION_MEMBER }) }; | 613 | GCALIGNED_UNION_MEMBER }) }; |
| 615 | static_assert (LISP_ALIGNMENT % GCALIGNMENT == 0); | 614 | static_assert (LISP_ALIGNMENT % GCALIGNMENT == 0); |
| 616 | 615 | ||
| 617 | /* Verify Emacs's assumption that malloc (N) returns storage suitably | 616 | /* Emacs assumes that malloc (N) returns storage suitably aligned for |
| 618 | aligned for Lisp objects whenever N is a multiple of LISP_ALIGNMENT. | 617 | any Lisp object whenever N is a multiple of LISP_ALIGNMENT. |
| 619 | This assumption holds for current Emacs porting targets; | 618 | This Emacs assumption holds for current Emacs porting targets. |
| 620 | if the assumption fails on a new platform, this check should | 619 | |
| 621 | cause compilation to fail and some porting work will need to be done. | 620 | On all current Emacs porting targets, it also happens that |
| 622 | 621 | alignof (max_align_t) is a multiple of LISP_ALIGNMENT. | |
| 623 | In practice the assumption holds when alignof (max_align_t) is also a | 622 | Check this with a static_assert. If the static_assert fails on an |
| 624 | multiple of LISP_ALIGNMENT. This works even for buggy platforms | 623 | unusual platform, Emacs may well not work, so inspect this module's |
| 625 | like MinGW circa 2020, where alignof (max_align_t) is 16 even though | 624 | source code carefully with the unusual platform's quirks in mind. |
| 626 | the malloc alignment is only 8, and where Emacs still works because | 625 | |
| 627 | it never does anything that requires an alignment of 16. */ | 626 | In practice the static_assert works even for buggy platforms where |
| 627 | malloc can yield an unaligned address if given a large but unaligned | ||
| 628 | size; Emacs avoids the bug because it aligns the size before calling | ||
| 629 | malloc. The static_assert also works for MinGW circa 2020, where | ||
| 630 | alignof (max_align_t) is 16 even though the malloc alignment is only 8; | ||
| 631 | Emacs avoids the bug because on this platform it never does anything | ||
| 632 | that requires an alignment of 16. */ | ||
| 628 | enum { MALLOC_IS_LISP_ALIGNED = alignof (max_align_t) % LISP_ALIGNMENT == 0 }; | 633 | enum { MALLOC_IS_LISP_ALIGNED = alignof (max_align_t) % LISP_ALIGNMENT == 0 }; |
| 629 | static_assert (MALLOC_IS_LISP_ALIGNED); | 634 | static_assert (MALLOC_IS_LISP_ALIGNED); |
| 630 | 635 | ||
| @@ -900,7 +905,8 @@ void *lisp_malloc_loser EXTERNALLY_VISIBLE; | |||
| 900 | #endif | 905 | #endif |
| 901 | 906 | ||
| 902 | /* Allocate memory for Lisp data. | 907 | /* Allocate memory for Lisp data. |
| 903 | NBYTES is the number of bytes to allocate; it must be Lisp-aligned. | 908 | NBYTES is the number of bytes to allocate; |
| 909 | it must be a multiple of LISP_ALIGNMENT. | ||
| 904 | If CLEARIT, arrange for the allocated memory to be cleared | 910 | If CLEARIT, arrange for the allocated memory to be cleared |
| 905 | by using calloc, which can be faster than malloc+memset. | 911 | by using calloc, which can be faster than malloc+memset. |
| 906 | TYPE describes the intended use of the allocated memory block | 912 | TYPE describes the intended use of the allocated memory block |